summaryrefslogtreecommitdiff
path: root/odb/relational/pgsql
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational/pgsql')
-rw-r--r--odb/relational/pgsql/common.cxx351
-rw-r--r--odb/relational/pgsql/common.hxx159
-rw-r--r--odb/relational/pgsql/context.cxx786
-rw-r--r--odb/relational/pgsql/context.hxx192
-rw-r--r--odb/relational/pgsql/header.cxx271
-rw-r--r--odb/relational/pgsql/inline.cxx42
-rw-r--r--odb/relational/pgsql/model.cxx101
-rw-r--r--odb/relational/pgsql/schema.cxx266
-rw-r--r--odb/relational/pgsql/source.cxx1140
9 files changed, 0 insertions, 3308 deletions
diff --git a/odb/relational/pgsql/common.cxx b/odb/relational/pgsql/common.cxx
deleted file mode 100644
index 6a59954..0000000
--- a/odb/relational/pgsql/common.cxx
+++ /dev/null
@@ -1,351 +0,0 @@
-// file : odb/relational/pgsql/common.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <cassert>
-
-#include <odb/relational/pgsql/common.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace pgsql
- {
- //
- // member_base
- //
-
- sql_type const& member_base::
- member_sql_type (semantics::data_member& m)
- {
- return parse_sql_type (column_type (m, key_prefix_), m);
- }
-
- void member_base::
- traverse_simple (member_info& mi)
- {
- switch (mi.st->type)
- {
- // Integral types.
- //
- case sql_type::BOOLEAN:
- case sql_type::SMALLINT:
- case sql_type::INTEGER:
- case sql_type::BIGINT:
- {
- traverse_integer (mi);
- break;
- }
-
- // Float types.
- //
- case sql_type::REAL:
- case sql_type::DOUBLE:
- {
- traverse_float (mi);
- break;
- }
- case sql_type::NUMERIC:
- {
- traverse_numeric (mi);
- break;
- }
-
- // Data-time types.
- //
- case sql_type::DATE:
- case sql_type::TIME:
- case sql_type::TIMESTAMP:
- {
- traverse_date_time (mi);
- break;
- }
-
- // String and binary types.
- //
- case sql_type::CHAR:
- case sql_type::VARCHAR:
- case sql_type::TEXT:
- case sql_type::BYTEA:
- {
- traverse_string (mi);
- break;
- }
- case sql_type::BIT:
- {
- traverse_bit (mi);
- break;
- }
- case sql_type::VARBIT:
- {
- traverse_varbit (mi);
- break;
- }
- // Other types.
- //
- case sql_type::UUID:
- {
- traverse_uuid (mi);
- break;
- }
- case sql_type::invalid:
- {
- assert (false);
- break;
- }
- }
- }
-
- //
- // member_image_type
- //
-
- namespace
- {
- const char* integer_types[] =
- {
- "bool",
- "short",
- "int",
- "long long"
- };
-
- const char* float_types[] =
- {
- "float",
- "double"
- };
-
- const char* date_time_types[] =
- {
- "int",
- "long long",
- "long long"
- };
- }
-
- member_image_type::
- member_image_type (base const& x)
- : member_base::base (x), // virtual base
- base (x)
- {
- }
-
- member_image_type::
- member_image_type ()
- : relational::member_base (0, 0, string (), string ()) {}
-
- member_image_type::
- member_image_type (semantics::type* type,
- const custom_cxx_type* ct,
- string const& fq_type,
- string const& key_prefix)
- : relational::member_base (type, ct, fq_type, key_prefix) {}
-
- string member_image_type::
- image_type (semantics::data_member& m)
- {
- type_.clear ();
- member_base::traverse (m, true);
- return type_;
- }
-
- void member_image_type::
- traverse_composite (member_info& mi)
- {
- type_ = "composite_value_traits< " + mi.fq_type () +
- ", id_pgsql >::image_type";
- }
-
- void member_image_type::
- traverse_integer (member_info& mi)
- {
- type_ += integer_types[mi.st->type - sql_type::BOOLEAN];
- }
-
- void member_image_type::
- traverse_float (member_info& mi)
- {
- type_ = float_types[mi.st->type - sql_type::REAL];
- }
-
- void member_image_type::
- traverse_numeric (member_info&)
- {
- type_ = "details::buffer";
- }
-
- void member_image_type::
- traverse_date_time (member_info& mi)
- {
- type_ = date_time_types[mi.st->type - sql_type::DATE];
- }
-
- void member_image_type::
- traverse_string (member_info&)
- {
- type_ = "details::buffer";
- }
-
- void member_image_type::
- traverse_bit (member_info&)
- {
- type_ = "unsigned char*";
- }
-
- void member_image_type::
- traverse_varbit (member_info&)
- {
- type_ = "details::ubuffer";
- }
-
- void member_image_type::
- traverse_uuid (member_info&)
- {
- type_ = "unsigned char*";
- }
-
- entry<member_image_type> member_image_type_;
-
- //
- // member_database_type
- //
-
- namespace
- {
- const char* integer_database_id[] =
- {
- "id_boolean",
- "id_smallint",
- "id_integer",
- "id_bigint"
- };
-
- const char* float_database_id[] =
- {
- "id_real",
- "id_double"
- };
-
- const char* date_time_database_id[] =
- {
- "id_date",
- "id_time",
- "id_timestamp"
- };
-
- const char* char_bin_database_id[] =
- {
- "id_string", // CHAR
- "id_string", // VARCHAR
- "id_string", // TEXT,
- "id_bytea" // BYTEA
- };
- }
-
- member_database_type_id::
- member_database_type_id (base const& x)
- : member_base::base (x), // virtual base
- base (x) {}
-
- member_database_type_id::
- member_database_type_id ()
- : member_base::base (0, 0, string (), string ()), // virtual base
- base (0, 0, string (), string ()) {}
-
- member_database_type_id::
- member_database_type_id (semantics::type* type,
- const custom_cxx_type* ct,
- string const& fq_type,
- string const& key_prefix)
- : member_base::base (type, ct, fq_type, key_prefix), // virtual base
- base (type, ct, fq_type, key_prefix) {}
-
- string member_database_type_id::
- database_type_id (type& m)
- {
- type_id_.clear ();
- member_base::traverse (m, true);
- return type_id_;
- }
-
- void member_database_type_id::
- traverse_composite (member_info&)
- {
- assert (false);
- }
-
- void member_database_type_id::
- traverse_integer (member_info& mi)
- {
- type_id_ = string ("pgsql::") +
- integer_database_id[mi.st->type - sql_type::BOOLEAN];
- }
-
- void member_database_type_id::
- traverse_float (member_info& mi)
- {
- type_id_ = string ("pgsql::") +
- float_database_id[mi.st->type - sql_type::REAL];
- }
-
- void member_database_type_id::
- traverse_numeric (member_info&)
- {
- type_id_ = "pgsql::id_numeric";
- }
-
- void member_database_type_id::
- traverse_date_time (member_info& mi)
- {
- type_id_ = string ("pgsql::") +
- date_time_database_id[mi.st->type - sql_type::DATE];
- }
-
- void member_database_type_id::
- traverse_string (member_info& mi)
- {
- type_id_ = string ("pgsql::") +
- char_bin_database_id[mi.st->type - sql_type::CHAR];
- }
-
- void member_database_type_id::
- traverse_bit (member_info&)
- {
- type_id_ = "pgsql::id_bit";
- }
-
- void member_database_type_id::
- traverse_varbit (member_info&)
- {
- type_id_ = "pgsql::id_varbit";
- }
-
- void member_database_type_id::
- traverse_uuid (member_info&)
- {
- type_id_ = "pgsql::id_uuid";
- }
-
- entry<member_database_type_id> member_database_type_id_;
-
- //
- // query_columns
- //
-
- struct query_columns: relational::query_columns, context
- {
- query_columns (base const& x): base_impl (x) {}
-
- virtual string
- database_type_id (semantics::data_member& m)
- {
- return member_database_type_id_.database_type_id (m);
- }
-
- private:
- member_database_type_id member_database_type_id_;
- };
- entry<query_columns> query_columns_;
- }
-}
diff --git a/odb/relational/pgsql/common.hxx b/odb/relational/pgsql/common.hxx
deleted file mode 100644
index 1d383bf..0000000
--- a/odb/relational/pgsql/common.hxx
+++ /dev/null
@@ -1,159 +0,0 @@
-// file : odb/relational/pgsql/common.hxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_RELATIONAL_PGSQL_COMMON_HXX
-#define ODB_RELATIONAL_PGSQL_COMMON_HXX
-
-#include <odb/relational/common.hxx>
-#include <odb/relational/pgsql/context.hxx>
-
-namespace relational
-{
- namespace pgsql
- {
- struct member_base: virtual relational::member_base_impl<sql_type>, context
- {
- member_base (base const& x): base (x), base_impl (x) {}
-
- // This c-tor is for the direct use inside the pgsql namespace.
- // If you do use this c-tor, you should also explicitly call
- // relational::member_base (aka base).
- //
- member_base () {}
-
- virtual sql_type const&
- member_sql_type (semantics::data_member&);
-
- virtual void
- traverse_simple (member_info&);
-
- virtual void
- traverse_integer (member_info&)
- {
- }
-
- virtual void
- traverse_float (member_info&)
- {
- }
-
- virtual void
- traverse_numeric (member_info&)
- {
- }
-
- virtual void
- traverse_date_time (member_info&)
- {
- }
-
- virtual void
- traverse_string (member_info&)
- {
- }
-
- virtual void
- traverse_bit (member_info&)
- {
- }
-
- virtual void
- traverse_varbit (member_info&)
- {
- }
-
- virtual void
- traverse_uuid (member_info&)
- {
- }
- };
-
- struct member_image_type: relational::member_image_type,
- member_base
- {
- member_image_type (base const&);
- member_image_type ();
- member_image_type (semantics::type* type,
- const custom_cxx_type*,
- string const& fq_type = string (),
- string const& key_prefix = string ());
- virtual string
- image_type (semantics::data_member&);
-
- virtual void
- traverse_composite (member_info&);
-
- virtual void
- traverse_integer (member_info&);
-
- virtual void
- traverse_float (member_info&);
-
- virtual void
- traverse_numeric (member_info&);
-
- virtual void
- traverse_date_time (member_info&);
-
- virtual void
- traverse_string (member_info&);
-
- virtual void
- traverse_bit (member_info&);
-
- virtual void
- traverse_varbit (member_info&);
-
- virtual void
- traverse_uuid (member_info&);
-
- private:
- string type_;
- };
-
- struct member_database_type_id: relational::member_database_type_id,
- member_base
- {
- member_database_type_id (base const&);
- member_database_type_id ();
- member_database_type_id (semantics::type* type,
- const custom_cxx_type*,
- string const& fq_type = string (),
- string const& key_prefix = string ());
-
- virtual string
- database_type_id (type&);
-
- virtual void
- traverse_composite (member_info&);
-
- virtual void
- traverse_integer (member_info&);
-
- virtual void
- traverse_float (member_info&);
-
- virtual void
- traverse_numeric (member_info&);
-
- virtual void
- traverse_date_time (member_info&);
-
- virtual void
- traverse_string (member_info&);
-
- virtual void
- traverse_bit (member_info&);
-
- virtual void
- traverse_varbit (member_info&);
-
- virtual void
- traverse_uuid (member_info&);
-
- private:
- string type_id_;
- };
- }
-}
-#endif // ODB_RELATIONAL_PGSQL_COMMON_HXX
diff --git a/odb/relational/pgsql/context.cxx b/odb/relational/pgsql/context.cxx
deleted file mode 100644
index a9f34dd..0000000
--- a/odb/relational/pgsql/context.cxx
+++ /dev/null
@@ -1,786 +0,0 @@
-// file : odb/relational/pgsql/context.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <cassert>
-#include <sstream>
-
-#include <odb/diagnostics.hxx>
-
-#include <odb/sql-token.hxx>
-#include <odb/sql-lexer.hxx>
-
-#include <odb/relational/pgsql/context.hxx>
-#include <odb/relational/pgsql/common.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace pgsql
- {
- namespace
- {
- struct type_map_entry
- {
- char const* const cxx_type;
- char const* const db_type;
- char const* const db_id_type;
- bool const null;
- };
-
- type_map_entry type_map[] =
- {
- {"bool", "BOOLEAN", 0, false},
-
- {"char", "CHAR(1)", 0, false},
- {"signed char", "SMALLINT", 0, false},
- {"unsigned char", "SMALLINT", 0, false},
-
- {"short int", "SMALLINT", 0, false},
- {"short unsigned int", "SMALLINT", 0, false},
-
- {"int", "INTEGER", 0, false},
- {"unsigned int", "INTEGER", 0, false},
-
- {"long int", "BIGINT", 0, false},
- {"long unsigned int", "BIGINT", 0, false},
-
- {"long long int", "BIGINT", 0, false},
- {"long long unsigned int", "BIGINT", 0, false},
-
- {"float", "REAL", 0, false},
- {"double", "DOUBLE PRECISION", 0, false},
-
- {"::std::string", "TEXT", 0, false},
-
- {"::size_t", "BIGINT", 0, false},
- {"::std::size_t", "BIGINT", 0, false}
- };
- }
-
- context* context::current_;
-
- context::
- ~context ()
- {
- if (current_ == this)
- current_ = 0;
- }
-
- context::
- context (ostream& os,
- semantics::unit& u,
- options_type const& ops,
- features_type& f,
- sema_rel::model* m)
- : root_context (os, u, ops, f, data_ptr (new (shared) data (os))),
- base_context (static_cast<data*> (root_context::data_.get ()), m),
- data_ (static_cast<data*> (base_context::data_))
- {
- assert (current_ == 0);
- current_ = this;
-
- generate_grow = true;
- need_alias_as = true;
- insert_send_auto_id = false;
- delay_freeing_statement_result = false;
- need_image_clone = false;
- generate_bulk = false;
- global_index = true;
- global_fkey = false;
- data_->bind_vector_ = "pgsql::bind*";
- data_->truncated_vector_ = "bool*";
-
- // Populate the C++ type to DB type map.
- //
- for (size_t i (0); i < sizeof (type_map) / sizeof (type_map_entry); ++i)
- {
- type_map_entry const& e (type_map[i]);
-
- type_map_type::value_type v (
- e.cxx_type,
- db_type_type (
- e.db_type, e.db_id_type ? e.db_id_type : e.db_type, e.null));
-
- data_->type_map_.insert (v);
- }
- }
-
- context::
- context ()
- : data_ (current ().data_)
- {
- }
-
- namespace
- {
- struct has_grow: traversal::class_
- {
- has_grow (bool& r, user_section* s)
- : r_ (r), section_ (s)
- {
- *this >> inherits_ >> *this;
- }
-
- virtual void
- traverse (type& c)
- {
- // Ignore transient bases.
- //
- if (!(context::object (c) || context::composite (c)))
- return;
-
- if (section_ == 0 && c.count ("pgsql-grow"))
- r_ = c.get<bool> ("pgsql-grow");
- else
- {
- // r_ should be false.
- //
- inherits (c);
-
- if (!r_)
- names (c);
-
- if (section_ == 0)
- c.set ("pgsql-grow", r_);
- }
- }
-
- private:
- bool& r_;
- user_section* section_;
- traversal::inherits inherits_;
- };
-
- struct has_grow_member: member_base
- {
- has_grow_member (bool& r, user_section* section = 0)
- : relational::member_base (0, 0, string (), string (), section),
- r_ (r) {}
-
- has_grow_member (bool& r,
- user_section* section,
- semantics::type* t,
- const custom_cxx_type* ct,
- string const& key_prefix = string ())
- : relational::member_base (t, ct, string (), key_prefix, section),
- r_ (r) {}
-
- virtual bool
- pre (member_info& mi)
- {
- // If we have a key prefix (container), then it can't be in a
- // section (while mi.m can). The same for top-level -- if we got
- // called, then we shouldn't ignore it.
- //
- return !key_prefix_.empty () || top_level_ ||
- (section_ == 0 && !separate_load (mi.m)) ||
- (section_ != 0 && *section_ == section (mi.m));
- }
-
- virtual void
- traverse_composite (member_info& mi)
- {
- // By calling grow() instead of recursing, we reset any overrides.
- // We also don't pass section since they don't apply inside
- // composites.
- //
- r_ = r_ || context::grow (dynamic_cast<semantics::class_&> (mi.t));
- }
-
- virtual void
- traverse_numeric (member_info&)
- {
- r_ = true;
- }
-
- virtual void
- traverse_string (member_info&)
- {
- r_ = true;
- }
-
- virtual void
- traverse_varbit (member_info&)
- {
- r_ = true;
- }
-
- private:
- bool& r_;
- };
- }
-
- bool context::
- grow_impl (semantics::class_& c, user_section* section)
- {
- if (section == 0 && c.count ("pgsql-grow"))
- return c.get<bool> ("pgsql-grow");
-
- bool r (false);
- has_grow ct (r, section);
- has_grow_member mt (r, section);
- traversal::names names;
- ct >> names >> mt;
- ct.traverse (c);
- return r;
- }
-
- bool context::
- grow_impl (semantics::data_member& m)
- {
- bool r (false);
- has_grow_member mt (r);
- mt.traverse (m, true);
- return r;
- }
-
- bool context::
- grow_impl (semantics::data_member& m,
- semantics::type& t,
- const custom_cxx_type* ct,
- string const& kp)
- {
- bool r (false);
- has_grow_member mt (r, 0, &t, ct, kp);
- mt.traverse (m, true);
- return r;
- }
-
- string const& context::
- convert_expr (string const& sqlt, semantics::data_member& m, bool to)
- {
- sql_type const& t (parse_sql_type (sqlt, m));
- return to ? t.to : t.from;
- }
-
- string context::
- quote_id_impl (qname const& id) const
- {
- string r;
-
- bool f (true);
- for (qname::iterator i (id.begin ()); i < id.end (); ++i)
- {
- if (i->empty ())
- continue;
-
- // Warn if the name is greater than the (NAMEDATALEN - 1) limit,
- // which is 63 in the default PG build.
- //
- if (i->size () > 63)
- {
- cerr << "warning: SQL name '" << *i << "' is longer than "
- << "the default PostgreSQL name limit of 63 characters "
- << "and may be truncated" << endl;
-
- cerr << "info: consider shortening it using #pragma db "
- << "table/column/index or --*-regex options" << endl;
- }
-
- if (f)
- f = false;
- else
- r += '.';
-
- r += '"';
- r += *i;
- r += '"';
- }
-
- return r;
- }
-
- string context::
- statement_name (string const& type, string const& name, semantics::node& n)
- {
- // Put the type first so that in the case of truncation it
- // remains thus lowering the chance of a clash.
- //
- string r (type);
- r += '_';
- r += name;
-
- r = transform_name (r, sql_name_statement);
-
- // Warn if the name is greater than the (NAMEDATALEN - 1) limit,
- // which is 63 in the default PG build.
- //
- // Note that we have to do it in addition to the above since this
- // name doesn't go through quote_id().
- //
- if (r.size () > 63)
- {
- location const& l (n.location ());
-
- warn (l) << "prepared statement name '" << r << "' is longer than "
- << "the default PostgreSQL name limit of 63 characters "
- << "and may be truncated" << endl;
-
- info (l) << "consider shortening the corresponding namespace "
- << "name, class name, or data member name" << endl;
-
- info (l) << "or shortening the statement name itself using the "
- << "--statement-regex option" << endl;
- }
-
- return r;
- }
-
- string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- bool id,
- bool* null)
- {
- string r (base_context::database_type_impl (t, hint, id, null));
-
- if (!r.empty ())
- return r;
-
- using semantics::array;
-
- // char[N] mapping.
- //
- if (array* a = dynamic_cast<array*> (&t))
- {
- semantics::type& bt (a->base_type ());
- if (bt.is_a<semantics::fund_char> ())
- {
- unsigned long long n (a->size ());
-
- if (n == 0)
- return r;
- else if (n == 1)
- r = "CHAR(";
- else
- {
- r = "VARCHAR(";
- n--;
- }
-
- ostringstream ostr;
- ostr << n;
- r += ostr.str ();
- r += ')';
- }
- }
-
- return r;
- }
-
- //
- // SQL type parsing.
- //
-
- sql_type const& context::
- parse_sql_type (string const& t, semantics::data_member& m, bool custom)
- {
- // If this proves to be too expensive, we can maintain a cache of
- // parsed types across contexts.
- //
- data::sql_type_cache::iterator i (data_->sql_type_cache_.find (t));
-
- if (i != data_->sql_type_cache_.end ()
- && (custom ? i->second.custom_cached : i->second.straight_cached))
- {
- return (custom ? i->second.custom : i->second.straight);
- }
- else
- {
- try
- {
- sql_type st (
- parse_sql_type (
- t,
- custom ? &unit.get<custom_db_types> ("custom-db-types") : 0));
-
- if (custom)
- return data_->sql_type_cache_[t].cache_custom (st);
- else
- return data_->sql_type_cache_[t].cache_straight (st);
- }
- catch (invalid_sql_type const& e)
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: " << e.message () << endl;
-
- throw operation_failed ();
- }
- }
- }
-
- inline sql_type
- error (bool fail, string const& m)
- {
- if (!fail)
- return sql_type ();
- else
- throw context::invalid_sql_type (m);
- }
-
- sql_type context::
- parse_sql_type (string sqlt, custom_db_types const* ct)
- {
- try
- {
- sql_type r;
-
- // First run the type through the custom mapping, if requested.
- //
- if (ct != 0)
- {
- for (custom_db_types::const_iterator i (ct->begin ());
- i != ct->end (); ++i)
- {
- custom_db_type const& t (*i);
-
- if (t.type.match (sqlt))
- {
- r.to = t.type.replace (sqlt, t.to);
- r.from = t.type.replace (sqlt, t.from);
- sqlt = t.type.replace (sqlt, t.as);
- break;
- }
- }
- }
-
- sql_lexer l (sqlt);
-
- // While most type names use single identifier, there are
- // a couple of exceptions to this rule:
- //
- // BIT VARYING (VARBIT)
- // CHARACTER VARYING (VARRCHAR)
- // DOUBLE PRECISION (DOUBLE)
- // TIME WITH TIME ZONE (not currently supported)
- // TIMESTAMP WITH TIME ZONE (not currently supported)
- //
-
- enum state
- {
- parse_prefix,
- parse_name,
- parse_range,
- parse_suffix,
- parse_done
- };
-
- state s (parse_prefix);
- string prefix;
- bool flt (false);
-
- for (sql_token t (l.next ());
- s != parse_done && t.type () != sql_token::t_eos;
- t = l.next ())
- {
- sql_token::token_type tt (t.type ());
-
- switch (s)
- {
- case parse_prefix:
- {
- if (tt == sql_token::t_identifier)
- {
- string const& id (context::upcase (t.identifier ()));
-
- if (id == "BIT" ||
- id == "CHARACTER" ||
- id == "DOUBLE")
- {
- prefix = id;
- s = parse_name;
- continue;
- }
- }
-
- s = parse_name;
- }
- // Fall through.
- case parse_name:
- {
- if (tt == sql_token::t_identifier)
- {
- bool match (true);
- string const& id (context::upcase (t.identifier ()));
-
- //
- // Numeric types.
- //
- if (id == "BOOL" || id == "BOOLEAN")
- {
- r.type = sql_type::BOOLEAN;
- }
- else if (id == "SMALLINT" || id == "INT2")
- {
- r.type = sql_type::SMALLINT;
- }
- else if (id == "INT" ||
- id == "INTEGER" ||
- id == "INT4")
- {
- r.type = sql_type::INTEGER;
- }
- else if (id == "BIGINT")
- {
- r.type = sql_type::BIGINT;
- }
- else if (id == "REAL" || id == "FLOAT4")
- {
- r.type = sql_type::REAL;
- }
- else if ((id == "PRECISION" && prefix == "DOUBLE") ||
- id == "FLOAT8")
- {
- r.type = sql_type::DOUBLE;
- }
- else if (id == "FLOAT")
- {
- // Assign a type only once we know the precision of the
- // float.
- //
- flt = true;
- }
- else if (id == "NUMERIC" || id == "DECIMAL")
- {
- r.type = sql_type::NUMERIC;
- }
- //
- // Date-time types.
- //
- else if (id == "DATE")
- {
- r.type = sql_type::DATE;
- }
- else if (id == "TIME")
- {
- r.type = sql_type::TIME;
- }
- else if (id == "TIMETZ")
- {
- return error (ct, "PostgreSQL time zones are not currently "
- "supported");
- }
- else if (id == "TIMESTAMP")
- {
- r.type = sql_type::TIMESTAMP;
- }
- else if (id == "TIMESTAMPTZ")
- {
- return error (ct, "PostgreSQL time zones are not currently "
- "supported");
- }
- //
- // String and binary types.
- //
- else if (id == "CHAR")
- {
- r.type = sql_type::CHAR;
- }
- else if (id == "VARCHAR")
- {
- r.type = sql_type::VARCHAR;
- }
- else if (id == "TEXT")
- {
- r.type = sql_type::TEXT;
- }
- else if (id == "VARYING")
- {
- if (prefix == "BIT")
- r.type = sql_type::VARBIT;
- else if (prefix == "CHARACTER")
- r.type = sql_type::VARCHAR;
- }
- else if (id == "BYTEA")
- {
- r.type = sql_type::BYTEA;
- }
- else if (id == "VARBIT")
- {
- r.type = sql_type::VARBIT;
- }
- //
- // Other types.
- //
- else if (id == "UUID")
- {
- r.type = sql_type::UUID;
- }
- else
- match = false;
-
- if (match)
- {
- s = parse_range;
- continue;
- }
- }
-
- // Some prefixes can also be type names if not followed
- // by the actual type name.
- //
- if (!prefix.empty ())
- {
- if (prefix == "BIT")
- {
- r.type = sql_type::BIT;
- }
- else if (prefix == "CHARACTER")
- {
- r.type = sql_type::CHAR;
- }
- }
-
- if (r.type == sql_type::invalid)
- {
- return error (
- ct,
- tt == sql_token::t_identifier
- ? "unknown PostgreSQL type '" + t.identifier () + "'"
- : "expected PostgreSQL type name");
- }
-
- s = parse_range;
- }
- // Fall through.
- case parse_range:
- {
- if (t.punctuation () == sql_token::p_lparen)
- {
- t = l.next ();
-
- if (t.type () != sql_token::t_int_lit)
- {
- return error (ct, "integer range expected in PostgreSQL "
- "type declaration");
- }
-
- unsigned int v;
- istringstream is (t.literal ());
-
- if (!(is >> v && is.eof ()))
- {
- return error (ct, "invalid range value '" + t.literal () +
- "' in PostgreSQL type declaration");
- }
-
- r.range = true;
- r.range_value = v;
-
- t = l.next ();
-
- if (t.punctuation () == sql_token::p_comma)
- {
- // We have the second range value. Skip it.
- //
- l.next ();
- t = l.next ();
- }
-
- if (t.punctuation () != sql_token::p_rparen)
- {
- return error (ct, "expected ')' in PostgreSQL type "
- "declaration");
- }
-
- s = parse_suffix;
- continue;
- }
-
- s = parse_suffix;
- }
- // Fall through.
- case parse_suffix:
- {
- if (r.type == sql_type::TIME || r.type == sql_type::TIMESTAMP)
- {
- string const& id1 (context::upcase (t.identifier ()));
-
- if (id1 == "WITH")
- {
- t = l.next ();
- tt = t.type ();
-
- if (tt == sql_token::t_identifier)
- {
- string const& id2 (context::upcase (t.identifier ()));
-
- if (id2 == "TIME")
- {
- t = l.next ();
- tt = t.type ();
-
- if (tt == sql_token::t_identifier)
- {
- string const& id3 (context::upcase (t.identifier ()));
-
- if (id3 == "ZONE")
- {
- // This code shall not fall through.
- //
- return error (ct, "PostgreSQL time zones are not "
- "currently supported");
- }
- }
- }
- }
- }
- }
-
- return error (
- ct,
- tt == sql_token::t_identifier
- ? "unknown PostgreSQL type '" + t.identifier () + "'"
- : "unknown PostgreSQL type");
- }
- case parse_done:
- {
- assert (false);
- break;
- }
- }
- }
-
- if (s == parse_name && !prefix.empty ())
- {
- // Some prefixes can also be type names if not followed
- // by the actual type name.
- //
- if (prefix == "BIT")
- {
- r.type = sql_type::BIT;
- }
- else if (prefix == "CHARACTER")
- {
- r.type = sql_type::CHAR;
- }
- }
-
- if (flt)
- {
- r.type = r.range && r.range_value < 25 ?
- sql_type::REAL :
- sql_type::DOUBLE;
- }
-
- if (r.type == sql_type::invalid)
- return error (ct, "incomplete PostgreSQL type declaration");
-
- // If range is omitted for CHAR or BIT types, it defaults to 1.
- //
- if ((r.type == sql_type::CHAR || r.type == sql_type::BIT) && !r.range)
- {
- r.range = true;
- r.range_value = 1;
- }
-
- return r;
- }
- catch (sql_lexer::invalid_input const& e)
- {
- return error (ct, "invalid PostgreSQL type declaration: " + e.message);
- }
- }
- }
-}
diff --git a/odb/relational/pgsql/context.hxx b/odb/relational/pgsql/context.hxx
deleted file mode 100644
index 64e0b1a..0000000
--- a/odb/relational/pgsql/context.hxx
+++ /dev/null
@@ -1,192 +0,0 @@
-// file : odb/relational/pgsql/context.hxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_RELATIONAL_PGSQL_CONTEXT_HXX
-#define ODB_RELATIONAL_PGSQL_CONTEXT_HXX
-
-#include <map>
-
-#include <odb/relational/context.hxx>
-
-namespace relational
-{
- namespace pgsql
- {
- struct sql_type
- {
- // Keep the order in each block of types.
- //
- enum core_type
- {
- // Integral types.
- //
- BOOLEAN,
- SMALLINT,
- INTEGER,
- BIGINT,
-
- // Float types.
- //
- REAL,
- DOUBLE,
- NUMERIC,
-
- // Data-time types.
- //
- DATE,
- TIME,
- TIMESTAMP,
-
- // String and binary types.
- //
- CHAR,
- VARCHAR,
- TEXT,
- BYTEA,
- BIT,
- VARBIT,
-
- // Other types.
- //
- UUID,
-
- // Invalid type.
- //
- invalid
- };
-
- sql_type () : type (invalid), range (false) {}
-
- core_type type;
-
- // VARBIT maximum length is 2^31 - 1 bit. String types can hold a
- // maximum of 1GB of data.
- //
- bool range;
- unsigned int range_value;
-
- // Conversion expressions for custom database types.
- //
- std::string to;
- std::string from;
- };
-
- class context: public virtual relational::context
- {
- public:
- sql_type const&
- parse_sql_type (string const&,
- semantics::data_member&,
- bool custom = true);
- public:
- struct invalid_sql_type
- {
- invalid_sql_type (string const& message): message_ (message) {}
-
- string const&
- message () const {return message_;}
-
- private:
- string message_;
- };
-
- // If custom_db_types is NULL, then this function returns
- // invalid type instead of throwing in case an unknown type
- // is encountered.
- //
- static sql_type
- parse_sql_type (string, custom_db_types const* = 0);
-
- public:
- // Construct statement name from a given type and name.
- //
- string
- statement_name (string const& type,
- string const& name,
- semantics::node&);
-
- protected:
- virtual string const&
- convert_expr (string const&, semantics::data_member&, bool);
-
- virtual string
- quote_id_impl (qname const&) const;
-
- virtual bool
- grow_impl (semantics::class_&, user_section*);
-
- virtual bool
- grow_impl (semantics::data_member&);
-
- virtual bool
- grow_impl (semantics::data_member&,
- semantics::type&,
- const custom_cxx_type*,
- string const&);
-
- protected:
- virtual string
- database_type_impl (semantics::type&, semantics::names*, bool, bool*);
-
- public:
- virtual
- ~context ();
-
- context ();
- context (std::ostream&,
- semantics::unit&,
- options_type const&,
- features_type&,
- sema_rel::model*);
-
- static context&
- current ()
- {
- return *current_;
- }
-
- private:
- static context* current_;
-
- private:
- struct data: base_context::data
- {
- data (std::ostream& os): base_context::data (os) {}
-
- struct sql_type_cache_entry
- {
- sql_type_cache_entry ()
- : custom_cached (false), straight_cached (false) {}
-
- sql_type const&
- cache_custom (sql_type const& t)
- {
- custom = t;
- custom_cached = true;
- return custom;
- }
-
- sql_type const&
- cache_straight (sql_type const& t)
- {
- straight = t;
- straight_cached = true;
- return straight;
- }
-
- sql_type custom; // With custom mapping.
- sql_type straight; // Without custom mapping.
-
- bool custom_cached;
- bool straight_cached;
- };
-
- typedef std::map<string, sql_type_cache_entry> sql_type_cache;
- sql_type_cache sql_type_cache_;
- };
- data* data_;
- };
- }
-}
-
-#endif // ODB_RELATIONAL_PGSQL_CONTEXT_HXX
diff --git a/odb/relational/pgsql/header.cxx b/odb/relational/pgsql/header.cxx
deleted file mode 100644
index ff00eaa..0000000
--- a/odb/relational/pgsql/header.cxx
+++ /dev/null
@@ -1,271 +0,0 @@
-// file : odb/relational/pgsql/header.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/header.hxx>
-
-#include <odb/relational/pgsql/common.hxx>
-#include <odb/relational/pgsql/context.hxx>
-
-namespace relational
-{
- namespace pgsql
- {
- namespace header
- {
- namespace relational = relational::header;
-
- struct class1: relational::class1
- {
- class1 (base const& x): base (x) {}
-
- virtual void
- object_public_extra_post (type& c)
- {
- bool abst (abstract (c));
-
- type* poly_root (polymorphic (c));
- bool poly (poly_root != 0);
- bool poly_derived (poly && poly_root != &c);
-
- if (abst && !poly)
- return;
-
- data_member_path* id (id_member (c));
- semantics::data_member* optimistic (context::optimistic (c));
-
- column_count_type const& cc (column_count (c));
-
- size_t update_columns (
- cc.total - cc.id - cc.inverse - cc.readonly - cc.separate_update);
-
- // Statement names.
- //
- os << "static const char persist_statement_name[];";
-
- if (id != 0)
- {
- if (poly_derived)
- os << "static const char* const find_statement_names[" <<
- (abst ? "1" : "depth") << "];";
- else
- os << "static const char find_statement_name[];";
-
- if (poly && !poly_derived)
- os << "static const char find_discriminator_statement_name[];";
-
- if (update_columns != 0)
- os << "static const char update_statement_name[];";
-
- os << "static const char erase_statement_name[];";
-
- if (optimistic != 0)
- os << "static const char optimistic_erase_statement_name[];";
- }
-
- // Query statement name.
- //
- if (options.generate_query ())
- os << "static const char query_statement_name[];"
- << "static const char erase_query_statement_name[];";
-
- os << endl;
-
- // Statement types.
- //
- os << "static const unsigned int persist_statement_types[];";
-
- if (id != 0)
- {
- os << "static const unsigned int find_statement_types[];";
-
- if (update_columns != 0)
- os << "static const unsigned int update_statement_types[];";
-
- if (optimistic != 0)
- os << "static const unsigned int " <<
- "optimistic_erase_statement_types[];";
- }
-
- os << endl;
- }
-
- virtual void
- view_public_extra_post (type&)
- {
- // Statement names.
- //
- os << "static const char query_statement_name[];"
- << endl;
- }
- };
- entry<class1> class1_entry_;
-
- struct container_traits: relational::container_traits, context
- {
- container_traits (base const& x): base (x) {}
-
- virtual void
- container_public_extra_pre (semantics::data_member& m,
- semantics::type& t)
- {
- if (!object (c_) || (abstract (c_) && !polymorphic (c_)))
- return;
-
- bool smart (!inverse (m, "value") && !unordered (m) &&
- container_smart (t));
-
- // Container statement names.
- //
- os << "static const char select_name[];"
- << "static const char insert_name[];";
-
- if (smart)
- os << "static const char update_name[];";
-
- os << "static const char delete_name[];"
- << endl;
-
- // Container statement types.
- //
- os << "static const unsigned int insert_types[];";
-
- if (smart)
- os << "static const unsigned int update_types[];"
- << "static const unsigned int delete_types[];";
-
- os << endl;
- }
- };
- entry<container_traits> container_traits_;
-
- struct section_traits: relational::section_traits, context
- {
- section_traits (base const& x): base (x) {}
-
- virtual void
- section_public_extra_post (user_section& s)
- {
- semantics::class_* poly_root (polymorphic (c_));
- bool poly (poly_root != 0);
-
- if (!poly && (abstract (c_) ||
- s.special == user_section::special_version))
- return;
-
- bool load (s.total != 0 && s.separate_load ());
- bool load_opt (s.optimistic () && s.separate_load ());
-
- bool update (s.total != s.inverse + s.readonly); // Always separate.
- bool update_opt (s.optimistic () && (s.readwrite_containers || poly));
-
- // Statement names.
- //
- if (load || load_opt)
- os << "static const char select_name[];"
- << endl;
-
- if (update || update_opt)
- os << "static const char update_name[];"
- << endl;
-
- // Statement types.
- //
- if (update || update_opt)
- os << "static const unsigned int update_types[];";
- }
- };
- entry<section_traits> section_traits_;
-
- struct image_member: relational::image_member_impl<sql_type>,
- member_base
- {
- image_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x) {}
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_numeric (member_info& mi)
- {
- // Exchanged as strings. Can have up to 1000 digits not counting
- // '-' and '.'.
- //
-
- os << image_type << " " << mi.var << "value;"
- << "std::size_t " << mi.var << "size;"
- << "bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_date_time (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "std::size_t " << mi.var << "size;"
- << "bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_bit (member_info& mi)
- {
- // Additional 4 bytes at the beginning of the array specify
- // the number of significant bits in the image. This number
- // is stored in network byte order.
- //
- unsigned int n (4 + mi.st->range / 8 + (mi.st->range % 8 ? 1 : 0));
-
- os << "unsigned char " << mi.var << "value[" << n << "];"
- << "std::size_t " << mi.var << "size;"
- << "bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_varbit (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "std::size_t " << mi.var << "size;"
- << "bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_uuid (member_info& mi)
- {
- // UUID is a 16-byte sequence.
- //
- os << "unsigned char " << mi.var << "value[16];"
- << "bool " << mi.var << "null;"
- << endl;
- }
- };
- entry<image_member> image_member_;
- }
- }
-}
diff --git a/odb/relational/pgsql/inline.cxx b/odb/relational/pgsql/inline.cxx
deleted file mode 100644
index 08688c3..0000000
--- a/odb/relational/pgsql/inline.cxx
+++ /dev/null
@@ -1,42 +0,0 @@
-// file : odb/relational/pgsql/inline.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/inline.hxx>
-
-#include <odb/relational/pgsql/common.hxx>
-#include <odb/relational/pgsql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace pgsql
- {
- namespace inline_
- {
- namespace relational = relational::inline_;
-
- struct null_member: relational::null_member_impl<sql_type>,
- member_base
- {
- null_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- traverse_simple (member_info& mi)
- {
- if (get_)
- os << "r = r && i." << mi.var << "null;";
- else
- os << "i." << mi.var << "null = true;";
- }
- };
- entry<null_member> null_member_;
- }
- }
-}
diff --git a/odb/relational/pgsql/model.cxx b/odb/relational/pgsql/model.cxx
deleted file mode 100644
index 092f8bb..0000000
--- a/odb/relational/pgsql/model.cxx
+++ /dev/null
@@ -1,101 +0,0 @@
-// file : odb/relational/pgsql/model.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <sstream>
-
-#include <odb/diagnostics.hxx>
-
-#include <odb/relational/model.hxx>
-
-#include <odb/relational/pgsql/common.hxx>
-#include <odb/relational/pgsql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace pgsql
- {
- namespace model
- {
- namespace relational = relational::model;
-
- struct object_columns: relational::object_columns, context
- {
- object_columns (base const& x): base (x) {}
-
- virtual void
- traverse_object (semantics::class_& c)
- {
- base::traverse_object (c);
-
- if (context::top_object == &c)
- {
- // Make sure that the auto id type is INTEGER or BIGINT.
- //
- if (pkey_ != 0 && pkey_->auto_ ())
- {
- // Should be a single column.
- //
- sema_rel::column& c (pkey_->contains_begin ()->column ());
-
- // This should never fail since we have already parsed this.
- //
- sql_type const& t (parse_sql_type (c.type ()));
-
- if (t.type != sql_type::INTEGER && t.type != sql_type::BIGINT)
- {
- location const& l (c.get<location> ("cxx-location"));
- error (l) << "automatically assigned object id must map "
- << "to PostgreSQL INTEGER or BIGINT" << endl;
- throw operation_failed ();
- }
- }
- }
- }
-
- virtual string
- default_bool (semantics::data_member&, bool v)
- {
- return v ? "TRUE" : "FALSE";
- }
-
- virtual string
- default_enum (semantics::data_member& m, tree en, string const&)
- {
- // Make sure the column is mapped to an integer type.
- //
- switch (parse_sql_type (column_type (), m, false).type)
- {
- case sql_type::SMALLINT:
- case sql_type::INTEGER:
- case sql_type::BIGINT:
- break;
- default:
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: column with default value specified as C++ "
- << "enumerator must map to PostgreSQL integer type" << endl;
-
- throw operation_failed ();
- }
- }
-
- using semantics::enumerator;
-
- enumerator& e (dynamic_cast<enumerator&> (*unit.find (en)));
-
- ostringstream ostr;
-
- if (e.enum_ ().unsigned_ ())
- ostr << e.value ();
- else
- ostr << static_cast<long long> (e.value ());
-
- return ostr.str ();
- }
- };
- entry<object_columns> object_columns_;
- }
- }
-}
diff --git a/odb/relational/pgsql/schema.cxx b/odb/relational/pgsql/schema.cxx
deleted file mode 100644
index b9c3f2e..0000000
--- a/odb/relational/pgsql/schema.cxx
+++ /dev/null
@@ -1,266 +0,0 @@
-// file : odb/relational/pgsql/schema.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/schema.hxx>
-
-#include <odb/relational/pgsql/common.hxx>
-#include <odb/relational/pgsql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace pgsql
- {
- namespace schema
- {
- namespace relational = relational::schema;
- using relational::table_set;
-
- //
- // Drop.
- //
-
- struct drop_table: relational::drop_table, context
- {
- drop_table (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::table& t, bool migration)
- {
- // For migration drop foreign keys explicitly in pre-migration.
- //
- if (migration)
- {
- base::traverse (t, migration);
- return;
- }
-
- // For schema creation we use the CASCADE clause to drop foreign
- // keys.
- //
- if (pass_ != 2)
- return;
-
- pre_statement ();
- os << "DROP TABLE " << (migration ? "" : "IF EXISTS ") <<
- quote_id (t.name ()) << " CASCADE" << endl;
- post_statement ();
- }
- };
- entry<drop_table> drop_table_;
-
- //
- // Create.
- //
-
- struct create_column: relational::create_column, context
- {
- create_column (base const& x): base (x) {}
-
- virtual void
- type (sema_rel::column& c, bool auto_)
- {
- if (auto_)
- {
- // This should never fail since we have already parsed this.
- //
- sql_type const& t (parse_sql_type (c.type ()));
-
- // The model creation code makes sure it is one of these type.
- //
- if (t.type == sql_type::INTEGER)
- os << "SERIAL";
- else if (t.type == sql_type::BIGINT)
- os << "BIGSERIAL";
- }
- else
- base::type (c, auto_);
- }
- };
- entry<create_column> create_column_;
-
- struct create_foreign_key: relational::create_foreign_key, context
- {
- create_foreign_key (base const& x): base (x) {}
-
- virtual void
- deferrable (sema_rel::deferrable d)
- {
- os << endl
- << " INITIALLY " << d;
- }
- };
- entry<create_foreign_key> create_foreign_key_;
-
- struct create_index: relational::create_index, context
- {
- create_index (base const& x): base (x) {}
-
- virtual void
- create (sema_rel::index& in)
- {
- os << "CREATE ";
-
- if (!in.type ().empty ())
- {
- // Handle the CONCURRENTLY keyword.
- //
- string const& t (in.type ());
-
- if (t == "concurrently" || t == "CONCURRENTLY")
- {
- os << "INDEX " << t;
- }
- else
- {
- size_t p (t.rfind (' '));
- string s (t, (p != string::npos ? p + 1 : 0), string::npos);
-
- if (s == "concurrently" || s == "CONCURRENTLY")
- os << string (t, 0, p) << " INDEX " << s;
- else
- os << t << " INDEX";
- }
- }
- else
- os << "INDEX";
-
- os << " " << name (in) << endl
- << " ON " << table_name (in);
-
- if (!in.method ().empty ())
- os << " USING " << in.method ();
-
- os << " (";
- columns (in);
- os << ")" << endl;
-
- if (!in.options ().empty ())
- os << ' ' << in.options () << endl;
- }
- };
- entry<create_index> create_index_;
-
- //
- // Alter.
- //
-
- struct alter_column: relational::alter_column, context
- {
- alter_column (base const& x): base (x) {}
-
- virtual void
- alter (sema_rel::column& c)
- {
- os << quote_id (c.name ()) << " " <<
- (c.null () ? "DROP" : "SET") << " NOT NULL";
- }
- };
- entry<alter_column> alter_column_;
-
- //
- // Schema version table.
- //
-
- struct version_table: relational::version_table, context
- {
- version_table (base const& x): base (x) {}
-
- // PostgreSQL prior to 9.1 doesn't support IF NOT EXISTS in
- // CREATE TABLE. We also cannot use IF-ELSE construct in plain
- // SQL. To make it at least work for a single schema, we are
- // going to drop the schema version table after the DROP
- // statements and then unconditionally create it after CREATE.
- //
- virtual void
- create_table ()
- {
- if (options.pgsql_server_version () >= pgsql_version (9, 1))
- {
- pre_statement ();
-
- os << "CREATE TABLE IF NOT EXISTS " << qt_ << " (" << endl
- << " " << qn_ << " TEXT NOT NULL PRIMARY KEY," << endl
- << " " << qv_ << " BIGINT NOT NULL," << endl
- << " " << qm_ << " BOOLEAN NOT NULL)" << endl;
-
- post_statement ();
- }
- }
-
- virtual void
- drop ()
- {
- pre_statement ();
-
- if (options.pgsql_server_version () >= pgsql_version (9, 1))
- os << "DELETE FROM " << qt_ << endl
- << " WHERE " << qn_ << " = " << qs_ << endl;
- else
- os << "DROP TABLE IF EXISTS " << qt_ << endl;
-
- post_statement ();
- }
-
- virtual void
- create (sema_rel::version v)
- {
- pre_statement ();
-
- if (options.pgsql_server_version () >= pgsql_version (9, 1))
- {
- os << "INSERT INTO " << qt_ << " (" << endl
- << " " << qn_ << ", " << qv_ << ", " << qm_ << ")" << endl
- << " SELECT " << qs_ << ", " << v << ", FALSE" << endl
- << " WHERE NOT EXISTS (" << endl
- << " SELECT 1 FROM " << qt_ << " WHERE " << qn_ << " = " <<
- qs_ << ")" << endl;
- }
- else
- {
- os << "CREATE TABLE " << qt_ << " (" << endl
- << " " << qn_ << " TEXT NOT NULL PRIMARY KEY," << endl
- << " " << qv_ << " BIGINT NOT NULL," << endl
- << " " << qm_ << " BOOLEAN NOT NULL)" << endl;
-
- post_statement ();
- pre_statement ();
-
- os << "INSERT INTO " << qt_ << " (" << endl
- << " " << qn_ << ", " << qv_ << ", " << qm_ << ")" << endl
- << " VALUES (" << qs_ << ", " << v << ", FALSE)" << endl;
- }
-
- post_statement ();
- }
-
- virtual void
- migrate_pre (sema_rel::version v)
- {
- pre_statement ();
-
- os << "UPDATE " << qt_ << endl
- << " SET " << qv_ << " = " << v << ", " << qm_ << " = TRUE" << endl
- << " WHERE " << qn_ << " = " << qs_ << endl;
-
- post_statement ();
- }
-
- virtual void
- migrate_post ()
- {
- pre_statement ();
-
- os << "UPDATE " << qt_ << endl
- << " SET " << qm_ << " = FALSE" << endl
- << " WHERE " << qn_ << " = " << qs_ << endl;
-
- post_statement ();
- }
-
- };
- entry<version_table> version_table_;
- }
- }
-}
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
deleted file mode 100644
index 580103d..0000000
--- a/odb/relational/pgsql/source.cxx
+++ /dev/null
@@ -1,1140 +0,0 @@
-// file : odb/relational/pgsql/source.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <sstream>
-
-#include <odb/relational/source.hxx>
-
-#include <odb/relational/pgsql/common.hxx>
-#include <odb/relational/pgsql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace pgsql
- {
- namespace source
- {
- namespace relational = relational::source;
-
- struct query_parameters: relational::query_parameters
- {
- query_parameters (base const& x): base (x), i_ (0) {}
-
- virtual string
- next (semantics::data_member&, const string&, const string&)
- {
- ostringstream ss;
- ss << "$" << ++i_;
-
- return ss.str ();
- }
-
- virtual string
- auto_id (semantics::data_member&, const string&, const string&)
- {
- return "DEFAULT";
- }
-
- private:
- size_t i_;
- };
- entry<query_parameters> query_parameters_;
-
- namespace
- {
- const char* integer_buffer_types[] =
- {
- "pgsql::bind::boolean_",
- "pgsql::bind::smallint",
- "pgsql::bind::integer",
- "pgsql::bind::bigint"
- };
-
- const char* float_buffer_types[] =
- {
- "pgsql::bind::real",
- "pgsql::bind::double_"
- };
-
- const char* char_bin_buffer_types[] =
- {
- "pgsql::bind::text", // CHAR
- "pgsql::bind::text", // VARCHAR
- "pgsql::bind::text", // TEXT
- "pgsql::bind::bytea" // BYTEA
- };
-
- const char* date_time_buffer_types[] =
- {
- "pgsql::bind::date",
- "pgsql::bind::time",
- "pgsql::bind::timestamp"
- };
-
- const char* oids[] =
- {
- "pgsql::bool_oid", // BOOLEAN
- "pgsql::int2_oid", // SMALLINT
- "pgsql::int4_oid", // INTEGER
- "pgsql::int8_oid", // BIGINT
- "pgsql::float4_oid", // REAL
- "pgsql::float8_oid", // DOUBLE
- "pgsql::numeric_oid", // NUMERIC
- "pgsql::date_oid", // DATE
- "pgsql::time_oid", // TIME
- "pgsql::timestamp_oid", // TIMESTAMP
- "pgsql::text_oid", // CHAR
- "pgsql::text_oid", // VARCHAR
- "pgsql::text_oid", // TEXT
- "pgsql::bytea_oid", // BYTEA
- "pgsql::bit_oid", // BIT
- "pgsql::varbit_oid", // VARBIT
- "pgsql::uuid_oid" // UUID
- };
- }
-
- struct statement_oids: object_columns_base, context
- {
- statement_oids (statement_kind sk,
- bool first = true,
- object_section* section = 0)
- : object_columns_base (first, column_prefix (), section), sk_ (sk)
- {
- }
-
- virtual bool
- section_test (data_member_path const& mp)
- {
- object_section& s (section (mp));
-
- // Include eager loaded members into the main section for
- // SELECT statements.
- //
- return section_ == 0 ||
- *section_ == s ||
- (sk_ == statement_select &&
- *section_ == main_section &&
- !s.separate_load ());
- }
-
- virtual void
- traverse_pointer (semantics::data_member& m, semantics::class_& c)
- {
- // Ignore certain columns depending on what kind statement we are
- // generating. See object_columns in common source generator for
- // details.
- //
- if (!(inverse (m, key_prefix_) && sk_ != statement_select))
- object_columns_base::traverse_pointer (m, c);
- }
-
- virtual bool
- traverse_column (semantics::data_member& m,
- string const&,
- bool first)
- {
- // Ignore certain columns depending on what kind statement we are
- // generating. See object_columns in common source generator for
- // details.
- //
- if (id ())
- {
- if (sk_ == statement_update ||
- (sk_ == statement_insert && auto_ (m)))
- return false;
- }
-
- if (sk_ == statement_update &&
- readonly (member_path_, member_scope_))
- return false;
-
- if ((sk_ == statement_insert || sk_ == statement_update) &&
- version (m))
- return false;
-
- if (!first)
- os << ',' << endl;
-
- os << oids[parse_sql_type (column_type (), m).type];
-
- return true;
- }
-
- private:
- statement_kind sk_;
- };
-
- //
- // bind
- //
-
- struct bind_member: relational::bind_member_impl<sql_type>,
- member_base
- {
- bind_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << b << ".type = " <<
- integer_buffer_types[mi.st->type - sql_type::BOOLEAN] << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << b << ".type = " <<
- float_buffer_types[mi.st->type - sql_type::REAL] << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_numeric (member_info& mi)
- {
- os << b << ".type = pgsql::bind::numeric;"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
- << b << ".capacity = " << arg << "." << mi.var <<
- "value.capacity ();"
- << b << ".size = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_date_time (member_info& mi)
- {
- os << b << ".type = " <<
- date_time_buffer_types[mi.st->type - sql_type::DATE] << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << b << ".type = " <<
- char_bin_buffer_types[mi.st->type - sql_type::CHAR] << ";"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
- << b << ".capacity = " << arg << "." << mi.var <<
- "value.capacity ();"
- << b << ".size = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_bit (member_info& mi)
- {
- os << b << ".type = pgsql::bind::bit;"
- << b << ".buffer = " << arg << "." << mi.var << "value;"
- << b << ".capacity = sizeof (" << arg << "." << mi.var << "value);"
- << b << ".size = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_varbit (member_info& mi)
- {
- os << b << ".type = pgsql::bind::varbit;"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
- << b << ".capacity = " << arg << "." << mi.var <<
- "value.capacity ();"
- << b << ".size = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_uuid (member_info& mi)
- {
- os << b << ".type = pgsql::bind::uuid;"
- << b << ".buffer = " << arg << "." << mi.var << "value;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
- };
- entry<bind_member> bind_member_;
-
- //
- // grow
- //
-
- struct grow_member: relational::grow_member_impl<sql_type>,
- member_base
- {
- grow_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x) {}
-
- virtual void
- traverse_integer (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
-
- virtual void
- traverse_float (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
-
- virtual void
- traverse_numeric (member_info& mi)
- {
- os << "if (" << e << ")" << endl
- << "{"
- << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_date_time (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << "if (" << e << ")" << endl
- << "{"
- << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_bit (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
-
- virtual void
- traverse_varbit (member_info& mi)
- {
- os << "if (" << e << ")" << endl
- << "{"
- << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_uuid (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
- };
- entry<grow_member> grow_member_;
-
- //
- // init image
- //
-
- struct init_image_member: relational::init_image_member_impl<sql_type>,
- member_base
- {
- init_image_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- set_null (member_info& mi)
- {
- os << "i." << mi.var << "null = true;";
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "null = is_null;";
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "null = is_null;";
- }
-
- virtual void
- traverse_numeric (member_info& mi)
- {
- // @@ Optimization: can remove growth check if buffer is fixed.
- //
- os << "std::size_t size (0);"
- << "std::size_t cap (i." << mi.var << "value.capacity ());"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "null = is_null;"
- << "i." << mi.var << "size = size;"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
- }
-
- virtual void
- traverse_date_time (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "null = is_null;";
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << "std::size_t size (0);"
- << "std::size_t cap (i." << mi.var << "value.capacity ());"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "null = is_null;"
- << "i." << mi.var << "size = size;"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
- }
-
- virtual void
- traverse_bit (member_info& mi)
- {
- os << "std::size_t size (0);"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "sizeof (i." << mi.var << "value)," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "null = is_null;"
- << "i." << mi.var << "size = size;";
- }
-
- virtual void
- traverse_varbit (member_info& mi)
- {
- os << "std::size_t size (0);"
- << "std::size_t cap (i." << mi.var << "value.capacity ());"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "null = is_null;"
- << "i." << mi.var << "size = size;"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
- }
-
- virtual void
- traverse_uuid (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "null = is_null;";
- }
- };
- entry<init_image_member> init_image_member_;
-
- //
- // init value
- //
-
- struct init_value_member: relational::init_value_member_impl<sql_type>,
- member_base
- {
- init_value_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- get_null (string const& var) const
- {
- os << "i." << var << "null";
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_numeric (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_date_time (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_bit (member_info& mi)
- {
- // Presented as byte.
- //
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_varbit (member_info& mi)
- {
- // Presented as bytea.
- //
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_uuid (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
- };
- entry<init_value_member> init_value_member_;
-
- struct class_: relational::class_, context
- {
- class_ (base const& x): base (x) {}
-
- virtual string
- persist_statement_extra (type& c,
- relational::query_parameters&,
- persist_position p)
- {
- string r;
-
- if (p == persist_after_values)
- {
- data_member_path* id (id_member (c));
-
- type* poly_root (polymorphic (c));
- bool poly_derived (poly_root != 0 && poly_root != &c);
-
- // Top-level auto id.
- //
- if (id != 0 && !poly_derived && auto_ (*id))
- r = "RETURNING " +
- convert_from (column_qname (*id), *id->back ());
- }
-
- return r;
- }
-
- virtual void
- object_extra (type& c)
- {
- bool abst (abstract (c));
-
- type* poly_root (polymorphic (c));
- bool poly (poly_root != 0);
- bool poly_derived (poly && poly_root != &c);
-
- if (abst && !poly)
- return;
-
- data_member_path* id (id_member (c));
- semantics::data_member* optimistic (context::optimistic (c));
-
- column_count_type const& cc (column_count (c));
-
- size_t update_columns (
- cc.total - cc.id - cc.inverse - cc.readonly - cc.separate_update);
-
- string const& n (class_fq_name (c));
- string const& fn (flat_name (n));
- string traits ("access::object_traits_impl< " + n + ", id_pgsql >");
-
- os << "const char " << traits << "::" << endl
- << "persist_statement_name[] = " <<
- strlit (statement_name ("persist", fn, c)) << ";"
- << endl;
-
- if (id != 0)
- {
- if (poly_derived)
- {
- os << "const char* const " << traits << "::" << endl
- << "find_statement_names[] ="
- << "{";
-
- for (size_t i (0), n (abst ? 1 : polymorphic_depth (c));
- i < n;
- ++i)
- {
- if (i != 0)
- os << "," << endl;
-
- ostringstream ostr;
- ostr << "find_" << i;
- os << strlit (statement_name (ostr.str (), fn, c));
- }
-
- os << "};";
- }
- else
- os << "const char " << traits << "::" << endl
- << "find_statement_name[] = " <<
- strlit (statement_name ("find", fn, c)) << ";"
- << endl;
-
- if (poly && !poly_derived)
- os << "const char " << traits << "::" << endl
- << "find_discriminator_statement_name[] = " <<
- strlit (statement_name ("find_discriminator", fn, c)) << ";"
- << endl;
-
- if (update_columns != 0)
- os << "const char " << traits << "::" << endl
- << "update_statement_name[] = " <<
- strlit (statement_name ("update", fn, c)) << ";"
- << endl;
-
- os << "const char " << traits << "::" << endl
- << "erase_statement_name[] = " <<
- strlit (statement_name ("erase", fn, c)) << ";"
- << endl;
-
- if (optimistic != 0)
- os << "const char " << traits << "::" << endl
- << "optimistic_erase_statement_name[] = " <<
- strlit (statement_name ("erase_optimistic", fn, c)) << ";"
- << endl;
- }
-
- // Query statement name.
- //
- if (options.generate_query ())
- {
- os << "const char " << traits << "::" << endl
- << "query_statement_name[] = " <<
- strlit (statement_name ("query", fn, c)) << ";"
- << endl
- << "const char " << traits << "::" << endl
- << "erase_query_statement_name[] = " <<
- strlit (statement_name ("erase_query", fn, c)) << ";"
- << endl;
- }
-
- // Statement types.
- //
-
- // persist_statement_types.
- //
- {
- os << "const unsigned int " << traits << "::" << endl
- << "persist_statement_types[] ="
- << "{";
-
- statement_oids st (statement_insert);
- st.traverse (c);
-
- // Empty array is not portable. So add a dummy member if we
- // are not sending anything with the insert statement.
- //
- if (cc.total == cc.inverse + cc.optimistic_managed +
- (id != 0 && !poly_derived && auto_ (*id) ? cc.id : 0))
- os << "0";
-
- os << "};";
- }
-
- // find_statement_types.
- //
- if (id != 0)
- {
- os << "const unsigned int " << traits << "::" << endl
- << "find_statement_types[] ="
- << "{";
-
- statement_oids st (statement_select, true);
- st.traverse (*id);
-
- os << "};";
- }
-
- // update_statement_types.
- //
- if (id != 0 && update_columns != 0)
- {
- os << "const unsigned int " << traits << "::" << endl
- << "update_statement_types[] ="
- << "{";
-
- {
- statement_oids st (statement_update, true, &main_section);
- st.traverse (c);
- }
-
- // Not the same as update_columns.
- //
- bool first (cc.total == cc.id + cc.inverse + cc.readonly +
- cc.separate_update + cc.optimistic_managed);
-
- statement_oids st (statement_where, first);
- st.traverse (*id);
-
- if (optimistic != 0)
- st.traverse (*optimistic);
-
- os << "};";
- }
-
- if (id != 0 && optimistic != 0)
- {
- os << "const unsigned int " << traits << "::" << endl
- << "optimistic_erase_statement_types[] ="
- << "{";
-
- statement_oids st (statement_where);
- st.traverse (*id);
- st.traverse (*optimistic);
-
- os << "};";
- }
- }
-
- virtual void
- extra_statement_cache_extra_args (bool c, bool s)
- {
- bool u (c || s);
-
- os << "," << endl
- << db << "::native_binding&" << (u ? " idn" : "") << "," << endl
- << "const unsigned int*" << (u ? " idt" : "");
- }
-
- virtual void
- view_extra (type& c)
- {
- string const& n (class_fq_name (c));
- string const& fn (flat_name (n));
- string traits ("access::view_traits_impl< " + n + ", id_pgsql >");
-
- os << "const char " << traits << "::" << endl
- << "query_statement_name[] = " <<
- strlit (statement_name ("query", fn, c)) << ";"
- << endl;
- }
-
- virtual void
- object_query_statement_ctor_args (type&,
- string const& q,
- bool process,
- bool prep)
- {
- os << "sts.connection ()," << endl;
-
- if (prep)
- os << "n," << endl;
- else
- os << "query_statement_name," << endl;
-
- os << "text," << endl
- << process << "," << endl // Process.
- << "true," << endl // Optimize.
- << q << ".parameter_types ()," << endl
- << q << ".parameter_count ()," << endl
- << q << ".parameters_binding ()," << endl
- << "imb";
- }
-
- virtual void
- object_erase_query_statement_ctor_args (type&)
- {
- os << "conn," << endl
- << "erase_query_statement_name," << endl
- << "text," << endl
- << "q.parameter_types ()," << endl
- << "q.parameter_count ()," << endl
- << "q.parameters_binding ()";
- }
-
- virtual void
- view_query_statement_ctor_args (type&,
- string const& q,
- bool process,
- bool prep)
- {
- os << "sts.connection ()," << endl;
-
- if (prep)
- os << "n," << endl;
- else
- os << "query_statement_name," << endl;
-
- os << q << ".clause ()," << endl
- << process << "," << endl // Process.
- << "true," << endl // Optimize.
- << q << ".parameter_types ()," << endl
- << q << ".parameter_count ()," << endl
- << q << ".parameters_binding ()," << endl
- << "imb";
- }
-
- virtual void
- post_query_ (type&, bool once_off)
- {
- if (once_off)
- os << "st->deallocate ();";
- }
- };
- entry<class_> class_entry_;
-
- struct container_traits : relational::container_traits, context
- {
- container_traits (base const& x): base (x) {}
-
- virtual void
- container_extra (semantics::data_member& m, semantics::type& t)
- {
- if (!object (c_) || (abstract (c_) && !polymorphic (c_)))
- return;
-
- container_kind_type ck (container_kind (t));
-
- string const& pn (public_name (m));
- string scope (scope_ + "::" + flat_prefix_ + pn + "_traits");
-
- data_member_path* imp (inverse (m, "value"));
- bool inv (imp != 0);
-
- bool smart (!inv && !unordered (m) && container_smart (t));
-
- // Statment names.
- //
-
- // Prefix top-object name to avoid conflicts with inherited
- // member statement names.
- //
- string fn (
- flat_name (
- class_fq_name (*top_object) + "_" + flat_prefix_ + pn));
-
- os << "const char " << scope << "::" << endl
- << "select_name[] = " <<
- strlit (statement_name ("select", fn, m)) << ";"
- << endl
- << "const char " << scope << "::" << endl
- << "insert_name[] = " <<
- strlit (statement_name ("insert", fn, m)) << ";"
- << endl;
-
- if (smart)
- os << "const char " << scope << "::" << endl
- << "update_name[] = " <<
- strlit (statement_name ("update", fn, m)) << ";"
- << endl;
-
- os << "const char " << scope << "::" << endl
- << "delete_name[] = " <<
- strlit (statement_name ("delete", fn, m)) << ";"
- << endl;
-
- // Statement types.
- //
-
- semantics::type& vt (container_vt (m));
- semantics::type& idt (container_idt (m));
-
- // insert statement types.
- //
- {
- os << "const unsigned int " << scope << "::" << endl
- << "insert_types[] ="
- << "{";
-
- if (!inv)
- {
- statement_oids so (statement_insert);
-
- so.traverse (m, idt, "id", "object_id");
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (!unordered (m))
- so.traverse (m, container_it (m), "index", "index");
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- so.traverse (m, container_kt (m), "key", "key");
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- so.traverse (m, vt, "value", "value");
- }
- else
- // MSVC does not allow zero length arrays or uninitialized
- // non-extern const values.
- //
- os << "0";
-
- os << "};";
- }
-
- // update statement types.
- //
- if (smart)
- {
- os << "const unsigned int " << scope << "::" << endl
- << "update_types[] ="
- << "{";
-
- {
- // Use insert instead of update to include read-only members.
- //
- statement_oids so (statement_insert);
- so.traverse (m, vt, "value", "value");
- }
-
- statement_oids so (statement_where, false);
- so.traverse (m, idt, "id", "object_id");
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (!unordered (m))
- so.traverse (m, container_it (m), "index", "index");
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- //so.traverse (m, container_kt (t), "key", "key");
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- //so.traverse (m, vt, "value", "value");
- break;
- }
- }
-
- os << "};";
- }
-
- // delete statement types.
- //
- if (smart)
- {
- os << "const unsigned int " << scope << "::" << endl
- << "delete_types[] ="
- << "{";
-
- statement_oids so (statement_where);
- so.traverse (m, idt, "id", "object_id");
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (!unordered (m))
- so.traverse (m, container_it (m), "index", "index");
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- //so.traverse (m, container_kt (t), "key", "key");
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- //so.traverse (m, vt, "value", "value");
- break;
- }
- }
-
- os << "};";
- }
- }
- };
- entry<container_traits> container_traits_;
-
- struct section_traits : relational::section_traits, context
- {
- section_traits (base const& x): base (x) {}
-
- virtual void
- section_extra (user_section& s)
- {
- semantics::class_* poly_root (polymorphic (c_));
- bool poly (poly_root != 0);
-
- if (!poly && (abstract (c_) ||
- s.special == user_section::special_version))
- return;
-
- semantics::data_member* opt (optimistic (c_));
-
- bool load (s.total != 0 && s.separate_load ());
- bool load_opt (s.optimistic () && s.separate_load ());
-
- bool update (s.total != s.inverse + s.readonly); // Always separate.
- bool update_opt (s.optimistic () && (s.readwrite_containers || poly));
-
- string name (public_name (*s.member));
- string scope (scope_ + "::" + name + "_traits");
-
- // Statment names.
- //
-
- // Prefix object name to avoid conflicts with inherited member
- // statement names.
- //
- string fn (flat_name (class_fq_name (c_) + "_" + name));
-
- if (load || load_opt)
- os << "const char " << scope << "::" << endl
- << "select_name[] = " <<
- strlit (statement_name ("select", fn, *s.member)) << ";"
- << endl;
-
- if (update || update_opt)
- os << "const char " << scope << "::" << endl
- << "update_name[] = " <<
- strlit (statement_name ("update", fn, *s.member)) << ";"
- << endl;
-
- // Statement types.
- //
- if (update || update_opt)
- {
- os << "const unsigned int " << scope << "::" << endl
- << "update_types[] ="
- << "{";
-
- {
- statement_oids st (statement_update, true, &s);
- st.traverse (c_);
- }
-
- statement_oids st (statement_where, !update);
- st.traverse (*id_member (c_));
-
- if (s.optimistic ()) // Note: not update_opt.
- st.traverse (*opt);
-
- os << "};";
- }
- }
- };
- entry<section_traits> section_traits_;
-
- struct container_cache_init_members:
- relational::container_cache_init_members
- {
- container_cache_init_members (base const& x): base (x) {}
-
- virtual void
- extra_members ()
- {
- os << ", idn, idt";
- }
- };
- entry<container_cache_init_members> container_cache_init_members_;
-
- struct section_cache_init_members:
- relational::section_cache_init_members
- {
- section_cache_init_members (base const& x): base (x) {}
-
- virtual void
- extra_members ()
- {
- os << ", idn, idt";
- }
- };
- entry<section_cache_init_members> section_cache_init_members_;
- }
- }
-}