From 823026b58211a4166de06ac243d978dcb9930271 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 22 Jan 2024 15:58:08 +0300 Subject: Turn odb repository into muti-package repository Also remove the autoconf/make-based build system. --- odb/relational/pgsql/common.cxx | 351 ------------ odb/relational/pgsql/common.hxx | 159 ------ odb/relational/pgsql/context.cxx | 786 -------------------------- odb/relational/pgsql/context.hxx | 192 ------- odb/relational/pgsql/header.cxx | 285 ---------- odb/relational/pgsql/inline.cxx | 42 -- odb/relational/pgsql/model.cxx | 101 ---- odb/relational/pgsql/schema.cxx | 266 --------- odb/relational/pgsql/source.cxx | 1140 -------------------------------------- 9 files changed, 3322 deletions(-) delete mode 100644 odb/relational/pgsql/common.cxx delete mode 100644 odb/relational/pgsql/common.hxx delete mode 100644 odb/relational/pgsql/context.cxx delete mode 100644 odb/relational/pgsql/context.hxx delete mode 100644 odb/relational/pgsql/header.cxx delete mode 100644 odb/relational/pgsql/inline.cxx delete mode 100644 odb/relational/pgsql/model.cxx delete mode 100644 odb/relational/pgsql/schema.cxx delete mode 100644 odb/relational/pgsql/source.cxx (limited to 'odb/relational/pgsql') 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 - -#include - -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_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_; - - // - // 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_; - } -} 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 -#include - -namespace relational -{ - namespace pgsql - { - struct member_base: virtual relational::member_base_impl, 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 7f99f5d..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 -#include - -#include - -#include -#include - -#include -#include - -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 (root_context::data_.get ()), m), - data_ (static_cast (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 = true; - 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 ("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 (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 ("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 (&t)) - { - semantics::type& bt (a->base_type ()); - if (bt.is_a ()) - { - 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") : 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 - -#include - -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 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 c3efc3e..0000000 --- a/odb/relational/pgsql/header.cxx +++ /dev/null @@ -1,285 +0,0 @@ -// file : odb/relational/pgsql/header.cxx -// license : GNU GPL v3; see accompanying LICENSE file - -#include - -#include -#include - -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; - - if (poly_derived) - return; - - // Bulk operations batch size. - // - { - unsigned long long b (c.count ("bulk") - ? c.get ("bulk") - : 1); - - os << "static const std::size_t batch = " << b << "UL;" - << endl; - } - } - - virtual void - view_public_extra_post (type&) - { - // Statement names. - // - os << "static const char query_statement_name[];" - << endl; - } - }; - entry 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_; - - 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_; - - struct image_member: relational::image_member_impl, - 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_; - } - } -} 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 - -#include -#include - -using namespace std; - -namespace relational -{ - namespace pgsql - { - namespace inline_ - { - namespace relational = relational::inline_; - - struct null_member: relational::null_member_impl, - 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_; - } - } -} 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 - -#include - -#include - -#include -#include - -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 ("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 (*unit.find (en))); - - ostringstream ostr; - - if (e.enum_ ().unsigned_ ()) - ostr << e.value (); - else - ostr << static_cast (e.value ()); - - return ostr.str (); - } - }; - entry 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 - -#include -#include - -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_; - - // - // 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_; - - 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_; - - 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_; - - // - // 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_; - - // - // 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_; - } - } -} diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx deleted file mode 100644 index b881e48..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 - -#include - -#include -#include - -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_; - - 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, - 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_ptr ();" - << 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_ptr ();" - << 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_ptr ();" - << 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_; - - // - // grow - // - - struct grow_member: relational::grow_member_impl, - 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_; - - // - // init image - // - - struct init_image_member: relational::init_image_member_impl, - 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 value - // - - struct init_value_member: relational::init_value_member_impl, - 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_; - - 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_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_; - - 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_; - - 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_; - - 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_; - } - } -} -- cgit v1.1