From 164b277b51a14573cd99e117f21f1624fbe5a562 Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Fri, 10 Jun 2011 09:12:52 +0200 Subject: Implement remainder of PostgreSQL context --- odb/relational/pgsql/context.cxx | 388 +++++++++++++++------------------------ odb/relational/pgsql/context.hxx | 50 ++--- 2 files changed, 177 insertions(+), 261 deletions(-) (limited to 'odb') diff --git a/odb/relational/pgsql/context.cxx b/odb/relational/pgsql/context.cxx index fb25936..ea18d1f 100644 --- a/odb/relational/pgsql/context.cxx +++ b/odb/relational/pgsql/context.cxx @@ -10,7 +10,7 @@ #include #include -//#include +#include using namespace std; @@ -66,31 +66,31 @@ namespace relational current_ = 0; } - // context:: - // context (ostream& os, semantics::unit& u, options_type const& ops) - // : root_context (os, u, ops, data_ptr (new (shared) data (os))), - // base_context (static_cast (root_context::data_.get ())), - // data_ (static_cast (base_context::data_)) - // { - // assert (current_ == 0); - // current_ = this; + context:: + context (ostream& os, semantics::unit& u, options_type const& ops) + : root_context (os, u, ops, data_ptr (new (shared) data (os))), + base_context (static_cast (root_context::data_.get ())), + data_ (static_cast (base_context::data_)) + { + assert (current_ == 0); + current_ = this; - // data_->bind_vector_ = "MYSQL_BIND*"; - // data_->truncated_vector_ = "my_bool*"; + 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]); + // 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)); + 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)); - // data_->type_map_.insert (v); - // } - // } + data_->type_map_.insert (v); + } + } context:: context () @@ -98,205 +98,117 @@ namespace relational { } - // string context:: - // quote_id_impl (string const& id) const - // { - // string r; - // r.reserve (id.size ()); - // r += '`'; - // r += id; - // r += '`'; - // return r; - // } - - // namespace - // { - // struct has_grow: traversal::class_ - // { - // has_grow (bool& r) - // : r_ (r) - // { - // *this >> inherits_ >> *this; - // } - - // virtual void - // traverse (type& c) - // { - // // Ignore transient bases. - // // - // if (!(c.count ("object") || context::comp_value (c))) - // return; - - // if (c.count ("mysql-grow")) - // r_ = c.get ("mysql-grow"); - // else - // { - // // r_ should be false. - // // - // inherits (c); - - // if (!r_) - // names (c); - - // c.set ("mysql-grow", r_); - // } - // } - - // private: - // bool& r_; - // traversal::inherits inherits_; - // }; - - // struct has_grow_member: member_base - // { - // has_grow_member (bool& r, - // semantics::type* type = 0, - // string const& key_prefix = string ()) - // : relational::member_base (type, string (), key_prefix), - // r_ (r) - // { - // } - - // virtual void - // traverse_composite (member_info& mi) - // { - // // By calling grow() instead of recursing, we reset any overrides. - // // - // r_ = r_ || context::grow (dynamic_cast (mi.t)); - // } - - // virtual void - // traverse_decimal (member_info&) - // { - // r_ = true; - // } - - // virtual void - // traverse_long_string (member_info&) - // { - // r_ = true; - // } - - // virtual void - // traverse_short_string (member_info&) - // { - // r_ = true; // @@ Short string optimization disabled. - // } - - // virtual void - // traverse_enum (member_info&) - // { - // r_ = true; - // } - - // virtual void - // traverse_set (member_info&) - // { - // r_ = true; - // } - - // private: - // bool& r_; - // }; - // } - - // bool context:: - // grow_impl (semantics::class_& c) - // { - // if (c.count ("mysql-grow")) - // return c.get ("mysql-grow"); - - // bool r (false); - // has_grow ct (r); - // has_grow_member mt (r); - // 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); - // return r; - // } - - // bool context:: - // grow_impl (semantics::data_member& m, semantics::type& t, string const& kp) - // { - // bool r (false); - // has_grow_member mt (r, &t, kp); - // mt.traverse (m); - // return r; - // } - - // string context:: - // database_type_impl (semantics::type& t, - // semantics::names* hint, - // semantics::context& ctx, - // column_type_flags f) - // { - // string r (base_context::database_type_impl (t, hint, ctx, f)); - - // if (!r.empty ()) - // return r; - - // using semantics::enum_; - // using semantics::enumerator; - - // if (enum_* e = dynamic_cast (&t)) - // { - // // We can only map to ENUM if the C++ enumeration is contiguous - // // and starts with 0. - // // - // if (e->unsigned_ ()) - // { - // enum_::enumerates_iterator i (e->enumerates_begin ()), - // end (e->enumerates_end ()); - - // if (i != end) - // { - // r += "ENUM ("; - - // for (unsigned long long j (0); i != end; ++i, ++j) - // { - // enumerator const& er (i->enumerator ()); - - // if (er.value () != j) - // break; - - // if (j != 0) - // r += ", "; - - // r += '\''; - // r += er.name (); - // r += '\''; - // } - - // if (i == end) - // r += ")"; - // else - // r.clear (); - // } - // } - - // if (r.empty ()) - // { - // r = "INT"; - - // if (e->unsigned_ ()) - // r += " UNSIGNED"; - // } - - // if ((f & ctf_default_null) == 0) - // r += " NOT NULL"; - // } - - // return r; - // } + namespace + { + struct has_grow: traversal::class_ + { + has_grow (bool& r) + : r_ (r) + { + *this >> inherits_ >> *this; + } + + virtual void + traverse (type& c) + { + // Ignore transient bases. + // + if (!(c.count ("object") || context::comp_value (c))) + return; + + if (c.count ("pgsql-grow")) + r_ = c.get ("pgsql-grow"); + else + { + // r_ should be false. + // + inherits (c); + + if (!r_) + names (c); + + c.set ("pgsql-grow", r_); + } + } + + private: + bool& r_; + traversal::inherits inherits_; + }; + + struct has_grow_member: member_base + { + has_grow_member (bool& r, + semantics::type* type = 0, + string const& key_prefix = string ()) + : relational::member_base (type, string (), key_prefix), + r_ (r) + { + } + + virtual void + traverse_composite (member_info& mi) + { + // By calling grow() instead of recursing, we reset any overrides. + // + 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) + { + if (c.count ("pgsql-grow")) + return c.get ("pgsql-grow"); + + bool r (false); + has_grow ct (r); + has_grow_member mt (r); + 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); + return r; + } + + bool context:: + grow_impl (semantics::data_member& m, semantics::type& t, string const& kp) + { + bool r (false); + has_grow_member mt (r, &t, kp); + mt.traverse (m); + return r; + } // // SQL type parsing. @@ -305,18 +217,18 @@ namespace relational static sql_type parse_sql_type (semantics::data_member& m, std::string const& sql); - // sql_type const& context:: - // column_sql_type (semantics::data_member& m, string const& kp) - // { - // string key (kp.empty () - // ? string ("mysql-column-sql-type") - // : "mysql-" + kp + "-column-sql-type"); + sql_type const& context:: + column_sql_type (semantics::data_member& m, string const& kp) + { + string key (kp.empty () + ? string ("pgsql-column-sql-type") + : "pgsql-" + kp + "-column-sql-type"); - // if (!m.count (key)) - // m.set (key, parse_sql_type (m, column_type (m, kp))); + if (!m.count (key)) + m.set (key, parse_sql_type (m, column_type (m, kp))); - // return m.get (key); - // } + return m.get (key); + } static sql_type parse_sql_type (semantics::data_member& m, string const& sql) @@ -329,9 +241,11 @@ namespace relational // 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) + // 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 @@ -417,11 +331,11 @@ namespace relational // Assign a type only once we know the precision of the // float. // - flt_ = true; + flt = true; } - else if (id == "DECIMAL" || id == "NUMERIC") + else if (id == "NUMERIC" || id == "DECIMAL") { - r.type = sql_type::DECIMAL; + r.type = sql_type::NUMERIC; } // // Date-time types. diff --git a/odb/relational/pgsql/context.hxx b/odb/relational/pgsql/context.hxx index f570c86..3190bb3 100644 --- a/odb/relational/pgsql/context.hxx +++ b/odb/relational/pgsql/context.hxx @@ -29,7 +29,7 @@ namespace relational // REAL, DOUBLE, - DECIMAL, + NUMERIC, // Data-time types. // @@ -68,35 +68,37 @@ namespace relational class context: public virtual relational::context { - // public: - // sql_type const& - // column_sql_type (semantics::data_member&, - // string const& key_prefix = string ()); - - // protected: - // virtual bool - // grow_impl (semantics::class_&); - - // virtual bool - // grow_impl (semantics::data_member&); - - // virtual bool - // grow_impl (semantics::data_member&, semantics::type&, string const&); - - // protected: - // virtual string - // database_type_impl (semantics::type&, - // semantics::names*, - // semantics::context&, - // column_type_flags); + public: + sql_type const& + column_sql_type (semantics::data_member&, + string const& key_prefix = string ()); + + protected: + virtual bool + grow_impl (semantics::class_&); + + virtual bool + grow_impl (semantics::data_member&); + + virtual bool + grow_impl (semantics::data_member&, semantics::type&, string const&); + + protected: + virtual string + database_type_impl (semantics::type& t, + semantics::names* hint, + semantics::context& ctx, + column_type_flags f) + { + return base_context::database_type_impl (t, hint, ctx, f); + } public: virtual ~context (); context (); - - // context (std::ostream&, semantics::unit&, options_type const&); + context (std::ostream&, semantics::unit&, options_type const&); static context& current () -- cgit v1.1