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
commit9715f388db714fb663b854883e4cad5f2aa3c860 (patch)
treefebbbba7980a6891784440d86911b13befe108a7
parentb5ed13549a87dccb56f756d6fbc5f7bf537e9640 (diff)
Support for versioning simple value in object
-rw-r--r--odb/pgsql/no-id-object-result.hxx5
-rw-r--r--odb/pgsql/no-id-object-result.txx12
-rw-r--r--odb/pgsql/polymorphic-object-result.hxx5
-rw-r--r--odb/pgsql/polymorphic-object-result.txx26
-rw-r--r--odb/pgsql/polymorphic-object-statements.hxx18
-rw-r--r--odb/pgsql/polymorphic-object-statements.txx13
-rw-r--r--odb/pgsql/simple-object-result.hxx6
-rw-r--r--odb/pgsql/simple-object-result.txx14
-rw-r--r--odb/pgsql/simple-object-statements.hxx16
-rw-r--r--odb/pgsql/simple-object-statements.txx19
-rw-r--r--odb/pgsql/statement-cache.hxx5
-rw-r--r--odb/pgsql/statement-cache.txx13
-rw-r--r--odb/pgsql/statement.cxx44
-rw-r--r--odb/pgsql/traits-calls.hxx132
14 files changed, 261 insertions, 67 deletions
diff --git a/odb/pgsql/no-id-object-result.hxx b/odb/pgsql/no-id-object-result.hxx
index 0fabf9e..83f3ce9 100644
--- a/odb/pgsql/no-id-object-result.hxx
+++ b/odb/pgsql/no-id-object-result.hxx
@@ -16,6 +16,7 @@
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/forward.hxx> // query_base
#include <odb/pgsql/statement.hxx>
+#include <odb/pgsql/traits-calls.hxx>
namespace odb
{
@@ -40,7 +41,8 @@ namespace odb
no_id_object_result_impl (const query_base&,
details::shared_ptr<select_statement>,
- statements_type&);
+ statements_type&,
+ const schema_version_migration*);
virtual void
load (object_type&);
@@ -62,6 +64,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ traits_calls<object_type> tc_;
std::size_t count_;
};
}
diff --git a/odb/pgsql/no-id-object-result.txx b/odb/pgsql/no-id-object-result.txx
index c65fa56..4b3f1ab 100644
--- a/odb/pgsql/no-id-object-result.txx
+++ b/odb/pgsql/no-id-object-result.txx
@@ -35,10 +35,12 @@ namespace odb
no_id_object_result_impl<T>::
no_id_object_result_impl (const query_base&,
details::shared_ptr<select_statement> statement,
- statements_type& statements)
+ statements_type& statements,
+ const schema_version_migration* svm)
: base_type (statements.connection ()),
statement_ (statement),
statements_ (statements),
+ tc_ (svm),
count_ (0)
{
}
@@ -55,7 +57,7 @@ namespace odb
if (im.version != statements_.select_image_version ())
{
binding& b (statements_.select_image_binding ());
- object_traits::bind (b.bind, im, statement_select);
+ tc_.bind (b.bind, im, statement_select);
statements_.select_image_version (im.version);
b.version++;
}
@@ -64,13 +66,13 @@ namespace odb
if (r == select_statement::truncated)
{
- if (object_traits::grow (im, statements_.select_image_truncated ()))
+ if (tc_.grow (im, statements_.select_image_truncated ()))
im.version++;
if (im.version != statements_.select_image_version ())
{
binding& b (statements_.select_image_binding ());
- object_traits::bind (b.bind, im, statement_select);
+ tc_.bind (b.bind, im, statement_select);
statements_.select_image_version (im.version);
b.version++;
statement_->reload ();
@@ -78,7 +80,7 @@ namespace odb
}
object_traits::callback (this->db_, obj, callback_event::pre_load);
- object_traits::init (obj, im, &this->db_);
+ tc_.init (obj, im, &this->db_);
object_traits::callback (this->db_, obj, callback_event::post_load);
}
diff --git a/odb/pgsql/polymorphic-object-result.hxx b/odb/pgsql/polymorphic-object-result.hxx
index a7d5077..acbfd43 100644
--- a/odb/pgsql/polymorphic-object-result.hxx
+++ b/odb/pgsql/polymorphic-object-result.hxx
@@ -16,6 +16,7 @@
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/forward.hxx> // query_base
#include <odb/pgsql/statement.hxx>
+#include <odb/pgsql/traits-calls.hxx>
namespace odb
{
@@ -47,7 +48,8 @@ namespace odb
polymorphic_object_result_impl (const query_base&,
details::shared_ptr<select_statement>,
- statements_type&);
+ statements_type&,
+ const schema_version_migration*);
virtual void
load (object_type*, bool fetch);
@@ -79,6 +81,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ traits_calls<object_type> tc_;
std::size_t count_;
};
}
diff --git a/odb/pgsql/polymorphic-object-result.txx b/odb/pgsql/polymorphic-object-result.txx
index 4b956bd..233d7ce 100644
--- a/odb/pgsql/polymorphic-object-result.txx
+++ b/odb/pgsql/polymorphic-object-result.txx
@@ -38,10 +38,12 @@ namespace odb
polymorphic_object_result_impl<T>::
polymorphic_object_result_impl (const query_base&,
details::shared_ptr<select_statement> st,
- statements_type& sts)
+ statements_type& sts,
+ const schema_version_migration* svm)
: base_type (sts.connection ()),
statement_ (st),
statements_ (sts),
+ tc_ (svm),
count_ (0)
{
}
@@ -121,7 +123,7 @@ namespace odb
callback_event ce (callback_event::pre_load);
pi.dispatch (info_type::call_callback, this->db_, pobj, &ce);
- object_traits::init (*pobj, i, &this->db_);
+ tc_.init (*pobj, i, &this->db_);
// Initialize the id image and binding and load the rest of the object
// (containers, dynamic part, etc).
@@ -148,7 +150,7 @@ namespace odb
pi.dispatch (info_type::call_load, this->db_, pobj, &d);
};
- rsts.load_delayed ();
+ rsts.load_delayed (tc_.version ());
l.unlock ();
ce = callback_event::post_load;
@@ -199,14 +201,16 @@ namespace odb
typedef object_traits_impl<T, id_pgsql> traits;
static bool
- rebind (typename traits::statements_type& sts)
+ rebind (typename traits::statements_type& sts,
+ const schema_version_migration* svm)
{
typename traits::image_type& im (sts.image ());
if (traits::check_version (sts.select_image_versions (), im))
{
binding& b (sts.select_image_binding (traits::depth));
- traits::bind (b.bind, 0, 0, im, statement_select);
+ traits_calls<T> tc (svm);
+ tc.bind (b.bind, 0, 0, im, statement_select);
traits::update_version (
sts.select_image_versions (), im, sts.select_image_bindings ());
return true;
@@ -224,14 +228,16 @@ namespace odb
typedef object_traits_impl<R, id_pgsql> traits;
static bool
- rebind (typename traits::statements_type& sts)
+ rebind (typename traits::statements_type& sts,
+ const schema_version_migration* svm)
{
typename traits::image_type& im (sts.image ());
if (im.version != sts.select_image_version ())
{
binding& b (sts.select_image_binding ());
- traits::bind (b.bind, im, statement_select);
+ traits_calls<R> tc (svm);
+ tc.bind (b.bind, im, statement_select);
sts.select_image_version (im.version);
b.version++;
return true;
@@ -250,7 +256,7 @@ namespace odb
// The image can grow between calls to load() as a result of other
// statements execution.
//
- image_rebind::rebind (statements_);
+ image_rebind::rebind (statements_, tc_.version ());
select_statement::result r (statement_->load ());
@@ -258,10 +264,10 @@ namespace odb
{
typename object_traits::image_type& im (statements_.image ());
- if (object_traits::grow (im, statements_.select_image_truncated ()))
+ if (tc_.grow (im, statements_.select_image_truncated ()))
im.version++;
- if (image_rebind::rebind (statements_))
+ if (image_rebind::rebind (statements_, tc_.version ()))
statement_->reload ();
}
}
diff --git a/odb/pgsql/polymorphic-object-statements.hxx b/odb/pgsql/polymorphic-object-statements.hxx
index 93f711a..f5ddcea 100644
--- a/odb/pgsql/polymorphic-object-statements.hxx
+++ b/odb/pgsql/polymorphic-object-statements.hxx
@@ -128,6 +128,18 @@ namespace odb
virtual
~polymorphic_root_object_statements ();
+ // Static "override" (statements type).
+ //
+ void
+ load_delayed (const schema_version_migration* svm)
+ {
+ assert (this->locked ());
+
+ if (!this->delayed_.empty ())
+ this->template load_delayed_<polymorphic_root_object_statements> (
+ svm);
+ }
+
public:
static const std::size_t id_column_count =
object_statements<T>::id_column_count;
@@ -205,8 +217,10 @@ namespace odb
// Delayed loading.
//
static void
- delayed_loader (odb::database&, const id_type&, root_type&);
-
+ delayed_loader (odb::database&,
+ const id_type&,
+ root_type&,
+ const schema_version_migration*);
public:
// Root and immediate base statements.
//
diff --git a/odb/pgsql/polymorphic-object-statements.txx b/odb/pgsql/polymorphic-object-statements.txx
index 56a20a4..cc8d31a 100644
--- a/odb/pgsql/polymorphic-object-statements.txx
+++ b/odb/pgsql/polymorphic-object-statements.txx
@@ -124,7 +124,10 @@ namespace odb
template <typename T>
void polymorphic_derived_object_statements<T>::
- delayed_loader (odb::database& db, const id_type& id, root_type& robj)
+ delayed_loader (odb::database& db,
+ const id_type& id,
+ root_type& robj,
+ const schema_version_migration* svm)
{
connection_type& conn (transaction::current ().connection ());
polymorphic_derived_object_statements& sts (
@@ -135,14 +138,16 @@ namespace odb
// The same code as in object_statements::load_delayed_().
//
- if (!object_traits::find_ (sts, &id))
+ traits_calls<T> tc (svm);
+
+ if (!tc.find_ (sts, &id))
throw object_not_persistent ();
object_traits::callback (db, obj, callback_event::pre_load);
- object_traits::init (obj, sts.image (), &db);
+ tc.init (obj, sts.image (), &db);
object_traits::load_ (sts, obj); // Load containers, etc.
- rsts.load_delayed ();
+ rsts.load_delayed (svm);
{
typename root_statements_type::auto_unlock u (rsts);
diff --git a/odb/pgsql/simple-object-result.hxx b/odb/pgsql/simple-object-result.hxx
index b2e04c9..e6a558b 100644
--- a/odb/pgsql/simple-object-result.hxx
+++ b/odb/pgsql/simple-object-result.hxx
@@ -9,6 +9,7 @@
#include <cstddef> // std::size_t
+#include <odb/schema-version.hxx>
#include <odb/simple-object-result.hxx>
#include <odb/details/shared-ptr.hxx>
@@ -16,6 +17,7 @@
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/forward.hxx> // query_base
#include <odb/pgsql/statement.hxx>
+#include <odb/pgsql/traits-calls.hxx>
namespace odb
{
@@ -41,7 +43,8 @@ namespace odb
object_result_impl (const query_base&,
details::shared_ptr<select_statement>,
- statements_type&);
+ statements_type&,
+ const schema_version_migration*);
virtual void
load (object_type&, bool fetch);
@@ -70,6 +73,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ traits_calls<object_type> tc_;
std::size_t count_;
};
}
diff --git a/odb/pgsql/simple-object-result.txx b/odb/pgsql/simple-object-result.txx
index f1fdd7e..02d8e6d 100644
--- a/odb/pgsql/simple-object-result.txx
+++ b/odb/pgsql/simple-object-result.txx
@@ -37,10 +37,12 @@ namespace odb
object_result_impl<T>::
object_result_impl (const query_base&,
details::shared_ptr<select_statement> statement,
- statements_type& statements)
+ statements_type& statements,
+ const schema_version_migration* svm)
: base_type (statements.connection ()),
statement_ (statement),
statements_ (statements),
+ tc_ (svm),
count_ (0)
{
}
@@ -60,7 +62,7 @@ namespace odb
object_traits::callback (this->db_, obj, callback_event::pre_load);
typename object_traits::image_type& i (statements_.image ());
- object_traits::init (obj, i, &this->db_);
+ tc_.init (obj, i, &this->db_);
// Initialize the id image and binding and load the rest of the object
// (containers, etc).
@@ -77,7 +79,7 @@ namespace odb
}
object_traits::load_ (statements_, obj);
- statements_.load_delayed ();
+ statements_.load_delayed (tc_.version ());
l.unlock ();
object_traits::callback (this->db_, obj, callback_event::post_load);
}
@@ -118,7 +120,7 @@ namespace odb
if (im.version != statements_.select_image_version ())
{
binding& b (statements_.select_image_binding ());
- object_traits::bind (b.bind, im, statement_select);
+ tc_.bind (b.bind, im, statement_select);
statements_.select_image_version (im.version);
b.version++;
}
@@ -127,13 +129,13 @@ namespace odb
if (r == select_statement::truncated)
{
- if (object_traits::grow (im, statements_.select_image_truncated ()))
+ if (tc_.grow (im, statements_.select_image_truncated ()))
im.version++;
if (im.version != statements_.select_image_version ())
{
binding& b (statements_.select_image_binding ());
- object_traits::bind (b.bind, im, statement_select);
+ tc_.bind (b.bind, im, statement_select);
statements_.select_image_version (im.version);
b.version++;
statement_->reload ();
diff --git a/odb/pgsql/simple-object-statements.hxx b/odb/pgsql/simple-object-statements.hxx
index a8d7ce3..afa869a 100644
--- a/odb/pgsql/simple-object-statements.hxx
+++ b/odb/pgsql/simple-object-statements.hxx
@@ -268,9 +268,10 @@ namespace odb
// Delayed loading.
//
- typedef void (*loader_function) (
- odb::database&, const id_type&, object_type&);
-
+ typedef void (*loader_function) (odb::database&,
+ const id_type&,
+ object_type&,
+ const schema_version_migration*);
void
delay_load (const id_type& id,
object_type& obj,
@@ -281,12 +282,12 @@ namespace odb
}
void
- load_delayed ()
+ load_delayed (const schema_version_migration* svm)
{
assert (locked ());
if (!delayed_.empty ())
- load_delayed_ ();
+ load_delayed_<object_statements> (svm);
}
void
@@ -508,9 +509,10 @@ namespace odb
object_statements (const object_statements&);
object_statements& operator= (const object_statements&);
- private:
+ protected:
+ template <typename STS>
void
- load_delayed_ ();
+ load_delayed_ (const schema_version_migration*);
void
clear_delayed_ ();
diff --git a/odb/pgsql/simple-object-statements.txx b/odb/pgsql/simple-object-statements.txx
index 999dc9c..5933aa5 100644
--- a/odb/pgsql/simple-object-statements.txx
+++ b/odb/pgsql/simple-object-statements.txx
@@ -8,6 +8,7 @@
#include <odb/exceptions.hxx>
#include <odb/pgsql/connection.hxx>
+#include <odb/pgsql/traits-calls.hxx>
namespace odb
{
@@ -96,8 +97,9 @@ namespace odb
}
template <typename T>
+ template <typename STS>
void object_statements<T>::
- load_delayed_ ()
+ load_delayed_ (const schema_version_migration* svm)
{
database& db (connection ().database ());
@@ -112,7 +114,9 @@ namespace odb
if (l.loader == 0)
{
- if (!object_traits::find_ (*this, &l.id))
+ traits_calls<T> tc (svm);
+
+ if (!tc.find_ (static_cast<STS&> (*this), &l.id))
throw object_not_persistent ();
object_traits::callback (db, *l.obj, callback_event::pre_load);
@@ -121,11 +125,14 @@ namespace odb
// loads being added to the delayed_ vector. We need to process
// those before we call the post callback.
//
- object_traits::init (*l.obj, image (), &db);
- object_traits::load_ (*this, *l.obj); // Load containers, etc.
+ tc.init (*l.obj, image (), &db);
+
+ // Load containers, etc.
+ //
+ object_traits::load_ (static_cast<STS&> (*this), *l.obj);
if (!delayed_.empty ())
- load_delayed_ ();
+ load_delayed_<STS> (svm);
// Temporarily unlock the statement for the post_load call so that
// it can load objects of this type recursively. This is safe to do
@@ -141,7 +148,7 @@ namespace odb
}
}
else
- l.loader (db, l.id, *l.obj);
+ l.loader (db, l.id, *l.obj, svm);
pointer_cache_traits::load (ig.position ());
ig.release ();
diff --git a/odb/pgsql/statement-cache.hxx b/odb/pgsql/statement-cache.hxx
index 6a4c645..3ad4644 100644
--- a/odb/pgsql/statement-cache.hxx
+++ b/odb/pgsql/statement-cache.hxx
@@ -29,7 +29,9 @@ namespace odb
class LIBODB_PGSQL_EXPORT statement_cache
{
public:
- statement_cache (connection& conn): conn_ (conn) {}
+ statement_cache (connection& conn)
+ : conn_ (conn),
+ version_seq_ (conn.database ().schema_version_sequence ()) {}
template <typename T>
typename object_traits_impl<T, id_pgsql>::statements_type&
@@ -45,6 +47,7 @@ namespace odb
details::type_info_comparator> map;
connection& conn_;
+ unsigned int version_seq_;
map map_;
};
}
diff --git a/odb/pgsql/statement-cache.txx b/odb/pgsql/statement-cache.txx
index 1a35d38..48bc9da 100644
--- a/odb/pgsql/statement-cache.txx
+++ b/odb/pgsql/statement-cache.txx
@@ -15,6 +15,16 @@ namespace odb
typename object_traits_impl<T, id_pgsql>::statements_type
statements_type;
+ // Clear the cache if the database version has changed. This
+ // makes sure we don't re-use statements that correspond to
+ // the old schema.
+ //
+ if (version_seq_ != conn_.database ().schema_version_sequence ())
+ {
+ map_.clear ();
+ version_seq_ = conn_.database ().schema_version_sequence ();
+ }
+
map::iterator i (map_.find (&typeid (T)));
if (i != map_.end ())
@@ -31,6 +41,9 @@ namespace odb
view_statements<T>& statement_cache::
find_view ()
{
+ // We don't cache any statements for views so no need to clear
+ // the cache.
+
map::iterator i (map_.find (&typeid (T)));
if (i != map_.end ())
diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx
index feebe06..b65eb5b 100644
--- a/odb/pgsql/statement.cxx
+++ b/odb/pgsql/statement.cxx
@@ -228,7 +228,8 @@ namespace odb
n.formats[i] = 1;
- if (current_bind.is_null != 0 && *current_bind.is_null)
+ if (current_bind.buffer == 0 || // Skip NULL entries.
+ (current_bind.is_null != 0 && *current_bind.is_null))
{
n.values[i] = 0;
n.lengths[i] = 0;
@@ -312,19 +313,18 @@ namespace odb
bool truncated)
{
bool r (true);
- int int_row (static_cast<int> (row));
+ int col_count (PQnfields (result));
- // Make sure that the number of columns in the result returned by
- // the database matches the number that we expect. A common cause
- // of this assertion is a native view with a number of data members
- // not matching the number of columns in the SELECT-list.
- //
- assert (static_cast<size_t> (PQnfields (result)) == count);
-
- for (int i (0); i < static_cast<int> (count); ++i)
+ int col (0);
+ for (size_t i (0); i != count && col != col_count; ++i)
{
const bind& b (p[i]);
+ if (b.buffer == 0) // Skip NULL entries.
+ continue;
+
+ int c (col++);
+
if (truncated && (b.truncated == 0 || !*b.truncated))
continue;
@@ -335,13 +335,13 @@ namespace odb
//
if (!truncated)
{
- *b.is_null = PQgetisnull (result, int_row, i) == 1;
+ *b.is_null = PQgetisnull (result, static_cast<int> (row), c) == 1;
if (*b.is_null)
continue;
}
- const char* v (PQgetvalue (result, int_row, i));
+ const char* v (PQgetvalue (result, static_cast<int> (row), c));
switch (b.type)
{
@@ -349,47 +349,40 @@ namespace odb
{
*static_cast<bool*> (b.buffer) =
*reinterpret_cast<const bool*> (v);
-
break;
}
case bind::smallint:
{
*static_cast<short*> (b.buffer) =
*reinterpret_cast<const short*> (v);
-
break;
}
case bind::integer:
{
*static_cast<int*> (b.buffer) = *reinterpret_cast<const int*> (v);
-
break;
}
case bind::bigint:
{
*static_cast<long long*> (b.buffer) =
*reinterpret_cast<const long long*> (v);
-
break;
}
case bind::real:
{
*static_cast<float*> (b.buffer) =
*reinterpret_cast<const float*> (v);
-
break;
}
case bind::double_:
{
*static_cast<double*> (b.buffer) =
*reinterpret_cast<const double*> (v);
-
break;
}
case bind::date:
{
*static_cast<int*> (b.buffer) = *reinterpret_cast<const int*> (v);
-
break;
}
case bind::time:
@@ -397,7 +390,6 @@ namespace odb
{
*static_cast<long long*> (b.buffer) =
*reinterpret_cast<const long long*> (v);
-
break;
}
case bind::numeric:
@@ -406,7 +398,8 @@ namespace odb
case bind::bit:
case bind::varbit:
{
- *b.size = static_cast<size_t> (PQgetlength (result, int_row, i));
+ *b.size = static_cast<size_t> (
+ PQgetlength (result, static_cast<int> (row), c));
if (b.capacity < *b.size)
{
@@ -418,18 +411,23 @@ namespace odb
}
memcpy (b.buffer, v, *b.size);
-
break;
}
case bind::uuid:
{
memcpy (b.buffer, v, 16);
-
break;
}
}
}
+ // Make sure that the number of columns in the result returned by
+ // the database matches the number that we expect. A common cause
+ // of this assertion is a native view with a number of data members
+ // not matching the number of columns in the SELECT-list.
+ //
+ assert (col == col_count);
+
return r;
}
diff --git a/odb/pgsql/traits-calls.hxx b/odb/pgsql/traits-calls.hxx
new file mode 100644
index 0000000..5f2e11b
--- /dev/null
+++ b/odb/pgsql/traits-calls.hxx
@@ -0,0 +1,132 @@
+// file : odb/pgsql/traits-calls.hxx
+// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_PGSQL_TRAITS_CALLS_HXX
+#define ODB_PGSQL_TRAITS_CALLS_HXX
+
+#include <odb/pre.hxx>
+
+#include <cstddef> // std::size_t
+
+#include <odb/forward.hxx>
+#include <odb/schema-version.hxx>
+#include <odb/traits.hxx>
+
+#include <odb/pgsql/forward.hxx>
+#include <odb/pgsql/pgsql-types.hxx>
+
+namespace odb
+{
+ namespace pgsql
+ {
+ template <typename T,
+ bool versioned = object_traits_impl<T, id_pgsql>::versioned>
+ struct traits_calls;
+
+ template <typename T>
+ struct traits_calls<T, false>
+ {
+ typedef object_traits_impl<T, id_pgsql> traits;
+ typedef typename traits::image_type image_type;
+ typedef pgsql::bind bind_type;
+
+ traits_calls (const schema_version_migration*) {}
+
+ const schema_version_migration*
+ version () const {return 0;}
+
+ static bool
+ grow (image_type& i, bool* t)
+ {
+ return traits::grow (i, t);
+ }
+
+ static void
+ bind (bind_type* b, image_type& i, statement_kind sk)
+ {
+ traits::bind (b, i, sk);
+ }
+
+ // Poly-derived version.
+ //
+ static void
+ bind (bind_type* b,
+ const bind_type* id, std::size_t id_size,
+ image_type& i,
+ statement_kind sk)
+ {
+ traits::bind (b, id, id_size, i, sk);
+ }
+
+ static void
+ init (T& o, const image_type& i, odb::database* db)
+ {
+ traits::init (o, i, db);
+ }
+
+ static bool
+ find_ (typename traits::statements_type& sts,
+ const typename traits::id_type* id)
+ {
+ return traits::find_ (sts, id);
+ }
+ };
+
+ template <typename T>
+ struct traits_calls<T, true>
+ {
+ typedef object_traits_impl<T, id_pgsql> traits;
+ typedef typename traits::image_type image_type;
+ typedef pgsql::bind bind_type;
+
+ traits_calls (const schema_version_migration* svm): svm_ (*svm) {}
+
+ const schema_version_migration*
+ version () const {return &svm_;}
+
+ bool
+ grow (image_type& i, bool* t) const
+ {
+ return traits::grow (i, t, svm_);
+ }
+
+ void
+ bind (bind_type* b, image_type& i, statement_kind sk) const
+ {
+ traits::bind (b, i, sk, svm_);
+ }
+
+ // Poly-derived version.
+ //
+ void
+ bind (bind_type* b,
+ const bind_type* id, std::size_t id_size,
+ image_type& i,
+ statement_kind sk) const
+ {
+ traits::bind (b, id, id_size, i, sk, svm_);
+ }
+
+ void
+ init (T& o, const image_type& i, odb::database* db) const
+ {
+ traits::init (o, i, db, svm_);
+ }
+
+ bool
+ find_ (typename traits::statements_type& sts,
+ const typename traits::id_type* id) const
+ {
+ return traits::find_ (sts, id, svm_);
+ }
+
+ private:
+ const schema_version_migration& svm_;
+ };
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_PGSQL_TRAITS_CALLS_HXX