aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-06-29 08:32:36 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-07-05 14:43:38 +0200
commite12f2adb8f345ecbff5d92d6bd2ba672769bd410 (patch)
tree9d04023bc9c9d920a37e8bf328034dd572afb945
parentba529a8179f27d3ccbc584925fde6cd270f790ce (diff)
Implement PostgreSQL container statement name and types array generation
-rw-r--r--odb/relational/pgsql/header.cxx63
-rw-r--r--odb/relational/pgsql/source.cxx297
2 files changed, 289 insertions, 71 deletions
diff --git a/odb/relational/pgsql/header.cxx b/odb/relational/pgsql/header.cxx
index 172bf03..e66529e 100644
--- a/odb/relational/pgsql/header.cxx
+++ b/odb/relational/pgsql/header.cxx
@@ -23,28 +23,55 @@ namespace relational
virtual void
object_public_extra_post (type& t)
{
- if (!abstract (t))
- {
- // Statement names.
- //
- os << "static const char* const persist_statement_name;"
- << "static const char* const find_statement_name;"
- << "static const char* const update_statement_name;"
- << "static const char* const erase_statement_name;"
- << endl;
-
- // Statement oids.
- //
- os << "static const Oid persist_statement_types[];"
- << "static const Oid find_statement_types[];"
- << "static const Oid update_statement_types[];"
- << "static const Oid erase_statement_types[];"
- << endl;
- }
+ if (abstract (t))
+ return;
+
+ // Statement names.
+ //
+ os << "static const char* const persist_statement_name;"
+ << "static const char* const find_statement_name;"
+ << "static const char* const update_statement_name;"
+ << "static const char* const erase_statement_name;"
+ << endl;
+
+ // Statement types.
+ //
+ os << "static const Oid persist_statement_types[];"
+ << "static const Oid find_statement_types[];"
+ << "static const Oid update_statement_types[];"
+ << "static const Oid erase_statement_types[];"
+ << endl;
}
};
entry<class_> class_entry_;
+ struct container_traits: relational::container_traits, context
+ {
+ container_traits (base const& x): base (x) {}
+
+ virtual void
+ container_public_extra_pre (semantics::data_member&)
+ {
+ if (abstract (c_))
+ return;
+
+ // Container statement names.
+ //
+ os << "static const char* const select_all_name;"
+ << "static const char* const insert_one_name;"
+ << "static const char* const delete_all_name;"
+ << endl;
+
+ // Container statement types.
+ //
+ os << "static const Oid select_all_types[];"
+ << "static const Oid insert_one_types[];"
+ << "static const Oid delete_all_types[];"
+ << endl;
+ }
+ };
+ entry<container_traits> container_traits_;
+
struct image_member: relational::image_member, member_base
{
image_member (base const& x)
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index 20f11cc..8fb2b0e 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -112,37 +112,38 @@ namespace relational
struct statement_oids: object_columns_base, context
{
- statement_oids (ostringstream& os)
- : column_oids (os)
+ statement_oids (): first_ (true) {}
+
+ bool
+ container_column (semantics::data_member& m,
+ std::string const& key_prefix,
+ bool)
{
+ write_oid_ (column_sql_type (m, key_prefix));
+ return true;
}
virtual bool
- column (semantics::data_member& m, std::string const&, bool first)
+ column (semantics::data_member& m, std::string const&, bool)
{
- semantics::data_member* im (inverse (m));
-
- if (im != 0)
- return false;
-
- const sql_type& t (column_sql_type (m));
-
- if (!first)
- column_oids << ',' << endl;
+ write_oid_ (column_sql_type (m));
+ return true;
+ }
- column_oids << oids[t.type - sql_type::BOOLEAN];
+ private:
+ void
+ write_oid_ (sql_type const& t)
+ {
+ if (!first_)
+ os << ',' << endl;
- if (m.count ("id"))
- id_oid = oids[t.type - sql_type::BOOLEAN];
+ os << oids[t.type];
- return true;
+ first_ = false;
}
- public:
- string id_oid;
-
private:
- ostringstream& column_oids;
+ bool first_;
};
//
@@ -874,56 +875,246 @@ namespace relational
if (abstract (t))
return;
- string const& type (t.fq_name ());
- string traits ("access::object_traits< " + type + " >::");
+ string const& tn (t.fq_name ());
+ string traits ("access::object_traits< " + tn + " >::");
+ string const& fn (flat_name (tn));
+ string name_decl ("const char* const " + traits);
+
+ os << name_decl << endl
+ << "persist_statement_name =" << strlit (fn + "_persist") << ";"
+ << endl
+ << name_decl << endl
+ << "find_statement_name =" << strlit (fn + "_find") << ";"
+ << endl
+ << name_decl << endl
+ << "update_statement_name =" << strlit (fn + "_update") << ";"
+ << endl
+ << name_decl << endl
+ << "erase_statement_name =" << strlit (fn + "_erase") << ";"
+ << endl;
+
+ string oid_decl ("const Oid " + traits);
+ // persist_statement_types.
//
- // Statement names.
+ {
+ os << oid_decl << endl
+ << "persist_statement_types[] ={";
+
+ instance<statement_oids> st;
+ st->traverse (t);
+
+ os << "};";
+ }
+
+ // find_statement_types.
//
+ {
+ os << oid_decl << endl
+ << "find_statement_types[] ={";
- string fn (flat_name (type));
- string name_decl ("const char* const " + traits);
+ instance<statement_oids> st;
+ st->column (*id_member (t), "", true);
- os << name_decl << "persist_statement_name =" << endl
- << strlit ( fn + "_persist" ) << ";"
- << name_decl << "find_statement_name =" << endl
- << strlit ( fn + "_find" ) << ";"
- << name_decl << "update_statement_name =" << endl
- << strlit ( fn + "_update" ) << ";"
- << name_decl << "erase_statement_name =" << endl
- << strlit ( fn + "_erase" ) << ";"
- << endl;
+ os << "};";
+ }
+
+ // update_statement_types.
+ //
+ {
+ os << oid_decl << endl
+ << "update_statement_types[] ={";
+
+ instance<statement_oids> st;
+ st->traverse (t);
+ st->column (*id_member (t), "", false);
+
+ os << "};";
+ }
+
+ // erase_statement_types.
+ //
+ {
+ os << oid_decl << endl
+ << "erase_statement_types[] ={";
+
+ instance<statement_oids> st;
+ st->column (*id_member (t), "", true);
+
+ os << "};";
+ }
+ }
+ };
+ entry<class_> class_entry_;
+
+ //
+ // container traits
+ //
+
+ struct container_traits : relational::container_traits, context
+ {
+ container_traits (base const& x): base (x) {}
+
+ virtual void
+ container_extra (semantics::data_member& m)
+ {
+ if (!c_.count ("object") || abstract (c_))
+ return;
+
+ string scope (scope_ + "::" + prefix_ + public_name (m) + "_traits");
+
+ //
+ // Statment names.
+ //
+
+ string stmt_decl ("const char* const " + scope + "::");
+ string stmt_prefix (flat_name ( m.fq_name ()));
+
+ os << stmt_decl << endl
+ << "insert_one_name = "
+ << strlit (stmt_prefix + "_select_all") << ";" << endl
+ << stmt_decl << endl
+ << "select_all_name = "
+ << strlit (stmt_prefix + "_insert_one") << ";" << endl
+ << stmt_decl << endl
+ << "delete_all_name = "
+ << strlit (stmt_prefix + "_delete_all") << ";" << endl;
//
// Statement types.
//
- ostringstream ss;
- instance<statement_oids> st (ss);
- st->traverse (t);
+ string type_decl ("const Oid " + scope + "::");
- string oid_decl ("const Oid " + traits);
+ semantics::data_member* inv_m (inverse (m, "value"));
+ bool inv (inv_m != 0);
- os << oid_decl << endl
- << "persist_statement_types[] ="
- << "{" << ss.str () << "};"
- << endl;
+ semantics::type& mt (m.type ());
+ semantics::type& vt (container_vt (mt));
+ semantics::type* kt (0), *it (0);
- os << oid_decl << "find_statement_types[] ="
- << "{" << st->id_oid << "};"
- << endl;
+ container_kind_type ck (container_kind (mt));
+ bool ordered (false);
- os << oid_decl << "update_statement_types[] ="
- << "{" << ss.str () << "," << endl
- << st->id_oid << "};"
- << endl;
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ if (!unordered (m))
+ {
+ it = &container_it (mt);
+ ordered = true;
+ }
- os << oid_decl << "erase_statement_types[] ="
- << "{" << st->id_oid << "};"
- << endl;
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ kt = &container_kt (mt);
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ break;
+ }
+ }
+
+ //
+ // select_all statement types.
+ //
+ {
+ instance<statement_oids> st;
+ os << type_decl << endl
+ << "select_all_types[] ={";
+
+ if (inv)
+ {
+ semantics::class_* c (object_pointer (vt));
+
+ // many(i)-to-many
+ //
+ if (context::container (inv_m->type ()))
+ st->container_column (*inv_m, "id", true);
+ // many(i)-to-one
+ //
+ else
+ st->column (*id_member (*c), "", true);
+ }
+ else
+ {
+ st->container_column (m, "id", true);
+ }
+
+ os << "};";
+ }
+
+ //
+ // insert_one statement types.
+ //
+ {
+ instance<statement_oids> st;
+ os << type_decl << endl
+ << "insert_one_types[] ={";
+
+ if (!inv)
+ {
+ st->container_column (m, "id", true);
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ if (ordered)
+ st->container_column (m, "index", false);
+
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ if (semantics::class_* ktc = comp_value (*kt))
+ st->traverse_composite (m, *ktc, "key", "key");
+ else
+ st->container_column (m, "key", false);
+
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ break;
+ }
+ }
+
+ if (semantics::class_* vtc = comp_value (vt))
+ st->traverse_composite (m, *vtc, "value", "value");
+ else
+ st->container_column (m, "value", false);
+ }
+
+ os << "};";
+ }
+
+ //
+ // delete_all statement types.
+ //
+ {
+ os << type_decl << endl
+ << "delete_all_types[] ={";
+
+ if (!inv)
+ {
+ instance<statement_oids> st;
+ st->container_column (m, "id", true);
+ }
+
+ os << "};";
+ }
}
};
- entry<class_> class_entry_;
+ entry<container_traits> container_traits_;
}
}
}