From 7871bd9b681f449cc3938750ce70fa1ed5400dcd Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 1 Nov 2011 12:41:02 +0200 Subject: Implement support for optimistic concurrency New pragmas: optimistic, version. New test: optimistic. New database function: reload(). --- odb/relational/pgsql/header.cxx | 41 ++++++++++++++++++++++--------- odb/relational/pgsql/source.cxx | 53 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 15 deletions(-) (limited to 'odb/relational/pgsql') diff --git a/odb/relational/pgsql/header.cxx b/odb/relational/pgsql/header.cxx index 474b69c..db7a939 100644 --- a/odb/relational/pgsql/header.cxx +++ b/odb/relational/pgsql/header.cxx @@ -26,17 +26,27 @@ namespace relational if (abstract (c)) return; + semantics::data_member* id (id_member (c)); + semantics::data_member* optimistic (context::optimistic (c)); + column_count_type const& cc (column_count (c)); // Statement names. // - os << "static const char persist_statement_name[];" - << "static const char find_statement_name[];"; + os << "static const char persist_statement_name[];"; + + if (id != 0) + { + os << "static const char find_statement_name[];"; - if (cc.total != cc.id + cc.inverse + cc.readonly) - os << "static const char update_statement_name[];"; + if (cc.total != cc.id + cc.inverse + cc.readonly) + os << "static const char update_statement_name[];"; - os << "static const char erase_statement_name[];"; + os << "static const char erase_statement_name[];"; + + if (optimistic != 0) + os << "static const char optimistic_erase_statement_name[];"; + } // Query statement name. // @@ -48,14 +58,23 @@ namespace relational // Statement types. // - os << "static const unsigned int persist_statement_types[];" - << "static const unsigned int find_statement_types[];"; + os << "static const unsigned int persist_statement_types[];"; - if (cc.total != cc.id + cc.inverse + cc.readonly) - os << "static const unsigned int update_statement_types[];"; + if (id != 0) + { + os << "static const unsigned int find_statement_types[];"; - os << "static const unsigned int erase_statement_types[];" - << endl; + if (cc.total != cc.id + cc.inverse + cc.readonly) + os << "static const unsigned int update_statement_types[];"; + + os << "static const unsigned int erase_statement_types[];"; + + if (optimistic != 0) + os << "static const unsigned int " << + "optimistic_erase_statement_types[];"; + } + + os << endl; } virtual void diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx index 6bfa3d9..0ff0bf1 100644 --- a/odb/relational/pgsql/source.cxx +++ b/odb/relational/pgsql/source.cxx @@ -122,6 +122,10 @@ namespace relational sk_ == statement_update) return false; + if ((sk_ == statement_insert || sk_ == statement_update) && + version (m)) + return false; + if (!first) os << ',' << endl; @@ -164,7 +168,7 @@ namespace relational os << "// " << mi.m.name () << endl << "//" << endl; - if (inverse (mi.m, key_prefix_)) + if (inverse (mi.m, key_prefix_) || version (mi.m)) os << "if (sk == statement_select)" << "{"; // If the whole class is readonly, then we will never be @@ -209,7 +213,7 @@ namespace relational << "sk == statement_select ? 0 : "; if (cc.inverse != 0) - os << cc.inverse << "UL" << endl; + os << cc.inverse << "UL"; if (!ro && cc.readonly != 0) { @@ -233,7 +237,7 @@ namespace relational // The same logic as in pre(). // - if (inverse (mi.m, key_prefix_)) + if (inverse (mi.m, key_prefix_) || version (mi.m)) block = true; else if (!readonly (*context::top_object)) { @@ -493,6 +497,12 @@ namespace relational member = member_override_; else { + // If we are generating standard init() and this member + // contains version, ignore it. + // + if (version (mi.m)) + return false; + string const& name (mi.m.name ()); member = "o." + name; @@ -1001,6 +1011,7 @@ namespace relational return; semantics::data_member* id (id_member (c)); + semantics::data_member* optimistic (context::optimistic (c)); column_count_type const& cc (column_count (c)); string const& n (c.fq_name ()); @@ -1028,6 +1039,12 @@ namespace relational os << name_decl << endl << "erase_statement_name[] = " << strlit (fn + "_erase") << ";" << endl; + + if (optimistic != 0) + os << name_decl << endl + << "optimistic_erase_statement_name[] = " << + strlit (fn + "_optimistic_erase") << ";" + << endl; } // Query statement name. @@ -1087,9 +1104,18 @@ namespace relational st->traverse (c); } + bool first (cc.total == cc.id + cc.inverse + cc.readonly + + cc.optimistic_managed); + { instance st (statement_where); - st->traverse_column (*id, "", false); + st->traverse_column (*id, "", first); + } + + if (optimistic != 0) + { + instance st (statement_where); + st->traverse_column (*optimistic, "", false); } os << "};"; @@ -1108,6 +1134,25 @@ namespace relational os << "};"; } + + if (id != 0 && optimistic != 0) + { + os << oid_decl << endl + << "optimistic_erase_statement_types[] =" + << "{"; + + { + instance st (statement_where); + st->traverse_column (*id, "", true); + } + + { + instance st (statement_where); + st->traverse_column (*optimistic, "", false); + } + + os << "};"; + } } virtual void -- cgit v1.1