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
commita3372ca4e3eb1ba4e87dfa9ccb0c78c379935441 (patch)
treefda49b86acd9c9f79d0ea7bd9262ed6f5a41803e
parent1d287936950aa96a7b4a12b0d05633f257ab2c90 (diff)
Schema versioning support
-rw-r--r--odb/oracle/container-statements.hxx25
-rw-r--r--odb/oracle/container-statements.txx5
-rw-r--r--odb/oracle/database.cxx7
-rw-r--r--odb/oracle/forward.hxx4
-rw-r--r--odb/oracle/no-id-object-result.hxx6
-rw-r--r--odb/oracle/no-id-object-result.txx12
-rw-r--r--odb/oracle/no-id-object-statements.hxx1
-rw-r--r--odb/oracle/polymorphic-object-result.hxx6
-rw-r--r--odb/oracle/polymorphic-object-result.txx25
-rw-r--r--odb/oracle/polymorphic-object-statements.hxx23
-rw-r--r--odb/oracle/polymorphic-object-statements.txx16
-rw-r--r--odb/oracle/query.cxx16
-rw-r--r--odb/oracle/section-statements.hxx3
-rw-r--r--odb/oracle/simple-object-result.hxx6
-rw-r--r--odb/oracle/simple-object-result.txx12
-rw-r--r--odb/oracle/simple-object-statements.hxx21
-rw-r--r--odb/oracle/simple-object-statements.txx19
-rw-r--r--odb/oracle/statement-cache.hxx5
-rw-r--r--odb/oracle/statement-cache.txx15
-rw-r--r--odb/oracle/statement.cxx223
-rw-r--r--odb/oracle/statement.hxx55
-rw-r--r--odb/oracle/traits-calls.hxx191
-rw-r--r--odb/oracle/view-result.hxx6
-rw-r--r--odb/oracle/view-result.txx12
24 files changed, 599 insertions, 115 deletions
diff --git a/odb/oracle/container-statements.hxx b/odb/oracle/container-statements.hxx
index 4da7af4..ef1733d 100644
--- a/odb/oracle/container-statements.hxx
+++ b/odb/oracle/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/oracle/version.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&
@@ -109,7 +118,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_;
}
@@ -122,6 +135,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_,
4096)); // Hardcode a 4kB LOB prefetch size.
@@ -161,6 +176,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_;
@@ -260,7 +278,10 @@ namespace odb
if (update_ == 0)
update_.reset (
new (details::shared) update_statement_type (
- this->conn_, update_text_, update_image_binding_));
+ this->conn_,
+ update_text_,
+ this->versioned_, // Process if versioned.
+ update_image_binding_));
return *update_;
}
diff --git a/odb/oracle/container-statements.txx b/odb/oracle/container-statements.txx
index 814414a..f872c05 100644
--- a/odb/oracle/container-statements.txx
+++ b/odb/oracle/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;
@@ -69,6 +70,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/oracle/database.cxx b/odb/oracle/database.cxx
index 60dc4f4..a16ac82 100644
--- a/odb/oracle/database.cxx
+++ b/odb/oracle/database.cxx
@@ -309,7 +309,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/oracle/forward.hxx b/odb/oracle/forward.hxx
index 6163fdf..1f7fafb 100644
--- a/odb/oracle/forward.hxx
+++ b/odb/oracle/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/oracle/no-id-object-result.hxx b/odb/oracle/no-id-object-result.hxx
index 150db3d..f3a695b 100644
--- a/odb/oracle/no-id-object-result.hxx
+++ b/odb/oracle/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/oracle/version.hxx>
#include <odb/oracle/forward.hxx> // query_base
#include <odb/oracle/statement.hxx>
+#include <odb/oracle/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&);
@@ -68,6 +71,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ object_traits_calls<object_type> tc_;
bool use_copy_;
typename object_traits::image_type* image_copy_;
};
diff --git a/odb/oracle/no-id-object-result.txx b/odb/oracle/no-id-object-result.txx
index c70661c..c58e0af 100644
--- a/odb/oracle/no-id-object-result.txx
+++ b/odb/oracle/no-id-object-result.txx
@@ -46,10 +46,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),
use_copy_ (false),
image_copy_ (0)
{
@@ -61,9 +63,9 @@ namespace odb
{
object_traits::callback (this->db_, obj, callback_event::pre_load);
- object_traits::init (obj,
- use_copy_ ? *image_copy_ : statements_.image (),
- &this->db_);
+ tc_.init (obj,
+ use_copy_ ? *image_copy_ : statements_.image (),
+ &this->db_);
// If we are using a copy, make sure the callback information for
// LOB data also comes from the copy.
@@ -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++;
}
diff --git a/odb/oracle/no-id-object-statements.hxx b/odb/oracle/no-id-object-statements.hxx
index 0510283..0be8dac 100644
--- a/odb/oracle/no-id-object-statements.hxx
+++ b/odb/oracle/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/oracle/polymorphic-object-result.hxx b/odb/oracle/polymorphic-object-result.hxx
index f23a199..6879645 100644
--- a/odb/oracle/polymorphic-object-result.hxx
+++ b/odb/oracle/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/oracle/version.hxx>
#include <odb/oracle/forward.hxx> // query_base
#include <odb/oracle/statement.hxx>
+#include <odb/oracle/traits-calls.hxx>
namespace odb
{
@@ -48,7 +50,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);
@@ -82,6 +85,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ object_traits_calls<object_type> tc_;
bool use_copy_;
image_type* image_copy_;
};
diff --git a/odb/oracle/polymorphic-object-result.txx b/odb/oracle/polymorphic-object-result.txx
index a67dce4..19b4fa3 100644
--- a/odb/oracle/polymorphic-object-result.txx
+++ b/odb/oracle/polymorphic-object-result.txx
@@ -52,10 +52,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),
use_copy_ (false),
image_copy_ (0)
{
@@ -133,7 +135,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_);
// If we are using a copy, make sure the callback information for
// LOB data also comes from the copy.
@@ -156,7 +158,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.
@@ -167,7 +169,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;
@@ -210,14 +212,16 @@ namespace odb
typedef object_traits_impl<T, id_oracle> traits;
static void
- 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 ());
}
@@ -242,14 +246,16 @@ namespace odb
typedef object_traits_impl<R, id_oracle> traits;
static void
- 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++;
}
@@ -278,7 +284,8 @@ namespace odb
}
use_copy_ = false;
- polymorphic_image_rebind<object_type, root_type>::rebind (statements_);
+ polymorphic_image_rebind<object_type, root_type>::rebind (
+ statements_, tc_.version ());
if (statement_->fetch () == select_statement::no_data)
{
diff --git a/odb/oracle/polymorphic-object-statements.hxx b/odb/oracle/polymorphic-object-statements.hxx
index 3a3cceb..81ea3c3 100644
--- a/odb/oracle/polymorphic-object-statements.hxx
+++ b/odb/oracle/polymorphic-object-statements.hxx
@@ -101,6 +101,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_,
0)); // No LOB prefetch (discriminator cannot be LOB).
@@ -114,6 +116,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;
@@ -185,7 +199,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.
@@ -287,6 +304,7 @@ namespace odb
new (details::shared) insert_statement_type (
conn_,
object_traits::persist_statement,
+ object_traits::versioned, // Process if versioned.
insert_image_binding_,
false));
@@ -304,6 +322,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],
4096)); // Hardcode a 4kB LOB prefetch size.
@@ -319,6 +339,7 @@ namespace odb
new (details::shared) update_statement_type (
conn_,
object_traits::update_statement,
+ object_traits::versioned, // Process if versioned.
update_image_binding_));
return *update_;
diff --git a/odb/oracle/polymorphic-object-statements.txx b/odb/oracle/polymorphic-object-statements.txx
index 83e88de..54ea3a8 100644
--- a/odb/oracle/polymorphic-object-statements.txx
+++ b/odb/oracle/polymorphic-object-statements.txx
@@ -10,6 +10,7 @@
#include <odb/oracle/connection.hxx>
#include <odb/oracle/transaction.hxx>
#include <odb/oracle/statement-cache.hxx>
+#include <odb/oracle/traits-calls.hxx>
namespace odb
{
@@ -102,7 +103,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 (
@@ -113,15 +117,17 @@ 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);
+ tc.init (obj, sts.image (), &db);
sts.find_[0]->stream_result ();
- object_traits::load_ (sts, obj); // Load containers, etc.
+ 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/oracle/query.cxx b/odb/oracle/query.cxx
index 9fbdc63..439d2c7 100644
--- a/odb/oracle/query.cxx
+++ b/odb/oracle/query.cxx
@@ -99,8 +99,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;
@@ -184,7 +184,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;
}
@@ -244,7 +244,7 @@ namespace odb
{
case clause_part::kind_column:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
r += i->part;
@@ -252,7 +252,7 @@ namespace odb
}
case clause_part::kind_param:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
ostringstream os;
@@ -283,8 +283,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;
@@ -292,7 +292,7 @@ namespace odb
}
case clause_part::kind_bool:
{
- if (last != ' ' && last != '(')
+ if (last != ' ' && last != '\n' && last != '(')
r += ' ';
// Oracle does not have TRUE and FALSE boolean literals (these
diff --git a/odb/oracle/section-statements.hxx b/odb/oracle/section-statements.hxx
index 8579be5..47e3bb7 100644
--- a/odb/oracle/section-statements.hxx
+++ b/odb/oracle/section-statements.hxx
@@ -97,6 +97,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_,
4096)); // Hardcode a 4kB LOB prefetch size.
@@ -112,6 +114,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/oracle/simple-object-result.hxx b/odb/oracle/simple-object-result.hxx
index 19837e7..6ee56ba 100644
--- a/odb/oracle/simple-object-result.hxx
+++ b/odb/oracle/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/oracle/version.hxx>
#include <odb/oracle/forward.hxx> // query_base
#include <odb/oracle/statement.hxx>
+#include <odb/oracle/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);
@@ -72,6 +75,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ object_traits_calls<object_type> tc_;
bool use_copy_;
typename object_traits::image_type* image_copy_;
};
diff --git a/odb/oracle/simple-object-result.txx b/odb/oracle/simple-object-result.txx
index 53d752d..114c919 100644
--- a/odb/oracle/simple-object-result.txx
+++ b/odb/oracle/simple-object-result.txx
@@ -48,10 +48,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),
use_copy_ (false),
image_copy_ (0)
{
@@ -71,7 +73,7 @@ namespace odb
typename object_traits::image_type& i (
use_copy_ ? *image_copy_ : statements_.image ());
- object_traits::init (obj, i, &this->db_);
+ tc_.init (obj, i, &this->db_);
// If we are using a copy, make sure the callback information for
// LOB data also comes from the copy.
@@ -94,8 +96,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);
}
@@ -129,7 +131,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++;
}
diff --git a/odb/oracle/simple-object-statements.hxx b/odb/oracle/simple-object-statements.hxx
index 17e6085..ff76e91 100644
--- a/odb/oracle/simple-object-statements.hxx
+++ b/odb/oracle/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_,
object_traits::auto_id));
@@ -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_,
4096)); // Hardcode a 4kB LOB prefetch size.
@@ -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_));
return *update_;
@@ -452,14 +458,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/oracle/simple-object-statements.txx b/odb/oracle/simple-object-statements.txx
index 6723b1c..61bbc5f 100644
--- a/odb/oracle/simple-object-statements.txx
+++ b/odb/oracle/simple-object-statements.txx
@@ -8,6 +8,7 @@
#include <odb/exceptions.hxx>
#include <odb/oracle/connection.hxx>
+#include <odb/oracle/traits-calls.hxx>
namespace odb
{
@@ -67,8 +68,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 ());
@@ -83,7 +85,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);
@@ -92,12 +96,15 @@ 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);
+ tc.init (*l.obj, image (), &db);
find_->stream_result ();
- object_traits::load_ (*this, *l.obj); // Load containers, etc.
+
+ // 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
@@ -113,7 +120,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/oracle/statement-cache.hxx b/odb/oracle/statement-cache.hxx
index 2795fa4..10f08ea 100644
--- a/odb/oracle/statement-cache.hxx
+++ b/odb/oracle/statement-cache.hxx
@@ -29,7 +29,9 @@ namespace odb
class LIBODB_ORACLE_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_oracle>::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/oracle/statement-cache.txx b/odb/oracle/statement-cache.txx
index a593674..ba747e2 100644
--- a/odb/oracle/statement-cache.txx
+++ b/odb/oracle/statement-cache.txx
@@ -2,6 +2,8 @@
// copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC
// license : ODB NCUEL; see accompanying LICENSE file
+#include <odb/oracle/database.hxx>
+
namespace odb
{
namespace oracle
@@ -15,6 +17,16 @@ namespace odb
typename object_traits_impl<T, id_oracle>::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/oracle/statement.cxx b/odb/oracle/statement.cxx
index 13b9553..5ad867a 100644
--- a/odb/oracle/statement.cxx
+++ b/odb/oracle/statement.cxx
@@ -137,6 +137,9 @@ namespace odb
statement::
~statement ()
{
+ if (empty ())
+ return;
+
{
odb::tracer* t;
if ((t = conn_.transaction_tracer ()) ||
@@ -192,22 +195,73 @@ namespace odb
}
statement::
- statement (connection_type& conn, const string& text)
+ statement (connection_type& conn,
+ const string& text,
+ statement_kind sk,
+ const binding* process,
+ bool optimize)
: conn_ (conn), udata_ (0), usize_ (0)
{
- init (text.c_str (), text.size ());
+ init (text.c_str (), text.size (), sk, process, optimize);
}
statement::
- statement (connection_type& conn, const char* text)
+ statement (connection_type& conn,
+ const char* text,
+ statement_kind sk,
+ const binding* process,
+ bool optimize)
: conn_ (conn), udata_ (0), usize_ (0)
{
- init (text, strlen (text));
+ init (text, strlen (text), sk, process, optimize);
}
void statement::
- init (const char* text, size_t text_size)
+ init (const char* text,
+ 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,
+ false); // No AS in JOINs.
+ 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;
+
OCIError* err (conn_.error_handle ());
OCIStmt* handle (0);
@@ -254,7 +308,7 @@ namespace odb
return reinterpret_cast<char*> (s);
}
- void statement::
+ ub4 statement::
bind_param (bind* b, size_t n)
{
// Figure out how many unbind elements we will need and allocate them.
@@ -264,6 +318,9 @@ namespace odb
for (size_t i (0); i < n; ++i)
{
+ if (b[i].buffer == 0) // Skip NULL entries.
+ continue;
+
switch (b[i].type)
{
case bind::timestamp:
@@ -301,13 +358,14 @@ namespace odb
OCIError* err (conn_.error_handle ());
OCIEnv* env (conn_.database ().environment ());
- // The parameter position in OCIBindByPos is specified as a 1-based
- // index.
- //
- n++;
-
- for (ub4 i (1); i < n; ++i, ++b)
+ ub4 i (0);
+ for (bind* end (b + n); b != end; ++b)
{
+ if (b->buffer == 0) // Skip NULL entries.
+ continue;
+
+ i++; // Column index is 1-based.
+
void* value;
sb4 capacity;
ub2* size (0);
@@ -617,9 +675,11 @@ namespace odb
translate_error (err, r);
}
}
+
+ return i;
}
- void statement::
+ ub4 statement::
bind_result (bind* b, size_t c, size_t p)
{
ODB_POTENTIALLY_UNUSED (p);
@@ -628,8 +688,14 @@ namespace odb
OCIError* err (conn_.error_handle ());
OCIEnv* env (conn_.database ().environment ());
- for (size_t i (1); i <= c; ++i, ++b)
+ ub4 i (0);
+ for (bind* end (b + c); b != end; ++b)
{
+ if (b->buffer == 0) // Skip NULL entries.
+ continue;
+
+ i++; // Column index is 1-based.
+
void* value;
sb4 capacity;
ub2* size (0);
@@ -816,6 +882,8 @@ namespace odb
translate_error (err, r);
}
}
+
+ return i;
}
void statement::
@@ -826,8 +894,14 @@ namespace odb
sword r;
OCIEnv* env (conn_.database ().environment ());
- for (size_t i (1); i <= c; ++i, ++b)
+ ub4 i (0);
+ for (bind* end (b + c); b != end; ++b)
{
+ if (b->buffer == 0) // Skip NULL entries.
+ continue;
+
+ i++; // Column index is 1-based.
+
void* value;
switch (b->type)
@@ -971,8 +1045,11 @@ namespace odb
{
OCIError* err (conn_.error_handle ());
- for (size_t i (0); i < c; ++i, ++b)
+ for (bind* end (b + c); b != end; ++b)
{
+ if (b->buffer == 0) // Skip NULL entries.
+ continue;
+
// Only stream if the bind specifies a LOB type.
//
if (b->type == bind::blob ||
@@ -1091,14 +1168,20 @@ namespace odb
generic_statement::
generic_statement (connection_type& conn, const string& text)
- : statement (conn, text), bound_ (false)
+ : statement (conn,
+ text, statement_generic,
+ 0, false),
+ bound_ (false)
{
init ();
}
generic_statement::
generic_statement (connection_type& conn, const char* text)
- : statement (conn, text), bound_ (false)
+ : statement (conn,
+ text, statement_generic,
+ 0, false),
+ bound_ (false)
{
init ();
}
@@ -1270,65 +1353,93 @@ namespace odb
select_statement::
select_statement (connection_type& conn,
const string& text,
+ bool process,
+ bool optimize,
binding& param,
binding& result,
size_t lob_prefetch_size)
- : statement (conn, text),
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
result_ (result),
- result_version_ (0),
lob_prefetch_size_ (lob_prefetch_size),
done_ (true)
{
- bind_param (param.bind, param.count);
- bind_result (result.bind, result.count, lob_prefetch_size);
- result_version_ = result_.version;
+ if (!empty ())
+ {
+ bind_param (param.bind, param.count);
+ result_count_ = bind_result (
+ result.bind, result.count, lob_prefetch_size);
+ result_version_ = result_.version;
+ }
}
select_statement::
select_statement (connection_type& conn,
const char* text,
+ bool process,
+ bool optimize,
binding& param,
binding& result,
size_t lob_prefetch_size)
- : statement (conn, text),
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
result_ (result),
- result_version_ (0),
lob_prefetch_size_ (lob_prefetch_size),
done_ (true)
{
- bind_param (param.bind, param.count);
- bind_result (result.bind, result.count, lob_prefetch_size);
- result_version_ = result_.version;
+ if (!empty ())
+ {
+ bind_param (param.bind, param.count);
+ result_count_ = bind_result (
+ result.bind, result.count, lob_prefetch_size);
+ result_version_ = result_.version;
+ }
}
select_statement::
select_statement (connection_type& conn,
const string& text,
+ bool process,
+ bool optimize,
binding& result,
size_t lob_prefetch_size)
- : statement (conn, text),
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
result_ (result),
- result_version_ (0),
lob_prefetch_size_ (lob_prefetch_size),
done_ (true)
{
- bind_result (result.bind, result.count, lob_prefetch_size);
- result_version_ = result_.version;
+ if (!empty ())
+ {
+ result_count_ = bind_result (
+ result.bind, result.count, lob_prefetch_size);
+ result_version_ = result_.version;
+ }
}
select_statement::
select_statement (connection_type& conn,
const char* text,
+ bool process,
+ bool optimize,
binding& result,
size_t lob_prefetch_size)
- : statement (conn, text),
+ : statement (conn,
+ text, statement_select,
+ (process ? &result : 0), optimize),
result_ (result),
- result_version_ (0),
lob_prefetch_size_ (lob_prefetch_size),
done_ (true)
{
- bind_result (result.bind, result.count, lob_prefetch_size);
- result_version_ = result_.version;
+ if (!empty ())
+ {
+ result_count_ = bind_result (
+ result.bind, result.count, lob_prefetch_size);
+ result_version_ = result_.version;
+ }
}
void select_statement::
@@ -1374,7 +1485,7 @@ namespace odb
// of this assertion is a native view with a number of data members
// not matching the number of columns in the SELECT-list.
//
- assert (n == result_.count);
+ assert (n == result_count_);
#endif
}
@@ -1495,9 +1606,12 @@ namespace odb
insert_statement::
insert_statement (connection_type& conn,
const string& text,
+ bool process,
binding& param,
bool returning)
- : statement (conn, text)
+ : statement (conn,
+ text, statement_insert,
+ (process ? &param : 0), false)
{
init (param, returning);
}
@@ -1505,9 +1619,12 @@ namespace odb
insert_statement::
insert_statement (connection_type& conn,
const char* text,
+ bool process,
binding& param,
bool returning)
- : statement (conn, text)
+ : statement (conn,
+ text, statement_insert,
+ (process ? &param : 0), false)
{
init (param, returning);
}
@@ -1515,7 +1632,7 @@ namespace odb
void insert_statement::
init (binding& param, bool returning)
{
- bind_param (param.bind, param.count);
+ ub4 param_count (bind_param (param.bind, param.count));
if (returning)
{
@@ -1525,7 +1642,7 @@ namespace odb
sword r (OCIBindByPos (stmt_,
&h,
err,
- param.count + 1,
+ param_count + 1,
0,
#if (OCI_MAJOR_VERSION == 11 && OCI_MINOR_VERSION >=2) \
|| OCI_MAJOR_VERSION > 11
@@ -1636,19 +1753,27 @@ namespace odb
update_statement::
update_statement (connection_type& conn,
const string& text,
+ bool process,
binding& param)
- : statement (conn, text)
+ : statement (conn,
+ text, statement_update,
+ (process ? &param : 0), false)
{
- bind_param (param.bind, param.count);
+ if (!empty ())
+ bind_param (param.bind, param.count);
}
update_statement::
update_statement (connection_type& conn,
const char* text,
+ bool process,
binding& param)
- : statement (conn, text)
+ : statement (conn,
+ text, statement_update,
+ (process ? &param : 0), false)
{
- bind_param (param.bind, param.count);
+ if (!empty ())
+ bind_param (param.bind, param.count);
}
unsigned long long update_statement::
@@ -1707,7 +1832,9 @@ namespace odb
delete_statement (connection_type& conn,
const string& text,
binding& param)
- : statement (conn, text)
+ : statement (conn,
+ text, statement_delete,
+ 0, false)
{
bind_param (param.bind, param.count);
}
@@ -1716,7 +1843,9 @@ namespace odb
delete_statement (connection_type& conn,
const char* text,
binding& param)
- : statement (conn, text)
+ : statement (conn,
+ text, statement_delete,
+ 0, false)
{
bind_param (param.bind, param.count);
}
diff --git a/odb/oracle/statement.hxx b/odb/oracle/statement.hxx
index d246992..cf336c4 100644
--- a/odb/oracle/statement.hxx
+++ b/odb/oracle/statement.hxx
@@ -48,13 +48,39 @@ 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&, const std::string& text);
- statement (connection_type&, const char* 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);
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);
protected:
struct unbind
@@ -66,16 +92,18 @@ namespace odb
// Bind parameters for this statement. This function must only
// be called once. Multiple calls to it will result in memory
- // leaks due to lost OCIBind resources.
+ // leaks due to lost OCIBind resources. Return the actual number
+ // of columns bound.
//
- void
+ ub4
bind_param (bind*, std::size_t count);
// Bind results for this statement. This function must only be
// called once. Multiple calls to it will result in memory leaks
- // due to lost OCIDefine resources.
+ // due to lost OCIDefine resources. Return the actual number of
+ // columns bound.
//
- void
+ ub4
bind_result (bind*,
std::size_t count,
std::size_t lob_prefetch_size = 0);
@@ -146,23 +174,31 @@ namespace odb
select_statement (connection_type& conn,
const std::string& text,
+ bool process_text,
+ bool optimize_text,
binding& param,
binding& result,
std::size_t lob_prefetch_size = 0);
select_statement (connection_type& conn,
const char* text,
+ bool process_text,
+ bool optimize_text,
binding& param,
binding& result,
std::size_t lob_prefetch_size = 0);
select_statement (connection_type& conn,
const std::string& text,
+ bool process_text,
+ bool optimize_text,
binding& result,
std::size_t lob_prefetch_size = 0);
select_statement (connection_type& conn,
const char* text,
+ bool process_text,
+ bool optimize_text,
binding& result,
std::size_t lob_prefetch_size = 0);
@@ -197,6 +233,7 @@ namespace odb
private:
binding& result_;
std::size_t result_version_;
+ ub4 result_count_; // Actual number of bound columns.
const std::size_t lob_prefetch_size_;
bool done_;
};
@@ -222,11 +259,13 @@ namespace odb
insert_statement (connection_type& conn,
const std::string& text,
+ bool process_text,
binding& param,
bool returning);
insert_statement (connection_type& conn,
const char* text,
+ bool process_text,
binding& param,
bool returning);
@@ -282,10 +321,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);
unsigned long long
diff --git a/odb/oracle/traits-calls.hxx b/odb/oracle/traits-calls.hxx
new file mode 100644
index 0000000..e15e616
--- /dev/null
+++ b/odb/oracle/traits-calls.hxx
@@ -0,0 +1,191 @@
+// file : odb/oracle/traits-calls.hxx
+// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_ORACLE_TRAITS_CALLS_HXX
+#define ODB_ORACLE_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/oracle/forward.hxx>
+#include <odb/oracle/oracle-types.hxx>
+
+namespace odb
+{
+ namespace oracle
+ {
+ //
+ // object_traits_calls
+ //
+
+ template <typename T,
+ bool versioned = object_traits_impl<T, id_oracle>::versioned>
+ struct object_traits_calls;
+
+ template <typename T>
+ struct object_traits_calls<T, false>
+ {
+ typedef object_traits_impl<T, id_oracle> traits;
+ typedef typename traits::image_type image_type;
+ typedef oracle::bind bind_type;
+
+ object_traits_calls (const schema_version_migration*) {}
+
+ const schema_version_migration*
+ version () const {return 0;}
+
+ 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_oracle> traits;
+ typedef typename traits::image_type image_type;
+ typedef oracle::bind bind_type;
+
+ object_traits_calls (const schema_version_migration* svm): svm_ (*svm) {}
+
+ const schema_version_migration*
+ version () const {return &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_oracle>::versioned>
+ struct view_traits_calls;
+
+ template <typename T>
+ struct view_traits_calls<T, false>
+ {
+ typedef view_traits_impl<T, id_oracle> traits;
+ typedef typename traits::image_type image_type;
+ typedef oracle::bind bind_type;
+
+ view_traits_calls (const schema_version_migration*) {}
+
+ 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_oracle> traits;
+ typedef typename traits::image_type image_type;
+ typedef oracle::bind bind_type;
+
+ view_traits_calls (const schema_version_migration* svm): svm_ (*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_ORACLE_TRAITS_CALLS_HXX
diff --git a/odb/oracle/view-result.hxx b/odb/oracle/view-result.hxx
index 0adf0fe..424728b 100644
--- a/odb/oracle/view-result.hxx
+++ b/odb/oracle/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/oracle/version.hxx>
#include <odb/oracle/forward.hxx> // query_base, view_statements
#include <odb/oracle/statement.hxx>
+#include <odb/oracle/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&);
@@ -68,6 +71,7 @@ namespace odb
private:
details::shared_ptr<select_statement> statement_;
statements_type& statements_;
+ view_traits_calls<view_type> tc_;
bool use_copy_;
typename view_traits::image_type* image_copy_;
};
diff --git a/odb/oracle/view-result.txx b/odb/oracle/view-result.txx
index df2a833..402a571 100644
--- a/odb/oracle/view-result.txx
+++ b/odb/oracle/view-result.txx
@@ -46,10 +46,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),
use_copy_ (false),
image_copy_ (0)
{
@@ -61,9 +63,9 @@ namespace odb
{
view_traits::callback (this->db_, view, callback_event::pre_load);
- view_traits::init (view,
- use_copy_ ? *image_copy_ : statements_.image (),
- &this->db_);
+ tc_.init (view,
+ use_copy_ ? *image_copy_ : statements_.image (),
+ &this->db_);
// If we are using a copy, make sure the callback information for
// LOB data also comes from the copy.
@@ -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++;
}