From 0198441b5e7d3ed5f9307d400feca87cc63ad1a6 Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Fri, 23 Sep 2011 11:22:06 +0200 Subject: Add traits implementation --- odb/oracle/traits.cxx | 138 ++++++++++++ odb/oracle/traits.hxx | 590 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 728 insertions(+) create mode 100644 odb/oracle/traits.cxx create mode 100644 odb/oracle/traits.hxx 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 +// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include +#include + +#include + +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 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 (n % 100)); + sig = sig ? true : v != 0; + + if (sig) + s.push_front (static_cast (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 (~(c + 192)); + } + else + { + while (n != 0) + { + int v (static_cast (n % 100)); + sig = sig ? true : v != 0; + + if (sig) + s.push_front (static_cast (v + 1)); + + n /= 100; + ++c; + } + + // Exponent is one less than the number of base 100 digits. + // + exp = static_cast (c + 192); + } + + // Set the length. + // + b[0] = static_cast (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 +// 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 + +#include +#include +#include // std::size_t + +#include +#include + +#include +#include + +#include +#include + +#include + +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 + struct image_traits; + + template <> + struct image_traits {typedef int image_type;}; + + template <> + struct image_traits {typedef long long image_type;}; + + template <> + struct image_traits {typedef unsigned char[21] image_type;}; + + template <> + struct image_traits {typedef float image_type;}; + + template <> + struct image_traits {typedef double image_type;}; + + template <> + struct image_traits {typedef unsigned char[21] image_type;}; + + template <> + struct image_traits {typedef unsigned char[7] image_type;}; + + template <> + struct image_traits {typedef unsigned char* image_type;}; + + template <> + struct image_traits {typedef char* image_type;}; + + template <> + struct image_traits {typedef char* image_type;}; + + template <> + struct image_traits {typedef char* image_type;}; + + template <> + struct image_traits {typedef lob_callback image_type;}; + + template <> + struct image_traits {typedef lob_callback image_type;}; + + template <> + struct image_traits {typedef lob_callback image_type;}; + + // + // value_traits + // + + template + struct wrapped_value_traits; + + template + struct default_value_traits; + + template ::r> + struct select_traits; + + // template + // struct select_traits + // { + // typedef default_value_traits type; + // }; + + // template + // struct select_traits + // { + // typedef + // wrapped_value_traits::null_handler> + // type; + // }; + + // template + // class value_traits: public select_traits::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 + // struct wrapped_value_traits + // { + // typedef wrapper_traits wtraits; + // typedef typename wtraits::wrapped_type wrapped_type; + + // typedef W value_type; + // typedef wrapped_type query_type; + // typedef typename image_traits::image_type image_type; + + // typedef value_traits 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 + // struct wrapped_value_traits + // { + // typedef wrapper_traits wtraits; + // typedef typename wtraits::wrapped_type wrapped_type; + + // typedef W value_type; + // typedef wrapped_type query_type; + // typedef typename image_traits::image_type image_type; + + // typedef value_traits 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 + // struct default_value_traits + // { + // typedef T value_type; + // typedef T query_type; + // typedef typename image_traits::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 + // struct default_value_traits + // { + // 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 (i - 1); + // else + // v = T (); + // } + + // static void + // set_image (unsigned short& i, bool& is_null, const T& v) + // { + // is_null = false; + // i = static_cast (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: + // string_value_traits + // { + // }; + + // template <> + // struct LIBODB_MYSQL_EXPORT default_value_traits: + // string_value_traits + // { + // }; + + // template <> + // struct LIBODB_MYSQL_EXPORT default_value_traits: + // string_value_traits + // { + // }; + + // template <> + // struct LIBODB_MYSQL_EXPORT default_value_traits: + // 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: + // c_string_value_traits + // { + // }; + + // template <> + // struct LIBODB_MYSQL_EXPORT default_value_traits: + // c_string_value_traits + // { + // }; + + // template <> + // struct LIBODB_MYSQL_EXPORT default_value_traits: + // c_string_value_traits + // { + // }; + + // template <> + // struct LIBODB_MYSQL_EXPORT default_value_traits: + // c_string_value_traits + // { + // }; + + // template + // struct default_value_traits: c_string_value_traits + // { + // }; + + // template + // struct default_value_traits: c_string_value_traits + // { + // }; + + // template + // struct default_value_traits: c_string_value_traits + // { + // }; + + // template + // struct default_value_traits: c_string_value_traits + // { + // }; + + // // std::vector (buffer) specialization. + // // + // template <> + // struct LIBODB_MYSQL_EXPORT default_value_traits, id_blob> + // { + // public: + // typedef std::vector value_type; + // typedef std::vector 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 + struct default_type_traits; + + template + class type_traits: public default_type_traits + { + }; + + // Integral types. + // + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int32; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int32; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int32; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int32; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int32; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int32; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int32; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int64; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int64; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int64; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_int64; + }; + + // Float types. + // + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_float; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_double; + }; + + // String type. + // + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_string; + }; + + template <> + struct default_type_traits + { + static const database_type_id db_type_id = id_string; + }; + + template + struct default_type_traits + { + static const database_type_id db_type_id = id_string; + }; + } +} + +#include + +#endif // ODB_ORACLE_TRAITS_HXX -- cgit v1.1