From 00c758add3e11e93366df6c6c44a35be8cee9ffa Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 11 Sep 2012 13:55:46 +0200 Subject: Add support for mapping std::array to BLOB and char[16] to UUID types --- odb/mssql/traits.hxx | 233 ++++++++++++++++++++++++++++++++++++++++++++------- odb/mssql/traits.txx | 67 +++++++++++++++ 2 files changed, 268 insertions(+), 32 deletions(-) diff --git a/odb/mssql/traits.hxx b/odb/mssql/traits.hxx index 673016c..f31c38d 100644 --- a/odb/mssql/traits.hxx +++ b/odb/mssql/traits.hxx @@ -7,12 +7,18 @@ #include +#include // ODB_CXX11 + #include #include #include // std::size_t #include // std::memcpy, std::memset, std::strlen #include // std::wcslen +#ifdef ODB_CXX11 +# include +#endif + #ifdef _WIN32 typedef struct _GUID GUID; #endif @@ -633,13 +639,13 @@ namespace odb { }; - template - struct default_value_traits: c_string_value_traits + template + struct default_value_traits: c_string_value_traits { }; - template - struct default_value_traits: + template + struct default_value_traits: c_string_value_traits { }; @@ -731,14 +737,14 @@ namespace odb { }; - template - struct default_value_traits: + template + struct default_value_traits: c_string_long_value_traits { }; - template - struct default_value_traits: + template + struct default_value_traits: c_string_long_value_traits { }; @@ -852,14 +858,14 @@ namespace odb { }; - template - struct default_value_traits: + template + struct default_value_traits: c_wstring_value_traits { }; - template - struct default_value_traits: + template + struct default_value_traits: c_wstring_value_traits { }; @@ -1016,14 +1022,14 @@ namespace odb { }; - template - struct default_value_traits: + template + struct default_value_traits: c_wstring_long_value_traits<> { }; - template - struct default_value_traits: + template + struct default_value_traits: c_wstring_long_value_traits<> { }; @@ -1083,10 +1089,10 @@ namespace odb { }; - // char array (buffer) specialization for binary. + // C array (buffer) specialization for binary. // template - struct array_binary_value_traits + struct c_array_binary_value_traits { typedef C* value_type; typedef const C* query_type; @@ -1116,15 +1122,60 @@ namespace odb template struct default_value_traits: - array_binary_value_traits + c_array_binary_value_traits { }; template struct default_value_traits: + c_array_binary_value_traits + { + }; + +#ifdef ODB_CXX11 + // std::array (buffer) specialization for binary. + // + template + struct array_binary_value_traits + { + typedef std::array value_type; + typedef value_type query_type; + typedef char* image_type; + + static void + set_value (value_type& v, const char* b, std::size_t n, bool is_null) + { + if (!is_null) + std::memcpy (v.data (), b, n < N ? n : N); + else + std::memset (v.data (), 0, N); + } + + static void + set_image (char* b, + std::size_t c, + std::size_t& n, + bool& is_null, + const value_type& v) + { + is_null = false; + n = c > N ? N : c; + std::memcpy (b, v.data (), n); + } + }; + + template + struct default_value_traits, id_binary>: + array_binary_value_traits + { + }; + + template + struct default_value_traits, id_binary>: array_binary_value_traits { }; +#endif // std::vector (buffer) specialization for long_binary. // @@ -1226,10 +1277,10 @@ namespace odb std::size_t tmp_capacity); }; - // char array (buffer) specialization for long_binary. + // C array (buffer) specialization for long_binary. // template - struct array_long_binary_value_traits + struct c_array_long_binary_value_traits { typedef C* value_type; typedef const C* query_type; @@ -1277,15 +1328,78 @@ namespace odb template struct default_value_traits: - array_long_binary_value_traits + c_array_long_binary_value_traits { }; template struct default_value_traits: + c_array_long_binary_value_traits + { + }; + +#ifdef ODB_CXX11 + // std::array (buffer) specialization for long_binary. + // + template + struct array_long_binary_value_traits + { + typedef std::array value_type; + typedef value_type query_type; + typedef long_callback image_type; + + static void + set_value (value_type& v, + result_callback_type& cb, + void*& context) + { + cb = &result_callback; + context = v.data (); + } + + static void + set_image (param_callback_type& cb, + const void*& context, + bool& is_null, + const value_type& v) + { + is_null = false; + cb = ¶m_callback; + context = v.data (); + } + + static void + param_callback (const void* context, + std::size_t* position, + const void** buffer, + std::size_t* size, + chunk_type* chunk, + void* tmp_buffer, + std::size_t tmp_capacity); + + static void + result_callback (void* context, + std::size_t* position, + void** buffer, + std::size_t* size, + chunk_type chunk, + std::size_t size_left, + void* tmp_buffer, + std::size_t tmp_capacity); + }; + + template + struct default_value_traits, id_long_binary>: + array_long_binary_value_traits + { + }; + + template + struct default_value_traits, id_long_binary>: array_long_binary_value_traits { }; +#endif // GUID specialization for uniqueidentifier. // @@ -1315,6 +1429,33 @@ namespace odb }; #endif + // char[16] specialization for uniqueidentifier. + // + template <> + struct LIBODB_MSSQL_EXPORT default_value_traits + { + typedef char* value_type; + typedef const char* query_type; + typedef uniqueidentifier image_type; + + static void + set_value (char* const& v, const uniqueidentifier& i, bool is_null) + { + if (!is_null) + std::memcpy (v, &i, 16); + else + std::memset (v, 0, 16); + } + + static void + set_image (uniqueidentifier& i, bool& is_null, const char* v) + { + is_null = false; + std::memcpy (&i, v, 16); + } + }; + // unsigned long long specialization for rowversion. // template <> @@ -1444,7 +1585,7 @@ namespace odb static const database_type_id db_type_id = id_float8; }; - // String type. + // String types. // template <> struct default_type_traits @@ -1458,19 +1599,19 @@ namespace odb static const database_type_id db_type_id = id_long_string; }; - template - struct default_type_traits + template + struct default_type_traits { static const database_type_id db_type_id = id_long_string; }; - template - struct default_type_traits + template + struct default_type_traits { static const database_type_id db_type_id = id_long_string; }; - // Wide string type. + // Wide string types. // template <> struct default_type_traits @@ -1484,18 +1625,46 @@ namespace odb static const database_type_id db_type_id = id_long_nstring; }; - template - struct default_type_traits + template + struct default_type_traits { static const database_type_id db_type_id = id_long_nstring; }; - template - struct default_type_traits + template + struct default_type_traits { static const database_type_id db_type_id = id_long_nstring; }; + // Binary types. + // + template <> + struct default_type_traits > + { + static const database_type_id db_type_id = id_long_binary; + }; + + template <> + struct default_type_traits > + { + static const database_type_id db_type_id = id_long_binary; + }; + +#ifdef ODB_CXX11 + template + struct default_type_traits > + { + static const database_type_id db_type_id = id_long_binary; + }; + + template + struct default_type_traits > + { + static const database_type_id db_type_id = id_long_binary; + }; +#endif + // GUID. // #ifdef _WIN32 diff --git a/odb/mssql/traits.txx b/odb/mssql/traits.txx index f3ca176..634097e 100644 --- a/odb/mssql/traits.txx +++ b/odb/mssql/traits.txx @@ -52,6 +52,72 @@ namespace odb } // + // c_array_long_binary_value_traits + // + + template + void c_array_long_binary_value_traits:: + param_callback (const void* context, + std::size_t*, + const void** buffer, + std::size_t* size, + chunk_type* chunk, + void*, + std::size_t) + { + *buffer = context; + *size = N; + *chunk = chunk_one; + } + + template + void c_array_long_binary_value_traits:: + result_callback (void* context, + std::size_t*, + void** buffer, + std::size_t* size, + chunk_type chunk, + std::size_t size_left, + void* tmp_buf, + std::size_t tmp_capacity) + { + // The code is similar to the vector specialization. + // + switch (chunk) + { + case chunk_null: + case chunk_one: + { + std::memset (context, 0, N); + break; + } + case chunk_first: + { + assert (size_left != 0); + + *buffer = context; + *size = size_left < N ? size_left : N; + break; + } + case chunk_next: + { + // We can get here if total size is greater than N. There is + // no way to stop until we read all the data, so dump the + // remainder into the temporary buffer. + // + *buffer = tmp_buf; + *size = tmp_capacity; + break; + } + case chunk_last: + { + break; + } + } + } + +#ifdef ODB_CXX11 + // // array_long_binary_value_traits // @@ -115,5 +181,6 @@ namespace odb } } } +#endif } } -- cgit v1.1