summaryrefslogtreecommitdiff
path: root/odb/relational/mssql
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2024-01-22 15:58:08 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2024-01-24 17:02:47 +0300
commit823026b58211a4166de06ac243d978dcb9930271 (patch)
tree97b43039cb769f8bee410e8536f9f945f2825153 /odb/relational/mssql
parentb56b9c6796d8853758f0f5967488260d61b788e2 (diff)
Turn odb repository into muti-package repository
Also remove the autoconf/make-based build system.
Diffstat (limited to 'odb/relational/mssql')
-rw-r--r--odb/relational/mssql/common.cxx603
-rw-r--r--odb/relational/mssql/common.hxx293
-rw-r--r--odb/relational/mssql/context.cxx766
-rw-r--r--odb/relational/mssql/context.hxx194
-rw-r--r--odb/relational/mssql/header.cxx312
-rw-r--r--odb/relational/mssql/inline.cxx42
-rw-r--r--odb/relational/mssql/model.cxx66
-rw-r--r--odb/relational/mssql/schema.cxx651
-rw-r--r--odb/relational/mssql/source.cxx1201
9 files changed, 0 insertions, 4128 deletions
diff --git a/odb/relational/mssql/common.cxx b/odb/relational/mssql/common.cxx
deleted file mode 100644
index 1070d21..0000000
--- a/odb/relational/mssql/common.cxx
+++ /dev/null
@@ -1,603 +0,0 @@
-// file : odb/relational/mssql/common.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <cassert>
-
-#include <odb/relational/mssql/common.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace mssql
- {
- //
- // member_base
- //
-
- sql_type const& member_base::
- member_sql_type (semantics::data_member& m)
- {
- return parse_sql_type (column_type (m, key_prefix_), m);
- }
-
- void member_base::
- traverse_simple (member_info& mi)
- {
- const sql_type& st (*mi.st);
-
- // The same long/short data test as in context.cxx:long_data().
- //
- switch (st.type)
- {
- // Integral types.
- //
- case sql_type::BIT:
- case sql_type::TINYINT:
- case sql_type::SMALLINT:
- case sql_type::INT:
- case sql_type::BIGINT:
- {
- traverse_integer (mi);
- break;
- }
-
- // Fixed and floating point types.
- //
- case sql_type::DECIMAL:
- {
- traverse_decimal (mi);
- break;
- }
- case sql_type::SMALLMONEY:
- {
- traverse_smallmoney (mi);
- break;
- }
- case sql_type::MONEY:
- {
- traverse_money (mi);
- break;
- }
- case sql_type::FLOAT:
- {
- if (st.prec > 24)
- traverse_float8 (mi);
- else
- traverse_float4 (mi);
-
- break;
- }
-
- // String and binary types.
- //
- case sql_type::CHAR:
- case sql_type::VARCHAR:
- {
- // Zero precision means max in VARCHAR(max).
- //
- if (st.prec == 0 || st.prec > options.mssql_short_limit ())
- traverse_long_string (mi);
- else
- traverse_string (mi);
-
- break;
- }
- case sql_type::TEXT:
- {
- traverse_long_string (mi);
- break;
- }
- case sql_type::NCHAR:
- case sql_type::NVARCHAR:
- {
- // Zero precision means max in NVARCHAR(max). Note that
- // the precision is in 2-byte UCS-2 characters, not bytes.
- //
- if (st.prec == 0 || st.prec * 2 > options.mssql_short_limit ())
- traverse_long_nstring (mi);
- else
- traverse_nstring (mi);
-
- break;
- }
- case sql_type::NTEXT:
- {
- traverse_long_nstring (mi);
- break;
- }
- case sql_type::BINARY:
- case sql_type::VARBINARY:
- {
- // Zero precision means max in VARCHAR(max).
- //
- if (st.prec == 0 || st.prec > options.mssql_short_limit ())
- traverse_long_binary (mi);
- else
- traverse_binary (mi);
-
- break;
- }
- case sql_type::IMAGE:
- {
- traverse_long_binary (mi);
- break;
- }
-
- // Date-time types.
- //
- case sql_type::DATE:
- {
- traverse_date (mi);
- break;
- }
- case sql_type::TIME:
- {
- traverse_time (mi);
- break;
- }
- case sql_type::DATETIME:
- case sql_type::DATETIME2:
- case sql_type::SMALLDATETIME:
- {
- traverse_datetime (mi);
- break;
- }
- case sql_type::DATETIMEOFFSET:
- {
- traverse_datetimeoffset (mi);
- break;
- }
-
- // Other types.
- //
- case sql_type::UNIQUEIDENTIFIER:
- {
- traverse_uniqueidentifier (mi);
- break;
- }
- case sql_type::ROWVERSION:
- {
- traverse_rowversion (mi);
- break;
- }
- case sql_type::invalid:
- {
- assert (false);
- break;
- }
- }
- }
-
- //
- // member_image_type
- //
-
- static const char* integer_types[] =
- {
- "unsigned char",
- "unsigned char",
- "short",
- "int",
- "long long"
- };
-
- member_image_type::
- member_image_type (base const& x)
- : member_base::base (x), // virtual base
- base (x) {}
-
- member_image_type::
- member_image_type ()
- : relational::member_base (0, 0, string (), string ()) {}
-
- member_image_type::
- member_image_type (semantics::type* type,
- const custom_cxx_type* ct,
- string const& fq_type,
- string const& key_prefix)
- : relational::member_base (type, ct, fq_type, key_prefix) {}
-
- string member_image_type::
- image_type (semantics::data_member& m)
- {
- type_.clear ();
- member_base::traverse (m, true);
- return type_;
- }
-
- void member_image_type::
- traverse_composite (member_info& mi)
- {
- type_ = "composite_value_traits< " + mi.fq_type () +
- ", id_mssql >::image_type";
- }
-
- void member_image_type::
- traverse_integer (member_info& mi)
- {
- type_ = integer_types[mi.st->type - sql_type::BIT];
- }
-
- void member_image_type::
- traverse_decimal (member_info&)
- {
- type_ = "mssql::decimal";
- }
-
- void member_image_type::
- traverse_smallmoney (member_info&)
- {
- type_ = "mssql::smallmoney";
- }
-
- void member_image_type::
- traverse_money (member_info&)
- {
- type_ = "mssql::money";
- }
-
- void member_image_type::
- traverse_float4 (member_info&)
- {
- type_ = "float";
- }
-
- void member_image_type::
- traverse_float8 (member_info&)
- {
- type_ = "double";
- }
-
- void member_image_type::
- traverse_string (member_info&)
- {
- type_ = "char*";
- }
-
- void member_image_type::
- traverse_long_string (member_info&)
- {
- type_ = "mssql::long_callback";
- }
-
- void member_image_type::
- traverse_nstring (member_info&)
- {
- type_ = "mssql::ucs2_char*";
- }
-
- void member_image_type::
- traverse_long_nstring (member_info&)
- {
- type_ = "mssql::long_callback";
- }
-
- void member_image_type::
- traverse_binary (member_info&)
- {
- type_ = "char*";
- }
-
- void member_image_type::
- traverse_long_binary (member_info&)
- {
- type_ = "mssql::long_callback";
- }
-
- void member_image_type::
- traverse_date (member_info&)
- {
- type_ = "mssql::date";
- }
-
- void member_image_type::
- traverse_time (member_info&)
- {
- type_ = "mssql::time";
- }
-
- void member_image_type::
- traverse_datetime (member_info&)
- {
- type_ = "mssql::datetime";
- }
-
- void member_image_type::
- traverse_datetimeoffset (member_info&)
- {
- type_ = "mssql::datetimeoffset";
- }
-
- void member_image_type::
- traverse_uniqueidentifier (member_info&)
- {
- type_ = "mssql::uniqueidentifier";
- }
-
- void member_image_type::
- traverse_rowversion (member_info&)
- {
- type_ = "unsigned char*";
- }
-
- entry<member_image_type> member_image_type_;
-
- //
- // member_database_type
- //
-
- static const char* integer_database_id[] =
- {
- "mssql::id_bit",
- "mssql::id_tinyint",
- "mssql::id_smallint",
- "mssql::id_int",
- "mssql::id_bigint"
- };
-
- member_database_type_id::
- member_database_type_id (base const& x)
- : member_base::base (x), // virtual base
- base (x)
- {
- }
-
- member_database_type_id::
- member_database_type_id ()
- : member_base::base (0, 0, string (), string ()), // virtual base
- base (0, 0, string (), string ())
- {
- }
-
- member_database_type_id::
- member_database_type_id (semantics::type* type,
- const custom_cxx_type* ct,
- string const& fq_type,
- string const& key_prefix)
- : member_base::base (type, ct, fq_type, key_prefix), // virtual base
- base (type, ct, fq_type, key_prefix)
- {
- }
-
- string member_database_type_id::
- database_type_id (semantics::data_member& m)
- {
- type_id_.clear ();
- member_base::traverse (m, true);
- return type_id_;
- }
-
- void member_database_type_id::
- traverse_composite (member_info&)
- {
- assert (false);
- }
-
- void member_database_type_id::
- traverse_integer (member_info& mi)
- {
- type_id_ = integer_database_id[mi.st->type - sql_type::BIT];
- }
-
- void member_database_type_id::
- traverse_decimal (member_info&)
- {
- type_id_ = "mssql::id_decimal";
- }
-
- void member_database_type_id::
- traverse_smallmoney (member_info&)
- {
- type_id_ = "mssql::id_smallmoney";
- }
-
- void member_database_type_id::
- traverse_money (member_info&)
- {
- type_id_ = "mssql::id_money";
- }
-
- void member_database_type_id::
- traverse_float4 (member_info&)
- {
- type_id_ = "mssql::id_float4";
- }
-
- void member_database_type_id::
- traverse_float8 (member_info&)
- {
- type_id_ = "mssql::id_float8";
- }
-
- void member_database_type_id::
- traverse_string (member_info&)
- {
- type_id_ = "mssql::id_string";
- }
-
- void member_database_type_id::
- traverse_long_string (member_info&)
- {
- type_id_ = "mssql::id_long_string";
- }
-
- void member_database_type_id::
- traverse_nstring (member_info&)
- {
- type_id_ = "mssql::id_nstring";
- }
-
- void member_database_type_id::
- traverse_long_nstring (member_info&)
- {
- type_id_ = "mssql::id_long_nstring";
- }
-
- void member_database_type_id::
- traverse_binary (member_info&)
- {
- type_id_ = "mssql::id_binary";
- }
-
- void member_database_type_id::
- traverse_long_binary (member_info&)
- {
- type_id_ = "mssql::id_long_binary";
- }
-
- void member_database_type_id::
- traverse_date (member_info&)
- {
- type_id_ = "mssql::id_date";
- }
-
- void member_database_type_id::
- traverse_time (member_info&)
- {
- type_id_ = "mssql::id_time";
- }
-
- void member_database_type_id::
- traverse_datetime (member_info&)
- {
- type_id_ = "mssql::id_datetime";
- }
-
- void member_database_type_id::
- traverse_datetimeoffset (member_info&)
- {
- type_id_ = "mssql::id_datetimeoffset";
- }
-
- void member_database_type_id::
- traverse_uniqueidentifier (member_info&)
- {
- type_id_ = "mssql::id_uniqueidentifier";
- }
-
- void member_database_type_id::
- traverse_rowversion (member_info&)
- {
- type_id_ = "mssql::id_rowversion";
- }
-
- entry<member_database_type_id> member_database_type_id_;
-
- //
- // query_columns
- //
-
- struct query_columns: relational::query_columns, context
- {
- query_columns (base const& x): base_impl (x) {}
-
- virtual string
- database_type_id (semantics::data_member& m)
- {
- return member_database_type_id_.database_type_id (m);
- }
-
- virtual void
- column_ctor (string const& type, string const& name, string const& base)
- {
- os << name << " (";
-
- if (multi_dynamic)
- os << "odb::query_column< " << type << " >& qc," << endl;
-
- os << "const char* t," << endl
- << "const char* c," << endl
- << "const char* conv," << endl
- << "unsigned short p = 0," << endl
- << "unsigned short s = 0xFFFF)" << endl
- << " : " << base << " (" << (multi_dynamic ? "qc, " : "") <<
- "t, c, conv, p, s)"
- << "{"
- << "}";
- }
-
- virtual void
- column_ctor_args_extra (semantics::data_member& m)
- {
- // For some types we need to pass precision and scale.
- //
- sql_type const& st (parse_sql_type (column_type (), m));
-
- switch (st.type)
- {
- case sql_type::DECIMAL:
- {
- os << ", " << st.prec << ", " << st.scale;
- break;
- }
- case sql_type::FLOAT:
- {
- os << ", " << st.prec;
- break;
- }
- case sql_type::CHAR:
- case sql_type::VARCHAR:
- {
- os << ", " << st.prec;
- break;
- }
- case sql_type::TEXT:
- {
- os << ", 0"; // Unlimited.
- break;
- }
- case sql_type::NCHAR:
- case sql_type::NVARCHAR:
- {
- os << ", " << st.prec; // In 2-byte characters.
- break;
- }
- case sql_type::NTEXT:
- {
- os << ", 0"; // Unlimited.
- break;
- }
- case sql_type::BINARY:
- case sql_type::VARBINARY:
- {
- os << ", " << st.prec;
- break;
- }
- case sql_type::IMAGE:
- {
- os << ", 0"; // Unlimited.
- break;
- }
- // Date-time types.
- //
- case sql_type::TIME:
- case sql_type::DATETIME2:
- case sql_type::DATETIMEOFFSET:
- {
- os << ", 0, " << st.scale; // Fractional seconds (scale).
- break;
- }
- case sql_type::DATETIME:
- {
- os << ", 0, 3";
- break;
- }
- case sql_type::SMALLDATETIME:
- {
- os << ", 0, 8";
- break;
- }
- default:
- {
- break;
- }
- }
- }
-
- private:
- member_database_type_id member_database_type_id_;
- };
- entry<query_columns> query_columns_;
- }
-}
diff --git a/odb/relational/mssql/common.hxx b/odb/relational/mssql/common.hxx
deleted file mode 100644
index 42ea412..0000000
--- a/odb/relational/mssql/common.hxx
+++ /dev/null
@@ -1,293 +0,0 @@
-// file : odb/relational/mssql/common.hxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_RELATIONAL_MSSQL_COMMON_HXX
-#define ODB_RELATIONAL_MSSQL_COMMON_HXX
-
-#include <odb/relational/common.hxx>
-#include <odb/relational/mssql/context.hxx>
-
-namespace relational
-{
- namespace mssql
- {
- struct member_base: virtual relational::member_base_impl<sql_type>, context
- {
- member_base (base const& x): base (x), base_impl (x) {}
-
- // This c-tor is for the direct use inside the mssql namespace.
- // If you do use this c-tor, you should also explicitly call
- // relational::member_base (aka base).
- //
- member_base () {}
-
- virtual sql_type const&
- member_sql_type (semantics::data_member&);
-
- virtual void
- traverse_simple (member_info&);
-
- virtual void
- traverse_integer (member_info&)
- {
- }
-
- virtual void
- traverse_decimal (member_info&)
- {
- }
-
- virtual void
- traverse_smallmoney (member_info&)
- {
- }
-
- virtual void
- traverse_money (member_info&)
- {
- }
-
- virtual void
- traverse_float4 (member_info&)
- {
- }
-
- virtual void
- traverse_float8 (member_info&)
- {
- }
-
- virtual void
- traverse_string (member_info&)
- {
- }
-
- virtual void
- traverse_long_string (member_info&)
- {
- }
-
- virtual void
- traverse_nstring (member_info&)
- {
- }
-
- virtual void
- traverse_long_nstring (member_info&)
- {
- }
-
- virtual void
- traverse_binary (member_info&)
- {
- }
-
- virtual void
- traverse_long_binary (member_info&)
- {
- }
-
- virtual void
- traverse_date (member_info&)
- {
- }
-
- virtual void
- traverse_time (member_info&)
- {
- }
-
- virtual void
- traverse_datetime (member_info&)
- {
- }
-
- virtual void
- traverse_datetimeoffset (member_info&)
- {
- }
-
- virtual void
- traverse_uniqueidentifier (member_info&)
- {
- }
-
- virtual void
- traverse_rowversion (member_info&)
- {
- }
- };
-
- struct member_image_type: relational::member_image_type,
- member_base
- {
- member_image_type (base const&);
- member_image_type ();
- member_image_type (semantics::type* type,
- const custom_cxx_type*,
- string const& fq_type = string (),
- string const& key_prefix = string ());
- virtual string
- image_type (semantics::data_member&);
-
- virtual void
- traverse_composite (member_info&);
-
- virtual void
- traverse_integer (member_info&);
-
- virtual void
- traverse_decimal (member_info&);
-
- virtual void
- traverse_smallmoney (member_info&);
-
- virtual void
- traverse_money (member_info&);
-
- virtual void
- traverse_float4 (member_info&);
-
- virtual void
- traverse_float8 (member_info&);
-
- virtual void
- traverse_string (member_info&);
-
- virtual void
- traverse_long_string (member_info&);
-
- virtual void
- traverse_nstring (member_info&);
-
- virtual void
- traverse_long_nstring (member_info&);
-
- virtual void
- traverse_binary (member_info&);
-
- virtual void
- traverse_long_binary (member_info&);
-
- virtual void
- traverse_date (member_info&);
-
- virtual void
- traverse_time (member_info&);
-
- virtual void
- traverse_datetime (member_info&);
-
- virtual void
- traverse_datetimeoffset (member_info&);
-
- virtual void
- traverse_uniqueidentifier (member_info&);
-
- virtual void
- traverse_rowversion (member_info&);
-
- private:
- string type_;
- };
-
- struct member_database_type_id: relational::member_database_type_id,
- member_base
- {
- member_database_type_id (base const&);
- member_database_type_id ();
- member_database_type_id (semantics::type* type,
- const custom_cxx_type*,
- string const& fq_type = string (),
- string const& key_prefix = string ());
-
- virtual string
- database_type_id (semantics::data_member&);
-
- virtual void
- traverse_composite (member_info&);
-
- virtual void
- traverse_integer (member_info&);
-
- virtual void
- traverse_decimal (member_info&);
-
- virtual void
- traverse_smallmoney (member_info&);
-
- virtual void
- traverse_money (member_info&);
-
- virtual void
- traverse_float4 (member_info&);
-
- virtual void
- traverse_float8 (member_info&);
-
- virtual void
- traverse_string (member_info&);
-
- virtual void
- traverse_long_string (member_info&);
-
- virtual void
- traverse_nstring (member_info&);
-
- virtual void
- traverse_long_nstring (member_info&);
-
- virtual void
- traverse_binary (member_info&);
-
- virtual void
- traverse_long_binary (member_info&);
-
- virtual void
- traverse_date (member_info&);
-
- virtual void
- traverse_time (member_info&);
-
- virtual void
- traverse_datetime (member_info&);
-
- virtual void
- traverse_datetimeoffset (member_info&);
-
- virtual void
- traverse_uniqueidentifier (member_info&);
-
- virtual void
- traverse_rowversion (member_info&);
-
- private:
- string type_id_;
- };
-
- struct has_long_data: object_columns_base, context
- {
- has_long_data (bool& r): r_ (r) {}
-
- virtual void
- traverse_pointer (semantics::data_member& m, semantics::class_& c)
- {
- if (!inverse (m, key_prefix_))
- object_columns_base::traverse_pointer (m, c);
- }
-
- virtual bool
- traverse_column (semantics::data_member& m, string const&, bool)
- {
- if (long_data (parse_sql_type (column_type (), m)))
- r_ = true;
-
- return true;
- }
-
- private:
- bool& r_;
- };
- }
-}
-#endif // ODB_RELATIONAL_MSSQL_COMMON_HXX
diff --git a/odb/relational/mssql/context.cxx b/odb/relational/mssql/context.cxx
deleted file mode 100644
index afe1aa5..0000000
--- a/odb/relational/mssql/context.cxx
+++ /dev/null
@@ -1,766 +0,0 @@
-// file : odb/relational/mssql/context.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <cassert>
-#include <sstream>
-
-#include <odb/sql-token.hxx>
-#include <odb/sql-lexer.hxx>
-
-#include <odb/relational/mssql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace mssql
- {
- namespace
- {
- struct type_map_entry
- {
- char const* const cxx_type;
- char const* const db_type;
- char const* const db_id_type;
- bool const null;
- };
-
- type_map_entry type_map[] =
- {
- {"bool", "BIT", 0, false},
-
- {"char", "CHAR(1)", 0, false},
- {"wchar_t", "NCHAR(1)", 0, false},
- {"signed char", "TINYINT", 0, false},
- {"unsigned char", "TINYINT", 0, false},
-
- {"short int", "SMALLINT", 0, false},
- {"short unsigned int", "SMALLINT", 0, false},
-
- {"int", "INT", 0, false},
- {"unsigned int", "INT", 0, false},
-
- {"long int", "BIGINT", 0, false},
- {"long unsigned int", "BIGINT", 0, false},
-
- {"long long int", "BIGINT", 0, false},
- {"long long unsigned int", "BIGINT", 0, false},
-
- {"float", "REAL", 0, false},
- {"double", "FLOAT", 0, false},
-
- {"::std::string", "VARCHAR(512)", "VARCHAR(256)", false},
- {"::std::wstring", "NVARCHAR(512)", "NVARCHAR(256)", false},
-
- {"::size_t", "BIGINT", 0, false},
- {"::std::size_t", "BIGINT", 0, false},
-
- // Windows GUID/UUID (typedef struct _GUID {...} GUID, UUID;).
- //
- {"::_GUID", "UNIQUEIDENTIFIER", 0, false}
- };
- }
-
- context* context::current_;
-
- context::
- ~context ()
- {
- if (current_ == this)
- current_ = 0;
- }
-
- context::
- context (ostream& os,
- semantics::unit& u,
- options_type const& ops,
- features_type& f,
- sema_rel::model* m)
- : root_context (os, u, ops, f, data_ptr (new (shared) data (os))),
- base_context (static_cast<data*> (root_context::data_.get ()), m),
- data_ (static_cast<data*> (base_context::data_))
- {
- assert (current_ == 0);
- current_ = this;
-
- generate_grow = false;
- need_alias_as = true;
- 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*";
-
- // Populate the C++ type to DB type map.
- //
- for (size_t i (0); i < sizeof (type_map) / sizeof (type_map_entry); ++i)
- {
- type_map_entry const& e (type_map[i]);
-
- type_map_type::value_type v (
- e.cxx_type,
- db_type_type (
- e.db_type, e.db_id_type ? e.db_id_type : e.db_type, e.null));
-
- data_->type_map_.insert (v);
- }
- }
-
- context::
- context ()
- : data_ (current ().data_)
- {
- }
-
- string const& context::
- convert_expr (string const& sqlt, semantics::data_member& m, bool to)
- {
- sql_type const& t (parse_sql_type (sqlt, m));
- return to ? t.to : t.from;
- }
-
- string context::
- quote_id_impl (qname const& id) const
- {
- string r;
-
- bool f (true);
- for (qname::iterator i (id.begin ()); i < id.end (); ++i)
- {
- if (i->empty ())
- continue;
-
- // Warn if the name is greater than the 128 limit.
- //
- if (i->size () > 128)
- {
- cerr << "warning: SQL name '" << *i << "' is longer than the "
- << "SQL Server name limit of 128 characters and will be "
- << "truncated" << endl;
-
- cerr << "info: consider shortening it using #pragma db "
- << "table/column/index or --*-regex options" << endl;
- }
-
- if (f)
- f = false;
- else
- r += '.';
-
- r += '[';
- r.append (*i, 0, 128); // Max identifier length is 128.
- r += ']';
- }
-
- return r;
- }
-
- string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- bool id,
- bool* null)
- {
- string r (base_context::database_type_impl (t, hint, id, null));
-
- if (!r.empty ())
- return r;
-
- using semantics::array;
-
- // char[N] mapping.
- //
- if (array* a = dynamic_cast<array*> (&t))
- {
- semantics::type& bt (a->base_type ());
- bool c (bt.is_a<semantics::fund_char> ());
-
- if (c || bt.is_a<semantics::fund_wchar> ())
- {
- unsigned long long n (a->size ());
-
- if (n == 0)
- return r;
- if (n == 1)
- r = c ? "CHAR(" : "NCHAR(";
- else
- {
- r = c ? "VARCHAR(" : "NVARCHAR(";
- n--;
- }
-
- if (n > (c ? 8000 : 4000))
- r += "max)";
- else
- {
- ostringstream ostr;
- ostr << n;
- r += ostr.str ();
- r += ')';
- }
- }
- }
-
- return r;
- }
-
- bool context::
- long_data (sql_type const& st)
- {
- bool r (false);
-
- // The same test as in common.cxx:traverse_simple().
- //
- switch (st.type)
- {
- case sql_type::CHAR:
- case sql_type::VARCHAR:
- case sql_type::BINARY:
- case sql_type::VARBINARY:
- {
- // Zero precision means max in VARCHAR(max).
- //
- if (st.prec == 0 || st.prec > options.mssql_short_limit ())
- r = true;
-
- break;
- }
- case sql_type::NCHAR:
- case sql_type::NVARCHAR:
- {
- // Zero precision means max in NVARCHAR(max). Note that
- // the precision is in 2-byte UCS-2 characters, not bytes.
- //
- if (st.prec == 0 || st.prec * 2 > options.mssql_short_limit ())
- r = true;
-
- break;
- }
- case sql_type::TEXT:
- case sql_type::NTEXT:
- case sql_type::IMAGE:
- {
- r = true;
- break;
- }
- default:
- break;
- }
-
- return r;
- }
-
- //
- // SQL type parsing.
- //
-
- namespace
- {
- struct sql_parser
- {
- typedef context::invalid_sql_type invalid_sql_type;
-
- sql_parser (custom_db_types const* ct): ct_ (ct) {}
-
- sql_type
- parse (std::string sql)
- {
- r_ = sql_type ();
- m_.clear ();
-
- // First run the type through the custom mapping, if requested.
- //
- if (ct_ != 0)
- {
- for (custom_db_types::const_iterator i (ct_->begin ());
- i != ct_->end (); ++i)
- {
- custom_db_type const& t (*i);
-
- if (t.type.match (sql))
- {
- r_.to = t.type.replace (sql, t.to);
- r_.from = t.type.replace (sql, t.from);
- sql = t.type.replace (sql, t.as);
- break;
- }
- }
- }
-
- l_.lex (sql);
-
- bool ok (true);
-
- try
- {
- ok = parse_name ();
- }
- catch (sql_lexer::invalid_input const& e)
- {
- ok = false;
- m_ = "invalid SQL Server type declaration: " + e.message;
- }
-
- if (!ok)
- {
- if (ct_ == 0)
- return sql_type ();
- else
- throw invalid_sql_type (m_);
- }
-
- return r_;
- }
-
- bool
- parse_name ()
- {
- sql_token t (l_.next ());
-
- if (t.type () != sql_token::t_identifier)
- {
- m_ = "expected SQL Server type name instead of '" +
- t.string () + "'";
- return false;
- }
-
- string id (upcase (t.identifier ()));
-
- if (id == "BIT")
- {
- r_.type = sql_type::BIT;
- }
- else if (id == "TINYINT")
- {
- r_.type = sql_type::TINYINT;
- }
- else if (id == "SMALLINT")
- {
- r_.type = sql_type::SMALLINT;
- }
- else if (id == "INT" ||
- id == "INTEGER")
- {
- r_.type = sql_type::INT;
- }
- else if (id == "BIGINT")
- {
- r_.type = sql_type::BIGINT;
- }
- else if (id == "DECIMAL" ||
- id == "NUMERIC" ||
- id == "DEC")
- {
- r_.type = sql_type::DECIMAL;
-
- r_.has_prec = true;
- r_.prec = 18;
-
- r_.has_scale = true;
- r_.scale = 0;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "SMALLMONEY")
- {
- r_.type = sql_type::SMALLMONEY;
- }
- else if (id == "MONEY")
- {
- r_.type = sql_type::MONEY;
- }
- else if (id == "REAL")
- {
- r_.type = sql_type::FLOAT;
-
- r_.has_prec = true;
- r_.prec = 24;
- }
- else if (id == "FLOAT")
- {
- r_.type = sql_type::FLOAT;
-
- r_.has_prec = true;
- r_.prec = 53;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "DOUBLE")
- {
- t = l_.next ();
-
- if (t.type () != sql_token::t_identifier ||
- upcase (t.identifier ()) != "PRECISION")
- {
- m_ = "expected 'PRECISION' instead of '" + t.string () + "'";
- return false;
- }
-
- r_.type = sql_type::FLOAT;
-
- r_.has_prec = true;
- r_.prec = 53;
-
- // It appears that DOUBLE PRECISION can be followed by the
- // precision specification.
- //
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "CHAR" ||
- id == "CHARACTER")
- {
- if (!parse_char_trailer (false))
- return false;
- }
- else if (id == "VARCHAR")
- {
- r_.type = sql_type::VARCHAR;
-
- r_.has_prec = true;
- r_.prec = 1;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "TEXT")
- {
- r_.type = sql_type::TEXT;
- r_.has_prec = true;
- r_.prec = 0;
- }
- else if (id == "NCHAR")
- {
- r_.type = sql_type::NCHAR;
-
- r_.has_prec = true;
- r_.prec = 1;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "NVARCHAR")
- {
- r_.type = sql_type::NVARCHAR;
-
- r_.has_prec = true;
- r_.prec = 1;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "NTEXT")
- {
- r_.type = sql_type::NTEXT;
- r_.has_prec = true;
- r_.prec = 0;
- }
- else if (id == "NATIONAL")
- {
- t = l_.next ();
-
- if (t.type () == sql_token::t_identifier)
- id = upcase (t.identifier ());
-
- if (id == "TEXT")
- {
- r_.type = sql_type::NTEXT;
- r_.has_prec = true;
- r_.prec = 0;
- }
- else if (id == "CHAR" ||
- id == "CHARACTER")
- {
- if (!parse_char_trailer (true))
- return false;
- }
- else
- {
- m_ = "expected 'CHAR', 'CHARACTER', or 'TEXT' instead of '"
- + t.string () + "'";
- return false;
- }
- }
- else if (id == "BINARY")
- {
- // Can be just BINARY or BINARY VARYING.
- //
- t = l_.next ();
-
- if (t.type () == sql_token::t_identifier)
- id = upcase (t.identifier ());
-
- if (id == "VARYING")
- {
- r_.type = sql_type::VARBINARY;
- t = l_.next ();
- }
- else
- r_.type = sql_type::BINARY;
-
- r_.has_prec = true;
- r_.prec = 1;
-
- if (!parse_precision (t))
- return false;
- }
- else if (id == "VARBINARY")
- {
- r_.type = sql_type::VARBINARY;
-
- r_.has_prec = true;
- r_.prec = 1;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "IMAGE")
- {
- r_.type = sql_type::IMAGE;
- r_.has_prec = true;
- r_.prec = 0;
- }
- else if (id == "DATE")
- {
- r_.type = sql_type::DATE;
- }
- else if (id == "TIME")
- {
- r_.type = sql_type::TIME;
-
- r_.has_scale = true;
- r_.scale = 7;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "DATETIME")
- {
- r_.type = sql_type::DATETIME;
- }
- else if (id == "DATETIME2")
- {
- r_.type = sql_type::DATETIME2;
-
- r_.has_scale = true;
- r_.scale = 7;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "SMALLDATETIME")
- {
- r_.type = sql_type::SMALLDATETIME;
- }
- else if (id == "DATETIMEOFFSET")
- {
- r_.type = sql_type::DATETIMEOFFSET;
-
- r_.has_scale = true;
- r_.scale = 7;
-
- if (!parse_precision (l_.next ()))
- return false;
- }
- else if (id == "UNIQUEIDENTIFIER")
- {
- r_.type = sql_type::UNIQUEIDENTIFIER;
- }
- else if (id == "ROWVERSION" ||
- id == "TIMESTAMP")
- {
- r_.type = sql_type::ROWVERSION;
- }
- else
- {
- m_ = "unexpected SQL Server type name '" + t.identifier () + "'";
- return false;
- }
-
- return true;
- }
-
- bool
- parse_precision (sql_token t)
- {
- if (t.punctuation () == sql_token::p_lparen)
- {
- // Parse the precision.
- //
- t = l_.next ();
-
- if (t.type () == sql_token::t_identifier &&
- upcase (t.identifier ()) == "MAX")
- {
- r_.prec = 0;
- r_.has_prec = true;
- }
- else if (t.type () == sql_token::t_int_lit)
- {
- unsigned short v;
- istringstream is (t.literal ());
-
- if (!(is >> v && is.eof ()))
- {
- m_ = "invalid precision value '" + t.literal () + "' in SQL "
- "Server type declaration";
- return false;
- }
-
- switch (r_.type)
- {
- case sql_type::TIME:
- case sql_type::DATETIME2:
- case sql_type::DATETIMEOFFSET:
- {
- r_.scale = v;
- r_.has_scale = true;
- break;
- }
- default:
- {
- r_.prec = v;
- r_.has_prec = true;
- break;
- }
- }
- }
- else
- {
- m_ = "integer precision expected in SQL Server type declaration";
- return false;
- }
-
- // Parse the scale if present.
- //
- t = l_.next ();
-
- if (t.punctuation () == sql_token::p_comma)
- {
- // Scale can only be specified for the DECIMAL type.
- //
- if (r_.type != sql_type::DECIMAL)
- {
- m_ = "unexpected scale in SQL Server type declaration";
- return false;
- }
-
- t = l_.next ();
-
- if (t.type () != sql_token::t_int_lit)
- {
- m_ = "integer scale expected in SQL Server type declaration";
- return false;
- }
-
- istringstream is (t.literal ());
-
- if (!(is >> r_.scale && is.eof ()))
- {
- m_ = "invalid scale value '" + t.literal () + "' in SQL "
- "Server type declaration";
- return false;
- }
-
- r_.has_scale = true;
- t = l_.next ();
- }
-
- if (t.punctuation () != sql_token::p_rparen)
- {
- m_ = "expected ')' in SQL Server type declaration";
- return false;
- }
- }
-
- return true;
- }
-
- bool
- parse_char_trailer (bool nat)
- {
- sql_token t (l_.next ());
-
- string id;
-
- if (t.type () == sql_token::t_identifier)
- id = upcase (t.identifier ());
-
- if (id == "VARYING")
- {
- r_.type = nat ? sql_type::NVARCHAR : sql_type::VARCHAR;
- t = l_.next ();
- }
- else
- r_.type = nat ? sql_type::NCHAR : sql_type::CHAR;
-
- r_.has_prec = true;
- r_.prec = 1;
-
- return parse_precision (t);
- }
-
- private:
- string
- upcase (string const& s)
- {
- return context::upcase (s);
- }
-
- private:
- custom_db_types const* ct_;
- sql_lexer l_;
- sql_type r_;
- string m_; // Error message.
- };
- }
-
- sql_type const& context::
- parse_sql_type (string const& t, semantics::data_member& m, bool custom)
- {
- // If this proves to be too expensive, we can maintain a cache of
- // parsed types across contexts.
- //
- data::sql_type_cache::iterator i (data_->sql_type_cache_.find (t));
-
- if (i != data_->sql_type_cache_.end ()
- && (custom ? i->second.custom_cached : i->second.straight_cached))
- {
- return (custom ? i->second.custom : i->second.straight);
- }
- else
- {
- try
- {
- sql_type st (
- parse_sql_type (
- t,
- custom ? &unit.get<custom_db_types> ("custom-db-types") : 0));
-
- if (custom)
- return data_->sql_type_cache_[t].cache_custom (st);
- else
- return data_->sql_type_cache_[t].cache_straight (st);
- }
- catch (invalid_sql_type const& e)
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: " << e.message () << endl;
-
- throw operation_failed ();
- }
- }
- }
-
- sql_type context::
- parse_sql_type (string const& sqlt, custom_db_types const* ct)
- {
- sql_parser p (ct);
- return p.parse (sqlt);
- }
- }
-}
diff --git a/odb/relational/mssql/context.hxx b/odb/relational/mssql/context.hxx
deleted file mode 100644
index 7701aaa..0000000
--- a/odb/relational/mssql/context.hxx
+++ /dev/null
@@ -1,194 +0,0 @@
-// file : odb/relational/mssql/context.hxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_RELATIONAL_MSSQL_CONTEXT_HXX
-#define ODB_RELATIONAL_MSSQL_CONTEXT_HXX
-
-#include <map>
-
-#include <odb/relational/context.hxx>
-
-namespace relational
-{
- namespace mssql
- {
- struct sql_type
- {
- // Keep the order in each block of types.
- //
- enum core_type
- {
- // Integral types.
- //
- BIT,
- TINYINT,
- SMALLINT,
- INT,
- BIGINT,
-
- // Fixed and floating point types.
- //
- DECIMAL,
- SMALLMONEY,
- MONEY,
- FLOAT,
-
- // String and binary types.
- //
- CHAR,
- VARCHAR,
- TEXT,
-
- NCHAR,
- NVARCHAR,
- NTEXT,
-
- BINARY,
- VARBINARY,
- IMAGE,
-
- // Date-time types.
- //
- DATE,
- TIME,
- DATETIME,
- DATETIME2,
- SMALLDATETIME,
- DATETIMEOFFSET,
-
- // Other types.
- //
- UNIQUEIDENTIFIER,
- ROWVERSION,
-
- // Invalid type.
- //
- invalid
- };
-
- sql_type () :
- type (invalid),
- has_prec (false), prec (0),
- has_scale (false), scale (0)
- {
- }
-
- core_type type;
-
- bool has_prec;
- unsigned short prec; // Max numeric value is 8000. 0 indicates
- // 'max' as in VARCHAR(max).
- bool has_scale;
- unsigned short scale; // Max value is 38.
-
- // Conversion expressions for custom database types.
- //
- std::string to;
- std::string from;
- };
-
- class context: public virtual relational::context
- {
- public:
- sql_type const&
- parse_sql_type (string const&,
- semantics::data_member&,
- bool custom = true);
-
- // Return true if this type is long data.
- //
- bool
- long_data (sql_type const&);
-
- public:
- struct invalid_sql_type
- {
- invalid_sql_type (string const& message): message_ (message) {}
-
- string const&
- message () const {return message_;}
-
- private:
- string message_;
- };
-
- // If custom_db_types is NULL, then this function returns
- // invalid type instead of throwing in case an unknown type
- // is encountered.
- //
- static sql_type
- parse_sql_type (string const&, custom_db_types const* = 0);
-
- protected:
- virtual string const&
- convert_expr (string const&, semantics::data_member&, bool);
-
- virtual string
- quote_id_impl (qname const&) const;
-
- protected:
- virtual string
- database_type_impl (semantics::type&, semantics::names*, bool, bool*);
-
- public:
- virtual
- ~context ();
-
- context ();
- context (std::ostream&,
- semantics::unit&,
- options_type const&,
- features_type&,
- sema_rel::model*);
-
- static context&
- current ()
- {
- return *current_;
- }
-
- private:
- static context* current_;
-
- private:
- struct data: base_context::data
- {
- data (std::ostream& os): base_context::data (os) {}
-
- struct sql_type_cache_entry
- {
- sql_type_cache_entry ()
- : custom_cached (false), straight_cached (false) {}
-
- sql_type const&
- cache_custom (sql_type const& t)
- {
- custom = t;
- custom_cached = true;
- return custom;
- }
-
- sql_type const&
- cache_straight (sql_type const& t)
- {
- straight = t;
- straight_cached = true;
- return straight;
- }
-
- sql_type custom; // With custom mapping.
- sql_type straight; // Without custom mapping.
-
- bool custom_cached;
- bool straight_cached;
- };
-
- typedef std::map<string, sql_type_cache_entry> sql_type_cache;
- sql_type_cache sql_type_cache_;
- };
- data* data_;
- };
- }
-}
-
-#endif // ODB_RELATIONAL_MSSQL_CONTEXT_HXX
diff --git a/odb/relational/mssql/header.cxx b/odb/relational/mssql/header.cxx
deleted file mode 100644
index ebdc734..0000000
--- a/odb/relational/mssql/header.cxx
+++ /dev/null
@@ -1,312 +0,0 @@
-// file : odb/relational/mssql/header.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/header.hxx>
-
-#include <odb/relational/mssql/common.hxx>
-#include <odb/relational/mssql/context.hxx>
-
-namespace relational
-{
- namespace mssql
- {
- namespace header
- {
- namespace relational = relational::header;
-
- struct class1: relational::class1, context
- {
- class1 (base const& x): base (x) {}
-
- virtual void
- object_public_extra_pre (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;
-
- // 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);
- if (semantics::data_member* m = optimistic (c))
- {
- sql_type t (parse_sql_type (column_type (*m), *m));
- rv = (t.type == sql_type::ROWVERSION);
- }
-
- os << "static const bool rowversion = " << rv << ";"
- << endl;
-
- // Disable bulk update if we have ROWVERSION since we don't
- // yet support batch extraction of the version.
- //
- if (rv && c.count ("bulk-update"))
- c.remove ("bulk-update");
- }
-
- 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_;
-
- struct section_traits: relational::section_traits, context
- {
- section_traits (base const& x): base (x) {}
-
- virtual void
- section_public_extra_pre (user_section&)
- {
- if (abstract (c_) && !polymorphic (c_))
- return;
-
- // rowvesion
- //
- bool rv (false);
- if (semantics::data_member* m = optimistic (c_))
- {
- sql_type t (parse_sql_type (column_type (*m), *m));
- rv = (t.type == sql_type::ROWVERSION);
- }
-
- os << "static const bool rowversion = " << rv << ";"
- << endl;
- }
- };
- entry<section_traits> section_traits_;
-
- struct image_type: relational::image_type, context
- {
- image_type (base const& x): base (x) {};
-
- virtual void
- image_extra (type& c)
- {
- if (!(composite (c) || (abstract (c) && !polymorphic (c))))
- {
- type* poly_root (polymorphic (c));
-
- // If this is a polymorphic type, only add callback to the root.
- //
- if (poly_root == 0 || poly_root == &c)
- {
- bool gc (options.generate_query ());
-
- if (gc)
- os << "mssql::change_callback change_callback_;"
- << endl;
-
- os << "mssql::change_callback*" << endl
- << "change_callback ()"
- << "{";
-
- if (gc)
- os << "return &change_callback_;";
- else
- os << "return 0;";
-
- os << "}";
- }
- }
- }
- };
- entry<image_type> image_type_;
-
- struct image_member: relational::image_member_impl<sql_type>,
- member_base
- {
- image_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x) {}
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_smallmoney (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_money (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_float4 (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_float8 (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- // Extra character for the null-terminator that ODBC always adds.
- //
- os << "char " << mi.var << "value[" << mi.st->prec + 1 << "];"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << "mutable " << image_type << " " << mi.var << "callback;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_nstring (member_info& mi)
- {
- // Extra character for the null-terminator that ODBC always adds.
- //
- os << "mssql::ucs2_char " << mi.var << "value[" <<
- mi.st->prec + 1 << "];"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_long_nstring (member_info& mi)
- {
- os << "mutable " << image_type << " " << mi.var << "callback;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_binary (member_info& mi)
- {
- os << "char " << mi.var << "value[" << mi.st->prec << "];"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_long_binary (member_info& mi)
- {
- os << "mutable " << image_type << " " << mi.var << "callback;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_date (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_time (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_datetime (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_datetimeoffset (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_uniqueidentifier (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
-
- virtual void
- traverse_rowversion (member_info& mi)
- {
- os << "unsigned char " << mi.var << "value[8];"
- << "SQLLEN " << mi.var << "size_ind;"
- << endl;
- }
- };
- entry<image_member> image_member_;
- }
- }
-}
diff --git a/odb/relational/mssql/inline.cxx b/odb/relational/mssql/inline.cxx
deleted file mode 100644
index eb581d6..0000000
--- a/odb/relational/mssql/inline.cxx
+++ /dev/null
@@ -1,42 +0,0 @@
-// file : odb/relational/mssql/inline.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/inline.hxx>
-
-#include <odb/relational/mssql/common.hxx>
-#include <odb/relational/mssql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace mssql
- {
- namespace inline_
- {
- namespace relational = relational::inline_;
-
- struct null_member: relational::null_member_impl<sql_type>,
- member_base
- {
- null_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- traverse_simple (member_info& mi)
- {
- if (get_)
- os << "r = r && i." << mi.var << "size_ind == SQL_NULL_DATA;";
- else
- os << "i." << mi.var << "size_ind = SQL_NULL_DATA;";
- }
- };
- entry<null_member> null_member_;
- }
- }
-}
diff --git a/odb/relational/mssql/model.cxx b/odb/relational/mssql/model.cxx
deleted file mode 100644
index 0f5a85c..0000000
--- a/odb/relational/mssql/model.cxx
+++ /dev/null
@@ -1,66 +0,0 @@
-// file : odb/relational/mssql/model.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <sstream>
-
-#include <odb/relational/model.hxx>
-
-#include <odb/relational/mssql/common.hxx>
-#include <odb/relational/mssql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace mssql
- {
- namespace model
- {
- namespace relational = relational::model;
-
- struct object_columns: relational::object_columns, context
- {
- object_columns (base const& x): base (x) {}
-
- virtual string
- default_enum (semantics::data_member& m, tree en, string const&)
- {
- // Make sure the column is mapped to an integer or DECIMAL type.
- //
- switch (parse_sql_type (column_type (), m, false).type)
- {
- case sql_type::BIT:
- case sql_type::TINYINT:
- case sql_type::SMALLINT:
- case sql_type::INT:
- case sql_type::BIGINT:
- case sql_type::DECIMAL:
- break;
- default:
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: column with default value specified as C++ "
- << "enumerator must map to SQL Server integer type" << endl;
-
- throw operation_failed ();
- }
- }
-
- using semantics::enumerator;
-
- enumerator& e (dynamic_cast<enumerator&> (*unit.find (en)));
-
- ostringstream ostr;
-
- if (e.enum_ ().unsigned_ ())
- ostr << e.value ();
- else
- ostr << static_cast<long long> (e.value ());
-
- return ostr.str ();
- }
- };
- entry<object_columns> object_columns_;
- }
- }
-}
diff --git a/odb/relational/mssql/schema.cxx b/odb/relational/mssql/schema.cxx
deleted file mode 100644
index c5f6bc1..0000000
--- a/odb/relational/mssql/schema.cxx
+++ /dev/null
@@ -1,651 +0,0 @@
-// file : odb/relational/mssql/schema.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/schema.hxx>
-
-#include <odb/relational/mssql/common.hxx>
-#include <odb/relational/mssql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace mssql
- {
- namespace schema
- {
- namespace relational = relational::schema;
- using relational::table_set;
-
- struct sql_emitter: relational::sql_emitter
- {
- sql_emitter (const base& x): base (x) {}
-
- virtual void
- post ()
- {
- if (!first_) // Ignore empty statements.
- {
- os << ';' << endl
- << "GO" << endl
- << endl;
- }
- }
- };
- entry<sql_emitter> sql_emitter_;
-
- //
- // File.
- //
-
- struct sql_file: relational::sql_file, context
- {
- sql_file (const base& x): base (x) {}
-
- virtual void
- prologue ()
- {
- // Suppress the (x rows affected) messages from sqlcmd for DML
- // statements. We only use DML for schema version management.
- //
- if ((model == 0 || model->version () != 0) &&
- !options.suppress_schema_version ())
- os << "SET NOCOUNT ON;" << endl
- << endl;
- }
- };
- entry<sql_file> sql_file_;
-
- //
- // Drop.
- //
-
- struct drop_column: relational::drop_column, context
- {
- drop_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::drop_column& dc)
- {
- if (first_)
- first_ = false;
- else
- os << "," << endl
- << " ";
-
- os << quote_id (dc.name ());
- }
- };
- entry<drop_column> drop_column_;
-
- struct drop_foreign_key: relational::drop_foreign_key, context
- {
- drop_foreign_key (base const& x): base (x) {}
-
- virtual void
- drop (sema_rel::table& t, sema_rel::foreign_key& fk)
- {
- bool migration (dropped_ == 0);
-
- if (migration)
- {
- if (fk.not_deferrable ())
- pre_statement ();
- else
- {
- if (format_ != schema_format::sql)
- return;
-
- os << "/*" << endl;
- }
- }
- else
- {
- // Here we drop potentially deferrable keys and also need to
- // test if the key exists.
- //
- pre_statement ();
-
- os << "IF OBJECT_ID(" << quote_string (fk.name ()) << ", " <<
- quote_string ("F") << ") IS NOT NULL" << endl
- << " ";
- }
-
- os << "ALTER TABLE " << quote_id (t.name ()) << endl
- << (migration ? " " : " ") << "DROP CONSTRAINT " <<
- quote_id (fk.name ()) << endl;
-
-
- if (!migration || fk.not_deferrable ())
- post_statement ();
- else
- os << "*/" << endl
- << endl;
- }
-
- virtual void
- traverse (sema_rel::drop_foreign_key& dfk)
- {
- // Find the foreign key we are dropping in the base model.
- //
- sema_rel::foreign_key& fk (find<sema_rel::foreign_key> (dfk));
-
- bool c (!fk.not_deferrable () && !in_comment);
-
- if (c && format_ != schema_format::sql)
- return;
-
- if (!first_)
- os << (c ? "" : ",") << endl
- << " ";
-
- if (c)
- os << "/* ";
-
- os << quote_id (fk.name ());
-
- if (c)
- os << " */";
-
- if (first_)
- {
- if (c)
- // There has to be a real name otherwise the whole statement
- // would have been commented out.
- //
- os << endl
- << " ";
- else
- first_ = false;
- }
- }
- };
- entry<drop_foreign_key> drop_foreign_key_;
-
- struct drop_index: relational::drop_index, context
- {
- drop_index (base const& x): base (x) {}
-
- virtual void
- drop (sema_rel::index& in)
- {
- sema_rel::table& t (static_cast<sema_rel::table&> (in.scope ()));
-
- os << "DROP INDEX " << name (in) << " ON " <<
- quote_id (t.name ()) << endl;
- }
- };
- entry<drop_index> drop_index_;
-
- struct drop_table: relational::drop_table, context
- {
- drop_table (base const& x): base (x) {}
-
- virtual void
- drop (sema_rel::table& t, bool migration)
- {
- // SQL Server has no IF EXISTS conditional for dropping tables.
- // The following approach appears to be the recommended way to
- // drop a table if it exists.
- //
- sema_rel::qname const& name (t.name ());
-
- pre_statement ();
-
- if (!migration)
- os << "IF OBJECT_ID(" << quote_string (name.string ()) <<
- ", " << quote_string ("U") << ") IS NOT NULL" << endl
- << " ";
-
- os << "DROP TABLE " << quote_id (name) << endl;
-
- post_statement ();
- }
- };
- entry<drop_table> drop_table_;
-
- //
- // Create.
- //
-
- struct create_column: relational::create_column, context
- {
- create_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::add_column& ac)
- {
- if (first_)
- first_ = false;
- else
- os << "," << endl
- << " ";
-
- create (ac);
- }
-
- virtual void
- auto_ (sema_rel::primary_key&)
- {
- os << " IDENTITY";
- }
- };
- entry<create_column> create_column_;
-
- struct create_foreign_key: relational::create_foreign_key, context
- {
- create_foreign_key (base const& x): base (x) {}
-
- void
- diagnose (sema_rel::foreign_key& fk)
- {
- if (fk.on_delete () != sema_rel::foreign_key::no_action)
- {
- cerr << "warning: foreign key '" << fk.name () << "' has " <<
- "ON DELETE clause but is disabled in SQL Server due to lack "
- "of deferrable constraint support" << endl;
-
- cerr << "info: consider using non-deferrable foreign keys (" <<
- "--fkeys-deferrable-mode)" << endl;
- }
- }
-
- virtual void
- traverse_create (sema_rel::foreign_key& fk)
- {
- // SQL Server does not support deferrable constraint checking.
- // Output such foreign keys as comments, for documentation,
- // unless we are generating embedded schema.
- //
- if (fk.not_deferrable ())
- base::traverse_create (fk);
- else
- {
- diagnose (fk);
-
- // Don't bloat C++ code with comment strings if we are
- // generating embedded schema.
- //
- if (format_ != schema_format::sql)
- return;
-
- os << endl
- << " /*" << endl
- << " CONSTRAINT ";
- create (fk);
- os << endl
- << " */";
- }
- }
-
- virtual void
- traverse_add (sema_rel::foreign_key& fk)
- {
- bool c (!fk.not_deferrable () && !in_comment);
-
- if (c)
- diagnose (fk);
-
- if (c && format_ != schema_format::sql)
- return;
-
- if (!first_)
- os << (c ? "" : ",") << endl
- << " ";
-
- if (c)
- os << "/*" << endl
- << " ";
-
- os << "CONSTRAINT ";
- create (fk);
-
- if (c)
- os << endl
- << " */";
-
- if (first_)
- {
- if (c)
- // There has to be a real key otherwise the whole statement
- // would have been commented out.
- //
- os << endl
- << " ";
- else
- first_ = false;
- }
- }
-
- virtual void
- deferrable (sema_rel::deferrable)
- {
- // This will still be called to output the comment.
- }
- };
- entry<create_foreign_key> create_foreign_key_;
-
- struct create_table: relational::create_table, context
- {
- create_table (base const& x): base (x) {}
-
- // See if there are any undefined foreign keys that are not
- // deferrable.
- //
- bool
- check_undefined_fk_deferrable_only (sema_rel::table& t)
- {
- for (sema_rel::table::names_iterator i (t.names_begin ());
- i != t.names_end (); ++i)
- {
- using sema_rel::foreign_key;
-
- if (foreign_key* fk = dynamic_cast<foreign_key*> (&i->nameable ()))
- {
- if (!fk->count ("mssql-fk-defined") &&
- fk->not_deferrable ())
- return false;
- }
- }
- return true;
- }
-
- virtual void
- traverse (sema_rel::table& t)
- {
- if (pass_ == 1)
- base::traverse (t);
- else
- {
- // Add undefined foreign keys.
- //
- if (check_undefined_fk (t))
- {
- bool deferrable (check_undefined_fk_deferrable_only (t));
-
- if (!deferrable || format_ == schema_format::sql)
- {
- if (deferrable)
- {
- os << "/*" << endl;
- in_comment = true;
- }
- else
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (t.name ()) << endl
- << " ADD ";
-
- instance<create_foreign_key> cfk (*this);
- trav_rel::unames n (*cfk);
- names (t, n);
- os << endl;
-
- if (deferrable)
- {
- in_comment = false;
- os << "*/" << endl
- << endl;
- }
- else
- post_statement ();
- }
- }
- }
- }
- };
- entry<create_table> create_table_;
-
- //
- // Alter.
- //
-
- struct alter_column: relational::alter_column, context
- {
- alter_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::column& c)
- {
- // Relax (NULL) in pre and tighten (NOT NULL) in post.
- //
- if (pre_ != c.null ())
- return;
-
- using sema_rel::table;
- table& at (static_cast<table&> (c.scope ()));
-
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " ALTER COLUMN ";
- alter (c);
- os << endl;
-
- post_statement ();
- }
- };
- entry<alter_column> alter_column_;
-
- struct alter_table_pre: relational::alter_table_pre, context
- {
- alter_table_pre (base const& x): base (x) {}
-
- // Check if we are only dropping deferrable foreign keys.
- //
- bool
- check_drop_deferrable_only (sema_rel::alter_table& at)
- {
- for (sema_rel::alter_table::names_iterator i (at.names_begin ());
- i != at.names_end (); ++i)
- {
- using sema_rel::foreign_key;
- using sema_rel::drop_foreign_key;
-
- if (drop_foreign_key* dfk =
- dynamic_cast<drop_foreign_key*> (&i->nameable ()))
- {
- foreign_key& fk (find<foreign_key> (*dfk));
-
- if (fk.not_deferrable ())
- return false;
- }
- }
- return true;
- }
-
- virtual void
- alter (sema_rel::alter_table& at)
- {
- // SQL Server can only alter one kind of thing at a time.
- //
- if (check<sema_rel::drop_foreign_key> (at))
- {
- bool deferrable (check_drop_deferrable_only (at));
-
- if (!deferrable || format_ == schema_format::sql)
- {
- if (deferrable)
- {
- os << "/*" << endl;
- in_comment = true;
- }
- else
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " DROP CONSTRAINT ";
-
- instance<drop_foreign_key> dfc (*this);
- trav_rel::unames n (*dfc);
- names (at, n);
- os << endl;
-
- if (deferrable)
- {
- in_comment = false;
- os << "*/" << endl
- << endl;
- }
- else
- post_statement ();
- }
- }
-
- if (check<sema_rel::add_column> (at))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " ADD ";
-
- instance<create_column> cc (*this);
- trav_rel::unames n (*cc);
- names (at, n);
- os << endl;
-
- post_statement ();
- }
-
- // For ALTER COLUMN, SQL Server can only have one per ALTER TABLE.
- //
- {
- bool tl (true); // (Im)perfect forwarding.
- instance<alter_column> ac (*this, tl);
- trav_rel::unames n (*ac);
- names (at, n);
- }
- }
- };
- entry<alter_table_pre> alter_table_pre_;
-
- struct alter_table_post: relational::alter_table_post, context
- {
- alter_table_post (base const& x): base (x) {}
-
- // Check if we are only adding deferrable foreign keys.
- //
- bool
- check_add_deferrable_only (sema_rel::alter_table& at)
- {
- for (sema_rel::alter_table::names_iterator i (at.names_begin ());
- i != at.names_end (); ++i)
- {
- using sema_rel::add_foreign_key;
-
- if (add_foreign_key* afk =
- dynamic_cast<add_foreign_key*> (&i->nameable ()))
- {
- if (afk->not_deferrable ())
- return false;
- }
- }
- return true;
- }
-
- virtual void
- alter (sema_rel::alter_table& at)
- {
- // SQL Server can only alter one kind of thing at a time.
- //
- if (check<sema_rel::drop_column> (at))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " DROP COLUMN ";
-
- instance<drop_column> dc (*this);
- trav_rel::unames n (*dc);
- names (at, n);
- os << endl;
-
- post_statement ();
- }
-
- // For ALTER COLUMN, SQL Server can only have one per ALTER TABLE.
- //
- {
- bool fl (false); // (Im)perfect forwarding.
- instance<alter_column> ac (*this, fl);
- trav_rel::unames n (*ac);
- names (at, n);
- }
-
- if (check<sema_rel::add_foreign_key> (at))
- {
- bool deferrable (check_add_deferrable_only (at));
-
- if (!deferrable || format_ == schema_format::sql)
- {
- if (deferrable)
- {
- os << "/*" << endl;
- in_comment = true;
- }
- else
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " ADD ";
-
- instance<create_foreign_key> cfc (*this);
- trav_rel::unames n (*cfc);
- names (at, n);
- os << endl;
-
- if (deferrable)
- {
- in_comment = false;
- os << "*/" << endl
- << endl;
- }
- else
- post_statement ();
- }
- }
- }
- };
- entry<alter_table_post> alter_table_post_;
-
- //
- // Schema version table.
- //
-
- struct version_table: relational::version_table, context
- {
- version_table (base const& x): base (x) {}
-
- virtual void
- create_table ()
- {
- pre_statement ();
-
- os << "IF OBJECT_ID(" << quote_string (table_.string ()) <<
- ", " << quote_string ("U") << ") IS NULL" << endl
- << " CREATE TABLE " << qt_ << " (" << endl
- << " " << qn_ << " VARCHAR(256) NOT NULL PRIMARY KEY," << endl
- << " " << qv_ << " BIGINT NOT NULL," << endl
- << " " << qm_ << " BIT NOT NULL)" << endl;
-
- post_statement ();
- }
-
- virtual void
- create (sema_rel::version v)
- {
- pre_statement ();
-
- os << "IF NOT EXISTS (SELECT 1 FROM " << qt_ << " WHERE " << qn_ <<
- " = " << qs_ << ")" << endl
- << " INSERT INTO " << qt_ << " (" << endl
- << " " << qn_ << ", " << qv_ << ", " << qm_ << ")" << endl
- << " VALUES (" << qs_ << ", " << v << ", 0)" << endl;
-
- post_statement ();
- }
- };
- entry<version_table> version_table_;
- }
- }
-}
diff --git a/odb/relational/mssql/source.cxx b/odb/relational/mssql/source.cxx
deleted file mode 100644
index 573104d..0000000
--- a/odb/relational/mssql/source.cxx
+++ /dev/null
@@ -1,1201 +0,0 @@
-// file : odb/relational/mssql/source.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/source.hxx>
-
-#include <odb/relational/mssql/common.hxx>
-#include <odb/relational/mssql/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace mssql
- {
- namespace source
- {
- namespace relational = relational::source;
-
- //
- //
- struct query_parameters: relational::query_parameters
- {
- query_parameters (base const& x): base (x) {}
-
- virtual string
- auto_id (semantics::data_member&, const string&, const string&)
- {
- return "";
- }
- };
- entry<query_parameters> query_parameters_;
-
- //
- //
- struct object_columns: relational::object_columns, context
- {
- object_columns (base const& x)
- : base (x), rowversion_ (false), column_count_ (0) {}
-
- virtual bool
- column (semantics::data_member& m,
- string const& table,
- string const& column)
- {
- // Don't add a column for auto id in the INSERT statement.
- // Only simple, direct id can be auto.
- //
- if (sk_ == statement_insert && key_prefix_.empty () && auto_ (m))
- return false;
-
- // Don't update the ROWVERSION column explicitly.
- //
- if (sk_ == statement_update)
- {
- sql_type t (parse_sql_type (column_type (), m));
- if (t.type == sql_type::ROWVERSION)
- {
- rowversion_ = true;
- return false;
- }
- }
-
- bool r (base::column (m, table, column));
-
- // Count the number of columns in the UPDATE statement, but
- // excluding soft-deleted.
- //
- if (sk_ == statement_update && r && !deleted (member_path_))
- column_count_++;
-
- return r;
- }
-
- virtual void
- traverse_post (semantics::nameable& n)
- {
- if (rowversion_ && column_count_ == 0)
- {
- location l (n.location ());
- error (l) << "ROWVERSION in an object without any readwrite "
- "data members" << endl;
- error (l) << "UPDATE statement will be empty" << endl;
- throw operation_failed ();
- }
- }
-
- private:
- bool rowversion_;
- size_t column_count_;
- };
- entry<object_columns> object_columns_;
-
- //
- //
- struct persist_statement_params: relational::persist_statement_params,
- context
- {
- persist_statement_params (base const& x): base (x) {}
-
- virtual string
- version_value (semantics::data_member& m)
- {
- sql_type t (parse_sql_type (column_type (), m));
- return t.type == sql_type::ROWVERSION ? "DEFAULT" : "1";
- }
- };
- entry<persist_statement_params> persist_statement_params_;
-
- //
- // bind
- //
-
- static const char* integer_buffer_types[] =
- {
- "mssql::bind::bit",
- "mssql::bind::tinyint",
- "mssql::bind::smallint",
- "mssql::bind::int_",
- "mssql::bind::bigint"
- };
-
- struct bind_member: relational::bind_member_impl<sql_type>,
- member_base
- {
- bind_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << b << ".type = " <<
- integer_buffer_types[mi.st->type - sql_type::BIT] << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;";
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- os << b << ".type = mssql::bind::decimal;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- // Encode precision (p) and scale (s) as (p * 100 + s).
- //
- << b << ".capacity = " << mi.st->prec * 100 + mi.st->scale << ";";
- }
-
- virtual void
- traverse_smallmoney (member_info& mi)
- {
- os << b << ".type = mssql::bind::smallmoney;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;";
- }
-
- virtual void
- traverse_money (member_info& mi)
- {
- os << b << ".type = mssql::bind::money;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;";
- }
-
- virtual void
- traverse_float4 (member_info& mi)
- {
- os << b << ".type = mssql::bind::float4;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- << b << ".capacity = " << mi.st->prec << ";";
- }
-
- virtual void
- traverse_float8 (member_info& mi)
- {
- os << b << ".type = mssql::bind::float8;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- << b << ".capacity = " << mi.st->prec << ";";
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << b << ".type = mssql::bind::string;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- << b << ".capacity = static_cast<SQLLEN> (sizeof (" <<
- arg << "." << mi.var << "value));";
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << b << ".type = mssql::bind::long_string;"
- << b << ".buffer = &" << arg << "." << mi.var << "callback;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- // Encode the column size with 0 indicating unlimited.
- //
- << b << ".capacity = " << mi.st->prec << ";";
- }
-
- virtual void
- traverse_nstring (member_info& mi)
- {
- os << b << ".type = mssql::bind::nstring;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- << b << ".capacity = static_cast<SQLLEN> (sizeof (" <<
- arg << "." << mi.var << "value));";
- }
-
- virtual void
- traverse_long_nstring (member_info& mi)
- {
- os << b << ".type = mssql::bind::long_nstring;"
- << b << ".buffer = &" << arg << "." << mi.var << "callback;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- // Encode the column size (in bytes) with 0 indicating unlimited.
- //
- << b << ".capacity = " << mi.st->prec * 2 << ";";
- }
-
- virtual void
- traverse_binary (member_info& mi)
- {
- os << b << ".type = mssql::bind::binary;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- << b << ".capacity = static_cast<SQLLEN> (sizeof (" <<
- arg << "." << mi.var << "value));";
- }
-
- virtual void
- traverse_long_binary (member_info& mi)
- {
- os << b << ".type = mssql::bind::long_binary;"
- << b << ".buffer = &" << arg << "." << mi.var << "callback;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- // Encode the column size with 0 indicating unlimited.
- //
- << b << ".capacity = " << mi.st->prec << ";";
- }
-
- virtual void
- traverse_date (member_info& mi)
- {
- os << b << ".type = mssql::bind::date;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;";
- }
-
- virtual void
- traverse_time (member_info& mi)
- {
- os << b << ".type = mssql::bind::time;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- // Encode fractional seconds (scale).
- //
- << b << ".capacity = " << mi.st->scale << ";";
- }
-
- virtual void
- traverse_datetime (member_info& mi)
- {
- unsigned short scale (0);
-
- switch (mi.st->type)
- {
- case sql_type::DATETIME:
- {
- // Looks like it is 3 (rounded to 0.000, 0.003, or 0.007).
- //
- scale = 3;
- break;
- }
- case sql_type::DATETIME2:
- {
- scale = mi.st->scale;
- break;
- }
- case sql_type::SMALLDATETIME:
- {
- // No seconds in SMALLDATATIME. Encode it a special precision
- // value (8).
- //
- scale = 8;
- break;
- }
- default:
- {
- assert (false);
- break;
- }
- }
-
- os << b << ".type = mssql::bind::datetime;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- // Encode fractional seconds (scale).
- //
- << b << ".capacity = " << scale << ";";
- }
-
- virtual void
- traverse_datetimeoffset (member_info& mi)
- {
- os << b << ".type = mssql::bind::datetimeoffset;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;"
- // Encode fractional seconds (scale).
- //
- << b << ".capacity = " << mi.st->scale << ";";
- }
-
- virtual void
- traverse_uniqueidentifier (member_info& mi)
- {
- os << b << ".type = mssql::bind::uniqueidentifier;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;";
- }
-
- virtual void
- traverse_rowversion (member_info& mi)
- {
- os << b << ".type = mssql::bind::rowversion;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".size_ind = &" << arg << "." << mi.var << "size_ind;";
- }
- };
- entry<bind_member> bind_member_;
-
- //
- // init image
- //
-
- struct init_image_member: relational::init_image_member_impl<sql_type>,
- member_base
- {
- init_image_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- set_null (member_info& mi)
- {
- os << "i." << mi.var << "size_ind = SQL_NULL_DATA;";
- }
-
- virtual void
- check_accessor (member_info& mi, member_access& ma)
- {
- // We cannot use accessors that return by-value for long data
- // members.
- //
- if (long_data (*mi.st) && ma.by_value)
- {
- error (ma.loc) << "accessor returning a value cannot be used "
- << "for a data member of SQL Server long data "
- << "type" << endl;
- info (ma.loc) << "accessor returning a const reference is required"
- << endl;
- info (mi.m.location ()) << "data member is defined here" << endl;
- throw operation_failed ();
- }
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 0;";
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 0;";
- }
-
- virtual void
- traverse_smallmoney (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 4;";
- }
-
- virtual void
- traverse_money (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 8;";
- }
-
- virtual void
- traverse_float4 (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 0;";
- }
-
- virtual void
- traverse_float8 (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 0;";
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << "std::size_t size (0);"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- // Don't mention the extra character for the null-terminator.
- << "sizeof (i." << mi.var << "value) - 1," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size_ind =" << endl
- << " is_null ? SQL_NULL_DATA : static_cast<SQLLEN> (size);";
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "callback.callback.param," << endl
- << "i." << mi.var << "callback.context.param," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size_ind = is_null ? " <<
- "SQL_NULL_DATA : SQL_DATA_AT_EXEC;";
- }
-
- virtual void
- traverse_nstring (member_info& mi)
- {
- os << "std::size_t size (0);"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- // Don't mention the extra character for the null-terminator.
- << "sizeof (i." << mi.var << "value) / 2 - 1," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size_ind =" << endl
- << " is_null ? SQL_NULL_DATA : static_cast<SQLLEN> (size * 2);";
- }
-
- virtual void
- traverse_long_nstring (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "callback.callback.param," << endl
- << "i." << mi.var << "callback.context.param," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size_ind = is_null ? " <<
- "SQL_NULL_DATA : SQL_DATA_AT_EXEC;";
- }
-
- virtual void
- traverse_binary (member_info& mi)
- {
- os << "std::size_t size (0);"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "sizeof (i." << mi.var << "value)," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size_ind =" << endl
- << " is_null ? SQL_NULL_DATA : static_cast<SQLLEN> (size);";
- }
-
- virtual void
- traverse_long_binary (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "callback.callback.param," << endl
- << "i." << mi.var << "callback.context.param," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size_ind = is_null ? " <<
- "SQL_NULL_DATA : SQL_DATA_AT_EXEC;";
- }
-
- virtual void
- traverse_date (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 0;";
- }
-
- virtual void
- traverse_time (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, " << mi.st->scale << ", " <<
- "is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null" << endl
- << " ? SQL_NULL_DATA" << endl
- << " : static_cast<SQLLEN> (sizeof (i." << mi.var << "value));";
- }
-
- virtual void
- traverse_datetime (member_info& mi)
- {
- // The same code as in bind.
- //
- unsigned short scale (0);
-
- switch (mi.st->type)
- {
- case sql_type::DATETIME:
- {
- scale = 3;
- break;
- }
- case sql_type::DATETIME2:
- {
- scale = mi.st->scale;
- break;
- }
- case sql_type::SMALLDATETIME:
- {
- scale = 8;
- break;
- }
- default:
- {
- assert (false);
- break;
- }
- }
-
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, " << scale << ", " <<
- "is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 0;";
- }
-
- virtual void
- traverse_datetimeoffset (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, " << mi.st->scale << ", " <<
- "is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null" << endl
- << " ? SQL_NULL_DATA" << endl
- << " : static_cast<SQLLEN> (sizeof (i." << mi.var << "value));";
- }
-
- virtual void
- traverse_uniqueidentifier (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 0;";
- }
-
- virtual void
- traverse_rowversion (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 8;";
- }
- };
- entry<init_image_member> init_image_member_;
-
- //
- // init value
- //
-
- struct init_value_member: relational::init_value_member_impl<sql_type>,
- member_base
- {
- init_value_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- get_null (string const& var) const
- {
- os << "i." << var << "size_ind == SQL_NULL_DATA";
- }
-
- virtual void
- check_modifier (member_info& mi, member_access& ma)
- {
- // We cannot use by-value modifier for long data members.
- //
- if (long_data (*mi.st) && ma.placeholder ())
- {
- error (ma.loc) << "modifier accepting a value cannot be used "
- << "for a data member of SQL Server long data "
- << "type" << endl;
- info (ma.loc) << "modifier returning a non-const reference is "
- << "required" << endl;
- info (mi.m.location ()) << "data member is defined here" << endl;
- throw operation_failed ();
- }
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_smallmoney (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_money (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_float4 (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_float8 (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "static_cast<std::size_t> (i." << mi.var << "size_ind)," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "callback.callback.result," << endl
- << "i." << mi.var << "callback.context.result);"
- << endl;
- }
-
- virtual void
- traverse_nstring (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "static_cast<std::size_t> (" <<
- "i." << mi.var << "size_ind / 2)," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_long_nstring (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "callback.callback.result," << endl
- << "i." << mi.var << "callback.context.result);"
- << endl;
- }
-
- virtual void
- traverse_binary (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "static_cast<std::size_t> (i." << mi.var << "size_ind)," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_long_binary (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "callback.callback.result," << endl
- << "i." << mi.var << "callback.context.result);"
- << endl;
- }
-
- virtual void
- traverse_date (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_time (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_datetime (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_datetimeoffset (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_uniqueidentifier (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
-
- virtual void
- traverse_rowversion (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size_ind == SQL_NULL_DATA);"
- << endl;
- }
- };
- entry<init_value_member> init_value_member_;
-
- struct statement_columns_common: context
- {
- void
- process (relational::statement_columns& cols,
- statement_kind sk,
- bool dynamic)
- {
- using relational::statement_columns;
-
- // Long data columns must come last in the SELECT statement. If
- // this statement is going to be processed at runtime, then this
- // will be taken care of then.
- //
- if (sk != statement_select || dynamic)
- return;
-
- // Go over the columns list while keeping track of how many
- // columns we have examined. If the current column is long data,
- // then move it to the back. Stop once we have examined all the
- // columns.
- //
- size_t n (cols.size ());
- for (statement_columns::iterator i (cols.begin ()); n != 0; --n)
- {
- if (long_data (parse_sql_type (i->type, *i->member)))
- {
- cols.push_back (*i);
- i = cols.erase (i);
- }
- else
- ++i;
- }
- }
- };
-
- struct container_traits: relational::container_traits,
- statement_columns_common
- {
- container_traits (base const& x): base (x) {}
-
- virtual void
- cache_result (string const&)
- {
- // Caching is not necessary since with MARS enabled SQL Server
- // can execute several interleaving statements.
- //
- }
-
- virtual void
- init_value_extra ()
- {
- os << "sts.select_statement ().stream_result ();"
- << endl;
- }
-
- virtual void
- process_statement_columns (relational::statement_columns& cols,
- statement_kind sk,
- bool dynamic)
- {
- statement_columns_common::process (cols, sk, dynamic);
- }
- };
- entry<container_traits> container_traits_;
-
- struct section_traits: relational::section_traits,
- statement_columns_common
- {
- section_traits (base const& x): base (x) {}
-
- virtual void
- init_value_extra ()
- {
- os << "st.stream_result ();";
- }
-
- virtual void
- process_statement_columns (relational::statement_columns& cols,
- statement_kind sk,
- bool dynamic)
- {
- statement_columns_common::process (cols, sk, dynamic);
- }
-
- virtual string
- optimistic_version_increment (semantics::data_member& m)
- {
- sql_type t (parse_sql_type (column_type (m), m));
- return t.type != sql_type::ROWVERSION
- ? "1"
- : "version (sts.id_image ())";
- }
-
- virtual string
- update_statement_extra (user_section&)
- {
- string r;
-
- semantics::data_member* ver (optimistic (c_));
-
- if (ver == 0 ||
- parse_sql_type (column_type (*ver), *ver).type !=
- sql_type::ROWVERSION)
- return r;
-
- // ROWVERSION & SQL Server 2005 incompatibility is detected
- // in persist_statement_extra.
- //
- r = "OUTPUT INSERTED." +
- convert_from (column_qname (*ver, column_prefix ()), *ver);
-
- return r;
- }
- };
- entry<section_traits> section_traits_;
-
- struct class_: relational::class_, statement_columns_common
- {
- class_ (base const& x):
- base (x), init_version_value_member_id_image_ ("v", "version_") {}
-
- virtual void
- init_image_pre (type& c)
- {
- if (options.generate_query () &&
- !(composite (c) || (abstract (c) && !polymorphic (c))))
- {
- type* poly_root (polymorphic (c));
- bool poly_derived (poly_root != 0 && poly_root != &c);
-
- if (poly_derived)
- os << "{"
- << "root_traits::image_type& ri (root_image (i));"
- << endl;
-
- string i (poly_derived ? "ri" : "i");
-
- os << "if (" << i << ".change_callback_.callback != 0)" << endl
- << "(" << i << ".change_callback_.callback) (" <<
- i << ".change_callback_.context);";
-
- if (poly_derived)
- os << "}";
- else
- os << endl;
- }
- }
-
- virtual void
- init_value_extra ()
- {
- os << "st.stream_result ();";
- }
-
- virtual string
- persist_statement_extra (type& c,
- relational::query_parameters&,
- persist_position p)
- {
- string r;
-
- type* poly_root (polymorphic (c));
- bool poly_derived (poly_root != 0 && poly_root != &c);
-
- // If we are a derived type in a polymorphic hierarchy, then
- // auto id/version are handled by the root.
- //
- if (poly_derived)
- return r;
-
- // See if we have auto id or ROWVERSION version.
- //
- data_member_path* id (id_member (c));
- semantics::data_member* ver (optimistic (c));
-
- if (id != 0 && !auto_ (*id))
- id = 0;
-
- if (ver != 0)
- {
- sql_type t (parse_sql_type (column_type (*ver), *ver));
- if (t.type != sql_type::ROWVERSION)
- ver = 0;
- }
-
- if (id == 0 && ver == 0)
- return r;
-
- // SQL Server 2005 has a bug that causes it to fail on an
- // INSERT statement with the OUTPUT clause if data for one
- // of the inserted columns is supplied at execution (long
- // data). To work around this problem we use the less
- // efficient batch of INSERT and SELECT statements.
- //
- if (options.mssql_server_version () <= mssql_version (9, 0))
- {
- bool ld (false);
-
- if (c.count ("mssql-has-long-data"))
- ld = c.get<bool> ("mssql-has-long-data");
- else
- {
- has_long_data t (ld);
- t.traverse (c);
- c.set ("mssql-has-long-data", ld);
- }
-
- if (ld)
- {
- if (p == persist_after_values)
- {
- // SQL Server 2005 has no eqivalent of SCOPE_IDENTITY for
- // ROWVERSION.
- //
- if (ver != 0)
- {
- error (c.location ()) << "in SQL Server 2005 ROWVERSION " <<
- "value cannot be retrieved for a persistent class " <<
- "containing long data" << endl;
- 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->back ());
- }
-
- return r;
- }
- }
-
- if (p == persist_after_columns)
- {
- r = "OUTPUT ";
-
- // Top-level auto id column.
- //
- if (id != 0)
- r += "INSERTED." +
- convert_from (column_qname (*id), *id->back ());
-
- // Top-level version column.
- //
- if (ver != 0)
- {
- if (id != 0)
- r += ',';
-
- r += "INSERTED." + convert_from (
- column_qname (*ver, column_prefix ()), *ver);
- }
- }
-
- return r;
- }
-
- virtual string
- update_statement_extra (type& c)
- {
- string r;
-
- type* poly_root (polymorphic (c));
- bool poly_derived (poly_root != 0 && poly_root != &c);
-
- // If we are a derived type in a polymorphic hierarchy, then
- // version is handled by the root.
- //
- if (poly_derived)
- return r;
-
- semantics::data_member* ver (optimistic (c));
-
- if (ver == 0 ||
- parse_sql_type (column_type (*ver), *ver).type !=
- sql_type::ROWVERSION)
- return r;
-
- // Long data & SQL Server 2005 incompatibility is detected
- // in persist_statement_extra.
- //
- r = "OUTPUT INSERTED." +
- convert_from (column_qname (*ver, column_prefix ()), *ver);
-
- return r;
- }
-
- virtual void
- process_statement_columns (relational::statement_columns& cols,
- statement_kind sk,
- bool dynamic)
- {
- statement_columns_common::process (cols, sk, dynamic);
- }
-
- virtual string
- optimistic_version_init (semantics::data_member& m, bool index)
- {
- sql_type t (parse_sql_type (column_type (m), m));
- return t.type != sql_type::ROWVERSION
- ? "1"
- : (index
- ? "version (sts.id_image (i))"
- : "version (sts.id_image ())");
- }
-
- virtual string
- optimistic_version_increment (semantics::data_member& m, bool index)
- {
- sql_type t (parse_sql_type (column_type (m), m));
- return t.type != sql_type::ROWVERSION
- ? "1"
- : (index
- ? "version (sts.id_image (i))"
- : "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;"
- << "}";
- }
- }
- }
-
- virtual string
- from_trailer (type& c)
- {
- return c.get<view_query> ("query").for_update
- ? " WITH (UPDLOCK)"
- : "";
- }
-
- virtual string
- select_trailer (type&) {return "";}
-
- 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_;
- }
- }
-}