aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-11-17 09:08:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2014-11-25 06:44:31 +0200
commit2db43d4c2f2bed0348d781367090e633ad02779f (patch)
treec966a8dfb7855866e7bc89e6d4ef9c5c5fb3560c
parent6323bca38688f0f5be72481fb146313d2fc5fe78 (diff)
Implement bulk database operation support for Oracle and SQL Server
-rw-r--r--odb/pgsql/container-statements.hxx2
-rw-r--r--odb/pgsql/database.hxx4
-rw-r--r--odb/pgsql/database.ixx7
-rw-r--r--odb/pgsql/exceptions.cxx12
-rw-r--r--odb/pgsql/exceptions.hxx6
-rw-r--r--odb/pgsql/no-id-object-statements.hxx2
-rw-r--r--odb/pgsql/polymorphic-object-statements.hxx8
-rw-r--r--odb/pgsql/section-statements.hxx2
-rw-r--r--odb/pgsql/section-statements.txx1
-rw-r--r--odb/pgsql/simple-object-statements.hxx30
-rw-r--r--odb/pgsql/statement.cxx42
-rw-r--r--odb/pgsql/statement.hxx14
12 files changed, 63 insertions, 67 deletions
diff --git a/odb/pgsql/container-statements.hxx b/odb/pgsql/container-statements.hxx
index 0bd222d..80aa30c 100644
--- a/odb/pgsql/container-statements.hxx
+++ b/odb/pgsql/container-statements.hxx
@@ -135,7 +135,7 @@ namespace odb
insert_count_,
insert_image_binding_,
insert_image_native_binding_,
- false,
+ 0,
false));
return *insert_;
diff --git a/odb/pgsql/database.hxx b/odb/pgsql/database.hxx
index dda8d31..c6bc05a 100644
--- a/odb/pgsql/database.hxx
+++ b/odb/pgsql/database.hxx
@@ -93,6 +93,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/pgsql/database.ixx b/odb/pgsql/database.ixx
index 21b5729..5324fc8 100644
--- a/odb/pgsql/database.ixx
+++ b/odb/pgsql/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_pgsql> (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/pgsql/exceptions.cxx b/odb/pgsql/exceptions.cxx
index 23a47cb..f4ac22a 100644
--- a/odb/pgsql/exceptions.cxx
+++ b/odb/pgsql/exceptions.cxx
@@ -41,6 +41,12 @@ namespace odb
return what_.c_str ();
}
+ database_exception* database_exception::
+ clone () const
+ {
+ return new database_exception (*this);
+ }
+
//
// cli_exception
//
@@ -61,5 +67,11 @@ namespace odb
{
return what_.c_str ();
}
+
+ cli_exception* cli_exception::
+ clone () const
+ {
+ return new cli_exception (*this);
+ }
}
}
diff --git a/odb/pgsql/exceptions.hxx b/odb/pgsql/exceptions.hxx
index d15cec0..6296b75 100644
--- a/odb/pgsql/exceptions.hxx
+++ b/odb/pgsql/exceptions.hxx
@@ -43,6 +43,9 @@ namespace odb
virtual const char*
what () const throw ();
+ virtual database_exception*
+ clone () const;
+
private:
std::string sqlstate_;
std::string message_;
@@ -57,6 +60,9 @@ namespace odb
virtual const char*
what () const throw ();
+ virtual cli_exception*
+ clone () const;
+
private:
std::string what_;
};
diff --git a/odb/pgsql/no-id-object-statements.hxx b/odb/pgsql/no-id-object-statements.hxx
index a95b6c5..2616eab 100644
--- a/odb/pgsql/no-id-object-statements.hxx
+++ b/odb/pgsql/no-id-object-statements.hxx
@@ -92,7 +92,7 @@ namespace odb
insert_column_count,
insert_image_binding_,
insert_image_native_binding_,
- false,
+ 0,
false));
return *persist_;
diff --git a/odb/pgsql/polymorphic-object-statements.hxx b/odb/pgsql/polymorphic-object-statements.hxx
index f5ddcea..0e42cbf 100644
--- a/odb/pgsql/polymorphic-object-statements.hxx
+++ b/odb/pgsql/polymorphic-object-statements.hxx
@@ -330,7 +330,7 @@ namespace odb
insert_column_count,
insert_image_binding_,
insert_image_native_binding_,
- object_traits::auto_id,
+ 0,
false));
return *persist_;
@@ -405,6 +405,7 @@ namespace odb
return extra_statement_cache_.get (
conn_,
image_,
+ id_image (),
id_image_binding (),
&id_image_binding (), // Note, not id+version.
root_statements_.id_image_native_binding (),
@@ -446,8 +447,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/pgsql/section-statements.hxx b/odb/pgsql/section-statements.hxx
index e7dcd9e..fd4910e 100644
--- a/odb/pgsql/section-statements.hxx
+++ b/odb/pgsql/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 pgsql::select_statement select_statement_type;
typedef pgsql::update_statement update_statement_type;
@@ -44,6 +45,7 @@ namespace odb
section_statements (connection_type&,
image_type&,
+ id_image_type&,
binding& id,
binding& idv,
native_binding& idn,
diff --git a/odb/pgsql/section-statements.txx b/odb/pgsql/section-statements.txx
index 4781833..2e46e4d 100644
--- a/odb/pgsql/section-statements.txx
+++ b/odb/pgsql/section-statements.txx
@@ -12,6 +12,7 @@ namespace odb
section_statements<T, ST>::
section_statements (connection_type& conn,
image_type& im,
+ id_image_type&,
binding& id,
binding& idv,
native_binding& idn,
diff --git a/odb/pgsql/simple-object-statements.hxx b/odb/pgsql/simple-object-statements.hxx
index afa869a..f9d7e46 100644
--- a/odb/pgsql/simple-object-statements.hxx
+++ b/odb/pgsql/simple-object-statements.hxx
@@ -39,29 +39,31 @@ 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 pgsql::connection connection_type;
extra_statement_cache_ptr (): p_ (0) {}
~extra_statement_cache_ptr ()
{
if (p_ != 0)
- (this->*deleter_) (0, 0, 0, 0, 0, 0);
+ (this->*deleter_) (0, 0, 0, 0, 0, 0, 0);
}
T&
get (connection_type& c,
image_type& im,
+ id_image_type& idim,
binding& id,
binding* idv,
native_binding& idn,
const Oid* idt)
{
if (p_ == 0)
- allocate (&c, &im, &id, (idv != 0 ? idv : &id), &idn, idt);
+ allocate (&c, &im, &idim, &id, (idv != 0 ? idv : &id), &idn, idt);
return *p_;
}
@@ -69,21 +71,21 @@ namespace odb
private:
void
allocate (connection_type*,
- image_type*,
+ image_type*, id_image_type*,
binding*, binding*, native_binding*, const Oid*);
private:
T* p_;
void (extra_statement_cache_ptr::*deleter_) (
connection_type*,
- image_type*,
+ image_type*, id_image_type*,
binding*, binding*, native_binding*, const Oid*);
};
- template <typename T, typename I>
- void extra_statement_cache_ptr<T, I>::
+ template <typename T, typename I, typename ID>
+ void extra_statement_cache_ptr<T, I, ID>::
allocate (connection_type* c,
- image_type* im,
+ image_type* im, id_image_type* idim,
binding* id, binding* idv, native_binding* idn, const Oid* idt)
{
// To reduce object code size, this function acts as both allocator
@@ -91,8 +93,8 @@ namespace odb
//
if (p_ == 0)
{
- p_ = new T (*c, *im, *id, *idv, *idn, idt);
- deleter_ = &extra_statement_cache_ptr<T, I>::allocate;
+ p_ = new T (*c, *im, *idim, *id, *idv, *idn, idt);
+ deleter_ = &extra_statement_cache_ptr<T, I, ID>::allocate;
}
else
delete p_;
@@ -381,7 +383,7 @@ namespace odb
insert_column_count,
insert_image_binding_,
insert_image_native_binding_,
- object_traits::auto_id,
+ (object_traits::auto_id ? &id_image_binding_ : 0),
false));
return *persist_;
@@ -471,6 +473,7 @@ namespace odb
return extra_statement_cache_.get (
conn_,
image_,
+ id_image_,
id_image_binding_,
od_.id_image_binding (),
id_image_native_binding_,
@@ -521,8 +524,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/pgsql/statement.cxx b/odb/pgsql/statement.cxx
index 895cff5..bd27243 100644
--- a/odb/pgsql/statement.cxx
+++ b/odb/pgsql/statement.cxx
@@ -698,7 +698,7 @@ namespace odb
size_t types_count,
binding& param,
native_binding& native_param,
- bool returning)
+ binding* returning)
: statement (conn,
name, text, statement_insert,
(process ? &param : 0), false,
@@ -718,7 +718,7 @@ namespace odb
size_t types_count,
binding& param,
native_binding& native_param,
- bool returning,
+ binding* returning,
bool copy)
: statement (conn,
name, text, statement_insert,
@@ -767,42 +767,8 @@ namespace odb
translate_error (conn_, h);
}
- if (returning_)
- {
- // Get the id value that was returned using the RETURNING clause.
- //
- const char* v (PQgetvalue (h, 0, 0));
-
- // While the ODB auto id type can only be INT or BIGINT, handle the
- // SMALLINT integer in case we are dealing with a custom schema.
- //
- switch (PQftype (h, 0))
- {
- case int2_oid:
- {
- id_ = endian_traits::ntoh (
- *reinterpret_cast<const unsigned short*> (v));
- break;
- }
- case int4_oid:
- {
- id_ = endian_traits::ntoh (
- *reinterpret_cast<const unsigned int*> (v));
- break;
- }
- case int8_oid:
- {
- id_ = endian_traits::ntoh (
- *reinterpret_cast<const unsigned long long*> (v));
- break;
- }
- default:
- {
- assert (false);
- break;
- }
- }
- }
+ if (returning_ != 0)
+ bind_result (returning_->bind, 1, h, 0, false);
return true;
}
diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx
index 6c6095c..8ecaa19 100644
--- a/odb/pgsql/statement.hxx
+++ b/odb/pgsql/statement.hxx
@@ -278,7 +278,7 @@ namespace odb
std::size_t types_count,
binding& param,
native_binding& native_param,
- bool returning);
+ binding* returning);
insert_statement (connection_type& conn,
const char* name,
@@ -288,7 +288,7 @@ namespace odb
std::size_t types_count,
binding& param,
native_binding& native_param,
- bool returning,
+ binding* returning,
bool copy_name_text = true);
// Return true if successful and false if the row is a duplicate.
@@ -297,12 +297,6 @@ namespace odb
bool
execute ();
- unsigned long long
- id ()
- {
- return id_;
- }
-
private:
insert_statement (const insert_statement&);
insert_statement& operator= (const insert_statement&);
@@ -310,9 +304,7 @@ namespace odb
private:
binding& param_;
native_binding& native_param_;
-
- bool returning_;
- unsigned long long id_;
+ binding* returning_;
};
class LIBODB_PGSQL_EXPORT update_statement: public statement