diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2014-08-14 09:37:06 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-25 06:47:21 +0200 |
commit | 55b36b8297ef9aac9e4ccc7b98f8649534ee0ac1 (patch) | |
tree | e9f0d22285d7fc9ad814b75eac9d587c6d630995 /odb/relational/mssql | |
parent | 19ba3497c0788f02fc417f441d87c96ce23f9446 (diff) |
Implement bulk database operation support for Oracle and SQL Server
Diffstat (limited to 'odb/relational/mssql')
-rw-r--r-- | odb/relational/mssql/context.cxx | 1 | ||||
-rw-r--r-- | odb/relational/mssql/header.cxx | 35 | ||||
-rw-r--r-- | odb/relational/mssql/source.cxx | 69 |
3 files changed, 100 insertions, 5 deletions
diff --git a/odb/relational/mssql/context.cxx b/odb/relational/mssql/context.cxx index a0037eb..e99cdaf 100644 --- a/odb/relational/mssql/context.cxx +++ b/odb/relational/mssql/context.cxx @@ -89,6 +89,7 @@ namespace relational insert_send_auto_id = false; delay_freeing_statement_result = true; need_image_clone = true; + generate_bulk = true; global_index = false; global_fkey = true; data_->bind_vector_ = "mssql::bind*"; diff --git a/odb/relational/mssql/header.cxx b/odb/relational/mssql/header.cxx index f943a8a..3bc2cbd 100644 --- a/odb/relational/mssql/header.cxx +++ b/odb/relational/mssql/header.cxx @@ -31,6 +31,17 @@ namespace relational if (poly_derived || (abst && !poly)) return; + // Bulk operations batch size. + // + { + unsigned long long b (c.count ("bulk") + ? c.get<unsigned long long> ("bulk") + : 1); + + os << "static const std::size_t batch = " << b << "UL;" + << endl; + } + // rowvesion // bool rv (false); @@ -43,6 +54,30 @@ namespace relational os << "static const bool rowversion = " << rv << ";" << endl; } + + virtual void + object_public_extra_post (type& c) + { + bool abst (abstract (c)); + + type* poly_root (polymorphic (c)); + bool poly (poly_root != 0); + bool poly_derived (poly && poly_root != &c); + + if (poly_derived || (abst && !poly)) + return; + + if (semantics::data_member* m = optimistic (c)) + { + sql_type t (parse_sql_type (column_type (*m), *m)); + if (t.type == sql_type::ROWVERSION) + { + os << "static version_type" << endl + << "version (const id_image_type&);" + << endl; + } + } + } }; entry<class1> class1_entry_; diff --git a/odb/relational/mssql/source.cxx b/odb/relational/mssql/source.cxx index 83096ab..ffcfa3c 100644 --- a/odb/relational/mssql/source.cxx +++ b/odb/relational/mssql/source.cxx @@ -905,7 +905,7 @@ namespace relational sql_type t (parse_sql_type (column_type (m), m)); return t.type != sql_type::ROWVERSION ? "1" - : "sts.update_statement ().version ()"; + : "version (sts.id_image ())"; } virtual string @@ -920,7 +920,7 @@ namespace relational sql_type::ROWVERSION) return r; - // Long data & SQL Server 2005 incompatibility is detected + // ROWVERSION & SQL Server 2005 incompatibility is detected // in persist_statement_extra. // r = "OUTPUT INSERTED." + @@ -933,7 +933,8 @@ namespace relational struct class_: relational::class_, statement_columns_common { - class_ (base const& x): base (x) {} + class_ (base const& x): + base (x), init_version_value_member_id_image_ ("v", "version_") {} virtual void init_image_pre (type& c) @@ -1036,6 +1037,16 @@ namespace relational throw operation_failed (); } + // We also cannot support bulk INSERT. + // + if (c.count ("bulk-persist")) + { + error (c.location ()) << "in SQL Server 2005 bulk " << + "persist operation cannot be implemented for a " << + "persistent class containing long data" << endl; + throw operation_failed (); + } + r = "; SELECT " + convert_from ("SCOPE_IDENTITY()", *id); } @@ -1110,7 +1121,9 @@ namespace relational optimistic_version_init (semantics::data_member& m) { sql_type t (parse_sql_type (column_type (m), m)); - return t.type != sql_type::ROWVERSION ? "1" : "st.version ()"; + return t.type != sql_type::ROWVERSION + ? "1" + : "version (sts.id_image ())"; } virtual string @@ -1119,8 +1132,54 @@ namespace relational sql_type t (parse_sql_type (column_type (m), m)); return t.type != sql_type::ROWVERSION ? "1" - : "sts.update_statement ().version ()"; + : "version (sts.id_image ())"; } + + virtual bool + optimistic_insert_bind_version (semantics::data_member& m) + { + sql_type t (parse_sql_type (column_type (m), m)); + return t.type == sql_type::ROWVERSION; + } + + virtual void + object_extra (type& c) + { + bool abst (abstract (c)); + + type* poly_root (polymorphic (c)); + bool poly (poly_root != 0); + bool poly_derived (poly && poly_root != &c); + + if (poly_derived || (abst && !poly)) + return; + + if (semantics::data_member* m = optimistic (c)) + { + sql_type t (parse_sql_type (column_type (*m), *m)); + if (t.type == sql_type::ROWVERSION) + { + string const& type (class_fq_name (c)); + string traits ("access::object_traits_impl< " + type + ", id_" + + db.string () + " >"); + + os << traits << "::version_type" << endl + << traits << "::" << endl + << "version (const id_image_type& i)" + << "{" + << "version_type v;"; + init_version_value_member_id_image_->traverse (*m); + os << "return v;" + << "}"; + } + } + } + + private: + // Go via the dynamic creation to get access to the constructor. + // + instance<relational::init_value_member> + init_version_value_member_id_image_; }; entry<class_> class_entry_; } |