aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-09-02 08:33:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-09-02 08:33:25 +0200
commit3e23b0478aa8f426e0443d2c4c0189b4da0e6198 (patch)
treef3d3c7ba0e2cb26e7d060795c368f38eeb118f97
parentf3f682c074117fda84bf51a4ce9a378d950a04de (diff)
Support for versioning simple value in object
-rw-r--r--odb/context.cxx3
-rw-r--r--odb/context.hxx39
-rw-r--r--odb/processor.cxx51
-rw-r--r--odb/relational/header.cxx128
-rw-r--r--odb/relational/header.hxx2
-rw-r--r--odb/relational/inline.hxx93
-rw-r--r--odb/relational/pgsql/source.cxx35
-rw-r--r--odb/relational/source.cxx266
-rw-r--r--odb/relational/source.hxx235
9 files changed, 663 insertions, 189 deletions
diff --git a/odb/context.cxx b/odb/context.cxx
index 5fc14d4..af07007 100644
--- a/odb/context.cxx
+++ b/odb/context.cxx
@@ -2402,6 +2402,9 @@ namespace
if (discriminator (m))
c_.discriminator++;
+ if (added (member_path_) || deleted (member_path_))
+ c_.soft++;
+
if (separate_load (member_path_))
c_.separate_load++;
diff --git a/odb/context.hxx b/odb/context.hxx
index df32cdd..9c52282 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -726,7 +726,7 @@ public:
return m.count ("transient");
}
- // Return the deletion version or 0 if not fort-deleted.
+ // Return the deletion version or 0 if not soft-deleted.
//
static unsigned long long
deleted (semantics::class_& c)
@@ -735,6 +735,12 @@ public:
}
static unsigned long long
+ deleted (semantics::data_member& m)
+ {
+ return m.get<unsigned long long> ("deleted", 0);
+ }
+
+ static unsigned long long
deleted (data_member_path const& mp)
{
unsigned long long r (0);
@@ -745,7 +751,7 @@ public:
i != mp.rend (); ++i)
{
unsigned long long v ((*i)->get<unsigned long long> ("deleted", 0));
- if (v != 0 && v < r)
+ if (v != 0 && (r == 0 || v < r))
r = v;
}
@@ -755,6 +761,12 @@ public:
// Return the addition version or 0 if not soft-added.
//
static unsigned long long
+ added (semantics::data_member& m)
+ {
+ return m.get<unsigned long long> ("added", 0);
+ }
+
+ static unsigned long long
added (data_member_path const& mp)
{
unsigned long long r (0);
@@ -888,6 +900,26 @@ public:
return unit.get<model_version> ("model-version");
}
+ // Versioned object, view, or composite.
+ //
+ static bool
+ versioned (semantics::class_& c)
+ {
+ // Set by processor.
+ //
+ return c.count ("versioned") != 0;
+ }
+
+ // Versioned container.
+ //
+ static bool
+ versioned (semantics::data_member& m)
+ {
+ // Set by processor.
+ //
+ return container (m)->count ("versioned");
+ }
+
// Object sections.
//
static object_section&
@@ -1145,6 +1177,7 @@ public:
readonly (0),
optimistic_managed (0),
discriminator (0),
+ soft (0),
separate_load (0),
separate_update (0)
{
@@ -1157,6 +1190,8 @@ public:
size_t optimistic_managed;
size_t discriminator;
+ size_t soft; // Soft-added/deleted.
+
size_t separate_load;
size_t separate_update; // Only readwrite.
};
diff --git a/odb/processor.cxx b/odb/processor.cxx
index bc6c408..8c4efaf 100644
--- a/odb/processor.cxx
+++ b/odb/processor.cxx
@@ -1656,6 +1656,13 @@ namespace
t.set ("key-tree-hint", kh);
t.set ("key-not-null", true);
}
+
+ // Check if we are versioned.
+ //
+ // @@ TODO
+ //
+ if (force_versioned)
+ t.set ("versioned", true);
}
// Process member data.
@@ -1896,12 +1903,16 @@ namespace
if (k == class_object)
traverse_object_pre (c);
else if (k == class_view)
- traverse_view (c);
+ traverse_view_pre (c);
names (c);
if (k == class_object)
traverse_object_post (c);
+ else if (k == class_view)
+ traverse_view_post (c);
+ else if (k == class_composite)
+ traverse_composite_post (c);
}
//
@@ -2085,8 +2096,19 @@ namespace
traverse_object_post (type& c)
{
semantics::class_* poly_root (polymorphic (c));
+ bool poly_derived (poly_root != 0 && poly_root != &c);
+
semantics::data_member* opt (optimistic (c));
+ // Figure out if we are versioned. We are versioned if we have
+ // soft-added/deleted columns ourselves or our poly-base is
+ // versioned.
+ //
+ if (force_versioned ||
+ column_count (c).soft != 0 ||
+ (poly_derived && polymorphic_base (c).count ("versioned")))
+ c.set ("versioned", true);
+
// Sections.
//
user_sections& uss (c.get<user_sections> ("user-sections"));
@@ -2149,7 +2171,7 @@ namespace
//
virtual void
- traverse_view (type& c)
+ traverse_view_pre (type& c)
{
// Resolve referenced objects from tree nodes to semantic graph
// nodes. Also populate maps and compute counts.
@@ -2258,6 +2280,31 @@ namespace
}
}
+ virtual void
+ traverse_view_post (type& c)
+ {
+ // Figure out if we are versioned. When versioning is forced, ignore
+ // it for native views.
+ //
+ if ((force_versioned &&
+ c.get<view_query> ("query").kind == view_query::condition) ||
+ column_count (c).soft != 0)
+ c.set ("versioned", true);
+ }
+
+ //
+ // Composite.
+ //
+
+ virtual void
+ traverse_composite_post (type& c)
+ {
+ // Figure out if we are versioned.
+ //
+ if (force_versioned || column_count (c).soft != 0)
+ c.set ("versioned", true);
+ }
+
//
// Assign object/view pointer.
//
diff --git a/odb/relational/header.cxx b/odb/relational/header.cxx
index 9bf6f5e..f3df52b 100644
--- a/odb/relational/header.cxx
+++ b/odb/relational/header.cxx
@@ -26,6 +26,8 @@ traverse_object (type& c)
bool abst (abstract (c));
bool reuse_abst (abst && !poly);
+ bool versioned (context::versioned (c));
+
string const& type (class_fq_name (c));
// Sections.
@@ -237,10 +239,16 @@ traverse_object (type& c)
// false).
//
os << "static bool" << endl
- << "grow (image_type&, " << truncated_vector;
+ << "grow (image_type&," << endl
+ << truncated_vector;
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
if (poly_derived)
- os << ", std::size_t = depth";
+ os << "," << endl
+ << "std::size_t = depth";
os << ");"
<< endl;
@@ -259,7 +267,13 @@ traverse_object (type& c)
<< "std::size_t id_size," << endl;
os << "image_type&," << endl
- << db << "::statement_kind);"
+ << db << "::statement_kind";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
+
+ os << ");"
<< endl;
// bind (id_image_type)
@@ -275,16 +289,31 @@ traverse_object (type& c)
// init (image, object)
//
os << "static " << (generate_grow ? "bool" : "void") << endl
- << "init (image_type&, const object_type&, " << db << "::statement_kind);"
+ << "init (image_type&," << endl
+ << "const object_type&," << endl
+ << db << "::statement_kind";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
+
+ os << ");"
<< endl;
// init (object, image)
//
os << "static void" << endl
- << "init (object_type&, const image_type&, database*";
+ << "init (object_type&," << endl
+ << "const image_type&," << endl
+ << "database*";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
if (poly_derived)
- os << ", std::size_t = depth";
+ os << "," << endl
+ << "std::size_t = depth";
os << ");"
<< endl;
@@ -325,7 +354,6 @@ traverse_object (type& c)
}
column_count_type const& cc (column_count (c));
- bool versioned (force_versioned);
// Statements typedefs.
//
@@ -347,8 +375,6 @@ traverse_object (type& c)
<< "statements_type;"
<< endl
<< "typedef statements_type root_statements_type;"
- << "typedef " << db << "::object_statements<object_type> " <<
- "base_statements_type;"
<< endl;
}
else
@@ -610,17 +636,16 @@ traverse_object (type& c)
// Load the object image.
//
os << "static bool" << endl
- << "find_ (";
-
- if (poly && !poly_derived)
- os << "base_statements_type&, ";
- else
- os << "statements_type&, ";
+ << "find_ (statements_type&," << endl
+ << "const id_type*";
- os << "const id_type*";
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
if (poly_derived && !abst)
- os << ", std::size_t = depth";
+ os << "," << endl
+ << "std::size_t = depth";
os << ");"
<< endl;
@@ -630,14 +655,8 @@ traverse_object (type& c)
// id.
//
os << "static void" << endl
- << "load_ (";
-
- if (poly && !poly_derived)
- os << "base_statements_type&," << endl;
- else
- os << "statements_type&," << endl;
-
- os << "object_type&," << endl
+ << "load_ (statements_type&," << endl
+ << "object_type&," << endl
<< "bool reload = false";
if (poly_derived)
@@ -877,6 +896,8 @@ traverse_view (type& c)
void relational::header::class1::
traverse_composite (type& c)
{
+ bool versioned (context::versioned (c));
+
string const& type (class_fq_name (c));
os << "// " << class_name (c) << endl
@@ -913,27 +934,57 @@ traverse_composite (type& c)
if (generate_grow)
{
os << "static bool" << endl
- << "grow (image_type&, " << truncated_vector << ");"
+ << "grow (image_type&," << endl
+ << truncated_vector;
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
+
+ os << ");"
<< endl;
}
// bind (image_type)
//
os << "static void" << endl
- << "bind (" << bind_vector << ", image_type&, " <<
- db << "::statement_kind);"
+ << "bind (" << bind_vector << "," << endl
+ << "image_type&," << endl
+ << db << "::statement_kind";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
+
+ os << ");"
<< endl;
// init (image, value)
//
os << "static " << (generate_grow ? "bool" : "void") << endl
- << "init (image_type&, const value_type&, " << db << "::statement_kind);"
+ << "init (image_type&," << endl
+ << "const value_type&," << endl
+ << db << "::statement_kind";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
+
+ os << ");"
<< endl;
// init (value, image)
//
os << "static void" << endl
- << "init (value_type&, const image_type&, database*);"
+ << "init (value_type&," << endl
+ << "const image_type&," << endl
+ << "database*";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
+
+ os << ");"
<< endl;
if (!has_a (c, test_container))
@@ -941,13 +992,26 @@ traverse_composite (type& c)
// get_null (image)
//
os << "static bool" << endl
- << "get_null (const image_type&);"
+ << "get_null (const image_type&";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
+
+ os << ");"
<< endl;
// set_null (image)
//
os << "static void" << endl
- << "set_null (image_type&, " << db << "::statement_kind);"
+ << "set_null (image_type&," << endl
+ << db << "::statement_kind";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration&";
+
+ os << ");"
<< endl;
}
diff --git a/odb/relational/header.hxx b/odb/relational/header.hxx
index 0620a98..4aab05c 100644
--- a/odb/relational/header.hxx
+++ b/odb/relational/header.hxx
@@ -324,7 +324,7 @@ namespace relational
data_columns += value_columns;
}
- versioned = force_versioned;
+ versioned = context::versioned (m);
// Store column counts for the source generator.
//
diff --git a/odb/relational/inline.hxx b/odb/relational/inline.hxx
index 928982e..8bdf5a6 100644
--- a/odb/relational/inline.hxx
+++ b/odb/relational/inline.hxx
@@ -42,6 +42,27 @@ namespace relational
virtual bool
pre (member_info& mi)
{
+ // If the member is soft- added or deleted, check the version.
+ //
+ unsigned long long av (added (mi.m));
+ unsigned long long dv (deleted (mi.m));
+ if (av != 0 || dv != 0)
+ {
+ os << "if (";
+
+ if (av != 0)
+ os << "svm >= schema_version_migration (" << av << "ULL, true)";
+
+ if (av != 0 || dv != 0)
+ os << " &&" << endl;
+
+ if (dv != 0)
+ os << "svm <= schema_version_migration (" << dv << "ULL, true)";
+
+ os << ")"
+ << "{";
+ }
+
// If the whole value type is readonly, then set will never be
// called with sk == statement_update.
//
@@ -57,6 +78,13 @@ namespace relational
}
virtual void
+ post (member_info& mi)
+ {
+ if (added (mi.m) || deleted (mi.m))
+ os << "}";
+ }
+
+ virtual void
traverse_composite (member_info& mi)
{
string traits ("composite_value_traits< " + mi.fq_type () + ", id_" +
@@ -64,9 +92,14 @@ namespace relational
if (get_)
os << "r = r && " << traits << "::get_null (" <<
- "i." << mi.var << "value);";
+ "i." << mi.var << "value";
else
- os << traits << "::set_null (i." << mi.var << "value, sk);";
+ os << traits << "::set_null (i." << mi.var << "value, sk";
+
+ if (versioned (*composite (mi.t)))
+ os << ", svm";
+
+ os << ");";
}
};
@@ -94,9 +127,14 @@ namespace relational
os << "if (sk == statement_insert)" << endl;
if (get_)
- os << "r = r && " << traits << "::get_null (i);";
+ os << "r = r && " << traits << "::get_null (i";
else
- os << traits << "::set_null (i, sk);";
+ os << traits << "::set_null (i, sk";
+
+ if (versioned (c))
+ os << ", svm";
+
+ os << ");";
}
protected:
@@ -373,14 +411,9 @@ namespace relational
{
os << "inline" << endl
<< "void " << traits << "::" << endl
- << "load_ (";
-
- if (poly && !poly_derived)
- os << "base_statements_type&, ";
- else
- os << "statements_type&, ";
-
- os << "object_type& obj, bool)"
+ << "load_ (statements_type&," << endl
+ << "object_type& obj," << endl
+ << "bool)"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (obj);"
<< endl;
@@ -499,6 +532,8 @@ namespace relational
virtual void
traverse_composite (type& c)
{
+ bool versioned (context::versioned (c));
+
string const& type (class_fq_name (c));
string traits ("access::composite_value_traits< " + type + ", id_" +
db.string () + " >");
@@ -513,9 +548,20 @@ namespace relational
//
os << "inline" << endl
<< "bool " << traits << "::" << endl
- << "get_null (const image_type& i)"
- << "{"
- << "bool r (true);";
+ << "get_null (const image_type& i";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
+
+ os << ")"
+ << "{";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);"
+ << endl;
+
+ os << "bool r (true);";
inherits (c, get_null_base_inherits_);
names (c, get_null_member_names_);
@@ -527,10 +573,21 @@ namespace relational
//
os << "inline" << endl
<< "void " << traits << "::" << endl
- << "set_null (image_type& i, " << db << "::statement_kind sk)"
+ << "set_null (image_type& i," << endl
+ << db << "::statement_kind sk";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
+
+ os << ")"
<< "{"
- << "ODB_POTENTIALLY_UNUSED (sk);"
- << endl
+ << "ODB_POTENTIALLY_UNUSED (sk);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl
<< "using namespace " << db << ";"
<< endl;
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index 7c5f2f6..a7834a2 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -304,15 +304,44 @@ namespace relational
e = ostr.str ();
if (var_override_.empty ())
+ {
os << "// " << mi.m.name () << endl
<< "//" << endl;
+ // If the member is soft- added or deleted, check the version.
+ //
+ unsigned long long av (added (mi.m));
+ unsigned long long dv (deleted (mi.m));
+ if (av != 0 || dv != 0)
+ {
+ os << "if (";
+
+ if (av != 0)
+ os << "svm >= schema_version_migration (" << av << "ULL, true)";
+
+ if (av != 0 && dv != 0)
+ os << " &&" << endl;
+
+ if (dv != 0)
+ os << "svm <= schema_version_migration (" << dv << "ULL, true)";
+
+ os << ")"
+ << "{";
+ }
+ }
+
return true;
}
virtual void
post (member_info& mi)
{
+ if (var_override_.empty ())
+ {
+ if (added (mi.m) || deleted (mi.m))
+ os << "}";
+ }
+
if (semantics::class_* c = composite (mi.t))
index_ += column_count (*c).total;
else
@@ -324,10 +353,10 @@ namespace relational
{
os << "if (composite_value_traits< " << mi.fq_type () <<
", id_pgsql >::grow (" << endl
- << "i." << mi.var << "value, t + " << index_ << "UL))"
- << "{"
+ << "i." << mi.var << "value, t + " << index_ << "UL" <<
+ (versioned (*composite (mi.t)) ? ", svm" : "") << "))" << endl
<< "grew = true;"
- << "}";
+ << endl;
}
virtual void
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx
index 3805be2..6afff9c 100644
--- a/odb/relational/source.cxx
+++ b/odb/relational/source.cxx
@@ -49,6 +49,9 @@ traverse_object (type& c)
(opt ? context::grow (*opt) : false);
}
+ column_count_type const& cc (column_count (c));
+ bool versioned (context::versioned (c));
+
// Schema name as a string literal or empty.
//
string schema_name (options.schema_name ()[db]);
@@ -58,7 +61,6 @@ traverse_object (type& c)
string const& type (class_fq_name (c));
string traits ("access::object_traits_impl< " + type + ", id_" +
db.string () + " >");
- column_count_type const& cc (column_count (c));
user_sections& uss (c.get<user_sections> ("user-sections"));
user_sections* buss (poly_base != 0
@@ -230,16 +232,26 @@ traverse_object (type& c)
if (generate_grow)
{
os << "bool " << traits << "::" << endl
- << "grow (image_type& i, " << truncated_vector << " t";
+ << "grow (image_type& i," << endl
+ << truncated_vector << " t";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
if (poly_derived)
- os << ", std::size_t d";
+ os << "," << endl
+ << "std::size_t d";
os << ")"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (i);"
- << "ODB_POTENTIALLY_UNUSED (t);"
- << endl
+ << "ODB_POTENTIALLY_UNUSED (t);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl
<< "bool grew (false);"
<< endl;
@@ -257,6 +269,7 @@ traverse_object (type& c)
<< "{"
<< "if (base_traits::grow (*i.base, " <<
"t + " << cols << "UL" <<
+ (context::versioned (*poly_base) ? ", svm" : "") <<
(poly_base != poly_root ? ", d" : "") << "))" << endl
<< "i.base->version++;"
<< "}";
@@ -283,10 +296,20 @@ traverse_object (type& c)
<< "std::size_t id_size," << endl;
os << "image_type& i," << endl
- << db << "::statement_kind sk)"
+ << db << "::statement_kind sk";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
+
+ os << ")"
<< "{"
- << "ODB_POTENTIALLY_UNUSED (sk);"
- << endl
+ << "ODB_POTENTIALLY_UNUSED (sk);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl
<< "using namespace " << db << ";"
<< endl;
@@ -336,12 +359,13 @@ traverse_object (type& c)
os << "// " << class_name (*poly_base) << " base" << endl
<< "//" << endl
<< "if (sk == statement_select)" << endl
- << "base_traits::";
+ << "base_traits::bind (b + n, ";
- if (poly_base == poly_root)
- os << "bind (b + n, *i.base, sk);";
- else
- os << "bind (b + n, id, id_size, *i.base, sk);";
+ if (poly_base != poly_root)
+ os << "id, id_size, ";
+
+ os << "*i.base, sk" <<
+ (context::versioned (*poly_base) ? ", svm" : "") << ");";
}
os << "}";
@@ -378,13 +402,24 @@ traverse_object (type& c)
// init (image, object)
//
os << (generate_grow ? "bool " : "void ") << traits << "::" << endl
- << "init (image_type& i, const object_type& o, " <<
- db << "::statement_kind sk)"
+ << "init (image_type& i," << endl
+ << "const object_type& o," << endl
+ << db << "::statement_kind sk";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
+
+ os << ")"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (i);"
<< "ODB_POTENTIALLY_UNUSED (o);"
- << "ODB_POTENTIALLY_UNUSED (sk);"
- << endl
+ << "ODB_POTENTIALLY_UNUSED (sk);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl
<< "using namespace " << db << ";"
<< endl;
@@ -411,17 +446,28 @@ traverse_object (type& c)
// init (object, image)
//
os << "void " << traits << "::" << endl
- << "init (object_type& o, const image_type& i, database* db";
+ << "init (object_type& o," << endl
+ << "const image_type& i," << endl
+ << "database* db";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
if (poly_derived)
- os << ", std::size_t d";
+ os << "," << endl
+ << "std::size_t d";
os << ")"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (o);"
<< "ODB_POTENTIALLY_UNUSED (i);"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl;
+ << "ODB_POTENTIALLY_UNUSED (db);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl;
if (poly_derived)
{
@@ -429,6 +475,7 @@ traverse_object (type& c)
<< "//" << endl
<< "if (--d != 0)" << endl
<< "base_traits::init (o, *i.base, db" <<
+ (context::versioned (*poly_base) ? ", svm" : "") <<
(poly_base != poly_root ? ", d" : "") << ");"
<< endl;
}
@@ -477,8 +524,6 @@ traverse_object (type& c)
if (reuse_abst)
return;
- bool versioned (force_versioned);
-
//
// Containers (concrete).
//
@@ -1087,6 +1132,10 @@ traverse_object (type& c)
<< "throw abstract_class ();"
<< endl;
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "db.schema_version_migration (" << schema_name << "));";
+
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< "statements_type& sts (" << endl
@@ -1124,7 +1173,7 @@ traverse_object (type& c)
if (generate_grow)
os << "if (";
- os << "init (im, obj, statement_insert)";
+ os << "init (im, obj, statement_insert" << (versioned ? ", svm" : "") << ")";
if (generate_grow)
os << ")" << endl
@@ -1154,7 +1203,7 @@ traverse_object (type& c)
if (poly_derived)
os << "idb.bind, idb.count, ";
- os << "im, statement_insert);";
+ os << "im, statement_insert" << (versioned ? ", svm" : "") << ");";
if (poly_derived)
os << "sts.insert_id_binding_version (idb.version);";
@@ -1440,6 +1489,11 @@ traverse_object (type& c)
<< "}";
}
+ if (versioned && update_columns != 0)
+ os << "const schema_version_migration& svm (" <<
+ "db.schema_version_migration (" << schema_name << "));"
+ << endl;
+
if (poly_derived)
{
bool readonly_base (context::readonly (*poly_base));
@@ -1507,7 +1561,8 @@ traverse_object (type& c)
if (generate_grow)
os << "if (";
- os << "init (im, obj, statement_update)";
+ os << "init (im, obj, statement_update" <<
+ (versioned ? ", svm" : "") << ")";
if (generate_grow)
os << ")" << endl
@@ -1521,7 +1576,8 @@ traverse_object (type& c)
<< "im.version != sts.update_image_version () ||" << endl
<< "imb.version == 0)"
<< "{"
- << "bind (imb.bind, idb.bind, idb.count, im, statement_update);"
+ << "bind (imb.bind, idb.bind, idb.count, im, statement_update" <<
+ (versioned ? ", svm" : "") << ");"
<< "sts.update_id_binding_version (idb.version);"
<< "sts.update_image_version (im.version);"
<< "imb.version++;"
@@ -1590,7 +1646,8 @@ traverse_object (type& c)
if (generate_grow)
os << "if (";
- os << "init (im, obj, statement_update)";
+ os << "init (im, obj, statement_update" <<
+ (versioned ? ", svm" : "") << ")";
if (generate_grow)
os << ")" << endl
@@ -1599,7 +1656,7 @@ traverse_object (type& c)
os << ";"
<< endl;
- // Update binding is bound to two images (object and id)
+ // The update binding is bound to two images (object and id)
// so we have to track both versions.
//
os << "bool u (false);" // Avoid incrementing version twice.
@@ -1607,7 +1664,8 @@ traverse_object (type& c)
<< "if (im.version != sts.update_image_version () ||" << endl
<< "imb.version == 0)"
<< "{"
- << "bind (imb.bind, im, statement_update);"
+ << "bind (imb.bind, im, statement_update" <<
+ (versioned ? ", svm" : "") << ");"
<< "sts.update_image_version (im.version);"
<< "imb.version++;"
<< "u = true;"
@@ -2382,8 +2440,10 @@ traverse_object (type& c)
os << "}";
- // Get the connection.
- //
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "db.schema_version_migration (" << schema_name << "));";
+
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< "statements_type& sts (" << endl
@@ -2404,7 +2464,7 @@ traverse_object (type& c)
os << endl
<< "if (l.locked ())"
<< "{"
- << "if (!find_ (sts, &id))" << endl
+ << "if (!find_ (sts, &id" << (versioned ? ", svm" : "") << "))" << endl
<< "return pointer_type ();";
if (delay_freeing_statement_result)
@@ -2486,7 +2546,7 @@ traverse_object (type& c)
else
os << "callback (db, obj, callback_event::pre_load);";
- os << "init (obj, sts.image (), &db);";
+ os << "init (obj, sts.image (), &db" << (versioned ? ", svm" : "") << ");";
init_value_extra ();
@@ -2506,7 +2566,7 @@ traverse_object (type& c)
<< "pi.dispatch (info_type::call_load, db, &obj, &d);"
<< "}";
- os << rsts << ".load_delayed ();"
+ os << rsts << ".load_delayed (" << (versioned ? "&svm" : "0") << ");"
<< "l.unlock ();";
if (poly)
@@ -2573,6 +2633,10 @@ traverse_object (type& c)
if (!abst)
{
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "db.schema_version_migration (" << schema_name << "));";
+
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< "statements_type& sts (" << endl
@@ -2587,7 +2651,8 @@ traverse_object (type& c)
<< "statements_type::auto_lock l (" << rsts << ");"
<< endl;
- os << "if (!find_ (sts, &id))" << endl
+ os << "if (!find_ (sts, &id" <<
+ (versioned ? ", svm" : "") << "))" << endl
<< "return false;"
<< endl;
@@ -2604,7 +2669,8 @@ traverse_object (type& c)
<< "reference_cache_traits::insert_guard ig (pos);"
<< endl
<< "callback (db, obj, callback_event::pre_load);"
- << "init (obj, sts.image (), &db);";
+ << "init (obj, sts.image (), &db" <<
+ (versioned ? ", svm" : "") << ");";
init_value_extra ();
@@ -2612,7 +2678,7 @@ traverse_object (type& c)
os << "ar.free ();";
os << "load_ (sts, obj);"
- << rsts << ".load_delayed ();"
+ << rsts << ".load_delayed (" << (versioned ? "&svm" : "0") << ");"
<< "l.unlock ();"
<< "callback (db, obj, callback_event::post_load);"
<< "reference_cache_traits::load (pos);"
@@ -2673,6 +2739,10 @@ traverse_object (type& c)
if (!abst)
{
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "db.schema_version_migration (" << schema_name << "));";
+
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< "statements_type& sts (" << endl
@@ -2694,7 +2764,8 @@ traverse_object (type& c)
<< id_ma->translate ("obj") << ");"
<< endl;
- os << "if (!find_ (sts, &id))" << endl
+ os << "if (!find_ (sts, &id" <<
+ (versioned ? ", svm" : "") << "))" << endl
<< "return false;"
<< endl;
@@ -2720,7 +2791,8 @@ traverse_object (type& c)
}
os << "callback (db, obj, callback_event::pre_load);"
- << "init (obj, sts.image (), &db);";
+ << "init (obj, sts.image (), &db" <<
+ (versioned ? ", svm" : "") << ");";
init_value_extra ();
@@ -2728,7 +2800,7 @@ traverse_object (type& c)
os << "ar.free ();";
os << "load_ (sts, obj, true);"
- << rsts << ".load_delayed ();"
+ << rsts << ".load_delayed (" << (versioned ? "&svm" : "0") << ");"
<< "l.unlock ();"
<< "callback (db, obj, callback_event::post_load);"
<< "return true;";
@@ -3043,17 +3115,16 @@ traverse_object (type& c)
if (id != 0)
{
os << "bool " << traits << "::" << endl
- << "find_ (";
+ << "find_ (statements_type& sts," << endl
+ << "const id_type* id";
- if (poly && !poly_derived)
- os << "base_statements_type& sts, ";
- else
- os << "statements_type& sts, ";
-
- os << "const id_type* id";
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
if (poly_derived && !abst)
- os << ", std::size_t d";
+ os << "," << endl
+ << "std::size_t d";
os << ")"
<< "{"
@@ -3095,7 +3166,8 @@ traverse_object (type& c)
os << "if (imb.version == 0 ||" << endl
<< "check_version (sts.select_image_versions (), im))"
<< "{"
- << "bind (imb.bind, 0, 0, im, statement_select);"
+ << "bind (imb.bind, 0, 0, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "update_version (sts.select_image_versions ()," << endl
<< "im," << endl
<< "sts.select_image_bindings ());"
@@ -3106,7 +3178,8 @@ traverse_object (type& c)
os << "if (im.version != sts.select_image_version () ||" << endl
<< "imb.version == 0)"
<< "{"
- << "bind (imb.bind, im, statement_select);"
+ << "bind (imb.bind, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "sts.select_image_version (im.version);"
<< "imb.version++;"
<< "}";
@@ -3124,6 +3197,7 @@ traverse_object (type& c)
os << "if (r == select_statement::truncated)"
<< "{"
<< "if (grow (im, sts.select_image_truncated ()" <<
+ (versioned ? ", svm" : "") <<
(poly_derived ? (abst ? ", depth" : ", d") : "") << "))" << endl
<< "im.version++;"
<< endl;
@@ -3132,7 +3206,8 @@ traverse_object (type& c)
{
os << "if (check_version (sts.select_image_versions (), im))"
<< "{"
- << "bind (imb.bind, 0, 0, im, statement_select);"
+ << "bind (imb.bind, 0, 0, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "update_version (sts.select_image_versions ()," << endl
<< "im," << endl
<< "sts.select_image_bindings ());"
@@ -3143,7 +3218,8 @@ traverse_object (type& c)
{
os << "if (im.version != sts.select_image_version ())"
<< "{"
- << "bind (imb.bind, im, statement_select);"
+ << "bind (imb.bind, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "sts.select_image_version (im.version);"
<< "imb.version++;"
<< "st.refetch ();"
@@ -3183,14 +3259,8 @@ traverse_object (type& c)
(poly ? user_sections::count_load_empty : 0)) != 0)
{
os << "void " << traits << "::" << endl
- << "load_ (";
-
- if (poly && !poly_derived)
- os << "base_statements_type& sts," << endl;
- else
- os << "statements_type& sts," << endl;
-
- os << "object_type& obj," << endl
+ << "load_ (statements_type& sts," << endl
+ << "object_type& obj," << endl
<< "bool reload";
if (poly_derived)
@@ -3309,7 +3379,12 @@ traverse_object (type& c)
os << "if (d > " << (poly_depth - empty_depth) << "UL)"
<< "{";
- os << "if (!find_ (sts, 0, d))" << endl
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "db.schema_version_migration (" << schema_name << "));"
+ << endl;
+
+ os << "if (!find_ (sts, 0" << (versioned ? ", svm" : "") << ", d))" << endl
<< "throw object_not_persistent ();" // Database inconsistency.
<< endl;
@@ -3320,7 +3395,8 @@ traverse_object (type& c)
if (delay_freeing_statement_result)
os << "auto_result ar (st);";
- os << "init (obj, sts.image (), &db, d);";
+ os << "init (obj, sts.image (), &db" << (versioned ? ", svm" : "") <<
+ ", d);";
init_value_extra ();
@@ -3507,13 +3583,20 @@ traverse_object (type& c)
//
os << "result< " << traits << "::object_type >" << endl
<< traits << "::" << endl
- << "query (database&, const query_base_type& q)"
+ << "query (database& db, const query_base_type& q)"
<< "{"
+ << "ODB_POTENTIALLY_UNUSED (db);"
+ << endl
<< "using namespace " << db << ";"
<< "using odb::details::shared;"
<< "using odb::details::shared_ptr;"
- << endl
- << db << "::connection& conn (" << endl
+ << endl;
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "db.schema_version_migration (" << schema_name << "));";
+
+ os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< endl
<< "statements_type& sts (" << endl
@@ -3532,7 +3615,8 @@ traverse_object (type& c)
os << "if (imb.version == 0 ||" << endl
<< "check_version (sts.select_image_versions (), im))"
<< "{"
- << "bind (imb.bind, 0, 0, im, statement_select);"
+ << "bind (imb.bind, 0, 0, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "update_version (sts.select_image_versions ()," << endl
<< "im," << endl
<< "sts.select_image_bindings ());"
@@ -3543,7 +3627,8 @@ traverse_object (type& c)
os << "if (im.version != sts.select_image_version () ||" << endl
<< "imb.version == 0)"
<< "{"
- << "bind (imb.bind, im, statement_select);"
+ << "bind (imb.bind, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "sts.select_image_version (im.version);"
<< "imb.version++;"
<< "}";
@@ -3569,7 +3654,7 @@ traverse_object (type& c)
os << endl
<< "shared_ptr< odb::" << result_type << " > r (" << endl
<< "new (shared) " << db << "::" << result_type << " (" << endl
- << "q, st, sts));"
+ << "q, st, sts, " << (versioned ? "&svm" : "0") << "));"
<< endl
<< "return result<object_type> (r);"
<< "}";
@@ -3633,8 +3718,14 @@ traverse_object (type& c)
<< "using namespace " << db << ";"
<< "using odb::details::shared;"
<< "using odb::details::shared_ptr;"
- << endl
- << db << "::connection& conn (" << endl
+ << endl;
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" << endl
+ << "c.database ().schema_version_migration (" <<
+ schema_name << "));";
+
+ os << db << "::connection& conn (" << endl
<< "static_cast<" << db << "::connection&> (c));"
<< endl
<< "statements_type& sts (" << endl
@@ -3653,7 +3744,8 @@ traverse_object (type& c)
os << "if (imb.version == 0 ||" << endl
<< "check_version (sts.select_image_versions (), im))"
<< "{"
- << "bind (imb.bind, 0, 0, im, statement_select);"
+ << "bind (imb.bind, 0, 0, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "update_version (sts.select_image_versions ()," << endl
<< "im," << endl
<< "sts.select_image_bindings ());"
@@ -3664,7 +3756,8 @@ traverse_object (type& c)
os << "if (im.version != sts.select_image_version () ||" << endl
<< "imb.version == 0)"
<< "{"
- << "bind (imb.bind, im, statement_select);"
+ << "bind (imb.bind, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "sts.select_image_version (im.version);"
<< "imb.version++;"
<< "}";
@@ -3717,8 +3810,13 @@ traverse_object (type& c)
<< "shared_ptr<select_statement> st (" << endl
<< "odb::details::inc_ref (" << endl
<< "static_cast<select_statement*> (pq.stmt.get ())));"
- << endl
- << db << "::connection& conn (" << endl
+ << endl;
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "db.schema_version_migration (" << schema_name << "));";
+
+ os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< endl
<< "// The connection used by the current transaction and the" << endl
@@ -3742,7 +3840,8 @@ traverse_object (type& c)
os << "if (imb.version == 0 ||" << endl
<< "check_version (sts.select_image_versions (), im))"
<< "{"
- << "bind (imb.bind, 0, 0, im, statement_select);"
+ << "bind (imb.bind, 0, 0, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "update_version (sts.select_image_versions ()," << endl
<< "im," << endl
<< "sts.select_image_bindings ());"
@@ -3753,7 +3852,8 @@ traverse_object (type& c)
os << "if (im.version != sts.select_image_version () ||" << endl
<< "imb.version == 0)"
<< "{"
- << "bind (imb.bind, im, statement_select);"
+ << "bind (imb.bind, im, statement_select" <<
+ (versioned ? ", svm" : "") << ");"
<< "sts.select_image_version (im.version);"
<< "imb.version++;"
<< "}";
@@ -3766,7 +3866,7 @@ traverse_object (type& c)
os << endl
<< "return shared_ptr<result_impl> (" << endl
<< "new (shared) " << db << "::" << result_type << " (" << endl
- << "pq.query, st, sts));"
+ << "pq.query, st, sts, " << (versioned ? "&svm" : "0") << "));"
<< "}";
}
}
@@ -3870,13 +3970,11 @@ traverse_view (type& c)
view_query& vq (c.get<view_query> ("query"));
// Only process the view query if it is versioned since the query text
- // (e.g., in the native view) must be structured. Also, we probably
- // shouldn't try to optimize JOINs since the objects are JOINed
- // explicitly by the user, unless we are adding poly-bases/derived.
- //
- // When versioning is forced, don't do it for native views.
+ // (e.g., in the native view) must be structured. We also shouldn't try
+ // to optimize JOINs (since the objects are JOINed explicitly by the
+ // user), unless we are adding poly-base/derived JOINs.
//
- bool versioned (force_versioned && vq.kind == view_query::condition);
+ bool versioned (context::versioned (c));
bool query_optimize (false);
string const& type (class_fq_name (c));
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index aae34da..0db2cb4 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -1001,6 +1001,27 @@ namespace relational
os << "if (sk != statement_update)"
<< "{";
}
+
+ // If the member is soft- added or deleted, check the version.
+ //
+ unsigned long long av (added (mi.m));
+ unsigned long long dv (deleted (mi.m));
+ if (av != 0 || dv != 0)
+ {
+ os << "if (";
+
+ if (av != 0)
+ os << "svm >= schema_version_migration (" << av << "ULL, true)";
+
+ if (av != 0 && dv != 0)
+ os << " &&" << endl;
+
+ if (dv != 0)
+ os << "svm <= schema_version_migration (" << dv << "ULL, true)";
+
+ os << ")"
+ << "{";
+ }
}
return true;
@@ -1011,9 +1032,13 @@ namespace relational
{
if (var_override_.empty ())
{
- semantics::class_* c;
+ // We need to increment the index even if we skipped this
+ // member due to the schema version.
+ //
+ if (added (mi.m) || deleted (mi.m))
+ os << "}";
- if ((c = composite (mi.t)))
+ if (semantics::class_* c = composite (mi.t))
{
bool ro (readonly (*c));
column_count_type const& cc (column_count (*c));
@@ -1083,7 +1108,8 @@ namespace relational
{
os << "composite_value_traits< " << mi.fq_type () << ", id_" <<
db << " >::bind (" << endl
- << "b + n, " << arg << "." << mi.var << "value, sk);";
+ << "b + n, " << arg << "." << mi.var << "value, sk" <<
+ (versioned (*composite (mi.t)) ? ", svm" : "") << ");";
}
protected:
@@ -1123,7 +1149,8 @@ namespace relational
else
os << "composite_value_traits< ";
- os << class_fq_name (c) << ", id_" << db << " >::bind (b + n, i, sk);";
+ os << class_fq_name (c) << ", id_" << db << " >::bind (b + n, i, sk" <<
+ (versioned (c) ? ", svm" : "") << ");";
column_count_type const& cc (column_count (c));
@@ -1218,7 +1245,8 @@ namespace relational
os << "composite_value_traits< ";
os << class_fq_name (c) << ", id_" << db << " >::grow (" << endl
- << "i, t + " << index_ << "UL))" << endl
+ << "i, t + " << index_ << "UL" <<
+ (versioned (c) ? ", svm" : "") << "))" << endl
<< "grew = true;"
<< endl;
@@ -1299,7 +1327,7 @@ namespace relational
if (mi.ptr != 0 && mi.m.count ("polymorphic-ref"))
return false;
- bool comp (composite (mi.t));
+ semantics::class_* comp (composite (mi.t));
if (!member_override_.empty ())
{
@@ -1323,17 +1351,36 @@ namespace relational
os << "// " << mi.m.name () << endl
<< "//" << endl;
+ // If the member is soft- added or deleted, check the version.
+ //
+ unsigned long long av (added (mi.m));
+ unsigned long long dv (deleted (mi.m));
+ if (av != 0 || dv != 0)
+ {
+ os << "if (";
+
+ if (av != 0)
+ os << "svm >= schema_version_migration (" << av << "ULL, true)";
+
+ if (av != 0 && dv != 0)
+ os << " &&" << endl;
+
+ if (dv != 0)
+ os << "svm <= schema_version_migration (" << dv << "ULL, true)";
+
+ os << ")"
+ << "{";
+ }
+
// If the whole class is readonly, then we will never be
// called with sk == statement_update.
//
if (!readonly (*context::top_object))
{
- semantics::class_* c;
-
if (id (mi.m) ||
readonly (mi.m) ||
(section_ == 0 && separate_update (mi.m)) ||
- ((c = composite (mi.t)) && readonly (*c))) // Can't be id.
+ (comp != 0 && readonly (*comp))) // Can't be id.
{
// If we are generating section init(), then sk can only be
// statement_update.
@@ -1356,7 +1403,7 @@ namespace relational
// Make sure this kind of member can be accessed with this
// kind of accessor (database-specific, e.g., streaming).
//
- if (!comp)
+ if (comp == 0)
check_accessor (mi, ma);
// If this is not a synthesized expression, then output
@@ -1381,7 +1428,7 @@ namespace relational
// For simple values this is taken care of by the value_traits
// specializations.
//
- if (mi.wrapper != 0 && comp)
+ if (mi.wrapper != 0 && comp != 0)
{
// The wrapper type, not the wrapped type.
//
@@ -1397,7 +1444,8 @@ namespace relational
member << "))" << endl
<< "composite_value_traits< " << mi.fq_type () << ", id_" <<
db << " >::set_null (" << endl
- << "i." << mi.var << "value, sk);"
+ << "i." << mi.var << "value, sk" <<
+ (versioned (*comp) ? ", svm" : "") << ");"
<< "else"
<< "{";
}
@@ -1456,7 +1504,7 @@ namespace relational
member = "id";
}
- else if (comp)
+ else if (comp != 0)
type = mi.fq_type ();
else
{
@@ -1467,7 +1515,7 @@ namespace relational
os << "bool is_null (" << null (mi.m, key_prefix_) << ");";
}
- if (comp)
+ if (comp != 0)
traits = "composite_value_traits< " + type + ", id_" +
db.string () + " >";
else
@@ -1484,6 +1532,8 @@ namespace relational
virtual void
post (member_info& mi)
{
+ semantics::class_* comp (composite (mi.t));
+
if (mi.ptr != 0)
{
os << "}"
@@ -1491,13 +1541,14 @@ namespace relational
if (!null (mi.m, key_prefix_))
os << "throw null_pointer ();";
- else if (composite (mi.t))
- os << traits << "::set_null (i." << mi.var << "value, sk);";
+ else if (comp != 0)
+ os << traits << "::set_null (i." << mi.var << "value, sk" <<
+ (versioned (*comp) ? ", svm" : "") << ");";
else
set_null (mi);
}
- if (mi.wrapper != 0 && composite (mi.t))
+ if (mi.wrapper != 0 && comp != 0)
{
if (null (mi.m, key_prefix_) &&
mi.wrapper->template get<bool> ("wrapper-null-handler"))
@@ -1505,6 +1556,12 @@ namespace relational
}
os << "}";
+
+ if (member_override_.empty ())
+ {
+ if (added (mi.m) || deleted (mi.m))
+ os << "}";
+ }
}
virtual void
@@ -1518,7 +1575,13 @@ namespace relational
os << traits << "::init (" << endl
<< "i." << mi.var << "value," << endl
<< member << "," << endl
- << "sk)";
+ << "sk";
+
+ if (versioned (*composite (mi.t)))
+ os << "," << endl
+ << "svm";
+
+ os << ")";
if (grow)
os << ")" << endl
@@ -1570,7 +1633,8 @@ namespace relational
else
os << "composite_value_traits< ";
- os << class_fq_name (c) << ", id_" << db << " >::init (i, o, sk)";
+ os << class_fq_name (c) << ", id_" << db << " >::init (i, o, sk" <<
+ (versioned (c) ? ", svm" : "") << ")";
if (generate_grow)
os << ")" << endl
@@ -1661,7 +1725,7 @@ namespace relational
if (ignore_implicit_discriminator_ && discriminator (mi.m))
return false;
- bool comp (composite (mi.t));
+ semantics::class_* comp (composite (mi.t));
if (!member_override_.empty ())
{
@@ -1676,8 +1740,29 @@ namespace relational
return false;
os << "// " << mi.m.name () << endl
- << "//" << endl
- << "{";
+ << "//" << endl;
+
+ // If the member is soft- added or deleted, check the version.
+ //
+ unsigned long long av (added (mi.m));
+ unsigned long long dv (deleted (mi.m));
+ if (av != 0 || dv != 0)
+ {
+ os << "if (";
+
+ if (av != 0)
+ os << "svm >= schema_version_migration (" << av << "ULL, true)";
+
+ if (av != 0 && dv != 0)
+ os << " &&" << endl;
+
+ if (dv != 0)
+ os << "svm <= schema_version_migration (" << dv << "ULL, true)";
+
+ os << ")";
+ }
+
+ os << "{";
// Get the member using the accessor expression.
//
@@ -1686,7 +1771,7 @@ namespace relational
// Make sure this kind of member can be modified with this
// kind of accessor (database-specific, e.g., streaming).
//
- if (!comp)
+ if (comp == 0)
check_modifier (mi, ma);
// If this is not a synthesized expression, then output
@@ -1734,7 +1819,7 @@ namespace relational
// simple values this is taken care of by the value_traits
// specializations.
//
- if (mi.wrapper != 0 && comp)
+ if (mi.wrapper != 0 && comp != 0)
{
// The wrapper type, not the wrapped type.
//
@@ -1748,7 +1833,8 @@ namespace relational
{
os << "if (composite_value_traits< " << mi.fq_type () <<
", id_" << db << " >::get_null (" << endl
- << "i." << mi.var << "value))" << endl
+ << "i." << mi.var << "value" <<
+ (versioned (*comp) ? ", svm" : "") << "))" << endl
<< "wrapper_traits< " << wt << " >::set_null (" << member + ");"
<< "else" << endl;
}
@@ -1770,10 +1856,11 @@ namespace relational
os << "if (";
- if (comp)
+ if (comp != 0)
os << "composite_value_traits< " << type << ", id_" << db <<
" >::get_null (" << endl
- << "i." << mi.var << "value)";
+ << "i." << mi.var << "value" <<
+ (versioned (*comp) ? ", svm" : "") << ")";
else
get_null (mi);
@@ -1795,7 +1882,7 @@ namespace relational
else
type = mi.fq_type ();
- if (comp)
+ if (comp != 0)
traits = "composite_value_traits< " + type + ", id_" +
db.string () + " >";
else
@@ -1883,7 +1970,13 @@ namespace relational
os << traits << "::init (" << endl
<< member << "," << endl
<< "i." << mi.var << "value," << endl
- << "db);"
+ << "db";
+
+ if (versioned (*composite (mi.t)))
+ os << "," << endl
+ << "svm";
+
+ os << ");"
<< endl;
}
@@ -1918,7 +2011,8 @@ namespace relational
else
os << "composite_value_traits< ";
- os << class_fq_name (c) << ", id_" << db << " >::init (o, i, db);"
+ os << class_fq_name (c) << ", id_" << db << " >::init (o, i, db" <<
+ (versioned (c) ? ", svm" : "") << ");"
<< endl;
}
};
@@ -2083,7 +2177,7 @@ namespace relational
//
if (!reuse_abst)
{
- bool versioned (force_versioned);
+ bool versioned (context::versioned (m));
string sep (versioned ? "\n" : " ");
semantics::type& idt (container_idt (m));
@@ -2625,7 +2719,7 @@ namespace relational
<< "std::size_t n (0);"
<< endl;
- os << "// key" << endl
+ os << "// value" << endl
<< "//" << endl;
instance<bind_member> bm ("value_", "d", vt, "value_type", "value");
bm->traverse (m);
@@ -3682,7 +3776,7 @@ namespace relational
if (av != 0)
os << "svm >= schema_version_migration (" << av << "ULL, true)";
- if (av != 0 || dv != 0)
+ if (av != 0 && dv != 0)
os << " &&" << endl;
if (dv != 0)
@@ -5091,6 +5185,8 @@ namespace relational
virtual void
traverse_composite (type& c)
{
+ bool versioned (context::versioned (c));
+
string const& type (class_fq_name (c));
string traits ("access::composite_value_traits< " + type + ", id_" +
db.string () + " >");
@@ -5111,11 +5207,22 @@ namespace relational
if (generate_grow)
{
os << "bool " << traits << "::" << endl
- << "grow (image_type& i, " << truncated_vector << " t)"
+ << "grow (image_type& i," << endl
+ << truncated_vector << " t";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
+
+ os << ")"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (i);"
- << "ODB_POTENTIALLY_UNUSED (t);"
- << endl
+ << "ODB_POTENTIALLY_UNUSED (t);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl
<< "bool grew (false);"
<< endl;
@@ -5130,13 +5237,24 @@ namespace relational
// bind (image_type)
//
os << "void " << traits << "::" << endl
- << "bind (" << bind_vector << " b, image_type& i, " <<
- db << "::statement_kind sk)"
+ << "bind (" << bind_vector << " b," << endl
+ << "image_type& i," << endl
+ << db << "::statement_kind sk";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
+
+ os << ")"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (b);"
<< "ODB_POTENTIALLY_UNUSED (i);"
- << "ODB_POTENTIALLY_UNUSED (sk);"
- << endl
+ << "ODB_POTENTIALLY_UNUSED (sk);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl
<< "using namespace " << db << ";"
<< endl;
@@ -5156,13 +5274,24 @@ namespace relational
// init (image, value)
//
os << (generate_grow ? "bool " : "void ") << traits << "::" << endl
- << "init (image_type& i, const value_type& o, " <<
- db << "::statement_kind sk)"
+ << "init (image_type& i," << endl
+ << "const value_type& o," << endl
+ << db << "::statement_kind sk";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
+
+ os << ")"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (i);"
<< "ODB_POTENTIALLY_UNUSED (o);"
- << "ODB_POTENTIALLY_UNUSED (sk);"
- << endl
+ << "ODB_POTENTIALLY_UNUSED (sk);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl
<< "using namespace " << db << ";"
<< endl;
@@ -5185,12 +5314,24 @@ namespace relational
// init (value, image)
//
os << "void " << traits << "::" << endl
- << "init (value_type& o, const image_type& i, database* db)"
+ << "init (value_type& o," << endl
+ << "const image_type& i," << endl
+ << "database* db";
+
+ if (versioned)
+ os << "," << endl
+ << "const schema_version_migration& svm";
+
+ os << ")"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (o);"
<< "ODB_POTENTIALLY_UNUSED (i);"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl;
+ << "ODB_POTENTIALLY_UNUSED (db);";
+
+ if (versioned)
+ os << "ODB_POTENTIALLY_UNUSED (svm);";
+
+ os << endl;
inherits (c, init_value_base_inherits_);
names (c, init_value_member_names_);