aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-09-27 09:29:54 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-09-27 13:38:11 +0200
commit742cf0608bf8232cf2fc8392a0f70855b0316755 (patch)
tree6adacde0b07f484cbb0e8ab890d57bc5e67d72df
parent3eb25c0b2789aee57e006a92a25269b564789713 (diff)
Implement traits
-rw-r--r--odb/oracle/makefile1
-rw-r--r--odb/oracle/traits.cxx159
-rw-r--r--odb/oracle/traits.hxx975
3 files changed, 755 insertions, 380 deletions
diff --git a/odb/oracle/makefile b/odb/oracle/makefile
index 0725800..bd8d8cb 100644
--- a/odb/oracle/makefile
+++ b/odb/oracle/makefile
@@ -16,6 +16,7 @@ exceptions.cxx \
object-statements.cxx \
statement.cxx \
statements-base.cxx \
+traits.cxx \
transaction.cxx \
transaction-impl.cxx \
details/number.cxx
diff --git a/odb/oracle/traits.cxx b/odb/oracle/traits.cxx
index 16bfdee..6cf55c8 100644
--- a/odb/oracle/traits.cxx
+++ b/odb/oracle/traits.cxx
@@ -3,4 +3,163 @@
// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
// license : ODB NCUEL; see accompanying LICENSE file
+#include <cstddef> // std::size_t
+#include <cstring> // std::memcpy, std::strlen
+#include <cassert>
+
#include <odb/oracle/traits.hxx>
+
+using namespace std;
+
+namespace odb
+{
+ namespace oracle
+ {
+ //
+ // string_value_traits
+ //
+
+ void string_value_traits::
+ set_image (char* b,
+ size_t c,
+ size_t& n,
+ bool& is_null,
+ const string& v)
+ {
+ is_null = false;
+ n = v.size ();
+
+ assert (n <= c);
+
+ if (n != 0 && n <= c)
+ memcpy (b, v.c_str (), n);
+ }
+
+ //
+ // c_string_value_traits
+ //
+
+ void c_string_value_traits::
+ set_image (char* b,
+ size_t c,
+ size_t& n,
+ bool& is_null,
+ const char* v)
+ {
+ is_null = false;
+ n = strlen (v);
+
+ assert (n <= c);
+
+ if (n != 0 && n <= c)
+ memcpy (b, v, n);
+ }
+
+ //
+ // string_lob_value_traits
+ //
+
+ bool string_lob_value_traits::
+ param_callback (void* ctx,
+ ub4* pos_ctx,
+ void** b,
+ ub4* s,
+ chunk_position* p,
+ void* temp_b,
+ ub4 cap)
+ {
+ const string& v (*reinterpret_cast<string*> (ctx));
+
+ // @@ We rely on *pos_ctx == 0 for the first call. Make sure that this is
+ // set by the generated code, and update comment in oracle-types.hxx
+ // specifying that this is so.
+ //
+ *s = static_cast<ub4> (v.size ()) - *pos_ctx;
+
+ if (*s <= cap)
+ *p = *pos_ctx == 0 ? one_chunk : last_chunk;
+ else
+ {
+ *p = *pos_ctx == 0 ? first_chunk : next_chunk;
+ *s = cap;
+ *pos_ctx += *s;
+ }
+
+ *b = temp_b;
+ memcpy (temp_b, v.c_str () + *pos_ctx, *s);
+
+ return true;
+ }
+
+ //
+ // c_string_lob_value_traits
+ //
+
+ bool c_string_lob_value_traits::
+ param_callback (void* ctx,
+ ub4* pos_ctx,
+ void** b,
+ ub4* s,
+ chunk_position* p,
+ void* temp_b,
+ ub4 cap)
+ {
+ const char* v (reinterpret_cast<char*> (ctx));
+
+ // @@ We rely on *pos_ctx == 0 for the first call. Make sure that this is
+ // set by the generated code, and update comment in oracle-types.hxx
+ // specifying that this is so.
+ //
+ *s = static_cast<ub4> (strlen (v)) - *pos_ctx;
+
+ if (*s <= cap)
+ *p = *pos_ctx == 0 ? one_chunk : last_chunk;
+ else
+ {
+ *p = *pos_ctx == 0 ? first_chunk : next_chunk;
+ *s = cap;
+ *pos_ctx += *s;
+ }
+
+ *b = temp_b;
+ memcpy (temp_b, v + *pos_ctx, *s);
+
+ return true;
+ }
+
+ //
+ // default_value_traits<std::vector<char>, id_blob>
+ //
+ bool default_value_traits<std::vector<char>, id_blob>::
+ param_callback (void* ctx,
+ ub4* pos_ctx,
+ void** b,
+ ub4* s,
+ chunk_position* p,
+ void* temp_b,
+ ub4 cap)
+ {
+ const value_type& v (*reinterpret_cast<value_type*> (ctx));
+
+ // @@ We rely on *position_context == 0 for the first call. Make sure
+ // that this is set by the generated code and update the comment in
+ // oracle-types.hxx specifying that this is so.
+ //
+ *s = static_cast<ub4> (v.size ()) - *pos_ctx;
+
+ if (*s <= cap)
+ *p = *pos_ctx == 0 ? one_chunk : last_chunk;
+ else
+ {
+ *p = *pos_ctx == 0 ? first_chunk : next_chunk;
+ *s = cap;
+ *pos_ctx += *s;
+ }
+
+ *b = temp_b;
+ memcpy (temp_b, &v[*pos_ctx], *s);
+
+ return true;
+ }
+ }
+}
diff --git a/odb/oracle/traits.hxx b/odb/oracle/traits.hxx
index d3f006d..a05d74f 100644
--- a/odb/oracle/traits.hxx
+++ b/odb/oracle/traits.hxx
@@ -49,57 +49,152 @@ namespace odb
id_blob,
id_clob,
- id_nclob,
+ id_nclob
+ };
+
+ //
+ // int_traits
+ //
+
+ // Only mark fundamental unsigned integers as unsigned. In particular,
+ // treat enums as signed since in most cases and on most platforms the
+ // underlying integer type will be signed. On Windows with VC9 and up
+ // and with GCC, the __intN types are simply aliases for the respective
+ // standard integers so the below code will cover them as well. Also
+ // note that the ODB compiler performs a similar test, so if you change
+ // anything below you will probably also need to make a similar change
+ // there.
+ //
+ template <typename T>
+ struct int_traits {static const bool unsign = false;};
+
+ template <>
+ struct int_traits<bool> {static const bool unsign = true;};
+ template <>
+ struct int_traits<unsigned char> {static const bool unsign = true;};
+ template <>
+ struct int_traits<unsigned short> {static const bool unsign = true;};
+ template <>
+ struct int_traits<unsigned int> {static const bool unsign = true;};
+ template <>
+ struct int_traits<unsigned long> {static const bool unsign = true;};
+ template <>
+ struct int_traits<unsigned long long>
+ {
+ static const bool unsign = true;
};
//
// image_traits
//
- template <database_type_id>
+ template <typename T, database_type_id>
struct image_traits;
- template <>
- struct image_traits<id_int32> {typedef int image_type;};
+ // int32
+ //
+ template <bool unsign>
+ struct int32_image_traits;
template <>
- struct image_traits<id_int64> {typedef unsigned char[12] image_type;};
+ struct int32_image_traits<false>
+ {
+ typedef int image_type;
+ };
template <>
- struct image_traits<id_big_int> {typedef unsigned char[21] image_type;};
+ struct int32_image_traits<true>
+ {
+ typedef unsigned int image_type;
+ };
- template <>
- struct image_traits<id_float> {typedef float image_type;};
+ template <typename T>
+ struct image_traits<T, id_int32>: int32_image_traits<int_traits<T>::unsign>
+ {
+ };
- template <>
- struct image_traits<id_double> {typedef double image_type;};
+ // int64
+ //
+ template <bool unsign>
+ struct int64_image_traits;
template <>
- struct image_traits<id_big_float> {typedef unsigned char[21] image_type;};
+ struct int64_image_traits<false>
+ {
+ typedef long long image_type;
+ };
template <>
- struct image_traits<id_date> {typedef unsigned char[7] image_type;};
+ struct int64_image_traits<true>
+ {
+ typedef unsigned long long image_type;
+ };
- template <>
- struct image_traits<id_timestamp> {typedef unsigned char* image_type;};
+ template <typename T>
+ struct image_traits<T, id_int64>: int64_image_traits<int_traits<T>::unsign>
+ {
+ };
- template <>
- struct image_traits<id_string> {typedef char* image_type;};
+ // big_int
+ //
+ template <typename T>
+ struct image_traits<T, id_big_int>
+ {
+ // Image is a buffer containing native OCI NUMBER representation.
+ //
+ typedef char* image_type;
+ };
- template <>
- struct image_traits<id_nstring> {typedef char* image_type;};
+ template <typename T>
+ struct image_traits<T, id_float> {typedef float image_type;};
- template <>
- struct image_traits<id_raw> {typedef char* image_type;};
+ template <typename T>
+ struct image_traits<T, id_double> {typedef double image_type;};
- template <>
- struct image_traits<id_blob> {typedef lob_callback image_type;};
+ template <typename T>
+ struct image_traits<T, id_big_float>
+ {
+ // Image is a buffer containing the native OCI NUMBER representation.
+ //
+ typedef char* image_type;
+ };
- template <>
- struct image_traits<id_clob> {typedef lob_callback image_type;};
+ template <typename T>
+ struct image_traits<T, id_date>
+ {
+ // Image is a buffer containing the native OCI DATE representation. This
+ // buffer has a fixed length of 7 bytes.
+ //
+ typedef char* image_type;
+ };
- template <>
- struct image_traits<id_nclob> {typedef lob_callback image_type;};
+ template <typename T>
+ struct image_traits<T, id_timestamp>
+ {
+ // Image is a buffer containing the native OCI TIMESTAMP representation.
+ // This buffer has varying length, depending on the microsecond
+ // precision of the TIMESTAMP value.
+ //
+ typedef char* image_type;
+ };
+
+ template <typename T>
+ struct image_traits<T, id_string> {typedef char* image_type;};
+
+ template <typename T>
+ struct image_traits<T, id_nstring> {typedef char* image_type;};
+
+ template <typename T>
+ struct image_traits<T, id_raw> {typedef char* image_type;};
+
+ template <typename T>
+ struct image_traits<T, id_blob> {typedef lob_callback image_type;};
+
+ template <typename T>
+ struct image_traits<T, id_clob> {typedef lob_callback image_type;};
+
+ template <typename T>
+ struct image_traits<T, id_nclob> {typedef lob_callback image_type;};
//
// value_traits
@@ -114,360 +209,480 @@ namespace odb
template <typename T, database_type_id, bool w = details::wrapper_p<T>::r>
struct select_traits;
- // template <typename T, database_type_id ID>
- // struct select_traits<T, ID, false>
- // {
- // typedef default_value_traits<T, ID> type;
- // };
-
- // template <typename W, database_type_id ID>
- // struct select_traits<W, ID, true>
- // {
- // typedef
- // wrapped_value_traits<W, ID, wrapper_traits<W>::null_handler>
- // type;
- // };
-
- // template <typename T, database_type_id ID>
- // class value_traits: public select_traits<T, ID>::type
- // {
- // };
-
- // // The wrapped_value_traits specializations should be able to handle
- // // any value type which means we have to have every possible signature
- // // of the set_value() and set_image() functions.
- // //
- // template <typename W, database_type_id ID>
- // struct wrapped_value_traits<W, ID, false>
- // {
- // typedef wrapper_traits<W> wtraits;
- // typedef typename wtraits::wrapped_type wrapped_type;
-
- // typedef W value_type;
- // typedef wrapped_type query_type;
- // typedef typename image_traits<ID>::image_type image_type;
-
- // typedef value_traits<wrapped_type, ID> vtraits;
-
- // static void
- // set_value (W& v, const image_type& i, bool is_null)
- // {
- // vtraits::set_value (wtraits::set_ref (v), i, is_null);
- // }
-
- // static void
- // set_image (image_type& i, bool& is_null, const W& v)
- // {
- // vtraits::set_image (i, is_null, wtraits::get_ref (v));
- // }
-
- // // String, BLOB, ENUM, and SET.
- // //
- // static void
- // set_value (W& v, const details::buffer& b, std::size_t n, bool is_null)
- // {
- // vtraits::set_value (wtraits::set_ref (v), b, n, is_null);
- // }
-
- // static void
- // set_image (details::buffer& b, std::size_t& n, bool& is_null, const W& v)
- // {
- // vtraits::set_image (b, n, is_null, wtraits::get_ref (v));
- // }
-
- // // BIT.
- // //
- // static void
- // set_value (W& v, const unsigned char* i, std::size_t n, bool is_null)
- // {
- // vtraits::set_value (wtraits::set_ref (v), i, n, is_null);
- // }
-
- // static void
- // set_image (unsigned char* i,
- // std::size_t c,
- // std::size_t& n,
- // bool& is_null,
- // const W& v)
- // {
- // vtraits::set_image (i, c, n, is_null, wtraits::get_ref (v));
- // }
- // };
-
- // template <typename W, database_type_id ID>
- // struct wrapped_value_traits<W, ID, true>
- // {
- // typedef wrapper_traits<W> wtraits;
- // typedef typename wtraits::wrapped_type wrapped_type;
-
- // typedef W value_type;
- // typedef wrapped_type query_type;
- // typedef typename image_traits<ID>::image_type image_type;
-
- // typedef value_traits<wrapped_type, ID> vtraits;
-
- // static void
- // set_value (W& v, const image_type& i, bool is_null)
- // {
- // if (is_null)
- // wtraits::set_null (v);
- // else
- // vtraits::set_value (wtraits::set_ref (v), i, is_null);
- // }
-
- // static void
- // set_image (image_type& i, bool& is_null, const W& v)
- // {
- // is_null = wtraits::get_null (v);
-
- // if (!is_null)
- // vtraits::set_image (i, is_null, wtraits::get_ref (v));
- // }
-
- // // String, BLOB, ENUM, and SET.
- // //
- // static void
- // set_value (W& v, const details::buffer& b, std::size_t n, bool is_null)
- // {
- // if (is_null)
- // wtraits::set_null (v);
- // else
- // vtraits::set_value (wtraits::set_ref (v), b, n, is_null);
- // }
-
- // static void
- // set_image (details::buffer& b, std::size_t& n, bool& is_null, const W& v)
- // {
- // is_null = wtraits::get_null (v);
-
- // if (!is_null)
- // vtraits::set_image (b, n, is_null, wtraits::get_ref (v));
- // }
-
- // // BIT.
- // //
- // static void
- // set_value (W& v, const unsigned char* i, std::size_t n, bool is_null)
- // {
- // if (is_null)
- // wtraits::set_null (v);
- // else
- // vtraits::set_value (wtraits::set_ref (v), i, n, is_null);
- // }
-
- // static void
- // set_image (unsigned char* i,
- // std::size_t c,
- // std::size_t& n,
- // bool& is_null,
- // const W& v)
- // {
- // is_null = wtraits::get_null (v);
-
- // if (!is_null)
- // vtraits::set_image (i, c, n, is_null, wtraits::get_ref (v));
- // }
- // };
-
- // template <typename T, database_type_id ID>
- // struct default_value_traits
- // {
- // typedef T value_type;
- // typedef T query_type;
- // typedef typename image_traits<ID>::image_type image_type;
-
- // static void
- // set_value (T& v, const image_type& i, bool is_null)
- // {
- // if (!is_null)
- // v = T (i);
- // else
- // v = T ();
- // }
-
- // static void
- // set_image (image_type& i, bool& is_null, T v)
- // {
- // is_null = false;
- // i = image_type (v);
- // }
- // };
-
- // // Specialization for numeric enum representations (C++ enum, integer
- // // types, etc). In particular, this specialization works only for C++
- // // enum type as long as its numeric value space starts with 0, is
- // // ascending and contiguous (i.e., the default enumerator assignment).
- // //
- // template <typename T>
- // struct default_value_traits<T, id_enum>
- // {
- // typedef T value_type;
- // typedef T query_type;
- // typedef unsigned short image_type;
-
- // static void
- // set_value (T& v, unsigned short i, bool is_null)
- // {
- // // In MySQL first enumerator has index 1.
- // //
- // if (!is_null)
- // v = static_cast<T> (i - 1);
- // else
- // v = T ();
- // }
-
- // static void
- // set_image (unsigned short& i, bool& is_null, const T& v)
- // {
- // is_null = false;
- // i = static_cast<unsigned short> (v) + 1;
- // }
- // };
-
- // // std::string specialization.
- // //
- // class LIBODB_MYSQL_EXPORT string_value_traits
- // {
- // public:
- // typedef std::string value_type;
- // typedef std::string query_type;
- // typedef details::buffer image_type;
-
- // static void
- // set_value (std::string& v,
- // const details::buffer& b,
- // std::size_t n,
- // bool is_null)
- // {
- // if (!is_null)
- // v.assign (b.data (), n);
- // else
- // v.erase ();
- // }
-
- // static void
- // set_image (details::buffer&,
- // std::size_t& n,
- // bool& is_null,
- // const std::string&);
- // };
-
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<std::string, id_string>:
- // string_value_traits
- // {
- // };
-
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<std::string, id_decimal>:
- // string_value_traits
- // {
- // };
-
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<std::string, id_enum>:
- // string_value_traits
- // {
- // };
-
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<std::string, id_set>:
- // string_value_traits
- // {
- // };
-
- // // const char* specialization
- // //
- // // Specialization for const char* which only supports initialization
- // // of an image from the value but not the other way around. This way
- // // we can pass such values to the queries.
- // //
- // class LIBODB_MYSQL_EXPORT c_string_value_traits
- // {
- // public:
- // typedef const char* value_type;
- // typedef const char* query_type;
- // typedef details::buffer image_type;
-
- // static void
- // set_image (details::buffer&,
- // std::size_t& n,
- // bool& is_null,
- // const char*);
- // };
-
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<const char*, id_string>:
- // c_string_value_traits
- // {
- // };
-
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<const char*, id_decimal>:
- // c_string_value_traits
- // {
- // };
-
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<const char*, id_enum>:
- // c_string_value_traits
- // {
- // };
-
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<const char*, id_set>:
- // 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<char[n], id_decimal>: c_string_value_traits
- // {
- // };
-
- // template <std::size_t n>
- // struct default_value_traits<char[n], id_enum>: c_string_value_traits
- // {
- // };
-
- // template <std::size_t n>
- // struct default_value_traits<char[n], id_set>: c_string_value_traits
- // {
- // };
-
- // // std::vector<char> (buffer) specialization.
- // //
- // template <>
- // struct LIBODB_MYSQL_EXPORT default_value_traits<std::vector<char>, id_blob>
- // {
- // public:
- // typedef std::vector<char> value_type;
- // typedef std::vector<char> query_type;
- // typedef details::buffer image_type;
-
- // static void
- // set_value (value_type& v,
- // const details::buffer& b,
- // std::size_t n,
- // bool is_null)
- // {
- // if (!is_null)
- // v.assign (b.data (), b.data () + n);
- // else
- // v.clear ();
- // }
-
- // static void
- // set_image (details::buffer&,
- // std::size_t& n,
- // bool& is_null,
- // const value_type&);
- // };
+ template <typename T, database_type_id ID>
+ struct select_traits<T, ID, false>
+ {
+ typedef default_value_traits<T, ID> type;
+ };
+
+ template <typename W, database_type_id ID>
+ struct select_traits<W, ID, true>
+ {
+ typedef
+ wrapped_value_traits<W, ID, wrapper_traits<W>::null_handler>
+ type;
+ };
+
+ template <typename T, database_type_id ID>
+ class value_traits: public select_traits<T, ID>::type
+ {
+ };
+
+ // The wrapped_value_traits specializations should be able to handle
+ // any value type which means we have to have every possible signature
+ // of the set_value() and set_image() functions.
+ //
+ template <typename W, database_type_id ID>
+ struct wrapped_value_traits<W, ID, false>
+ {
+ typedef wrapper_traits<W> wtraits;
+ typedef typename wtraits::wrapped_type wrapped_type;
+
+ typedef W value_type;
+ typedef wrapped_type query_type;
+ typedef typename image_traits<wrapped_type, ID>::image_type image_type;
+
+ typedef value_traits<wrapped_type, ID> vtraits;
+
+ static void
+ set_value (W& v, const image_type& i, bool is_null)
+ {
+ vtraits::set_value (wtraits::set_ref (v), i, is_null);
+ }
+
+ static void
+ set_image (image_type& i, bool& is_null, const W& v)
+ {
+ vtraits::set_image (i, is_null, wtraits::get_ref (v));
+ }
+
+ // big_int, big_float, timestamp, string, nstring, raw.
+ //
+ static void
+ set_value (W& v, const char* i, std::size_t n, bool is_null)
+ {
+ vtraits::set_value (wtraits::set_ref (v), i, n, is_null);
+ }
+
+ static void
+ set_image (char* i,
+ std::size_t c,
+ std::size_t& n,
+ bool& is_null,
+ const W& v)
+ {
+ vtraits::set_image (i, c, n, is_null, wtraits::get_ref (v));
+ }
+
+ // blob, clob, nclob.
+ //
+ static void
+ set_value (W& v, result_callback_type& cb, void*& context, bool is_null)
+ {
+ vtraits::set_value (wtraits::set_ref (v), cb, context, is_null);
+ }
+
+ static void
+ set_image (param_callback_type& cb,
+ void*& context,
+ bool& is_null,
+ const W& v)
+ {
+ vtraits::set_image (cb, context, is_null, wtraits::get_ref (v));
+ }
+ };
+
+ template <typename W, database_type_id ID>
+ struct wrapped_value_traits<W, ID, true>
+ {
+ typedef wrapper_traits<W> wtraits;
+ typedef typename wtraits::wrapped_type wrapped_type;
+
+ typedef W value_type;
+ typedef wrapped_type query_type;
+ typedef typename image_traits<wrapped_type, ID>::image_type image_type;
+
+ typedef value_traits<wrapped_type, ID> vtraits;
+
+ static void
+ set_value (W& v, const image_type& i, bool is_null)
+ {
+ if (is_null)
+ wtraits::set_null (v);
+ else
+ vtraits::set_value (wtraits::set_ref (v), i, is_null);
+ }
+
+ static void
+ set_image (image_type& i, bool& is_null, const W& v)
+ {
+ is_null = wtraits::get_null (v);
+
+ if (!is_null)
+ vtraits::set_image (i, is_null, wtraits::get_ref (v));
+ }
+
+ // big_int, big_float, timestamp, string, nstring, raw.
+ //
+ static void
+ set_value (W& v, const char* i, std::size_t n, bool is_null)
+ {
+ if (is_null)
+ wtraits::set_null (v);
+ else
+ vtraits::set_value (wtraits::set_ref (v), i, n, is_null);
+ }
+
+ static void
+ set_image (char* i,
+ std::size_t c,
+ std::size_t& n,
+ bool& is_null,
+ const W& v)
+ {
+ is_null = wtraits::get_null (v);
+
+ if (!is_null)
+ vtraits::set_image (i, c, n, is_null, wtraits::get_ref (v));
+ }
+
+ // blob, clob, nclob.
+ //
+ static void
+ set_value (W& v, result_callback_type& cb, void*& context, bool is_null)
+ {
+ if (is_null)
+ wtraits::set_null (v);
+ else
+ vtraits::set_value (wtraits::set_ref (v), cb, context, is_null);
+ }
+
+ static void
+ set_image (param_callback_type& cb,
+ void*& context,
+ bool& is_null,
+ const W& v)
+ {
+ is_null = wtraits::get_null (v);
+
+ if (!is_null)
+ vtraits::set_image (cb, context, is_null, wtraits::get_ref (v));
+ }
+ };
+
+ template <typename T, database_type_id ID>
+ struct default_value_traits
+ {
+ typedef T value_type;
+ typedef T query_type;
+ typedef typename image_traits<T, ID>::image_type image_type;
+
+ static void
+ set_value (T& v, const image_type& i, bool is_null)
+ {
+ if (!is_null)
+ v = T (i);
+ else
+ v = T ();
+ }
+
+ static void
+ set_image (image_type& i, bool& is_null, T v)
+ {
+ is_null = false;
+ i = image_type (v);
+ }
+ };
+
+ // std::string specialization.
+ //
+ class LIBODB_ORACLE_EXPORT string_value_traits
+ {
+ public:
+ typedef std::string value_type;
+ typedef std::string query_type;
+ typedef char* image_type;
+
+ static void
+ set_value (std::string& v,
+ const char* b,
+ std::size_t n,
+ bool is_null)
+ {
+ if (!is_null)
+ v.assign (b, n);
+ else
+ v.erase ();
+ }
+
+ static void
+ set_image (char*,
+ std::size_t c,
+ std::size_t& n,
+ bool& is_null,
+ const std::string&);
+ };
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<std::string, id_string>:
+ string_value_traits
+ {
+ };
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<std::string, id_nstring>:
+ string_value_traits
+ {
+ };
+
+ // const char* specialization.
+ //
+ // Specialization for const char* which only supports initialization
+ // of an image from the value but not the other way around. This way
+ // we can pass such values to the queries.
+ //
+ class LIBODB_ORACLE_EXPORT c_string_value_traits
+ {
+ public:
+ typedef const char* value_type;
+ typedef const char* query_type;
+ typedef char* image_type;
+
+ static void
+ set_image (char*,
+ std::size_t c,
+ std::size_t& n,
+ bool& is_null,
+ const char*);
+ };
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<const char*, id_string>:
+ c_string_value_traits
+ {
+ };
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<const char*, id_nstring>:
+ 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<char[n], id_nstring>: c_string_value_traits
+ {
+ };
+
+ // std::string specialization for LOBs.
+ //
+ class string_lob_value_traits
+ {
+ public:
+ typedef std::string value_type;
+ typedef std::string query_type;
+ typedef lob_callback image_type;
+
+ static void
+ set_value (std::string& v,
+ result_callback_type& cb,
+ void*& context,
+ bool is_null)
+ {
+ if (!is_null)
+ {
+ cb = &result_callback;
+ context = &v;
+ }
+ else
+ v.erase ();
+ }
+
+ static void
+ set_image (param_callback_type& cb,
+ void*& context,
+ bool& is_null,
+ const std::string& v)
+ {
+ is_null = false;
+ cb = &param_callback;
+ context = const_cast<std::string*> (&v);
+ }
+
+ static bool
+ result_callback (void* context, void* buffer, ub4 size, chunk_position p)
+ {
+ std::string& v (*reinterpret_cast<std::string*> (context));
+
+ switch (p)
+ {
+ case one_chunk:
+ case first_chunk:
+ {
+ v.clear ();
+ }
+ case next_chunk:
+ case last_chunk:
+ {
+ v.append (reinterpret_cast<char*> (buffer), size);
+ }
+ }
+
+ return true;
+ }
+
+ static bool
+ param_callback (void* context,
+ ub4* position_context,
+ void** buffer,
+ ub4* size,
+ chunk_position*,
+ void* temp_buffer,
+ ub4 capacity);
+ };
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<std::string, id_clob>:
+ string_lob_value_traits
+ {
+ };
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<std::string, id_nclob>:
+ string_lob_value_traits
+ {
+ };
+
+ // const char* specialization for LOBs.
+ //
+ // Specialization for const char* which only supports initialization
+ // of an image from the value but not the other way around. This way
+ // we can such values to the queries.
+ //
+ class c_string_lob_value_traits
+ {
+ public:
+ typedef const char* value_type;
+ typedef const char* query_type;
+ typedef lob_callback image_type;
+
+ static void
+ set_image (param_callback_type& cb,
+ void*& context,
+ bool& is_null,
+ const char* v)
+ {
+ is_null = false;
+ cb = &param_callback;
+ context = const_cast<char*> (v);
+ }
+
+ static bool
+ param_callback (void* context,
+ ub4* position_context,
+ void** buffer,
+ ub4* size,
+ chunk_position*,
+ void* temp_buffer,
+ ub4 capacity);
+ };
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<const char*, id_clob>:
+ c_string_lob_value_traits
+ {
+ };
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<const char*, id_nclob>:
+ c_string_lob_value_traits
+ {
+ };
+
+ template <std::size_t n>
+ struct default_value_traits<char[n], id_clob>:
+ c_string_lob_value_traits
+ {
+ };
+
+ template <std::size_t n>
+ struct default_value_traits<char[n], id_nclob>:
+ c_string_lob_value_traits
+ {
+ };
+
+ // std::vector<char> (buffer) specialization.
+ //
+ template <>
+ struct default_value_traits<std::vector<char>, id_blob>
+ {
+ public:
+ typedef std::vector<char> value_type;
+ typedef std::vector<char> query_type;
+ typedef lob_callback image_type;
+
+ static void
+ set_value (value_type& v,
+ result_callback_type& cb,
+ void*& context,
+ bool is_null)
+ {
+ if (!is_null)
+ {
+ cb = &result_callback;
+ context = &v;
+ }
+ else
+ v.clear ();
+ }
+
+ static void
+ set_image (param_callback_type& cb,
+ void*& context,
+ bool& is_null,
+ const value_type& v)
+ {
+ is_null = false;
+ cb = &param_callback;
+ context = const_cast<value_type*> (&v);
+ }
+
+ static bool
+ result_callback (void* context, void* buffer, ub4 size, chunk_position p)
+ {
+ value_type& v (*reinterpret_cast<value_type*> (context));
+
+ switch (p)
+ {
+ case one_chunk:
+ case first_chunk:
+ {
+ v.clear ();
+ }
+ case next_chunk:
+ case last_chunk:
+ {
+ char* b (reinterpret_cast<char*> (buffer));
+ v.insert (v.end (), b, b + size);
+ }
+ }
+
+ return true;
+ }
+
+ static bool
+ param_callback (void* context,
+ ub4* position_context,
+ void** buffer,
+ ub4* size,
+ chunk_position*,
+ void* temp_buffer,
+ ub4 capacity);
+ };
//
// type_traits