diff options
Diffstat (limited to 'odb/odb/relational/mssql/common.cxx')
-rw-r--r-- | odb/odb/relational/mssql/common.cxx | 603 |
1 files changed, 603 insertions, 0 deletions
diff --git a/odb/odb/relational/mssql/common.cxx b/odb/odb/relational/mssql/common.cxx new file mode 100644 index 0000000..1070d21 --- /dev/null +++ b/odb/odb/relational/mssql/common.cxx @@ -0,0 +1,603 @@ +// 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_; + } +} |