aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/pgsql/traits.hxx228
1 files changed, 227 insertions, 1 deletions
diff --git a/odb/pgsql/traits.hxx b/odb/pgsql/traits.hxx
index f34a1ca..e0aff15 100644
--- a/odb/pgsql/traits.hxx
+++ b/odb/pgsql/traits.hxx
@@ -13,8 +13,10 @@
#include <cstddef> // std::size_t
#include <odb/traits.hxx>
+#include <odb/wrapper-traits.hxx>
#include <odb/details/buffer.hxx>
+#include <odb/details/wrapper-p.hxx>
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/pgsql-types.hxx>
@@ -108,12 +110,236 @@ namespace odb
// 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 default_value_traits<T, 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, BYTEA, and NUMERIC.
+ //
+ 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));
+ }
+
+ // VARBIT.
+ //
+ static void
+ set_value (W& v, const details::ubuffer& b, std::size_t n, bool is_null)
+ {
+ vtraits::set_value (wtraits::set_ref (v), b, n, is_null);
+ }
+
+ static void
+ set_image (details::ubuffer& b, std::size_t& n, bool& is_null, const W& v)
+ {
+ vtraits::set_image (b, n, is_null, wtraits::get_ref (v));
+ }
+
+ // UUID.
+ //
+ static void
+ set_value (W& v, const unsigned char* i, bool is_null)
+ {
+ vtraits::set_value (wtraits::set_ref (v), i, is_null);
+ }
+
+ static void
+ set_image (unsigned char* i, bool& is_null, const W& v)
+ {
+ vtraits::set_image (i, 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, BYTEA, and NUMERIC.
+ //
+ 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));
+ }
+
+ // VARBIT.
+ //
+ static void
+ set_value (W& v, const details::ubuffer& 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::ubuffer& 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));
+ }
+
+ // UUID.
+ //
+ static void
+ set_value (W& v, const unsigned char* 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 (unsigned char* 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));
+ }
};
template <typename T, database_type_id ID>