aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-11-17 13:34:17 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2014-11-25 06:43:50 +0200
commit6ba692aabf2afae6dab83139ca5e219bfc614890 (patch)
tree75eec5e22602a5ddae9bc82c5d8253f922853c0c
parent3bb29e43f60229bcac00777c839174703f848c16 (diff)
Implement bulk database operation support for Oracle and SQL Server
-rw-r--r--odb/sqlite/container-statements.hxx3
-rw-r--r--odb/sqlite/database.hxx4
-rw-r--r--odb/sqlite/database.ixx7
-rw-r--r--odb/sqlite/exceptions.cxx18
-rw-r--r--odb/sqlite/exceptions.hxx9
-rw-r--r--odb/sqlite/no-id-object-statements.hxx3
-rw-r--r--odb/sqlite/polymorphic-object-statements.hxx9
-rw-r--r--odb/sqlite/section-statements.hxx3
-rw-r--r--odb/sqlite/section-statements.txx2
-rw-r--r--odb/sqlite/simple-object-statements.hxx41
-rw-r--r--odb/sqlite/statement.cxx29
-rw-r--r--odb/sqlite/statement.hxx10
12 files changed, 100 insertions, 38 deletions
diff --git a/odb/sqlite/container-statements.hxx b/odb/sqlite/container-statements.hxx
index 058a255..4871fe8 100644
--- a/odb/sqlite/container-statements.hxx
+++ b/odb/sqlite/container-statements.hxx
@@ -126,7 +126,8 @@ namespace odb
conn_,
insert_text_,
versioned_, // Process if versioned.
- insert_image_binding_));
+ insert_image_binding_,
+ 0));
return *insert_;
}
diff --git a/odb/sqlite/database.hxx b/odb/sqlite/database.hxx
index 0eef6d5..f3d8248 100644
--- a/odb/sqlite/database.hxx
+++ b/odb/sqlite/database.hxx
@@ -124,6 +124,10 @@ namespace odb
template <typename T>
typename object_traits<T>::id_type
+ persist (const T& object);
+
+ template <typename T>
+ typename object_traits<T>::id_type
persist (T* obj_ptr);
template <typename T, template <typename> class P>
diff --git a/odb/sqlite/database.ixx b/odb/sqlite/database.ixx
index d5918f0..5b21e36 100644
--- a/odb/sqlite/database.ixx
+++ b/odb/sqlite/database.ixx
@@ -27,6 +27,13 @@ namespace odb
template <typename T>
inline typename object_traits<T>::id_type database::
+ persist (const T& obj)
+ {
+ return persist_<const T, id_sqlite> (obj);
+ }
+
+ template <typename T>
+ inline typename object_traits<T>::id_type database::
persist (T* p)
{
typedef typename object_traits<T>::pointer_type object_pointer;
diff --git a/odb/sqlite/exceptions.cxx b/odb/sqlite/exceptions.cxx
index 08cdf90..ece5def 100644
--- a/odb/sqlite/exceptions.cxx
+++ b/odb/sqlite/exceptions.cxx
@@ -22,6 +22,12 @@ namespace odb
return "transaction is forced to rollback";
}
+ forced_rollback* forced_rollback::
+ clone () const
+ {
+ return new forced_rollback (*this);
+ }
+
//
// database_exception
//
@@ -51,6 +57,12 @@ namespace odb
return what_.c_str ();
}
+ database_exception* database_exception::
+ clone () const
+ {
+ return new database_exception (*this);
+ }
+
//
// cli_exception
//
@@ -71,5 +83,11 @@ namespace odb
{
return what_.c_str ();
}
+
+ cli_exception* cli_exception::
+ clone () const
+ {
+ return new cli_exception (*this);
+ }
}
}
diff --git a/odb/sqlite/exceptions.hxx b/odb/sqlite/exceptions.hxx
index 8a21d5e..6bae164 100644
--- a/odb/sqlite/exceptions.hxx
+++ b/odb/sqlite/exceptions.hxx
@@ -29,6 +29,9 @@ namespace odb
{
virtual const char*
what () const throw ();
+
+ virtual forced_rollback*
+ clone () const;
};
struct LIBODB_SQLITE_EXPORT database_exception: odb::database_exception
@@ -60,6 +63,9 @@ namespace odb
virtual const char*
what () const throw ();
+ virtual database_exception*
+ clone () const;
+
private:
int error_;
int extended_error_;
@@ -75,6 +81,9 @@ namespace odb
virtual const char*
what () const throw ();
+ virtual cli_exception*
+ clone () const;
+
private:
std::string what_;
};
diff --git a/odb/sqlite/no-id-object-statements.hxx b/odb/sqlite/no-id-object-statements.hxx
index 2e0cb05..a42616d 100644
--- a/odb/sqlite/no-id-object-statements.hxx
+++ b/odb/sqlite/no-id-object-statements.hxx
@@ -88,7 +88,8 @@ namespace odb
conn_,
object_traits::persist_statement,
object_traits::versioned, // Process if versioned.
- insert_image_binding_));
+ insert_image_binding_,
+ 0));
}
return *persist_;
diff --git a/odb/sqlite/polymorphic-object-statements.hxx b/odb/sqlite/polymorphic-object-statements.hxx
index 2586cb0..4464fa3 100644
--- a/odb/sqlite/polymorphic-object-statements.hxx
+++ b/odb/sqlite/polymorphic-object-statements.hxx
@@ -315,7 +315,8 @@ namespace odb
conn_,
object_traits::persist_statement,
object_traits::versioned, // Process if versioned.
- insert_image_binding_));
+ insert_image_binding_,
+ 0));
}
return *persist_;
@@ -381,6 +382,7 @@ namespace odb
return extra_statement_cache_.get (
conn_,
image_,
+ id_image (),
id_image_binding (),
&id_image_binding ()); // Note, not id+version.
}
@@ -419,8 +421,9 @@ namespace odb
root_statements_type& root_statements_;
base_statements_type& base_statements_;
- extra_statement_cache_ptr<extra_statement_cache_type, image_type>
- extra_statement_cache_;
+ extra_statement_cache_ptr<extra_statement_cache_type,
+ image_type,
+ id_image_type> extra_statement_cache_;
image_type image_;
diff --git a/odb/sqlite/section-statements.hxx b/odb/sqlite/section-statements.hxx
index dff5ec5..f52d531 100644
--- a/odb/sqlite/section-statements.hxx
+++ b/odb/sqlite/section-statements.hxx
@@ -36,6 +36,7 @@ namespace odb
typedef ST traits;
typedef typename traits::image_type image_type;
+ typedef typename traits::id_image_type id_image_type;
typedef sqlite::select_statement select_statement_type;
typedef sqlite::update_statement update_statement_type;
@@ -43,7 +44,7 @@ namespace odb
typedef sqlite::connection connection_type;
section_statements (connection_type&,
- image_type&,
+ image_type&, id_image_type&,
binding& id, binding& idv);
connection_type&
diff --git a/odb/sqlite/section-statements.txx b/odb/sqlite/section-statements.txx
index f005f74..19f6968 100644
--- a/odb/sqlite/section-statements.txx
+++ b/odb/sqlite/section-statements.txx
@@ -11,7 +11,7 @@ namespace odb
template <typename T, typename ST>
section_statements<T, ST>::
section_statements (connection_type& conn,
- image_type& im,
+ image_type& im, id_image_type&,
binding& id, binding& idv)
: conn_ (conn),
svm_ (0),
diff --git a/odb/sqlite/simple-object-statements.hxx b/odb/sqlite/simple-object-statements.hxx
index f438d90..801f791 100644
--- a/odb/sqlite/simple-object-statements.hxx
+++ b/odb/sqlite/simple-object-statements.hxx
@@ -39,49 +39,56 @@ namespace odb
// deleter function which will be initialized during allocation
// (at that point we know that the cache class is defined).
//
- template <typename T, typename I>
+ template <typename T, typename I, typename ID>
struct extra_statement_cache_ptr
{
typedef I image_type;
+ typedef ID id_image_type;
typedef sqlite::connection connection_type;
extra_statement_cache_ptr (): p_ (0) {}
~extra_statement_cache_ptr ()
{
if (p_ != 0)
- (this->*deleter_) (0, 0, 0, 0);
+ (this->*deleter_) (0, 0, 0, 0, 0);
}
T&
- get (connection_type& c, image_type& im, binding& id, binding* idv)
+ get (connection_type& c,
+ image_type& im, id_image_type& idim,
+ binding& id, binding* idv)
{
if (p_ == 0)
- allocate (&c, &im, &id, (idv != 0 ? idv : &id));
+ allocate (&c, &im, &idim, &id, (idv != 0 ? idv : &id));
return *p_;
}
private:
void
- allocate (connection_type*, image_type*, binding*, binding*);
+ allocate (connection_type*,
+ image_type*, id_image_type*,
+ binding*, binding*);
private:
T* p_;
void (extra_statement_cache_ptr::*deleter_) (
- connection_type*, image_type*, binding*, binding*);
+ connection_type*, image_type*, id_image_type*, binding*, binding*);
};
- template <typename T, typename I>
- void extra_statement_cache_ptr<T, I>::
- allocate (connection_type* c, image_type* im, binding* id, binding* idv)
+ template <typename T, typename I, typename ID>
+ void extra_statement_cache_ptr<T, I, ID>::
+ allocate (connection_type* c,
+ image_type* im, id_image_type* idim,
+ binding* id, binding* idv)
{
// To reduce object code size, this function acts as both allocator
// and deleter.
//
if (p_ == 0)
{
- p_ = new T (*c, *im, *id, *idv);
- deleter_ = &extra_statement_cache_ptr<T, I>::allocate;
+ p_ = new T (*c, *im, *idim, *id, *idv);
+ deleter_ = &extra_statement_cache_ptr<T, I, ID>::allocate;
}
else
delete p_;
@@ -354,7 +361,8 @@ namespace odb
conn_,
object_traits::persist_statement,
object_traits::versioned, // Process if versioned.
- insert_image_binding_));
+ insert_image_binding_,
+ (object_traits::auto_id ? &id_image_binding_ : 0)));
}
return *persist_;
@@ -430,7 +438,9 @@ namespace odb
extra_statement_cache ()
{
return extra_statement_cache_.get (
- conn_, image_, id_image_binding_, od_.id_image_binding ());
+ conn_,
+ image_, id_image_,
+ id_image_binding_, od_.id_image_binding ());
}
public:
@@ -476,8 +486,9 @@ namespace odb
template <typename T1>
friend class polymorphic_derived_object_statements;
- extra_statement_cache_ptr<extra_statement_cache_type, image_type>
- extra_statement_cache_;
+ extra_statement_cache_ptr<extra_statement_cache_type,
+ image_type,
+ id_image_type> extra_statement_cache_;
image_type image_;
diff --git a/odb/sqlite/statement.cxx b/odb/sqlite/statement.cxx
index d56f45f..09188cb 100644
--- a/odb/sqlite/statement.cxx
+++ b/odb/sqlite/statement.cxx
@@ -605,11 +605,13 @@ namespace odb
insert_statement (connection_type& conn,
const string& text,
bool process,
- binding& param)
+ binding& param,
+ binding* returning)
: statement (conn,
text, statement_insert,
(process ? &param : 0), false),
- param_ (param)
+ param_ (param),
+ returning_ (returning)
{
}
@@ -617,11 +619,13 @@ namespace odb
insert_statement (connection_type& conn,
const char* text,
bool process,
- binding& param)
+ binding& param,
+ binding* returning)
: statement (conn,
text, statement_insert,
(process ? &param : 0), false),
- param_ (param)
+ param_ (param),
+ returning_ (returning)
{
}
@@ -679,14 +683,17 @@ namespace odb
translate_error (e, conn_);
}
- return true;
- }
+ if (returning_ != 0)
+ {
+ bind& b (returning_->bind[0]);
- unsigned long long insert_statement::
- id ()
- {
- return static_cast<unsigned long long> (
- sqlite3_last_insert_rowid (conn_.handle ()));
+ *b.is_null = false;
+ *static_cast<long long*> (b.buffer) =
+ static_cast<long long> (
+ sqlite3_last_insert_rowid (conn_.handle ()));
+ }
+
+ return true;
}
// update_statement
diff --git a/odb/sqlite/statement.hxx b/odb/sqlite/statement.hxx
index 7d7f021..84d90d7 100644
--- a/odb/sqlite/statement.hxx
+++ b/odb/sqlite/statement.hxx
@@ -328,12 +328,14 @@ namespace odb
insert_statement (connection_type& conn,
const std::string& text,
bool process_text,
- binding& param);
+ binding& param,
+ binding* returning);
insert_statement (connection_type& conn,
const char* text,
bool process_text,
- binding& param);
+ binding& param,
+ binding* returning);
// Return true if successful and false if the row is a duplicate.
// All other errors are reported by throwing exceptions.
@@ -341,15 +343,13 @@ namespace odb
bool
execute ();
- unsigned long long
- id ();
-
private:
insert_statement (const insert_statement&);
insert_statement& operator= (const insert_statement&);
private:
binding& param_;
+ binding* returning_;
};
class LIBODB_SQLITE_EXPORT update_statement: public statement