aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-11-17 13:35:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2014-11-25 06:43:14 +0200
commitd44d7c96d38453d5a971b813be4c6635bf0b38fb (patch)
tree3d3d0803f4ae707cf8926ce134ace4a35c08a8f5
parentf5826c7da4cc11d46a34e4a5e435cff2730c7263 (diff)
Implement bulk database operation support for Oracle and SQL Server
-rw-r--r--odb/mysql/container-statements.hxx1
-rw-r--r--odb/mysql/database.hxx4
-rw-r--r--odb/mysql/database.ixx7
-rw-r--r--odb/mysql/exceptions.cxx12
-rw-r--r--odb/mysql/exceptions.hxx6
-rw-r--r--odb/mysql/no-id-object-statements.hxx1
-rw-r--r--odb/mysql/polymorphic-object-statements.hxx7
-rw-r--r--odb/mysql/section-statements.hxx3
-rw-r--r--odb/mysql/section-statements.txx2
-rw-r--r--odb/mysql/simple-object-statements.hxx39
-rw-r--r--odb/mysql/statement.cxx44
-rw-r--r--odb/mysql/statement.hxx9
12 files changed, 104 insertions, 31 deletions
diff --git a/odb/mysql/container-statements.hxx b/odb/mysql/container-statements.hxx
index be86cda..191d9f6 100644
--- a/odb/mysql/container-statements.hxx
+++ b/odb/mysql/container-statements.hxx
@@ -128,6 +128,7 @@ namespace odb
insert_text_,
versioned_, // Process if versioned.
insert_image_binding_,
+ 0,
false));
return *insert_;
diff --git a/odb/mysql/database.hxx b/odb/mysql/database.hxx
index 8d11e72..9192138 100644
--- a/odb/mysql/database.hxx
+++ b/odb/mysql/database.hxx
@@ -180,6 +180,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/mysql/database.ixx b/odb/mysql/database.ixx
index 09fc641..68aecec 100644
--- a/odb/mysql/database.ixx
+++ b/odb/mysql/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_mysql> (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/mysql/exceptions.cxx b/odb/mysql/exceptions.cxx
index ddf5ce8..8e2375a 100644
--- a/odb/mysql/exceptions.cxx
+++ b/odb/mysql/exceptions.cxx
@@ -36,6 +36,12 @@ namespace odb
return what_.c_str ();
}
+ database_exception* database_exception::
+ clone () const
+ {
+ return new database_exception (*this);
+ }
+
//
// cli_exception
//
@@ -56,5 +62,11 @@ namespace odb
{
return what_.c_str ();
}
+
+ cli_exception* cli_exception::
+ clone () const
+ {
+ return new cli_exception (*this);
+ }
}
}
diff --git a/odb/mysql/exceptions.hxx b/odb/mysql/exceptions.hxx
index 824f678..ea4e493 100644
--- a/odb/mysql/exceptions.hxx
+++ b/odb/mysql/exceptions.hxx
@@ -49,6 +49,9 @@ namespace odb
virtual const char*
what () const throw ();
+ virtual database_exception*
+ clone () const;
+
private:
unsigned int error_;
std::string sqlstate_;
@@ -64,6 +67,9 @@ namespace odb
virtual const char*
what () const throw ();
+ virtual cli_exception*
+ clone () const;
+
private:
std::string what_;
};
diff --git a/odb/mysql/no-id-object-statements.hxx b/odb/mysql/no-id-object-statements.hxx
index 0da7368..b2c5ce2 100644
--- a/odb/mysql/no-id-object-statements.hxx
+++ b/odb/mysql/no-id-object-statements.hxx
@@ -88,6 +88,7 @@ namespace odb
object_traits::persist_statement,
object_traits::versioned, // Process if versioned.
insert_image_binding_,
+ 0,
false));
return *persist_;
diff --git a/odb/mysql/polymorphic-object-statements.hxx b/odb/mysql/polymorphic-object-statements.hxx
index 63662df..1607926 100644
--- a/odb/mysql/polymorphic-object-statements.hxx
+++ b/odb/mysql/polymorphic-object-statements.hxx
@@ -314,6 +314,7 @@ namespace odb
object_traits::persist_statement,
object_traits::versioned, // Process if versioned.
insert_image_binding_,
+ 0,
false));
return *persist_;
@@ -376,6 +377,7 @@ namespace odb
return extra_statement_cache_.get (
conn_,
image_,
+ id_image (),
id_image_binding (),
&id_image_binding ()); // Note, not id+version.
}
@@ -414,8 +416,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/mysql/section-statements.hxx b/odb/mysql/section-statements.hxx
index bc83942..c4e83ac 100644
--- a/odb/mysql/section-statements.hxx
+++ b/odb/mysql/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 mysql::select_statement select_statement_type;
typedef mysql::update_statement update_statement_type;
@@ -43,7 +44,7 @@ namespace odb
typedef mysql::connection connection_type;
section_statements (connection_type&,
- image_type&,
+ image_type&, id_image_type&,
binding& id, binding& idv);
connection_type&
diff --git a/odb/mysql/section-statements.txx b/odb/mysql/section-statements.txx
index 61bfafe..78fb183 100644
--- a/odb/mysql/section-statements.txx
+++ b/odb/mysql/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/mysql/simple-object-statements.hxx b/odb/mysql/simple-object-statements.hxx
index 1ce8472..f5d52c0 100644
--- a/odb/mysql/simple-object-statements.hxx
+++ b/odb/mysql/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 mysql::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_;
@@ -353,6 +360,7 @@ namespace odb
object_traits::persist_statement,
object_traits::versioned, // Process if versioned.
insert_image_binding_,
+ (object_traits::auto_id ? &id_image_binding_ : 0),
false));
return *persist_;
@@ -426,7 +434,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:
@@ -472,8 +482,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/mysql/statement.cxx b/odb/mysql/statement.cxx
index 4b80913..85732de 100644
--- a/odb/mysql/statement.cxx
+++ b/odb/mysql/statement.cxx
@@ -564,12 +564,14 @@ 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_version_ (0)
+ param_version_ (0),
+ returning_ (returning)
{
}
@@ -578,13 +580,15 @@ namespace odb
const char* text,
bool process,
binding& param,
+ binding* returning,
bool copy_text)
: statement (conn,
text, statement_insert,
(process ? &param : 0), false,
copy_text),
param_ (param),
- param_version_ (0)
+ param_version_ (0),
+ returning_ (returning)
{
}
@@ -625,13 +629,35 @@ namespace odb
translate_error (conn_, stmt_);
}
- return true;
- }
+ if (returning_ != 0)
+ {
+ unsigned long long i (mysql_stmt_insert_id (stmt_));
- unsigned long long insert_statement::
- id ()
- {
- return static_cast<unsigned long long> (mysql_stmt_insert_id (stmt_));
+ MYSQL_BIND& b (returning_->bind[0]);
+ void* v (b.buffer);
+
+ switch (b.buffer_type)
+ {
+ case MYSQL_TYPE_TINY:
+ *static_cast<unsigned char*> (v) = static_cast<unsigned char> (i);
+ break;
+ case MYSQL_TYPE_SHORT:
+ *static_cast<unsigned short*> (v) = static_cast<unsigned short> (i);
+ break;
+ case MYSQL_TYPE_LONG:
+ *static_cast<unsigned int*> (v) = static_cast<unsigned int> (i);
+ break;
+ case MYSQL_TYPE_LONGLONG:
+ *static_cast<unsigned long long*> (v) = i;
+ break;
+ default:
+ assert (false); // Auto id column type is not an integer.
+ }
+
+ *b.is_null = false;
+ }
+
+ return true;
}
// update_statement
diff --git a/odb/mysql/statement.hxx b/odb/mysql/statement.hxx
index 3e7afad..faf8e01 100644
--- a/odb/mysql/statement.hxx
+++ b/odb/mysql/statement.hxx
@@ -238,12 +238,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* returning,
bool copy_text = true);
// Return true if successful and false if the row is a duplicate.
@@ -252,9 +254,6 @@ namespace odb
bool
execute ();
- unsigned long long
- id ();
-
private:
insert_statement (const insert_statement&);
insert_statement& operator= (const insert_statement&);
@@ -262,6 +261,8 @@ namespace odb
private:
binding& param_;
std::size_t param_version_;
+
+ binding* returning_;
};
class LIBODB_MYSQL_EXPORT update_statement: public statement