aboutsummaryrefslogtreecommitdiff
path: root/odb/relational/pgsql
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-11-01 12:41:02 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-11-01 14:30:22 +0200
commit7871bd9b681f449cc3938750ce70fa1ed5400dcd (patch)
tree3784716722430f06799016e3b7bdae7231fd9120 /odb/relational/pgsql
parentc11ace0f4a665ac0dfb269860ef04dce284b75f5 (diff)
Implement support for optimistic concurrency
New pragmas: optimistic, version. New test: optimistic. New database function: reload().
Diffstat (limited to 'odb/relational/pgsql')
-rw-r--r--odb/relational/pgsql/header.cxx41
-rw-r--r--odb/relational/pgsql/source.cxx53
2 files changed, 79 insertions, 15 deletions
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<statement_oids> st (statement_where);
- st->traverse_column (*id, "", false);
+ st->traverse_column (*id, "", first);
+ }
+
+ if (optimistic != 0)
+ {
+ instance<statement_oids> 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<statement_oids> st (statement_where);
+ st->traverse_column (*id, "", true);
+ }
+
+ {
+ instance<statement_oids> st (statement_where);
+ st->traverse_column (*optimistic, "", false);
+ }
+
+ os << "};";
+ }
}
virtual void