aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-09-23 11:22:06 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-09-23 11:22:06 +0200
commit0198441b5e7d3ed5f9307d400feca87cc63ad1a6 (patch)
treeb5efa498be39221336aa0952adddf3c3eda209a3
parent992ec5b8a4f22204c935c5072c6ba4de0018959a (diff)
Add traits implementation
-rw-r--r--odb/oracle/traits.cxx138
-rw-r--r--odb/oracle/traits.hxx590
2 files changed, 728 insertions, 0 deletions
diff --git a/odb/oracle/traits.cxx b/odb/oracle/traits.cxx
new file mode 100644
index 0000000..c842755
--- /dev/null
+++ b/odb/oracle/traits.cxx
@@ -0,0 +1,138 @@
+// file : odb/oracle/traits.cxx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#include <cmath>
+#include <deque>
+
+#include <odb/oracle/traits.hxx>
+
+namespace odb
+{
+ namespace oracle
+ {
+ long long
+ out (unsigned char const* n)
+ {
+ // The first byte specifies the length of the number representation,
+ // including the exponent byte and significant digits but not the length
+ // itself.
+ //
+ int len (n[0]);
+
+ if (len == 1)
+ return 0;
+
+ long long v (0);
+ if (n[1] & 0x80)
+ {
+ // The exponent of a positive number is calculated as n[1] - 193.
+ // The base-100 exponent of the least significant digit can be
+ // calculated as exp - sig - 1, where sig is the number of significant
+ // digits. sig may be calculated as len - 2.
+ //
+ int exp (n[1] - 191 - len);
+
+ for (unsigned char const* m (n + len), *e (n + 1); m > e; --m, ++exp)
+ v += (*m - 1) * pow (100, exp);
+ }
+ else
+ {
+ // The exponent of a negative number is calculated as ~n[1] - 193.
+ // The base-100 exponent of the least significant digit can be
+ // calculated as exp - sig - 1, where sig is the number of significant
+ // digits. sig may be calculated as len - 2.
+ //
+ int exp (~n[1] - 190 - len);
+
+ for (unsigned char const* m (n + len - 1), *e (n + 1); m > e;
+ --m, ++exp)
+ v -= (101 - *m) * pow (100, exp);
+ }
+
+ return v;
+ }
+
+ void
+ in (unsigned char b[22], long long n)
+ {
+ if (n == 0)
+ {
+ b[0] = 1;
+ b[1] = 128;
+
+ return;
+ }
+
+ // @@ Is there some sort of reserve() implementation for deque?
+ //
+ deque<unsigned char> s;
+
+ bool sig (false);
+ size_t c (0);
+ unsigned char exp (0);
+
+ if (n < 0)
+ {
+ // Termination marker for negative numbers.
+ //
+ s.push_front (102);
+
+ while (n != 0)
+ {
+ int v (static_cast<int> (n % 100));
+ sig = sig ? true : v != 0;
+
+ if (sig)
+ s.push_front (static_cast<unsigned char> (101 + v));
+
+ n /= 100;
+ ++c;
+ }
+
+ // The exponent is one less than the number of base 100 digits. It is
+ // inverted for negative values.
+ //
+ exp = static_cast<unsigned char> (~(c + 192));
+ }
+ else
+ {
+ while (n != 0)
+ {
+ int v (static_cast<int> (n % 100));
+ sig = sig ? true : v != 0;
+
+ if (sig)
+ s.push_front (static_cast<unsigned char> (v + 1));
+
+ n /= 100;
+ ++c;
+ }
+
+ // Exponent is one less than the number of base 100 digits.
+ //
+ exp = static_cast<unsigned char> (c + 192);
+ }
+
+ // Set the length.
+ //
+ b[0] = static_cast<unsigned char> (s.size () + 1);
+
+ // Set the exponent.
+ //
+ b[1] = exp;
+
+ // Set the significant digits (big-endian byte order) and the terminator,
+ // if any.
+ //
+ c = 2;
+ while (!s.empty ())
+ {
+ b[i] = s.front ();
+ s.pop_front ();
+ ++c;
+ }
+ }
+ }
+}
diff --git a/odb/oracle/traits.hxx b/odb/oracle/traits.hxx
new file mode 100644
index 0000000..532f091
--- /dev/null
+++ b/odb/oracle/traits.hxx
@@ -0,0 +1,590 @@
+// file : odb/oracle/traits.hxx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_ORACLE_TRAITS_HXX
+#define ODB_ORACLE_TRAITS_HXX
+
+#include <odb/pre.hxx>
+
+#include <string>
+#include <vector>
+#include <cstddef> // std::size_t
+
+#include <odb/traits.hxx>
+#include <odb/wrapper-traits.hxx>
+
+#include <odb/oracle/version.hxx>
+#include <odb/oracle/oracle-types.hxx>
+
+#include <odb/details/buffer.hxx>
+#include <odb/details/wrapper-p.hxx>
+
+#include <odb/oracle/details/export.hxx>
+
+namespace odb
+{
+ namespace oracle
+ {
+ enum database_type_id
+ {
+ id_int32,
+ id_int64,
+
+ id_big_int,
+
+ id_float,
+ id_double,
+
+ id_big_float,
+
+ id_date,
+ id_timestamp,
+
+ id_string,
+ id_nstring,
+
+ id_raw,
+
+ id_blob,
+ id_clob,
+ id_nclob,
+ };
+
+ //
+ // image_traits
+ //
+
+ template <database_type_id>
+ struct image_traits;
+
+ template <>
+ struct image_traits<id_int32> {typedef int image_type;};
+
+ template <>
+ struct image_traits<id_int64> {typedef long long image_type;};
+
+ template <>
+ struct image_traits<id_big_int> {typedef unsigned char[21] image_type;};
+
+ template <>
+ struct image_traits<id_float> {typedef float image_type;};
+
+ template <>
+ struct image_traits<id_double> {typedef double image_type;};
+
+ template <>
+ struct image_traits<id_big_float> {typedef unsigned char[21] image_type;};
+
+ template <>
+ struct image_traits<id_date> {typedef unsigned char[7] image_type;};
+
+ template <>
+ struct image_traits<id_timestamp> {typedef unsigned char* image_type;};
+
+ template <>
+ struct image_traits<id_string> {typedef char* image_type;};
+
+ template <>
+ struct image_traits<id_nstring> {typedef char* image_type;};
+
+ template <>
+ struct image_traits<id_raw> {typedef char* image_type;};
+
+ template <>
+ struct image_traits<id_blob> {typedef lob_callback image_type;};
+
+ template <>
+ struct image_traits<id_clob> {typedef lob_callback image_type;};
+
+ template <>
+ struct image_traits<id_nclob> {typedef lob_callback image_type;};
+
+ //
+ // value_traits
+ //
+
+ template <typename W, database_type_id, bool null_handler>
+ struct wrapped_value_traits;
+
+ template <typename T, database_type_id>
+ struct default_value_traits;
+
+ 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&);
+ // };
+
+ //
+ // type_traits
+ //
+
+ template <typename T>
+ struct default_type_traits;
+
+ template <typename T>
+ class type_traits: public default_type_traits<T>
+ {
+ };
+
+ // Integral types.
+ //
+ template <>
+ struct default_type_traits<bool>
+ {
+ static const database_type_id db_type_id = id_int32;
+ };
+
+ template <>
+ struct default_type_traits<signed char>
+ {
+ static const database_type_id db_type_id = id_int32;
+ };
+
+ template <>
+ struct default_type_traits<unsigned char>
+ {
+ static const database_type_id db_type_id = id_int32;
+ };
+
+ template <>
+ struct default_type_traits<short>
+ {
+ static const database_type_id db_type_id = id_int32;
+ };
+
+ template <>
+ struct default_type_traits<unsigned short>
+ {
+ static const database_type_id db_type_id = id_int32;
+ };
+
+ template <>
+ struct default_type_traits<int>
+ {
+ static const database_type_id db_type_id = id_int32;
+ };
+
+ template <>
+ struct default_type_traits<unsigned int>
+ {
+ static const database_type_id db_type_id = id_int32;
+ };
+
+ template <>
+ struct default_type_traits<long>
+ {
+ static const database_type_id db_type_id = id_int64;
+ };
+
+ template <>
+ struct default_type_traits<unsigned long>
+ {
+ static const database_type_id db_type_id = id_int64;
+ };
+
+ template <>
+ struct default_type_traits<long long>
+ {
+ static const database_type_id db_type_id = id_int64;
+ };
+
+ template <>
+ struct default_type_traits<unsigned long long>
+ {
+ static const database_type_id db_type_id = id_int64;
+ };
+
+ // Float types.
+ //
+ template <>
+ struct default_type_traits<float>
+ {
+ static const database_type_id db_type_id = id_float;
+ };
+
+ template <>
+ struct default_type_traits<double>
+ {
+ static const database_type_id db_type_id = id_double;
+ };
+
+ // String type.
+ //
+ template <>
+ struct default_type_traits<std::string>
+ {
+ static const database_type_id db_type_id = id_string;
+ };
+
+ template <>
+ struct default_type_traits<const char*>
+ {
+ static const database_type_id db_type_id = id_string;
+ };
+
+ template <std::size_t n>
+ struct default_type_traits<char[n]>
+ {
+ static const database_type_id db_type_id = id_string;
+ };
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_ORACLE_TRAITS_HXX