aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-09-10 14:10:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-09-10 14:10:45 +0200
commit0ed9ceef3abbd9f4ff786f6a02fe8767780e8c2c (patch)
tree0bca6f9e302dd92eb4dc9136ab0b826f8fa61aff
parent075f64ca84e4e1be22bad30e4974e9b675d12ec8 (diff)
Schema versioning support
-rw-r--r--odb/mysql/container-statements.hxx21
-rw-r--r--odb/mysql/container-statements.txx5
-rw-r--r--odb/mysql/database.cxx8
-rw-r--r--odb/mysql/forward.hxx3
-rw-r--r--odb/mysql/no-id-object-result.hxx6
-rw-r--r--odb/mysql/no-id-object-result.txx13
-rw-r--r--odb/mysql/no-id-object-statements.hxx1
-rw-r--r--odb/mysql/polymorphic-object-result.hxx6
-rw-r--r--odb/mysql/polymorphic-object-result.txx29
-rw-r--r--odb/mysql/polymorphic-object-statements.hxx23
-rw-r--r--odb/mysql/polymorphic-object-statements.txx16
-rw-r--r--odb/mysql/query.cxx16
-rw-r--r--odb/mysql/section-statements.hxx3
-rw-r--r--odb/mysql/simple-object-result.hxx6
-rw-r--r--odb/mysql/simple-object-result.txx17
-rw-r--r--odb/mysql/simple-object-statements.hxx21
-rw-r--r--odb/mysql/simple-object-statements.txx19
-rw-r--r--odb/mysql/statement-cache.hxx5
-rw-r--r--odb/mysql/statement-cache.txx15
-rw-r--r--odb/mysql/statement.cxx272
-rw-r--r--odb/mysql/statement.hxx56
-rw-r--r--odb/mysql/traits-calls.hxx211
-rw-r--r--odb/mysql/view-result.hxx6
-rw-r--r--odb/mysql/view-result.txx12
24 files changed, 681 insertions, 109 deletions
diff --git a/odb/mysql/container-statements.hxx b/odb/mysql/container-statements.hxx
index 5d089d7..be86cda 100644
--- a/odb/mysql/container-statements.hxx
+++ b/odb/mysql/container-statements.hxx
@@ -10,6 +10,7 @@
#include <cstddef> // std::size_t
#include <odb/forward.hxx>
+#include <odb/schema-version.hxx>
#include <odb/traits.hxx>
#include <odb/mysql/mysql.hxx>
@@ -58,6 +59,14 @@ namespace odb
return functions_;
}
+ // Schema version.
+ //
+ const schema_version_migration&
+ version_migration () const {return *svm_;}
+
+ void
+ version_migration (const schema_version_migration& svm) {svm_ = &svm;}
+
// Id image binding (external).
//
const binding&
@@ -115,7 +124,11 @@ namespace odb
if (insert_ == 0)
insert_.reset (
new (details::shared) insert_statement_type (
- conn_, insert_text_, insert_image_binding_, false));
+ conn_,
+ insert_text_,
+ versioned_, // Process if versioned.
+ insert_image_binding_,
+ false));
return *insert_;
}
@@ -128,6 +141,8 @@ namespace odb
new (details::shared) select_statement_type (
conn_,
select_text_,
+ versioned_, // Process if versioned.
+ false, // Don't optimize.
id_binding_,
select_image_binding_,
false));
@@ -169,6 +184,9 @@ namespace odb
const char* select_text_;
const char* delete_text_;
+ bool versioned_;
+ const schema_version_migration* svm_;
+
details::shared_ptr<insert_statement_type> insert_;
details::shared_ptr<select_statement_type> select_;
details::shared_ptr<delete_statement_type> delete_;
@@ -273,6 +291,7 @@ namespace odb
new (details::shared) update_statement_type (
this->conn_,
update_text_,
+ this->versioned_, // Process if versioned.
update_image_binding_,
false));
diff --git a/odb/mysql/container-statements.txx b/odb/mysql/container-statements.txx
index 2458f4d..922ea43 100644
--- a/odb/mysql/container-statements.txx
+++ b/odb/mysql/container-statements.txx
@@ -18,7 +18,8 @@ namespace odb
id_binding_ (id),
functions_ (this),
insert_image_binding_ (0, 0), // Initialized by impl.
- select_image_binding_ (0, 0) // Initialized by impl.
+ select_image_binding_ (0, 0), // Initialized by impl.
+ svm_ (0)
{
functions_.insert_ = &traits::insert;
functions_.select_ = &traits::select;
@@ -80,6 +81,8 @@ namespace odb
this->insert_text_ = traits::insert_statement;
this->select_text_ = traits::select_statement;
this->delete_text_ = traits::delete_statement;
+
+ this->versioned_ = traits::versioned;
}
// smart_container_statements_impl
diff --git a/odb/mysql/database.cxx b/odb/mysql/database.cxx
index 9dac33b..d4ab6c4 100644
--- a/odb/mysql/database.cxx
+++ b/odb/mysql/database.cxx
@@ -310,7 +310,13 @@ namespace odb
try
{
- select_statement st (c, text.c_str (), param, result, false);
+ select_statement st (c,
+ text.c_str (),
+ false, // Don't process.
+ false, // Don't optimize.
+ param,
+ result,
+ false);
st.execute ();
auto_result ar (st);
diff --git a/odb/mysql/forward.hxx b/odb/mysql/forward.hxx
index 52ca8d2..88043b2 100644
--- a/odb/mysql/forward.hxx
+++ b/odb/mysql/forward.hxx
@@ -43,7 +43,8 @@ namespace odb
{
statement_select,
statement_insert,
- statement_update
+ statement_update,
+ statement_delete
};
class binding;
diff --git a/odb/mysql/no-id-object-result.hxx b/odb/mysql/no-id-object-result.hxx
index aae0e47..2a1f749 100644
--- a/odb/mysql/no-id-object-result.hxx
+++ b/odb/mysql/no-id-object-result.hxx
@@ -9,6 +9,7 @@
#include <cstddef> // std::size_t
+#include <odb/schema-version.hxx>
#include <odb/no-id-object-result.hxx>
#include <odb/details/shared-ptr.hxx>
@@ -16,6 +17,7 @@
#include <odb/mysql/version.hxx>
#include <odb/mysql/forward.hxx> // query_base
#include <odb/mysql/statement.hxx>
+#include <odb/mysql/traits-calls.hxx>
namespace odb
{
@@ -40,7 +42,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&);
@@ -66,6 +69,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ object_traits_calls<object_type> tc_;
std::size_t count_;
};
}
diff --git a/odb/mysql/no-id-object-result.txx b/odb/mysql/no-id-object-result.txx
index 84c3a3d..fd040e3 100644
--- a/odb/mysql/no-id-object-result.txx
+++ b/odb/mysql/no-id-object-result.txx
@@ -36,10 +36,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)
{
}
@@ -52,7 +54,7 @@ namespace odb
fetch ();
object_traits::callback (this->db_, obj, callback_event::pre_load);
- object_traits::init (obj, statements_.image (), &this->db_);
+ tc_.init (obj, statements_.image (), &this->db_);
object_traits::callback (this->db_, obj, callback_event::post_load);
}
@@ -95,7 +97,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++;
}
@@ -116,14 +118,13 @@ 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 (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_->refetch ();
diff --git a/odb/mysql/no-id-object-statements.hxx b/odb/mysql/no-id-object-statements.hxx
index 253a3a9..0da7368 100644
--- a/odb/mysql/no-id-object-statements.hxx
+++ b/odb/mysql/no-id-object-statements.hxx
@@ -86,6 +86,7 @@ namespace odb
new (details::shared) insert_statement_type (
conn_,
object_traits::persist_statement,
+ object_traits::versioned, // Process if versioned.
insert_image_binding_,
false));
diff --git a/odb/mysql/polymorphic-object-result.hxx b/odb/mysql/polymorphic-object-result.hxx
index b8c35d0..7d108e6 100644
--- a/odb/mysql/polymorphic-object-result.hxx
+++ b/odb/mysql/polymorphic-object-result.hxx
@@ -9,6 +9,7 @@
#include <cstddef> // std::size_t
+#include <odb/schema-version.hxx>
#include <odb/polymorphic-object-result.hxx>
#include <odb/details/shared-ptr.hxx>
@@ -16,6 +17,7 @@
#include <odb/mysql/version.hxx>
#include <odb/mysql/forward.hxx> // query_base
#include <odb/mysql/statement.hxx>
+#include <odb/mysql/traits-calls.hxx>
namespace odb
{
@@ -47,7 +49,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 +82,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ object_traits_calls<object_type> tc_;
std::size_t count_;
};
}
diff --git a/odb/mysql/polymorphic-object-result.txx b/odb/mysql/polymorphic-object-result.txx
index b84ac36..8072b37 100644
--- a/odb/mysql/polymorphic-object-result.txx
+++ b/odb/mysql/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)
{
}
@@ -128,7 +130,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).
@@ -144,7 +146,7 @@ namespace odb
idb.version++;
}
- object_traits::load_ (statements_, *pobj);
+ tc_.load_ (statements_, *pobj, false);
// Load the dynamic part of the object unless static and dynamic
// types are the same.
@@ -155,7 +157,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;
@@ -235,14 +237,16 @@ namespace odb
typedef object_traits_impl<T, id_mysql> 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);
+ object_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;
@@ -260,14 +264,16 @@ namespace odb
typedef object_traits_impl<R, id_mysql> 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);
+ object_traits_calls<R> tc (svm);
+ tc.bind (b.bind, im, statement_select);
sts.select_image_version (im.version);
b.version++;
return true;
@@ -287,7 +293,7 @@ namespace odb
// to fetch() as a result of other statements execution.
//
if (statement_->cached ())
- image_rebind::rebind (statements_);
+ image_rebind::rebind (statements_, tc_.version ());
while (!this->end_ && (!next || count_ > statement_->fetched ()))
{
@@ -304,11 +310,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_->refetch ();
// Fall throught.
diff --git a/odb/mysql/polymorphic-object-statements.hxx b/odb/mysql/polymorphic-object-statements.hxx
index 71b3d93..63662df 100644
--- a/odb/mysql/polymorphic-object-statements.hxx
+++ b/odb/mysql/polymorphic-object-statements.hxx
@@ -104,6 +104,8 @@ namespace odb
new (details::shared) select_statement_type (
this->conn_,
object_traits::find_discriminator_statement,
+ false, // Doesn't need to be processed.
+ false, // Don't optimize.
discriminator_id_image_binding_,
discriminator_image_binding_,
false));
@@ -117,6 +119,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;
@@ -190,7 +204,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.
@@ -295,6 +312,7 @@ namespace odb
new (details::shared) insert_statement_type (
conn_,
object_traits::persist_statement,
+ object_traits::versioned, // Process if versioned.
insert_image_binding_,
false));
@@ -312,6 +330,8 @@ namespace odb
new (details::shared) select_statement_type (
conn_,
object_traits::find_statements[i],
+ object_traits::versioned, // Process if versioned.
+ false, // Don't optimize.
root_statements_.id_image_binding (),
select_image_bindings_[i],
false));
@@ -327,6 +347,7 @@ namespace odb
new (details::shared) update_statement_type (
conn_,
object_traits::update_statement,
+ object_traits::versioned, // Process if versioned.
update_image_binding_,
false));
diff --git a/odb/mysql/polymorphic-object-statements.txx b/odb/mysql/polymorphic-object-statements.txx
index d8a7a1d..a228b72 100644
--- a/odb/mysql/polymorphic-object-statements.txx
+++ b/odb/mysql/polymorphic-object-statements.txx
@@ -10,6 +10,7 @@
#include <odb/mysql/connection.hxx>
#include <odb/mysql/transaction.hxx>
#include <odb/mysql/statement-cache.hxx>
+#include <odb/mysql/traits-calls.hxx>
namespace odb
{
@@ -111,7 +112,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 (
@@ -122,14 +126,16 @@ namespace odb
// The same code as in object_statements::load_delayed_().
//
- if (!object_traits::find_ (sts, &id))
+ object_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);
- object_traits::load_ (sts, obj); // Load containers, etc.
+ tc.init (obj, sts.image (), &db);
+ tc.load_ (sts, obj, false); // Load containers, etc.
- rsts.load_delayed ();
+ rsts.load_delayed (svm);
{
typename root_statements_type::auto_unlock u (rsts);
diff --git a/odb/mysql/query.cxx b/odb/mysql/query.cxx
index f925e76..c81f80c 100644
--- a/odb/mysql/query.cxx
+++ b/odb/mysql/query.cxx
@@ -98,8 +98,8 @@ namespace odb
// We don't want extra spaces after '(' as well as before ','
// and ')'.
//
- if (last != ' ' && last != '(' &&
- first != ' ' && first != ',' && first != ')')
+ if (last != ' ' && last != '\n' && last != '(' &&
+ first != ' ' && first != '\n' && first != ',' && first != ')')
s += ' ';
s += q;
@@ -183,7 +183,7 @@ namespace odb
// It either has to be an exact match, or there should be
// a whitespace following the keyword.
//
- if (s.size () == n || s[n] == ' ' || s[n] =='\t')
+ if (s.size () == n || s[n] == ' ' || s[n] == '\n' || s[n] =='\t')
return true;
}
@@ -242,7 +242,7 @@ namespace odb
{
case clause_part::kind_column:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
r += i->part;
@@ -250,7 +250,7 @@ namespace odb
}
case clause_part::kind_param:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
// Add the conversion expression, if any.
@@ -277,8 +277,8 @@ namespace odb
const string& p (i->part);
char first (!p.empty () ? p[0] : ' ');
- if (last != ' ' && last != '(' &&
- first != ' ' && first != ',' && first != ')')
+ if (last != ' ' && last != '\n' && last != '(' &&
+ first != ' ' && first != '\n' && first != ',' && first != ')')
r += ' ';
r += p;
@@ -286,7 +286,7 @@ namespace odb
}
case clause_part::kind_bool:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
r += i->bool_part ? "TRUE" : "FALSE";
diff --git a/odb/mysql/section-statements.hxx b/odb/mysql/section-statements.hxx
index 38cf88d..2e01df4 100644
--- a/odb/mysql/section-statements.hxx
+++ b/odb/mysql/section-statements.hxx
@@ -100,6 +100,8 @@ namespace odb
new (details::shared) select_statement_type (
conn_,
traits::select_statement,
+ traits::versioned, // Process if versioned.
+ false, // Don't optimize.
id_binding_,
select_image_binding_,
false));
@@ -115,6 +117,7 @@ namespace odb
new (details::shared) update_statement_type (
conn_,
traits::update_statement,
+ traits::versioned, // Process if versioned.
update_image_binding_,
false));
diff --git a/odb/mysql/simple-object-result.hxx b/odb/mysql/simple-object-result.hxx
index edbed4c..85eb4ff 100644
--- a/odb/mysql/simple-object-result.hxx
+++ b/odb/mysql/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/mysql/version.hxx>
#include <odb/mysql/forward.hxx> // query_base
#include <odb/mysql/statement.hxx>
+#include <odb/mysql/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_;
+ object_traits_calls<object_type> tc_;
std::size_t count_;
};
}
diff --git a/odb/mysql/simple-object-result.txx b/odb/mysql/simple-object-result.txx
index f1b9bfa..f444688 100644
--- a/odb/mysql/simple-object-result.txx
+++ b/odb/mysql/simple-object-result.txx
@@ -38,10 +38,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)
{
}
@@ -68,7 +70,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).
@@ -84,8 +86,8 @@ namespace odb
idb.version++;
}
- object_traits::load_ (statements_, obj);
- statements_.load_delayed ();
+ tc_.load_ (statements_, obj, false);
+ statements_.load_delayed (tc_.version ());
l.unlock ();
object_traits::callback (this->db_, obj, callback_event::post_load);
}
@@ -147,7 +149,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++;
}
@@ -168,14 +170,13 @@ 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 (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_->refetch ();
diff --git a/odb/mysql/simple-object-statements.hxx b/odb/mysql/simple-object-statements.hxx
index 73dc660..1ce8472 100644
--- a/odb/mysql/simple-object-statements.hxx
+++ b/odb/mysql/simple-object-statements.hxx
@@ -243,8 +243,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,
@@ -256,12 +258,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
@@ -349,6 +351,7 @@ namespace odb
new (details::shared) insert_statement_type (
conn_,
object_traits::persist_statement,
+ object_traits::versioned, // Process if versioned.
insert_image_binding_,
false));
@@ -363,6 +366,8 @@ namespace odb
new (details::shared) select_statement_type (
conn_,
object_traits::find_statement,
+ object_traits::versioned, // Process if versioned.
+ false, // Don't optimize.
id_image_binding_,
select_image_binding_,
false));
@@ -378,6 +383,7 @@ namespace odb
new (details::shared) update_statement_type (
conn_,
object_traits::update_statement,
+ object_traits::versioned, // Process if versioned.
update_image_binding_,
false));
@@ -454,14 +460,15 @@ 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_ ();
- private:
+ protected:
template <typename T1>
friend class polymorphic_derived_object_statements;
diff --git a/odb/mysql/simple-object-statements.txx b/odb/mysql/simple-object-statements.txx
index 082d9db..506b7a3 100644
--- a/odb/mysql/simple-object-statements.txx
+++ b/odb/mysql/simple-object-statements.txx
@@ -8,6 +8,7 @@
#include <odb/exceptions.hxx>
#include <odb/mysql/connection.hxx>
+#include <odb/mysql/traits-calls.hxx>
namespace odb
{
@@ -70,8 +71,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 ());
@@ -86,7 +88,9 @@ namespace odb
if (l.loader == 0)
{
- if (!object_traits::find_ (*this, &l.id))
+ object_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);
@@ -95,11 +99,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.
+ //
+ tc.load_ (static_cast<STS&> (*this), *l.obj, false);
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
@@ -115,7 +122,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/mysql/statement-cache.hxx b/odb/mysql/statement-cache.hxx
index 9c8cf52..7f41432 100644
--- a/odb/mysql/statement-cache.hxx
+++ b/odb/mysql/statement-cache.hxx
@@ -29,7 +29,9 @@ namespace odb
class LIBODB_MYSQL_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_mysql>::statements_type&
@@ -46,6 +48,7 @@ namespace odb
details::type_info_comparator> map;
connection& conn_;
+ unsigned int version_seq_;
map map_;
};
}
diff --git a/odb/mysql/statement-cache.txx b/odb/mysql/statement-cache.txx
index 0ac74a4..b110d97 100644
--- a/odb/mysql/statement-cache.txx
+++ b/odb/mysql/statement-cache.txx
@@ -2,6 +2,8 @@
// copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
+#include <odb/mysql/database.hxx>
+
namespace odb
{
namespace mysql
@@ -15,6 +17,16 @@ namespace odb
typename object_traits_impl<T, id_mysql>::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 +43,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/mysql/statement.cxx b/odb/mysql/statement.cxx
index 2a7a011..cf03a9b 100644
--- a/odb/mysql/statement.cxx
+++ b/odb/mysql/statement.cxx
@@ -2,7 +2,7 @@
// copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
-#include <cstring> // std::strlen
+#include <cstring> // std::strlen, std::memmove, std::memset
#include <cassert>
#include <odb/tracer.hxx>
@@ -23,19 +23,36 @@ namespace odb
//
statement::
- statement (connection_type& conn, const string& text)
- : conn_ (conn), text_copy_ (text), text_ (text_copy_.c_str ())
+ statement (connection_type& conn,
+ const string& text,
+ statement_kind sk,
+ const binding* process,
+ bool optimize)
+ : conn_ (conn)
{
- init (text_copy_.size ());
+ if (process == 0)
+ {
+ text_copy_ = text;
+ text_ = text_copy_.c_str ();
+ }
+ else
+ text_ = text.c_str (); // Temporary, see init().
+
+ init (text.size (), sk, process, optimize);
}
statement::
- statement (connection_type& conn, const char* text, bool copy)
+ statement (connection_type& conn,
+ const char* text,
+ statement_kind sk,
+ const binding* process,
+ bool optimize,
+ bool copy)
: conn_ (conn)
{
size_t n;
- if (copy)
+ if (process == 0 && copy)
{
text_copy_ = text;
text_ = text_copy_.c_str ();
@@ -43,16 +60,55 @@ namespace odb
}
else
{
- text_ = text;
+ text_ = text; // Potentially temporary, see init().
n = strlen (text_);
}
- init (n);
+ init (n, sk, process, optimize);
}
void statement::
- init (size_t text_size)
+ init (size_t text_size,
+ statement_kind sk,
+ const binding* proc,
+ bool optimize)
{
+ if (proc != 0)
+ {
+ switch (sk)
+ {
+ case statement_select:
+ process_select (text_,
+ &proc->bind->buffer, proc->count, sizeof (MYSQL_BIND),
+ '`', '`',
+ optimize,
+ text_copy_);
+ break;
+ case statement_insert:
+ process_insert (text_,
+ &proc->bind->buffer, proc->count, sizeof (MYSQL_BIND),
+ '?',
+ text_copy_);
+ break;
+ case statement_update:
+ process_update (text_,
+ &proc->bind->buffer, proc->count, sizeof (MYSQL_BIND),
+ '?',
+ text_copy_);
+ break;
+ case statement_delete:
+ assert (false);
+ }
+
+ text_ = text_copy_.c_str ();
+ text_size = text_copy_.size ();
+ }
+
+ // Empty statement.
+ //
+ if (*text_ == '\0')
+ return;
+
stmt_.reset (conn_.alloc_stmt_handle ());
conn_.clear ();
@@ -69,6 +125,61 @@ namespace odb
}
}
+ size_t statement::
+ process_bind (MYSQL_BIND* b, size_t n)
+ {
+ size_t shifts (0);
+ for (MYSQL_BIND* e (b + n); b != e;)
+ {
+ if (b->buffer == 0)
+ {
+ // It is possible that this array has already been processed
+ // (shared among multiple statements).
+ //
+ if (b->length != 0)
+ {
+ n -= e - b;
+ break;
+ }
+
+ e--;
+
+ // Shift the rest of the entries to the left.
+ //
+ memmove (b, b + 1, (e - b) * sizeof (MYSQL_BIND));
+
+ // Store the original position of the NULL entry at the end.
+ //
+ e->buffer = 0;
+ e->length = reinterpret_cast<unsigned long*> (b + shifts);
+
+ shifts++;
+ continue;
+ }
+
+ b++;
+ }
+
+ return n - shifts;
+ }
+
+ void statement::
+ restore_bind (MYSQL_BIND* b, size_t n)
+ {
+ for (MYSQL_BIND* e (b + n - 1); e->buffer == 0 && e->length != 0;)
+ {
+ MYSQL_BIND* p (reinterpret_cast<MYSQL_BIND*> (e->length));
+
+ // Shift the entries from the specified position to the right.
+ //
+ memmove (p + 1, p, (e - p) * sizeof (MYSQL_BIND));
+
+ // Restore the original NULL entry.
+ //
+ memset (p, 0, sizeof (MYSQL_BIND));
+ }
+ }
+
statement::
~statement ()
{
@@ -109,10 +220,14 @@ namespace odb
select_statement::
select_statement (connection_type& conn,
- const string& t,
+ const string& text,
+ bool process,
+ bool optimize,
binding& param,
binding& result)
- : statement (conn, t),
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
end_ (false),
cached_ (false),
freed_ (true),
@@ -126,11 +241,16 @@ namespace odb
select_statement::
select_statement (connection_type& conn,
- const char* t,
+ const char* text,
+ bool process,
+ bool optimize,
binding& param,
binding& result,
- bool ct)
- : statement (conn, t, ct),
+ bool copy_text)
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize,
+ copy_text),
end_ (false),
cached_ (false),
freed_ (true),
@@ -143,8 +263,14 @@ namespace odb
}
select_statement::
- select_statement (connection_type& conn, const string& t, binding& result)
- : statement (conn, t),
+ select_statement (connection_type& conn,
+ const string& text,
+ bool process,
+ bool optimize,
+ binding& result)
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
end_ (false),
cached_ (false),
freed_ (true),
@@ -157,10 +283,15 @@ namespace odb
select_statement::
select_statement (connection_type& conn,
- const char* t,
+ const char* text,
+ bool process,
+ bool optimize,
binding& result,
- bool ct)
- : statement (conn, t, ct),
+ bool copy_text)
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize,
+ copy_text),
end_ (false),
cached_ (false),
freed_ (true),
@@ -186,6 +317,8 @@ namespace odb
if (param_ != 0 && param_version_ != param_->version)
{
+ // For now cannot have NULL entries.
+ //
if (mysql_stmt_bind_param (stmt_, param_->bind))
translate_error (conn_, stmt_);
@@ -234,16 +367,21 @@ namespace odb
{
if (result_version_ != result_.version)
{
+ size_t count (process_bind (result_.bind, result_.count));
+
// 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 (mysql_stmt_field_count (stmt_) == result_.count);
+ assert (mysql_stmt_field_count (stmt_) == count);
if (mysql_stmt_bind_result (stmt_, result_.bind))
translate_error (conn_, stmt_);
+ if (count != result_.count)
+ restore_bind (result_.bind, result_.count);
+
result_version_ = result_.version;
}
@@ -287,16 +425,23 @@ namespace odb
{
// Re-fetch columns that were truncated.
//
+ unsigned int col (0);
for (size_t i (0); i < result_.count; ++i)
{
- if (*result_.bind[i].error)
+ MYSQL_BIND& b (result_.bind[i]);
+
+ if (b.buffer == 0) // Skip NULL entries.
+ continue;
+
+ if (*b.error)
{
- *result_.bind[i].error = 0;
+ *b.error = 0;
- if (mysql_stmt_fetch_column (
- stmt_, result_.bind + i, static_cast<unsigned int> (i), 0))
+ if (mysql_stmt_fetch_column (stmt_, &b, col, 0))
translate_error (conn_, stmt_);
}
+
+ col++;
}
}
@@ -338,17 +483,30 @@ namespace odb
}
insert_statement::
- insert_statement (connection_type& conn, const string& t, binding& param)
- : statement (conn, t), param_ (param), param_version_ (0)
+ insert_statement (connection_type& conn,
+ const string& text,
+ bool process,
+ binding& param)
+ : statement (conn,
+ text, statement_insert,
+ (process ? &param : 0), false),
+ param_ (param),
+ param_version_ (0)
{
}
insert_statement::
insert_statement (connection_type& conn,
- const char* t,
+ const char* text,
+ bool process,
binding& param,
- bool ct)
- : statement (conn, t, ct), param_ (param), param_version_ (0)
+ bool copy_text)
+ : statement (conn,
+ text, statement_insert,
+ (process ? &param : 0), false,
+ copy_text),
+ param_ (param),
+ param_version_ (0)
{
}
@@ -362,9 +520,14 @@ namespace odb
if (param_version_ != param_.version)
{
+ size_t count (process_bind (param_.bind, param_.count));
+
if (mysql_stmt_bind_param (stmt_, param_.bind))
translate_error (conn_, stmt_);
+ if (count != param_.count)
+ restore_bind (param_.bind, param_.count);
+
param_version_ = param_.version;
}
@@ -402,17 +565,30 @@ namespace odb
}
update_statement::
- update_statement (connection_type& conn, const string& t, binding& param)
- : statement (conn, t), param_ (param), param_version_ (0)
+ update_statement (connection_type& conn,
+ const string& text,
+ bool process,
+ binding& param)
+ : statement (conn,
+ text, statement_update,
+ (process ? &param : 0), false),
+ param_ (param),
+ param_version_ (0)
{
}
update_statement::
update_statement (connection_type& conn,
- const char* t,
+ const char* text,
+ bool process,
binding& param,
- bool ct)
- : statement (conn, t, ct), param_ (param), param_version_ (0)
+ bool copy_text)
+ : statement (conn,
+ text, statement_update,
+ (process ? &param : 0), false,
+ copy_text),
+ param_ (param),
+ param_version_ (0)
{
}
@@ -426,9 +602,14 @@ namespace odb
if (param_version_ != param_.version)
{
+ size_t count (process_bind (param_.bind, param_.count));
+
if (mysql_stmt_bind_param (stmt_, param_.bind))
translate_error (conn_, stmt_);
+ if (count != param_.count)
+ restore_bind (param_.bind, param_.count);
+
param_version_ = param_.version;
}
@@ -460,17 +641,28 @@ namespace odb
}
delete_statement::
- delete_statement (connection_type& conn, const string& t, binding& param)
- : statement (conn, t), param_ (param), param_version_ (0)
+ delete_statement (connection_type& conn,
+ const string& text,
+ binding& param)
+ : statement (conn,
+ text, statement_delete,
+ 0, false),
+ param_ (param),
+ param_version_ (0)
{
}
delete_statement::
delete_statement (connection_type& conn,
- const char* t,
+ const char* text,
binding& param,
- bool ct)
- : statement (conn, t, ct), param_ (param), param_version_ (0)
+ bool copy_text)
+ : statement (conn,
+ text, statement_delete,
+ 0, false,
+ copy_text),
+ param_ (param),
+ param_version_ (0)
{
}
@@ -484,6 +676,8 @@ namespace odb
if (param_version_ != param_.version)
{
+ // Cannot have NULL entries for now.
+ //
if (mysql_stmt_bind_param (stmt_, param_.bind))
translate_error (conn_, stmt_);
diff --git a/odb/mysql/statement.hxx b/odb/mysql/statement.hxx
index 0c4f22b..5fa53ef 100644
--- a/odb/mysql/statement.hxx
+++ b/odb/mysql/statement.hxx
@@ -50,6 +50,17 @@ namespace odb
return conn_;
}
+ // A statement can be empty. This is used to handle situations
+ // where a SELECT or UPDATE statement ends up not having any
+ // columns after processing. An empty statement cannot be
+ // executed.
+ //
+ bool
+ empty () const
+ {
+ return stmt_ == 0;
+ }
+
// Cancel the statement execution (e.g., result fetching) so
// that another statement can be executed on the connection.
//
@@ -57,12 +68,39 @@ namespace odb
cancel ();
protected:
- statement (connection_type&, const std::string& text);
- statement (connection_type&, const char* text, bool copy_text);
+ // We keep two versions to take advantage of std::string COW.
+ //
+ statement (connection_type&,
+ const std::string& text,
+ statement_kind,
+ const binding* process,
+ bool optimize);
+
+ statement (connection_type&,
+ const char* text,
+ statement_kind,
+ const binding* process,
+ bool optimize,
+ bool copy_text);
+
+ // Process the bind array so that all non-NULL entries are at
+ // the beginning. Return the actual number of bound columns.
+ //
+ static std::size_t
+ process_bind (MYSQL_BIND*, std::size_t n);
+
+ // Restore the original locations of the NULL entries in the bind
+ // array.
+ //
+ static void
+ restore_bind (MYSQL_BIND*, std::size_t n);
private:
void
- init (std::size_t text_size);
+ init (std::size_t text_size,
+ statement_kind,
+ const binding* process,
+ bool optimize);
protected:
connection_type& conn_;
@@ -79,21 +117,29 @@ namespace odb
select_statement (connection_type& conn,
const std::string& text,
+ bool process_text,
+ bool optimize_text,
binding& param,
binding& result);
select_statement (connection_type& conn,
const char* text,
+ bool process_text,
+ bool optimize_text,
binding& param,
binding& result,
bool copy_text = true);
select_statement (connection_type& conn,
const std::string& text,
+ bool process_text,
+ bool optimize_text,
binding& result);
select_statement (connection_type& conn,
const char* text,
+ bool process_text,
+ bool optimize_text,
binding& result,
bool copy_text = true);
@@ -187,10 +233,12 @@ namespace odb
insert_statement (connection_type& conn,
const std::string& text,
+ bool process_text,
binding& param);
insert_statement (connection_type& conn,
const char* text,
+ bool process_text,
binding& param,
bool copy_text = true);
@@ -220,10 +268,12 @@ namespace odb
update_statement (connection_type& conn,
const std::string& text,
+ bool process_text,
binding& param);
update_statement (connection_type& conn,
const char* text,
+ bool process_text,
binding& param,
bool copy_text = true);
diff --git a/odb/mysql/traits-calls.hxx b/odb/mysql/traits-calls.hxx
new file mode 100644
index 0000000..41a0a97
--- /dev/null
+++ b/odb/mysql/traits-calls.hxx
@@ -0,0 +1,211 @@
+// file : odb/mysql/traits-calls.hxx
+// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_MYSQL_TRAITS_CALLS_HXX
+#define ODB_MYSQL_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/mysql/forward.hxx>
+#include <odb/mysql/mysql-types.hxx>
+
+namespace odb
+{
+ namespace mysql
+ {
+ //
+ // object_traits_calls
+ //
+
+ template <typename T,
+ bool versioned = object_traits_impl<T, id_mysql>::versioned>
+ struct object_traits_calls;
+
+ template <typename T>
+ struct object_traits_calls<T, false>
+ {
+ typedef object_traits_impl<T, id_mysql> traits;
+ typedef typename traits::image_type image_type;
+
+ object_traits_calls (const schema_version_migration*) {}
+
+ const schema_version_migration*
+ version () const {return 0;}
+
+ static bool
+ grow (image_type& i, my_bool* t)
+ {
+ return traits::grow (i, t);
+ }
+
+ static void
+ bind (MYSQL_BIND* b, image_type& i, statement_kind sk)
+ {
+ traits::bind (b, i, sk);
+ }
+
+ // Poly-derived version.
+ //
+ static void
+ bind (MYSQL_BIND* b,
+ const MYSQL_BIND* 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);
+ }
+
+ static void
+ load_ (typename traits::statements_type& sts, T& o, bool reload)
+ {
+ return traits::load_ (sts, o, reload);
+ }
+ };
+
+ template <typename T>
+ struct object_traits_calls<T, true>
+ {
+ typedef object_traits_impl<T, id_mysql> traits;
+ typedef typename traits::image_type image_type;
+
+ object_traits_calls (const schema_version_migration* svm): svm_ (*svm) {}
+
+ const schema_version_migration*
+ version () const {return &svm_;}
+
+ bool
+ grow (image_type& i, my_bool* t) const
+ {
+ return traits::grow (i, t, svm_);
+ }
+
+ void
+ bind (MYSQL_BIND* b, image_type& i, statement_kind sk) const
+ {
+ traits::bind (b, i, sk, svm_);
+ }
+
+ // Poly-derived version.
+ //
+ void
+ bind (MYSQL_BIND* b,
+ const MYSQL_BIND* 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_);
+ }
+
+ void
+ load_ (typename traits::statements_type& sts, T& o, bool reload) const
+ {
+ return traits::load_ (sts, o, reload, svm_);
+ }
+
+ private:
+ const schema_version_migration& svm_;
+ };
+
+ //
+ // view_traits_calls
+ //
+
+ template <typename T,
+ bool versioned = view_traits_impl<T, id_mysql>::versioned>
+ struct view_traits_calls;
+
+ template <typename T>
+ struct view_traits_calls<T, false>
+ {
+ typedef view_traits_impl<T, id_mysql> traits;
+ typedef typename traits::image_type image_type;
+
+ view_traits_calls (const schema_version_migration*) {}
+
+ static bool
+ grow (image_type& i, my_bool* t)
+ {
+ return traits::grow (i, t);
+ }
+
+ static void
+ bind (MYSQL_BIND* b, image_type& i)
+ {
+ traits::bind (b, i);
+ }
+
+ static void
+ init (T& o, const image_type& i, odb::database* db)
+ {
+ traits::init (o, i, db);
+ }
+ };
+
+ template <typename T>
+ struct view_traits_calls<T, true>
+ {
+ typedef view_traits_impl<T, id_mysql> traits;
+ typedef typename traits::image_type image_type;
+
+ view_traits_calls (const schema_version_migration* svm): svm_ (*svm) {}
+
+ bool
+ grow (image_type& i, my_bool* t) const
+ {
+ return traits::grow (i, t, svm_);
+ }
+
+ void
+ bind (MYSQL_BIND* b, image_type& i) const
+ {
+ traits::bind (b, i, svm_);
+ }
+
+ void
+ init (T& o, const image_type& i, odb::database* db) const
+ {
+ traits::init (o, i, db, svm_);
+ }
+
+ private:
+ const schema_version_migration& svm_;
+ };
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_MYSQL_TRAITS_CALLS_HXX
diff --git a/odb/mysql/view-result.hxx b/odb/mysql/view-result.hxx
index 8fa9d7f..8f4d3fd 100644
--- a/odb/mysql/view-result.hxx
+++ b/odb/mysql/view-result.hxx
@@ -9,6 +9,7 @@
#include <cstddef> // std::size_t
+#include <odb/schema-version.hxx>
#include <odb/view-result.hxx>
#include <odb/details/shared-ptr.hxx>
@@ -16,6 +17,7 @@
#include <odb/mysql/version.hxx>
#include <odb/mysql/forward.hxx> // query_base, view_statements
#include <odb/mysql/statement.hxx>
+#include <odb/mysql/traits-calls.hxx>
namespace odb
{
@@ -40,7 +42,8 @@ namespace odb
view_result_impl (const query_base&,
details::shared_ptr<select_statement>,
- statements_type&);
+ statements_type&,
+ const schema_version_migration*);
virtual void
load (view_type&);
@@ -66,6 +69,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ view_traits_calls<view_type> tc_;
std::size_t count_;
};
}
diff --git a/odb/mysql/view-result.txx b/odb/mysql/view-result.txx
index 895f3fe..5d4c2e5 100644
--- a/odb/mysql/view-result.txx
+++ b/odb/mysql/view-result.txx
@@ -36,10 +36,12 @@ namespace odb
view_result_impl<T>::
view_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)
{
}
@@ -52,7 +54,7 @@ namespace odb
fetch ();
view_traits::callback (this->db_, view, callback_event::pre_load);
- view_traits::init (view, statements_.image (), &this->db_);
+ tc_.init (view, statements_.image (), &this->db_);
view_traits::callback (this->db_, view, callback_event::post_load);
}
@@ -95,7 +97,7 @@ namespace odb
if (im.version != statements_.image_version ())
{
binding& b (statements_.image_binding ());
- view_traits::bind (b.bind, im);
+ tc_.bind (b.bind, im);
statements_.image_version (im.version);
b.version++;
}
@@ -116,13 +118,13 @@ namespace odb
typename view_traits::image_type& im (statements_.image ());
- if (view_traits::grow (im, statements_.image_truncated ()))
+ if (tc_.grow (im, statements_.image_truncated ()))
im.version++;
if (im.version != statements_.image_version ())
{
binding& b (statements_.image_binding ());
- view_traits::bind (b.bind, im);
+ tc_.bind (b.bind, im);
statements_.image_version (im.version);
b.version++;
statement_->refetch ();