aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-09-11 13:55:46 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-09-11 13:55:46 +0200
commit00c758add3e11e93366df6c6c44a35be8cee9ffa (patch)
tree7ca5829294c23a9fff9a2d708aa5fb8f94ef9ba4
parent729dfc53117b56115a39890899ea5e0be0cc3560 (diff)
Add support for mapping std::array to BLOB and char[16] to UUID types
-rw-r--r--odb/mssql/traits.hxx233
-rw-r--r--odb/mssql/traits.txx67
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 <odb/pre.hxx>
+#include <odb/details/config.hxx> // ODB_CXX11
+
#include <string>
#include <vector>
#include <cstddef> // std::size_t
#include <cstring> // std::memcpy, std::memset, std::strlen
#include <cwchar> // std::wcslen
+#ifdef ODB_CXX11
+# include <array>
+#endif
+
#ifdef _WIN32
typedef struct _GUID GUID;
#endif
@@ -633,13 +639,13 @@ namespace odb
{
};
- template <std::size_t n>
- struct default_value_traits<char[n], id_string>: c_string_value_traits
+ template <std::size_t N>
+ struct default_value_traits<char[N], id_string>: c_string_value_traits
{
};
- template <std::size_t n>
- struct default_value_traits<const char[n], id_string>:
+ template <std::size_t N>
+ struct default_value_traits<const char[N], id_string>:
c_string_value_traits
{
};
@@ -731,14 +737,14 @@ namespace odb
{
};
- template <std::size_t n>
- struct default_value_traits<char[n], id_long_string>:
+ template <std::size_t N>
+ struct default_value_traits<char[N], id_long_string>:
c_string_long_value_traits
{
};
- template <std::size_t n>
- struct default_value_traits<const char[n], id_long_string>:
+ template <std::size_t N>
+ struct default_value_traits<const char[N], id_long_string>:
c_string_long_value_traits
{
};
@@ -852,14 +858,14 @@ namespace odb
{
};
- template <std::size_t n>
- struct default_value_traits<wchar_t[n], id_nstring>:
+ template <std::size_t N>
+ struct default_value_traits<wchar_t[N], id_nstring>:
c_wstring_value_traits
{
};
- template <std::size_t n>
- struct default_value_traits<const wchar_t[n], id_nstring>:
+ template <std::size_t N>
+ struct default_value_traits<const wchar_t[N], id_nstring>:
c_wstring_value_traits
{
};
@@ -1016,14 +1022,14 @@ namespace odb
{
};
- template <std::size_t n>
- struct default_value_traits<wchar_t[n], id_long_nstring>:
+ template <std::size_t N>
+ struct default_value_traits<wchar_t[N], id_long_nstring>:
c_wstring_long_value_traits<>
{
};
- template <std::size_t n>
- struct default_value_traits<const wchar_t[n], id_long_nstring>:
+ template <std::size_t N>
+ struct default_value_traits<const wchar_t[N], id_long_nstring>:
c_wstring_long_value_traits<>
{
};
@@ -1083,10 +1089,10 @@ namespace odb
{
};
- // char array (buffer) specialization for binary.
+ // C array (buffer) specialization for binary.
//
template <typename C, std::size_t N>
- 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 <std::size_t N>
struct default_value_traits<char[N], id_binary>:
- array_binary_value_traits<char, N>
+ c_array_binary_value_traits<char, N>
{
};
template <std::size_t N>
struct default_value_traits<unsigned char[N], id_binary>:
+ c_array_binary_value_traits<unsigned char, N>
+ {
+ };
+
+#ifdef ODB_CXX11
+ // std::array (buffer) specialization for binary.
+ //
+ template <typename C, std::size_t N>
+ struct array_binary_value_traits
+ {
+ typedef std::array<C, N> 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 <std::size_t N>
+ struct default_value_traits<std::array<char, N>, id_binary>:
+ array_binary_value_traits<char, N>
+ {
+ };
+
+ template <std::size_t N>
+ struct default_value_traits<std::array<unsigned char, N>, id_binary>:
array_binary_value_traits<unsigned char, N>
{
};
+#endif
// std::vector<char> (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 <typename C, std::size_t N>
- 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 <std::size_t N>
struct default_value_traits<char[N], id_long_binary>:
- array_long_binary_value_traits<char, N>
+ c_array_long_binary_value_traits<char, N>
{
};
template <std::size_t N>
struct default_value_traits<unsigned char[N], id_long_binary>:
+ c_array_long_binary_value_traits<unsigned char, N>
+ {
+ };
+
+#ifdef ODB_CXX11
+ // std::array (buffer) specialization for long_binary.
+ //
+ template <typename C, std::size_t N>
+ struct array_long_binary_value_traits
+ {
+ typedef std::array<C, N> 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 = &param_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 <std::size_t N>
+ struct default_value_traits<std::array<char, N>, id_long_binary>:
+ array_long_binary_value_traits<char, N>
+ {
+ };
+
+ template <std::size_t N>
+ struct default_value_traits<std::array<unsigned char, N>, id_long_binary>:
array_long_binary_value_traits<unsigned char, N>
{
};
+#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<char[16],
+ id_uniqueidentifier>
+ {
+ 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<std::string>
@@ -1458,19 +1599,19 @@ namespace odb
static const database_type_id db_type_id = id_long_string;
};
- template <std::size_t n>
- struct default_type_traits<char[n]>
+ template <std::size_t N>
+ struct default_type_traits<char[N]>
{
static const database_type_id db_type_id = id_long_string;
};
- template <std::size_t n>
- struct default_type_traits<const char[n]>
+ template <std::size_t N>
+ struct default_type_traits<const char[N]>
{
static const database_type_id db_type_id = id_long_string;
};
- // Wide string type.
+ // Wide string types.
//
template <>
struct default_type_traits<std::wstring>
@@ -1484,18 +1625,46 @@ namespace odb
static const database_type_id db_type_id = id_long_nstring;
};
- template <std::size_t n>
- struct default_type_traits<wchar_t[n]>
+ template <std::size_t N>
+ struct default_type_traits<wchar_t[N]>
{
static const database_type_id db_type_id = id_long_nstring;
};
- template <std::size_t n>
- struct default_type_traits<const wchar_t[n]>
+ template <std::size_t N>
+ struct default_type_traits<const wchar_t[N]>
{
static const database_type_id db_type_id = id_long_nstring;
};
+ // Binary types.
+ //
+ template <>
+ struct default_type_traits<std::vector<char> >
+ {
+ static const database_type_id db_type_id = id_long_binary;
+ };
+
+ template <>
+ struct default_type_traits<std::vector<unsigned char> >
+ {
+ static const database_type_id db_type_id = id_long_binary;
+ };
+
+#ifdef ODB_CXX11
+ template <std::size_t N>
+ struct default_type_traits<std::array<char, N> >
+ {
+ static const database_type_id db_type_id = id_long_binary;
+ };
+
+ template <std::size_t N>
+ struct default_type_traits<std::array<unsigned char, N> >
+ {
+ 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 <typename C, std::size_t N>
+ void c_array_long_binary_value_traits<C, N>::
+ 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 <typename C, std::size_t N>
+ void c_array_long_binary_value_traits<C, N>::
+ 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<char> 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
}
}