aboutsummaryrefslogtreecommitdiff
path: root/odb/sqlite
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-09-10 14:10:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-09-17 12:04:01 +0200
commit31fd2870497686667f20b2d43467a07482f8ab40 (patch)
tree9e8fc08cd23b52699c62149f665f32df8892c7c1 /odb/sqlite
parentc3248cd60418cee935508f62a3436970f9d234b2 (diff)
Schema versioning support
Diffstat (limited to 'odb/sqlite')
-rw-r--r--odb/sqlite/container-statements.hxx20
-rw-r--r--odb/sqlite/container-statements.txx5
-rw-r--r--odb/sqlite/database.cxx7
-rw-r--r--odb/sqlite/forward.hxx4
-rw-r--r--odb/sqlite/no-id-object-result.hxx6
-rw-r--r--odb/sqlite/no-id-object-result.txx14
-rw-r--r--odb/sqlite/no-id-object-statements.hxx1
-rw-r--r--odb/sqlite/polymorphic-object-result.hxx6
-rw-r--r--odb/sqlite/polymorphic-object-result.txx30
-rw-r--r--odb/sqlite/polymorphic-object-statements.hxx23
-rw-r--r--odb/sqlite/polymorphic-object-statements.txx16
-rw-r--r--odb/sqlite/query.cxx16
-rw-r--r--odb/sqlite/section-statements.hxx3
-rw-r--r--odb/sqlite/simple-object-result.hxx6
-rw-r--r--odb/sqlite/simple-object-result.txx18
-rw-r--r--odb/sqlite/simple-object-statements.hxx21
-rw-r--r--odb/sqlite/simple-object-statements.txx19
-rw-r--r--odb/sqlite/statement-cache.cxx1
-rw-r--r--odb/sqlite/statement-cache.hxx1
-rw-r--r--odb/sqlite/statement-cache.txx15
-rw-r--r--odb/sqlite/statement.cxx206
-rw-r--r--odb/sqlite/statement.hxx54
-rw-r--r--odb/sqlite/traits-calls.hxx215
-rw-r--r--odb/sqlite/view-result.hxx6
-rw-r--r--odb/sqlite/view-result.txx14
25 files changed, 607 insertions, 120 deletions
diff --git a/odb/sqlite/container-statements.hxx b/odb/sqlite/container-statements.hxx
index e9c2d3b..058a255 100644
--- a/odb/sqlite/container-statements.hxx
+++ b/odb/sqlite/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/sqlite/version.hxx>
@@ -57,6 +58,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&
@@ -114,7 +123,10 @@ namespace odb
if (insert_ == 0)
insert_.reset (
new (details::shared) insert_statement_type (
- conn_, insert_text_, insert_image_binding_));
+ conn_,
+ insert_text_,
+ versioned_, // Process if versioned.
+ insert_image_binding_));
return *insert_;
}
@@ -127,6 +139,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_));
@@ -167,6 +181,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_;
@@ -270,6 +287,7 @@ namespace odb
new (details::shared) update_statement_type (
this->conn_,
update_text_,
+ this->versioned_, // Process if versioned.
update_image_binding_));
return *update_;
diff --git a/odb/sqlite/container-statements.txx b/odb/sqlite/container-statements.txx
index 5024b5b..6458be8 100644
--- a/odb/sqlite/container-statements.txx
+++ b/odb/sqlite/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/sqlite/database.cxx b/odb/sqlite/database.cxx
index d5399f7..bed0b32 100644
--- a/odb/sqlite/database.cxx
+++ b/odb/sqlite/database.cxx
@@ -230,7 +230,12 @@ namespace odb
try
{
- select_statement st (c, text, param, result);
+ select_statement st (c,
+ text,
+ false, // Don't process.
+ false, // Don't optimize.
+ param,
+ result);
st.execute ();
auto_result ar (st);
diff --git a/odb/sqlite/forward.hxx b/odb/sqlite/forward.hxx
index 456ff43..8904011 100644
--- a/odb/sqlite/forward.hxx
+++ b/odb/sqlite/forward.hxx
@@ -43,7 +43,9 @@ namespace odb
{
statement_select,
statement_insert,
- statement_update
+ statement_update,
+ statement_delete,
+ statement_generic
};
class binding;
diff --git a/odb/sqlite/no-id-object-result.hxx b/odb/sqlite/no-id-object-result.hxx
index 236bf82..49576c3 100644
--- a/odb/sqlite/no-id-object-result.hxx
+++ b/odb/sqlite/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/sqlite/version.hxx>
#include <odb/sqlite/forward.hxx> // query_base, query_params
#include <odb/sqlite/statement.hxx>
+#include <odb/sqlite/traits-calls.hxx>
namespace odb
{
@@ -40,7 +42,8 @@ namespace odb
no_id_object_result_impl (const query_base&,
const details::shared_ptr<select_statement>&,
- statements_type&);
+ statements_type&,
+ const schema_version_migration*);
virtual void
load (object_type&);
@@ -66,6 +69,7 @@ namespace odb
details::shared_ptr<query_params> params_;
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ object_traits_calls<object_type> tc_;
};
}
}
diff --git a/odb/sqlite/no-id-object-result.txx b/odb/sqlite/no-id-object-result.txx
index e857820..cf0fc15 100644
--- a/odb/sqlite/no-id-object-result.txx
+++ b/odb/sqlite/no-id-object-result.txx
@@ -37,11 +37,13 @@ namespace odb
no_id_object_result_impl<T>::
no_id_object_result_impl (const query_base& q,
const details::shared_ptr<select_statement>& s,
- statements_type& sts)
+ statements_type& sts,
+ const schema_version_migration* svm)
: base_type (sts.connection ()),
params_ (q.parameters ()),
statement_ (s),
- statements_ (sts)
+ statements_ (sts),
+ tc_ (svm)
{
}
@@ -57,7 +59,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++;
}
@@ -66,13 +68,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 ();
@@ -80,7 +82,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/sqlite/no-id-object-statements.hxx b/odb/sqlite/no-id-object-statements.hxx
index 6939fc7..2e0cb05 100644
--- a/odb/sqlite/no-id-object-statements.hxx
+++ b/odb/sqlite/no-id-object-statements.hxx
@@ -87,6 +87,7 @@ namespace odb
new (details::shared) insert_statement_type (
conn_,
object_traits::persist_statement,
+ object_traits::versioned, // Process if versioned.
insert_image_binding_));
}
diff --git a/odb/sqlite/polymorphic-object-result.hxx b/odb/sqlite/polymorphic-object-result.hxx
index 493bced..7192a26 100644
--- a/odb/sqlite/polymorphic-object-result.hxx
+++ b/odb/sqlite/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/sqlite/version.hxx>
#include <odb/sqlite/forward.hxx> // query_base, query_params
#include <odb/sqlite/statement.hxx>
+#include <odb/sqlite/traits-calls.hxx>
namespace odb
{
@@ -48,7 +50,8 @@ namespace odb
polymorphic_object_result_impl (
const query_base&,
const details::shared_ptr<select_statement>&,
- statements_type&);
+ statements_type&,
+ const schema_version_migration*);
virtual void
load (object_type*, bool fetch);
@@ -84,6 +87,7 @@ namespace odb
details::shared_ptr<query_params> params_;
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ object_traits_calls<object_type> tc_;
};
}
}
diff --git a/odb/sqlite/polymorphic-object-result.txx b/odb/sqlite/polymorphic-object-result.txx
index 9c79414..6d761b5 100644
--- a/odb/sqlite/polymorphic-object-result.txx
+++ b/odb/sqlite/polymorphic-object-result.txx
@@ -40,11 +40,13 @@ namespace odb
polymorphic_object_result_impl (
const query_base& q,
const details::shared_ptr<select_statement>& s,
- statements_type& sts)
+ statements_type& sts,
+ const schema_version_migration* svm)
: base_type (sts.connection ()),
params_ (q.parameters ()),
statement_ (s),
- statements_ (sts)
+ statements_ (sts),
+ tc_ (svm)
{
}
@@ -123,7 +125,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).
@@ -139,7 +141,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.
@@ -150,7 +152,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_sqlite> 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;
@@ -224,14 +228,16 @@ namespace odb
typedef object_traits_impl<R, id_sqlite> 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;
@@ -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/sqlite/polymorphic-object-statements.hxx b/odb/sqlite/polymorphic-object-statements.hxx
index fa5f6af..2586cb0 100644
--- a/odb/sqlite/polymorphic-object-statements.hxx
+++ b/odb/sqlite/polymorphic-object-statements.hxx
@@ -105,6 +105,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_));
}
@@ -118,6 +120,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;
@@ -191,7 +205,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.
@@ -297,6 +314,7 @@ namespace odb
new (details::shared) insert_statement_type (
conn_,
object_traits::persist_statement,
+ object_traits::versioned, // Process if versioned.
insert_image_binding_));
}
@@ -315,6 +333,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]));
}
@@ -331,6 +351,7 @@ namespace odb
new (details::shared) update_statement_type (
conn_,
object_traits::update_statement,
+ object_traits::versioned, // Process if versioned.
update_image_binding_));
}
diff --git a/odb/sqlite/polymorphic-object-statements.txx b/odb/sqlite/polymorphic-object-statements.txx
index 999eb3e..b97cd14 100644
--- a/odb/sqlite/polymorphic-object-statements.txx
+++ b/odb/sqlite/polymorphic-object-statements.txx
@@ -10,6 +10,7 @@
#include <odb/sqlite/connection.hxx>
#include <odb/sqlite/transaction.hxx>
#include <odb/sqlite/statement-cache.hxx>
+#include <odb/sqlite/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/sqlite/query.cxx b/odb/sqlite/query.cxx
index 120be98..fc1a046 100644
--- a/odb/sqlite/query.cxx
+++ b/odb/sqlite/query.cxx
@@ -159,8 +159,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;
@@ -213,7 +213,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;
}
@@ -272,7 +272,7 @@ namespace odb
{
case clause_part::kind_column:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
r += i->part;
@@ -280,7 +280,7 @@ namespace odb
}
case clause_part::kind_param:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
// Add the conversion expression, if any.
@@ -307,8 +307,8 @@ namespace odb
const string& p (i->part);
char first (!p.empty () ? p[0] : ' ');
- if (last != ' ' && last != '(' &&
- first != ' ' && first != ',' && first != ')')
+ if (last != ' ' && first != '\n' && last != '(' &&
+ first != ' ' && last != '\n' && first != ',' && first != ')')
r += ' ';
r += p;
@@ -316,7 +316,7 @@ namespace odb
}
case clause_part::kind_bool:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
r += i->bool_part ? "1" : "0";
diff --git a/odb/sqlite/section-statements.hxx b/odb/sqlite/section-statements.hxx
index 3f0d9c4..8bdbda1 100644
--- a/odb/sqlite/section-statements.hxx
+++ b/odb/sqlite/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_));
@@ -114,6 +116,7 @@ namespace odb
new (details::shared) update_statement_type (
conn_,
traits::update_statement,
+ traits::versioned, // Process if versioned.
update_image_binding_));
return *update_;
diff --git a/odb/sqlite/simple-object-result.hxx b/odb/sqlite/simple-object-result.hxx
index 9dd258a..3888a56 100644
--- a/odb/sqlite/simple-object-result.hxx
+++ b/odb/sqlite/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/sqlite/version.hxx>
#include <odb/sqlite/forward.hxx> // query_base, query_params
#include <odb/sqlite/statement.hxx>
+#include <odb/sqlite/traits-calls.hxx>
namespace odb
{
@@ -41,7 +43,8 @@ namespace odb
object_result_impl (const query_base&,
const details::shared_ptr<select_statement>&,
- statements_type&);
+ statements_type&,
+ const schema_version_migration*);
virtual void
load (object_type&, bool fetch);
@@ -74,6 +77,7 @@ namespace odb
details::shared_ptr<query_params> params_;
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ object_traits_calls<object_type> tc_;
};
}
}
diff --git a/odb/sqlite/simple-object-result.txx b/odb/sqlite/simple-object-result.txx
index fe31300..2c4340d 100644
--- a/odb/sqlite/simple-object-result.txx
+++ b/odb/sqlite/simple-object-result.txx
@@ -39,11 +39,13 @@ namespace odb
object_result_impl<T>::
object_result_impl (const query_base& q,
const details::shared_ptr<select_statement>& s,
- statements_type& sts)
+ statements_type& sts,
+ const schema_version_migration* svm)
: base_type (sts.connection ()),
params_ (q.parameters ()),
statement_ (s),
- statements_ (sts)
+ statements_ (sts),
+ tc_ (svm)
{
}
@@ -62,7 +64,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).
@@ -78,8 +80,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);
}
@@ -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/sqlite/simple-object-statements.hxx b/odb/sqlite/simple-object-statements.hxx
index a1e7678..f438d90 100644
--- a/odb/sqlite/simple-object-statements.hxx
+++ b/odb/sqlite/simple-object-statements.hxx
@@ -244,8 +244,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,
@@ -257,12 +259,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
@@ -351,6 +353,7 @@ namespace odb
new (details::shared) insert_statement_type (
conn_,
object_traits::persist_statement,
+ object_traits::versioned, // Process if versioned.
insert_image_binding_));
}
@@ -366,6 +369,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_));
}
@@ -382,6 +387,7 @@ namespace odb
new (details::shared) update_statement_type (
conn_,
object_traits::update_statement,
+ object_traits::versioned, // Process if versioned.
update_image_binding_));
}
@@ -458,14 +464,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/sqlite/simple-object-statements.txx b/odb/sqlite/simple-object-statements.txx
index 15689c6..552806c 100644
--- a/odb/sqlite/simple-object-statements.txx
+++ b/odb/sqlite/simple-object-statements.txx
@@ -8,6 +8,7 @@
#include <odb/exceptions.hxx>
#include <odb/sqlite/connection.hxx>
+#include <odb/sqlite/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/sqlite/statement-cache.cxx b/odb/sqlite/statement-cache.cxx
index bb34aed..e29f83e 100644
--- a/odb/sqlite/statement-cache.cxx
+++ b/odb/sqlite/statement-cache.cxx
@@ -13,6 +13,7 @@ namespace odb
statement_cache::
statement_cache (connection& conn)
: conn_ (conn),
+ version_seq_ (conn.database ().schema_version_sequence ()),
// String lengths below include '\0', as per SQLite manual
// suggestions.
//
diff --git a/odb/sqlite/statement-cache.hxx b/odb/sqlite/statement-cache.hxx
index bd90a44..f943ffc 100644
--- a/odb/sqlite/statement-cache.hxx
+++ b/odb/sqlite/statement-cache.hxx
@@ -89,6 +89,7 @@ namespace odb
details::type_info_comparator> map;
connection& conn_;
+ unsigned int version_seq_;
details::shared_ptr<generic_statement> begin_;
mutable details::shared_ptr<generic_statement> begin_immediate_;
diff --git a/odb/sqlite/statement-cache.txx b/odb/sqlite/statement-cache.txx
index 4c6e3cd..8d8e358 100644
--- a/odb/sqlite/statement-cache.txx
+++ b/odb/sqlite/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/sqlite/database.hxx>
+
namespace odb
{
namespace sqlite
@@ -15,6 +17,16 @@ namespace odb
typename object_traits_impl<T, id_sqlite>::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/sqlite/statement.cxx b/odb/sqlite/statement.cxx
index de71e12..f20d8da 100644
--- a/odb/sqlite/statement.cxx
+++ b/odb/sqlite/statement.cxx
@@ -24,6 +24,9 @@ namespace odb
statement::
~statement ()
{
+ if (empty ())
+ return;
+
{
odb::tracer* t;
if ((t = conn_.transaction_tracer ()) ||
@@ -39,8 +42,50 @@ namespace odb
}
void statement::
- init (const char* text, std::size_t text_size)
+ init (const char* text,
+ std::size_t text_size,
+ statement_kind sk,
+ const binding* proc,
+ bool optimize)
{
+ string tmp;
+ if (proc != 0)
+ {
+ switch (sk)
+ {
+ case statement_select:
+ process_select (text,
+ &proc->bind->buffer, proc->count, sizeof (bind),
+ '"', '"',
+ optimize,
+ tmp);
+ break;
+ case statement_insert:
+ process_insert (text,
+ &proc->bind->buffer, proc->count, sizeof (bind),
+ '?',
+ tmp);
+ break;
+ case statement_update:
+ process_update (text,
+ &proc->bind->buffer, proc->count, sizeof (bind),
+ '?',
+ tmp);
+ break;
+ case statement_delete:
+ case statement_generic:
+ assert (false);
+ }
+
+ text = tmp.c_str ();
+ text_size = tmp.size ();
+ }
+
+ // Empty statement.
+ //
+ if (*text == '\0')
+ return;
+
int e;
sqlite3_stmt* stmt (0);
while ((e = sqlite3_prepare_v2 (conn_.handle (),
@@ -83,15 +128,18 @@ namespace odb
// SQLite parameters are counted from 1.
//
- n++;
- for (size_t i (1); e == SQLITE_OK && i < n; ++i, ++p)
+ for (size_t i (0), j (1); e == SQLITE_OK && i < n; ++i)
{
- const bind& b (*p);
- int j (static_cast<int> (i));
+ const bind& b (p[i]);
+
+ if (b.buffer == 0) // Skip NULL entries.
+ continue;
+
+ int c (static_cast<int> (j++));
if (b.is_null != 0 && *b.is_null)
{
- e = sqlite3_bind_null (stmt_, j);
+ e = sqlite3_bind_null (stmt_, c);
continue;
}
@@ -100,19 +148,19 @@ namespace odb
case bind::integer:
{
long long v (*static_cast<long long*> (b.buffer));
- e = sqlite3_bind_int64 (stmt_, j, static_cast<sqlite3_int64> (v));
+ e = sqlite3_bind_int64 (stmt_, c, static_cast<sqlite3_int64> (v));
break;
}
case bind::real:
{
double v (*static_cast<double*> (b.buffer));
- e = sqlite3_bind_double (stmt_, j, v);
+ e = sqlite3_bind_double (stmt_, c, v);
break;
}
case bind::text:
{
e = sqlite3_bind_text (stmt_,
- j,
+ c,
static_cast<const char*> (b.buffer),
static_cast<int> (*b.size),
SQLITE_STATIC);
@@ -121,7 +169,7 @@ namespace odb
case bind::text16:
{
e = sqlite3_bind_text16 (stmt_,
- j,
+ c,
b.buffer,
static_cast<int> (*b.size),
SQLITE_STATIC);
@@ -130,7 +178,7 @@ namespace odb
case bind::blob:
{
e = sqlite3_bind_blob (stmt_,
- j,
+ c,
b.buffer,
static_cast<int> (*b.size),
SQLITE_STATIC);
@@ -144,21 +192,20 @@ namespace odb
}
bool statement::
- bind_result (const bind* p, size_t n, bool truncated)
+ bind_result (const bind* p, size_t count, bool truncated)
{
- // 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> (sqlite3_data_count (stmt_)) == n);
-
bool r (true);
+ int col_count (sqlite3_data_count (stmt_));
- for (size_t i (0); i < n; ++i)
+ int col (0);
+ for (size_t i (0); i != count && col != col_count; ++i)
{
const bind& b (p[i]);
- int j (static_cast<int> (i));
+
+ if (b.buffer == 0) // Skip NULL entries.
+ continue;
+
+ int c (col++);
if (truncated && (b.truncated == 0 || !*b.truncated))
continue;
@@ -170,7 +217,7 @@ namespace odb
//
if (!truncated)
{
- *b.is_null = sqlite3_column_type (stmt_, j) == SQLITE_NULL;
+ *b.is_null = sqlite3_column_type (stmt_, c) == SQLITE_NULL;
if (*b.is_null)
continue;
@@ -181,13 +228,13 @@ namespace odb
case bind::integer:
{
*static_cast<long long*> (b.buffer) =
- static_cast<long long> (sqlite3_column_int64 (stmt_, j));
+ static_cast<long long> (sqlite3_column_int64 (stmt_, c));
break;
}
case bind::real:
{
*static_cast<double*> (b.buffer) =
- sqlite3_column_double (stmt_, j);
+ sqlite3_column_double (stmt_, c);
break;
}
case bind::text:
@@ -203,15 +250,15 @@ namespace odb
if (b.type != bind::text16)
{
d = b.type == bind::text
- ? sqlite3_column_text (stmt_, j)
- : sqlite3_column_blob (stmt_, j);
- *b.size = static_cast<size_t> (sqlite3_column_bytes (stmt_, j));
+ ? sqlite3_column_text (stmt_, c)
+ : sqlite3_column_blob (stmt_, c);
+ *b.size = static_cast<size_t> (sqlite3_column_bytes (stmt_, c));
}
else
{
- d = sqlite3_column_text16 (stmt_, j);
+ d = sqlite3_column_text16 (stmt_, c);
*b.size = static_cast<size_t> (
- sqlite3_column_bytes16 (stmt_, j));
+ sqlite3_column_bytes16 (stmt_, c));
}
if (*b.size > b.capacity)
@@ -229,6 +276,13 @@ namespace odb
}
}
+ // 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;
}
@@ -237,14 +291,18 @@ namespace odb
generic_statement::
generic_statement (connection_type& conn, const string& text)
- : statement (conn, text),
+ : statement (conn,
+ text, statement_generic,
+ 0, false),
result_set_ (stmt_ ? sqlite3_column_count (stmt_) != 0: false)
{
}
generic_statement::
generic_statement (connection_type& conn, const char* text)
- : statement (conn, text),
+ : statement (conn,
+ text, statement_generic,
+ 0, false),
result_set_ (stmt_ ? sqlite3_column_count (stmt_) != 0: false)
{
}
@@ -253,7 +311,9 @@ namespace odb
generic_statement (connection_type& conn,
const char* text,
std::size_t text_size)
- : statement (conn, text, text_size),
+ : statement (conn,
+ text, text_size, statement_generic,
+ 0, false),
result_set_ (stmt_ ? sqlite3_column_count (stmt_) != 0: false)
{
}
@@ -312,32 +372,58 @@ namespace odb
select_statement::
select_statement (connection_type& conn,
const string& text,
+ bool process,
+ bool optimize,
binding& param,
binding& result)
- : statement (conn, text), param_ (&param), result_ (result)
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
+ param_ (&param),
+ result_ (result)
{
}
select_statement::
select_statement (connection_type& conn,
const char* text,
+ bool process,
+ bool optimize,
binding& param,
binding& result)
- : statement (conn, text), param_ (&param), result_ (result)
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
+ param_ (&param),
+ result_ (result)
{
}
select_statement::
select_statement (connection_type& conn,
const string& text,
+ bool process,
+ bool optimize,
binding& result)
- : statement (conn, text), param_ (0), result_ (result)
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
+ param_ (0),
+ result_ (result)
{
}
select_statement::
- select_statement (connection_type& conn, const char* text, binding& result)
- : statement (conn, text), param_ (0), result_ (result)
+ select_statement (connection_type& conn,
+ const char* text,
+ bool process,
+ bool optimize,
+ binding& result)
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
+ param_ (0),
+ result_ (result)
{
}
@@ -428,14 +514,24 @@ namespace odb
insert_statement::
insert_statement (connection_type& conn,
const string& text,
+ bool process,
binding& param)
- : statement (conn, text), param_ (param)
+ : statement (conn,
+ text, statement_insert,
+ (process ? &param : 0), false),
+ param_ (param)
{
}
insert_statement::
- insert_statement (connection_type& conn, const char* text, binding& param)
- : statement (conn, text), param_ (param)
+ insert_statement (connection_type& conn,
+ const char* text,
+ bool process,
+ binding& param)
+ : statement (conn,
+ text, statement_insert,
+ (process ? &param : 0), false),
+ param_ (param)
{
}
@@ -499,14 +595,24 @@ namespace odb
update_statement::
update_statement (connection_type& conn,
const string& text,
+ bool process,
binding& param)
- : statement (conn, text), param_ (param)
+ : statement (conn,
+ text, statement_update,
+ (process ? &param : 0), false),
+ param_ (param)
{
}
update_statement::
- update_statement (connection_type& conn, const char* text, binding& param)
- : statement (conn, text), param_ (param)
+ update_statement (connection_type& conn,
+ const char* text,
+ bool process,
+ binding& param)
+ : statement (conn,
+ text, statement_update,
+ (process ? &param : 0), false),
+ param_ (param)
{
}
@@ -554,13 +660,21 @@ namespace odb
delete_statement (connection_type& conn,
const string& text,
binding& param)
- : statement (conn, text), param_ (param)
+ : statement (conn,
+ text, statement_delete,
+ 0, false),
+ param_ (param)
{
}
delete_statement::
- delete_statement (connection_type& conn, const char* text, binding& param)
- : statement (conn, text), param_ (param)
+ delete_statement (connection_type& conn,
+ const char* text,
+ binding& param)
+ : statement (conn,
+ text, statement_delete,
+ 0, false),
+ param_ (param)
{
}
diff --git a/odb/sqlite/statement.hxx b/odb/sqlite/statement.hxx
index eb55e58..05fa9bd 100644
--- a/odb/sqlite/statement.hxx
+++ b/odb/sqlite/statement.hxx
@@ -53,25 +53,49 @@ 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;
+ }
+
protected:
- statement (connection_type& conn, const std::string& text)
+ // We keep two versions to take advantage of std::string COW.
+ //
+ statement (connection_type& conn,
+ const std::string& text,
+ statement_kind sk,
+ const binding* process,
+ bool optimize)
: conn_ (conn)
{
- init (text.c_str (), text.size ());
+ init (text.c_str (), text.size (), sk, process, optimize);
}
- statement (connection_type& conn, const char* text)
+ statement (connection_type& conn,
+ const char* text,
+ statement_kind sk,
+ const binding* process,
+ bool optimize)
: conn_ (conn)
{
- init (text, std::strlen (text));
+ init (text, std::strlen (text), sk, process, optimize);
}
statement (connection_type& conn,
const char* text,
- std::size_t text_size)
+ std::size_t text_size,
+ statement_kind sk,
+ const binding* process,
+ bool optimize)
: conn_ (conn)
{
- init (text, text_size);
+ init (text, text_size, sk, process, optimize);
}
protected:
@@ -128,7 +152,11 @@ namespace odb
private:
void
- init (const char* text, std::size_t text_size);
+ init (const char* text,
+ std::size_t text_size,
+ statement_kind,
+ const binding* process,
+ bool optimize);
// Doubly-linked list of active statements.
//
@@ -188,20 +216,28 @@ namespace odb
public:
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);
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);
// Common select interface expected by the generated code.
@@ -283,10 +319,12 @@ namespace odb
public:
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);
// Return true if successful and false if the row is a duplicate.
@@ -311,10 +349,12 @@ namespace odb
public:
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);
unsigned long long
diff --git a/odb/sqlite/traits-calls.hxx b/odb/sqlite/traits-calls.hxx
new file mode 100644
index 0000000..1e5bd8d
--- /dev/null
+++ b/odb/sqlite/traits-calls.hxx
@@ -0,0 +1,215 @@
+// file : odb/sqlite/traits-calls.hxx
+// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_SQLITE_TRAITS_CALLS_HXX
+#define ODB_SQLITE_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/sqlite/forward.hxx>
+#include <odb/sqlite/sqlite-types.hxx>
+
+namespace odb
+{
+ namespace sqlite
+ {
+ //
+ // object_traits_calls
+ //
+
+ template <typename T,
+ bool versioned = object_traits_impl<T, id_sqlite>::versioned>
+ struct object_traits_calls;
+
+ template <typename T>
+ struct object_traits_calls<T, false>
+ {
+ typedef object_traits_impl<T, id_sqlite> traits;
+ typedef typename traits::image_type image_type;
+ typedef sqlite::bind bind_type;
+
+ object_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);
+ }
+
+ 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_sqlite> traits;
+ typedef typename traits::image_type image_type;
+ typedef sqlite::bind bind_type;
+
+ object_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_);
+ }
+
+ 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_sqlite>::versioned>
+ struct view_traits_calls;
+
+ template <typename T>
+ struct view_traits_calls<T, false>
+ {
+ typedef view_traits_impl<T, id_sqlite> traits;
+ typedef typename traits::image_type image_type;
+ typedef sqlite::bind bind_type;
+
+ view_traits_calls (const schema_version_migration*) {}
+
+ static bool
+ grow (image_type& i, bool* t)
+ {
+ return traits::grow (i, t);
+ }
+
+ static void
+ bind (bind_type* 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_sqlite> traits;
+ typedef typename traits::image_type image_type;
+ typedef sqlite::bind bind_type;
+
+ view_traits_calls (const schema_version_migration* svm): svm_ (*svm) {}
+
+ bool
+ grow (image_type& i, bool* t) const
+ {
+ return traits::grow (i, t, svm_);
+ }
+
+ void
+ bind (bind_type* 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_SQLITE_TRAITS_CALLS_HXX
diff --git a/odb/sqlite/view-result.hxx b/odb/sqlite/view-result.hxx
index fd189e6..0e05adb 100644
--- a/odb/sqlite/view-result.hxx
+++ b/odb/sqlite/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/sqlite/version.hxx>
#include <odb/sqlite/forward.hxx> // query_base, query_params
#include <odb/sqlite/statement.hxx>
+#include <odb/sqlite/traits-calls.hxx>
namespace odb
{
@@ -40,7 +42,8 @@ namespace odb
view_result_impl (const query_base&,
const details::shared_ptr<select_statement>&,
- statements_type&);
+ statements_type&,
+ const schema_version_migration*);
virtual void
load (view_type&);
@@ -66,6 +69,7 @@ namespace odb
details::shared_ptr<query_params> params_;
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ view_traits_calls<view_type> tc_;
};
}
}
diff --git a/odb/sqlite/view-result.txx b/odb/sqlite/view-result.txx
index d22a440..d13b58e 100644
--- a/odb/sqlite/view-result.txx
+++ b/odb/sqlite/view-result.txx
@@ -37,11 +37,13 @@ namespace odb
view_result_impl<T>::
view_result_impl (const query_base& q,
const details::shared_ptr<select_statement>& s,
- statements_type& sts)
+ statements_type& sts,
+ const schema_version_migration* svm)
: base_type (sts.connection ()),
params_ (q.parameters ()),
statement_ (s),
- statements_ (sts)
+ statements_ (sts),
+ tc_ (svm)
{
}
@@ -57,7 +59,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++;
}
@@ -66,13 +68,13 @@ namespace odb
if (r == select_statement::truncated)
{
- 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_->reload ();
@@ -80,7 +82,7 @@ namespace odb
}
view_traits::callback (this->db_, view, callback_event::pre_load);
- view_traits::init (view, im, &this->db_);
+ tc_.init (view, im, &this->db_);
view_traits::callback (this->db_, view, callback_event::post_load);
}