aboutsummaryrefslogtreecommitdiff
path: root/mssql/types
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-12-21 11:19:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-01-20 15:45:46 +0200
commit0e9d2582dc02ff507265fcafc99ef6a13f0dc3f7 (patch)
treeb06aa27e81e0813d432c43671a1e61d8518c2143 /mssql/types
parent07c02dcecd806810226db734f193bdcf4df8cae7 (diff)
ODB compiler implementation, traits, and types test for SQL Server
Diffstat (limited to 'mssql/types')
-rw-r--r--mssql/types/driver.cxx158
-rw-r--r--mssql/types/makefile107
-rw-r--r--mssql/types/test.hxx325
-rw-r--r--mssql/types/test.std0
-rw-r--r--mssql/types/traits.hxx225
5 files changed, 815 insertions, 0 deletions
diff --git a/mssql/types/driver.cxx b/mssql/types/driver.cxx
new file mode 100644
index 0000000..2266792
--- /dev/null
+++ b/mssql/types/driver.cxx
@@ -0,0 +1,158 @@
+// file : mssql/types/driver.cxx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+// Test SQL Server type conversion.
+//
+
+#include <memory> // std::auto_ptr
+#include <cassert>
+#include <iostream>
+
+#include <odb/mssql/database.hxx>
+#include <odb/mssql/transaction.hxx>
+
+#include <common/common.hxx>
+
+#include "test.hxx"
+#include "test-odb.hxx"
+
+using namespace std;
+using namespace odb::core;
+
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ auto_ptr<database> db (create_database (argc, argv, false));
+
+ {
+ object o (1);
+
+ o.bit_ = 1;
+ o.utint_ = 222;
+ o.stint_ = -123;
+ o.usint_ = 65000;
+ o.ssint_ = -12345;
+ o.uint_ = 4294967290U;
+ o.sint_ = -1234567890;
+ o.ubint_ = 18446744073709551610ULL;
+ o.sbint_ = -1234567890123456789LL;
+
+ o.fsm_ = -214748.3648F;
+ o.dsm_ = 214748.3647D;
+ o.ism_ = -2147483647 -1;
+
+ o.dm1_ = -922337203685477.5808D;
+ o.dm2_ = 922337203685476.3520D; // 922337203685477.5807
+ o.im_ = 9223372036854775807LL;
+
+ o.f4_ = 123.123F;
+ o.f8_ = 123.1234567D;
+
+ o.schar_ = "short data char ";
+ o.svchar_ = "short data varchar";
+
+ o.lchar_.assign (257, 'a');
+ o.lvchar_ = "long data varchar"; // Test the short string optimization.
+ o.mvchar_.assign (70000, 'm');
+ o.text_.assign (70000, 't');
+
+ o.snchar_ = L"short data nchar\x1FFF\xD7FF ";
+ o.snvchar_ = L"short data nvarchar \x1FFF\xD7FF";
+
+ o.lnchar_.assign (129, L'\x1234');
+ o.lnvchar_ = L""; // Test empty string.
+ o.mnvchar_.assign (70000, L'\x2345');
+ o.ntext_.assign (70000, L'\x4356');
+
+ const char sdata[] = "abc""\x00\x01""def";
+ memcpy (o.sbin_, sdata, sizeof (sdata));
+ o.svbin_.assign (sdata, sdata + sizeof (sdata));
+
+ string ldata (256 * 1024, '\x01');
+ memset (o.lbin_, 2, sizeof (o.lbin_));
+ o.lvbin_.assign (50, '\x03');
+ o.mvbin_.assign (ldata.begin (), ldata.end ());
+ o.image_.assign (ldata.begin (), ldata.end ());
+
+ o.date_ = date_time (2011, 12, 20, 0, 0, 0, 0, 0, 0);
+ o.time7_ = date_time (0, 0, 0, 13, 34, 39, 123456789, 0, 0);
+ o.time4_ = date_time (0, 0, 0, 13, 34, 39, 123456700, 0, 0);
+ o.sdt_ = date_time (2011, 12, 20, 15, 44, 29, 123456700, 0, 0);
+ o.dt_ = date_time (2011, 12, 20, 15, 44, 29, 123456700, 0, 0);
+ o.dt2_ = date_time (2011, 12, 20, 15, 44, 29, 123456700, 0, 0);
+ o.dto7_ = date_time (2011, 12, 20, 15, 44, 29, 123456700, 2, 0);
+ o.dto0_ = date_time (2011, 12, 20, 15, 44, 29, 123456700, 2, 0);
+
+#ifdef _WIN32
+ // 6F846D41-C89A-4E4D-B22F-56443CFA543F
+ o.guid_.Data1 = 0x6F846D41;
+ o.guid_.Data2 = 0xC89A;
+ o.guid_.Data3 = 0x4E4D;
+ memcpy (&o.guid_.Data4, "\xB2\x2F\x56\x44\x3C\xFA\x54\x3F", 8);
+#endif
+
+ // Persist.
+ //
+ {
+ transaction t (db->begin ());
+ db->persist (o);
+ t.commit ();
+ }
+
+ o.time7_ = date_time (0, 0, 0, 13, 34, 39, 123456700, 0, 0);
+ o.time4_ = date_time (0, 0, 0, 13, 34, 39, 123400000, 0, 0);
+ o.sdt_ = date_time (2011, 12, 20, 15, 44, 0, 0, 0, 0);
+ o.dt_ = date_time (2011, 12, 20, 15, 44, 29, 123000000, 0, 0);
+ o.dto0_ = date_time (2011, 12, 20, 15, 44, 29, 0, 2, 0);
+
+ // Load.
+ //
+ {
+ transaction t (db->begin ());
+ auto_ptr<object> o1 (db->load<object> (1));
+ t.commit ();
+
+ assert (o == *o1);
+ }
+ }
+
+ // Test long NULL data.
+ //
+ {
+ long_null o1 (1);
+ long_null o2 (2);
+ o2.str_.reset (new string);
+ o2.str_->assign (70000, 'x');
+
+ // Persist.
+ //
+ {
+ transaction t (db->begin ());
+ db->persist (o1);
+ db->persist (o2);
+ t.commit ();
+ }
+
+ // Load.
+ //
+ {
+ transaction t (db->begin ());
+ auto_ptr<long_null> p1 (db->load<long_null> (1));
+ auto_ptr<long_null> p2 (db->load<long_null> (2));
+ t.commit ();
+
+ assert (o1 == *p1);
+ assert (o2 == *p2);
+ }
+ }
+ }
+ catch (const odb::exception& e)
+ {
+ cerr << e.what () << endl;
+ return 1;
+ }
+}
diff --git a/mssql/types/makefile b/mssql/types/makefile
new file mode 100644
index 0000000..96f7d68
--- /dev/null
+++ b/mssql/types/makefile
@@ -0,0 +1,107 @@
+# file : mssql/types/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make
+
+cxx_tun := driver.cxx
+odb_hdr := test.hxx
+cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o) $(odb_hdr:.hxx=-odb.o))
+cxx_od := $(cxx_obj:.o=.o.d)
+
+common.l := $(out_root)/libcommon/common/common.l
+common.l.cpp-options := $(out_root)/libcommon/common/common.l.cpp-options
+
+driver := $(out_base)/driver
+dist := $(out_base)/.dist
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/odb/stub.make,\
+ odb: odb,odb-rules: odb_rules)
+
+# Build.
+#
+$(driver): $(cxx_obj) $(common.l)
+$(cxx_obj) $(cxx_od): cpp_options := -I$(out_base) -I$(src_base)
+$(cxx_obj) $(cxx_od): $(common.l.cpp-options)
+
+genf := $(addprefix $(odb_hdr:.hxx=-odb),.hxx .ixx .cxx) $(odb_hdr:.hxx=.sql)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): $(odb)
+$(gen): odb := $(odb)
+$(gen) $(dist): export odb_options += --database mssql --generate-schema \
+--hxx-prologue '\#include "traits.hxx"' --table-prefix mssql_types_
+$(gen): cpp_options := -I$(src_base)
+$(gen): $(common.l.cpp-options)
+
+$(call include-dep,$(cxx_od),$(cxx_obj),$(gen))
+
+# Alias for default target.
+#
+$(out_base)/: $(driver)
+
+# Dist
+#
+$(dist): sources := $(cxx_tun)
+$(dist): headers := $(odb_hdr)
+$(dist): export extra_headers := traits.hxx
+$(dist): data_dist := test.std
+$(dist): export name := $(subst /,-,$(subst $(src_root)/mssql/,,$(src_base)))
+$(dist): export extra_dist := $(data_dist) $(name)-vc9.vcproj \
+$(name)-vc10.vcxproj $(name)-vc10.vcxproj.filters
+$(dist):
+ $(call dist-data,$(sources) $(headers) $(extra_headers) $(data_dist))
+ $(call meta-automake,../template/Makefile.am)
+ $(call meta-vc9proj,../template/template-vc9.vcproj,$(name)-vc9.vcproj)
+ $(call meta-vc10proj,../template/template-vc10.vcxproj,$(name)-vc10.vcxproj)
+
+# Test.
+#
+$(test): $(driver) $(src_base)/test.std
+ $(call schema)
+ $(call message,test $<,$< --options-file $(dcf_root)/db.options \
+>$(out_base)/test.out)
+ $(call message,,diff -u $(src_base)/test.std $(out_base)/test.out)
+ $(call message,,rm -f $(out_base)/test.out)
+
+# Clean.
+#
+$(clean): \
+ $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(cxx_obj)) \
+ $(addsuffix .cxx.clean,$(cxx_od)) \
+ $(addprefix $(out_base)/,$(odb_hdr:.hxx=-odb.cxx.hxx.clean))
+ $(call message,,rm -f $(out_base)/test.out)
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# How to.
+#
+$(call include,$(bld_root)/dist.make)
+$(call include,$(bld_root)/meta/vc9proj.make)
+$(call include,$(bld_root)/meta/vc10proj.make)
+$(call include,$(bld_root)/meta/automake.make)
+
+$(call include,$(odb_rules))
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/o-e.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/libcommon/makefile)
diff --git a/mssql/types/test.hxx b/mssql/types/test.hxx
new file mode 100644
index 0000000..8cd689b
--- /dev/null
+++ b/mssql/types/test.hxx
@@ -0,0 +1,325 @@
+// file : mssql/types/test.hxx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef TEST_HXX
+#define TEST_HXX
+
+#ifdef _WIN32
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h> // GUID
+#elif defined(WIN32_CROSS)
+typedef struct _GUID
+{
+ unsigned int Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} GUID;
+#endif
+
+#include <string>
+#include <vector>
+#include <memory> // std::auto_ptr
+#include <cstring> // std::memcmp
+
+#include <odb/core.hxx>
+
+struct date_time
+{
+ date_time ()
+ {
+ }
+
+ date_time (short y,
+ unsigned short m,
+ unsigned short d,
+ unsigned short h,
+ unsigned short min,
+ unsigned short sec,
+ unsigned int f,
+ short tzh,
+ short tzm)
+ : year (y),
+ month (m),
+ day (d),
+ hour (h),
+ minute (min),
+ second (sec),
+ fraction (f),
+ timezone_hour (tzh),
+ timezone_minute (tzm)
+ {
+ }
+
+ bool
+ operator== (const date_time& y) const
+ {
+ return
+ year == y.year &&
+ month == y.month &&
+ day == y.day &&
+ hour == y.hour &&
+ minute == y.minute &&
+ second == y.second &&
+ fraction == y.fraction &&
+ timezone_hour == y.timezone_hour &&
+ timezone_minute == y.timezone_minute;
+ }
+
+ short year;
+ unsigned short month;
+ unsigned short day;
+ unsigned short hour;
+ unsigned short minute;
+ unsigned short second;
+ unsigned int fraction;
+ short timezone_hour;
+ short timezone_minute;
+};
+
+#pragma db object
+struct object
+{
+ object () {}
+ object (unsigned int id): id_ (id) {}
+
+ #pragma db id
+ unsigned int id_;
+
+ // Integer types.
+ //
+ #pragma db type ("BIT")
+ unsigned char bit_;
+
+ #pragma db type ("TINYINT")
+ unsigned char utint_;
+
+ #pragma db type ("TINYINT")
+ unsigned char stint_;
+
+ #pragma db type ("SMALLINT")
+ unsigned short usint_;
+
+ #pragma db type ("SMALLINT")
+ short ssint_;
+
+ #pragma db type ("INT")
+ unsigned int uint_;
+
+ #pragma db type ("INTEGER")
+ int sint_;
+
+ #pragma db type ("BIGINT")
+ unsigned long long ubint_;
+
+ #pragma db type ("BIGINT")
+ long long sbint_;
+
+ // Floating/fixed point types.
+ //
+ #pragma db type ("SMALLMONEY")
+ float fsm_;
+
+ #pragma db type ("SMALLMONEY")
+ double dsm_;
+
+ #pragma db type ("SMALLMONEY")
+ int ism_;
+
+ #pragma db type ("MONEY")
+ double dm1_;
+
+ #pragma db type ("MONEY")
+ double dm2_;
+
+ #pragma db type ("MONEY")
+ long long im_;
+
+ #pragma db type ("REAL")
+ float f4_;
+
+ #pragma db type ("FLOAT")
+ double f8_;
+
+ // Strings.
+ //
+ #pragma db type ("CHAR(20)")
+ std::string schar_;
+
+ #pragma db type ("VARCHAR(128)")
+ std::string svchar_;
+
+ #pragma db type ("CHAR(257)")
+ std::string lchar_;
+
+ #pragma db type ("CHARACTER VARYING(8000)")
+ std::string lvchar_;
+
+ #pragma db type ("VARCHAR(max)")
+ std::string mvchar_;
+
+ #pragma db type ("TEXT")
+ std::string text_;
+
+ // National strings.
+ //
+ #pragma db type ("NCHAR(20)")
+ std::wstring snchar_;
+
+ #pragma db type ("NVARCHAR(128)")
+ std::wstring snvchar_;
+
+ #pragma db type ("NCHAR(129)")
+ std::wstring lnchar_;
+
+ #pragma db type ("NATIONAL CHARACTER VARYING(4000)")
+ std::wstring lnvchar_;
+
+ #pragma db type ("NVARCHAR(max)")
+ std::wstring mnvchar_;
+
+ #pragma db type ("NTEXT")
+ std::wstring ntext_;
+
+ // Binary.
+ //
+ #pragma db type ("BINARY(9)")
+ unsigned char sbin_[9];
+
+ #pragma db type ("VARBINARY(256)")
+ std::vector<char> svbin_;
+
+ #pragma db type ("BINARY(257)")
+ char lbin_[257];
+
+ #pragma db type ("BINARY VARYING(8000)")
+ std::vector<char> lvbin_;
+
+ #pragma db type ("VARBINARY(max)")
+ std::vector<unsigned char> mvbin_;
+
+ #pragma db type ("IMAGE")
+ std::vector<char> image_;
+
+ // Date-time.
+ //
+ #pragma db type ("DATE")
+ date_time date_;
+
+ #pragma db type ("TIME")
+ date_time time7_;
+
+ #pragma db type ("TIME(4)")
+ date_time time4_;
+
+ #pragma db type ("SMALLDATETIME")
+ date_time sdt_;
+
+ #pragma db type ("DATETIME")
+ date_time dt_;
+
+ #pragma db type ("DATETIME2")
+ date_time dt2_;
+
+ #pragma db type ("DATETIMEOFFSET")
+ date_time dto7_;
+
+ #pragma db type ("DATETIMEOFFSET(0)")
+ date_time dto0_;
+
+ // Other types.
+ //
+#if defined(_WIN32) || defined(WIN32_CROSS)
+ //#pragma db type ("UNIQUEIDENTIFIER")
+ GUID guid_;
+#endif
+
+ bool
+ operator== (const object& y) const
+ {
+ return
+ id_ == y.id_ &&
+ bit_ == y.bit_ &&
+ utint_ == y.utint_ &&
+ stint_ == y.stint_ &&
+ usint_ == y.usint_ &&
+ ssint_ == y.ssint_ &&
+ uint_ == y.uint_ &&
+ sint_ == y.sint_ &&
+ ubint_ == y.ubint_ &&
+ sbint_ == y.sbint_ &&
+ fsm_ == y.fsm_ &&
+ dsm_ == y.dsm_ &&
+ ism_ == y.ism_ &&
+ dm1_ == y.dm1_ &&
+ dm2_ == y.dm2_ &&
+ im_ == y.im_ &&
+ f4_ == y.f4_ &&
+ f8_ == y.f8_ &&
+
+ schar_ == y.schar_ &&
+ svchar_ == y.svchar_ &&
+ lchar_ == y.lchar_ &&
+ lvchar_ == y.lvchar_ &&
+ mvchar_ == y.mvchar_ &&
+ text_ == y.text_ &&
+
+ snchar_ == y.snchar_ &&
+ snvchar_ == y.snvchar_ &&
+ lnchar_ == y.lnchar_ &&
+ lnvchar_ == y.lnvchar_ &&
+ mnvchar_ == y.mnvchar_ &&
+ ntext_ == y.ntext_ &&
+
+ std::memcmp (sbin_, y.sbin_, sizeof (sbin_)) == 0 &&
+ svbin_ == y.svbin_ &&
+ std::memcmp (lbin_, y.lbin_, sizeof (lbin_)) == 0 &&
+ lvbin_ == y.lvbin_ &&
+ mvbin_ == y.mvbin_ &&
+ image_ == y.image_ &&
+
+ date_ == y.date_ &&
+ time7_ == y.time7_ &&
+ time4_ == y.time4_ &&
+ sdt_ == y.sdt_ &&
+ dt_ == y.dt_ &&
+ dt2_ == y.dt2_ &&
+ dto7_ == y.dto7_ &&
+ dto0_ == y.dto0_
+
+#ifdef _WIN32
+ && std::memcmp (&guid_, &y.guid_, sizeof (guid_)) == 0
+#endif
+ ;
+ }
+};
+
+
+// Test long NULL data.
+//
+#pragma db object
+struct long_null
+{
+ long_null () {}
+ long_null (unsigned int id): id_ (id) {}
+
+ #pragma db id
+ unsigned int id_;
+
+ #pragma db type ("VARCHAR(max)") null
+ std::auto_ptr<std::string> str_;
+
+ bool
+ operator== (const long_null& y) const
+ {
+ return
+ id_ == y.id_ &&
+ ((str_.get () == 0 && y.str_.get () == 0) || *str_ == *y.str_);
+ }
+};
+
+#endif // TEST_HXX
diff --git a/mssql/types/test.std b/mssql/types/test.std
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mssql/types/test.std
diff --git a/mssql/types/traits.hxx b/mssql/types/traits.hxx
new file mode 100644
index 0000000..76a21c5
--- /dev/null
+++ b/mssql/types/traits.hxx
@@ -0,0 +1,225 @@
+// file : mssql/types/traits.hxx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef TRAITS_HXX
+#define TRAITS_HXX
+
+#include <odb/mssql/mssql-fwd.hxx> // date, time, datetime, datetimeoffset
+#include <odb/mssql/traits.hxx>
+
+#include "test.hxx" // date_time
+
+namespace odb
+{
+ namespace mssql
+ {
+ template <>
+ class value_traits<date_time, id_date>
+ {
+ public:
+ typedef date_time value_type;
+ typedef date_time query_type;
+ typedef date image_type;
+
+ static void
+ set_value (date_time& v, const date& i, bool is_null)
+ {
+ if (!is_null)
+ {
+ v.year = i.year;
+ v.month = i.month;
+ v.day = i.day;
+ v.hour = 0;
+ v.minute = 0;
+ v.second = 0;
+ v.fraction = 0;
+ v.timezone_hour = 0;
+ v.timezone_minute = 0;
+ }
+ }
+
+ static void
+ set_image (date& i, bool& is_null, const date_time& v)
+ {
+ is_null = false;
+ i.year = v.year;
+ i.month = v.month;
+ i.day = v.day;
+ }
+ };
+
+ template <>
+ class value_traits<date_time, id_time>
+ {
+ public:
+ typedef date_time value_type;
+ typedef date_time query_type;
+ typedef time image_type;
+
+ static void
+ set_value (date_time& v, const time& i, bool is_null)
+ {
+ if (!is_null)
+ {
+ v.year = 0;
+ v.month = 0;
+ v.day = 0;
+ v.hour = i.hour;
+ v.minute = i.minute;
+ v.second = i.second;
+ v.fraction = i.fraction;
+ v.timezone_hour = 0;
+ v.timezone_minute = 0;
+ }
+ }
+
+ static void
+ set_image (time& i, unsigned short s, bool& is_null, const date_time& v)
+ {
+ const unsigned int divider[8] =
+ {
+ 1000000000,
+ 100000000,
+ 10000000,
+ 1000000,
+ 100000,
+ 10000,
+ 1000,
+ 100
+ };
+
+ is_null = false;
+ i.hour = v.hour;
+ i.minute = v.minute;
+ i.second = v.second;
+ i.fraction = v.fraction - v.fraction % divider[s];
+ }
+ };
+
+ template <>
+ class value_traits<date_time, id_datetime>
+ {
+ public:
+ typedef date_time value_type;
+ typedef date_time query_type;
+ typedef datetime image_type;
+
+ static void
+ set_value (date_time& v, const datetime& i, bool is_null)
+ {
+ if (!is_null)
+ {
+ v.year = i.year;
+ v.month = i.month;
+ v.day = i.day;
+ v.hour = i.hour;
+ v.minute = i.minute;
+ v.second = i.second;
+ v.fraction = i.fraction;
+ v.timezone_hour = 0;
+ v.timezone_minute = 0;
+ }
+ }
+
+ static void
+ set_image (datetime& i,
+ unsigned short s,
+ bool& is_null,
+ const date_time& v)
+ {
+ const unsigned int divider[8] =
+ {
+ 1000000000,
+ 100000000,
+ 10000000,
+ 1000000,
+ 100000,
+ 10000,
+ 1000,
+ 100
+ };
+
+ is_null = false;
+ i.year = v.year;
+ i.month = v.month;
+ i.day = v.day;
+ i.hour = v.hour;
+ i.minute = v.minute;
+
+ // Scale value 8 indicates we are dealing with SMALLDATETIME
+ // which has the minutes precision.
+ //
+ if (s != 8)
+ {
+ i.second = v.second;
+ i.fraction = v.fraction - v.fraction % divider[s];
+ }
+ else
+ {
+ i.second = 0;
+ i.fraction = 0;
+ }
+ }
+ };
+
+ template <>
+ class value_traits<date_time, id_datetimeoffset>
+ {
+ public:
+ typedef date_time value_type;
+ typedef date_time query_type;
+ typedef datetimeoffset image_type;
+
+ static void
+ set_value (date_time& v, const datetimeoffset& i, bool is_null)
+ {
+ if (!is_null)
+ {
+ v.year = i.year;
+ v.month = i.month;
+ v.day = i.day;
+ v.hour = i.hour;
+ v.minute = i.minute;
+ v.second = i.second;
+ v.fraction = i.fraction;
+ v.timezone_hour = i.timezone_hour;
+ v.timezone_minute = i.timezone_minute;
+ }
+ }
+
+ static void
+ set_image (datetimeoffset& i,
+ unsigned short s,
+ bool& is_null,
+ const date_time& v)
+ {
+ const unsigned int divider[8] =
+ {
+ 1000000000,
+ 100000000,
+ 10000000,
+ 1000000,
+ 100000,
+ 10000,
+ 1000,
+ 100
+ };
+
+ is_null = false;
+ i.year = v.year;
+ i.month = v.month;
+ i.day = v.day;
+ i.hour = v.hour;
+ i.minute = v.minute;
+ i.second = v.second;
+ i.fraction = v.fraction - v.fraction % divider[s];
+ i.timezone_hour = v.timezone_hour;
+ i.timezone_minute = v.timezone_minute;
+ }
+ };
+ }
+}
+
+#endif // TRAITS_HXX