aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-01-24 15:10:22 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-01-24 15:10:22 +0200
commit877b93d4c98e21bababaca563ccb07ce26c56706 (patch)
tree4198aadf088b5ec248e52ba30f4d1c3d5eb979a4
parent43dc08e8df03eac590f92c4d92ecdb14c72050e2 (diff)
Add support for mapping char[N] to CHAR/VARCHAR database types
Also improve query support for arrays (decaying).
-rw-r--r--odb/oracle/query.hxx381
-rw-r--r--odb/oracle/query.txx10
-rw-r--r--odb/oracle/traits.cxx71
-rw-r--r--odb/oracle/traits.hxx244
4 files changed, 473 insertions, 233 deletions
diff --git a/odb/oracle/query.hxx b/odb/oracle/query.hxx
index cf35559..f3c94f4 100644
--- a/odb/oracle/query.hxx
+++ b/odb/oracle/query.hxx
@@ -39,37 +39,95 @@ namespace odb
// bytes per character).
//
template <typename T>
- class val_bind
+ struct val_bind
{
- public:
+ typedef const T& type;
+
explicit
- val_bind (const T& v, unsigned short p = 0xFFF, short s = 0xFFF)
- : val (v), prec (p), scale (s)
- {
- }
+ val_bind (type v, unsigned short p = 0xFFF, short s = 0xFFF)
+ : val (v), prec (p), scale (s) {}
- const T& val;
+ type val;
+
+ unsigned short prec;
+ short scale;
+ };
+
+ template <typename T, std::size_t N>
+ struct val_bind<T[N]>
+ {
+ typedef const T* type;
+
+ explicit
+ val_bind (type v, unsigned short p = 0xFFF, short s = 0xFFF)
+ : val (v), prec (p), scale (s) {}
+
+ type val;
unsigned short prec;
short scale;
};
template <typename T>
- class ref_bind
+ struct ref_bind
{
- public:
+ typedef const T& type;
+
explicit
- ref_bind (const T& r, unsigned short p = 0xFFF, short s = 0xFFF)
- : ref (r), prec (p), scale (s)
- {
- }
+ ref_bind (type r, unsigned short p = 0xFFF, short s = 0xFFF)
+ : ref (r), prec (p), scale (s) {}
+
+ const void*
+ ptr () const {return &ref;}
+
+ type ref;
+
+ unsigned short prec;
+ short scale;
+ };
+
+ template <typename T, std::size_t N>
+ struct ref_bind<T[N]>
+ {
+ typedef const T* type;
- const T& ref;
+ explicit
+ ref_bind (type r, unsigned short p = 0xFFF, short s = 0xFFF)
+ : ref (r), prec (p), scale (s) {}
+
+ // Allow implicit conversion from decayed ref_bind's.
+ //
+ ref_bind (ref_bind<T*> r): ref (r.ref), prec (r.prec), scale (r.scale) {}
+ ref_bind (ref_bind<const T*> r)
+ : ref (r.ref), prec (r.prec), scale (r.scale) {}
+
+ const void*
+ ptr () const {return ref;}
+
+ type ref;
unsigned short prec;
short scale;
};
+ template <typename T, database_type_id ID>
+ struct val_bind_typed: val_bind<T>
+ {
+ explicit
+ val_bind_typed (typename val_bind<T>::type v,
+ unsigned short p = 0xFFF,
+ short s = 0xFFF): val_bind<T> (v, p, s) {}
+ };
+
+ template <typename T, database_type_id ID>
+ struct ref_bind_typed: ref_bind<T>
+ {
+ explicit
+ ref_bind_typed (typename ref_bind<T>::type r,
+ unsigned short p = 0xFFF,
+ short s = 0xFFF): ref_bind<T> (r, p, s) {}
+ };
+
struct LIBODB_ORACLE_EXPORT query_param: details::shared_base
{
typedef oracle::bind bind_type;
@@ -165,8 +223,15 @@ namespace odb
query_base (val_bind<T> v)
: binding_ (0, 0)
{
- append<T, type_traits<T>::db_type_id> (
- v, details::conversion<T>::to ());
+ *this += v;
+ }
+
+ template <typename T, database_type_id ID>
+ explicit
+ query_base (val_bind_typed<T, ID> v)
+ : binding_ (0, 0)
+ {
+ *this += v;
}
template <typename T>
@@ -174,8 +239,15 @@ namespace odb
query_base (ref_bind<T> r)
: binding_ (0, 0)
{
- append<T, type_traits<T>::db_type_id> (
- r, details::conversion<T>::to ());
+ *this += r;
+ }
+
+ template <typename T, database_type_id ID>
+ explicit
+ query_base (ref_bind_typed<T, ID> r)
+ : binding_ (0, 0)
+ {
+ *this += r;
}
template <database_type_id ID>
@@ -236,6 +308,13 @@ namespace odb
return val_bind<T> (x, prec, scale);
}
+ template <database_type_id ID, typename T>
+ static val_bind_typed<T, ID>
+ _val (const T& x, unsigned short prec = 0xFFF, short scale = 0xFFF)
+ {
+ return val_bind_typed<T, ID> (x, prec, scale);
+ }
+
template <typename T>
static ref_bind<T>
_ref (const T& x, unsigned short prec = 0xFFF, short scale = 0xFFF)
@@ -243,6 +322,13 @@ namespace odb
return ref_bind<T> (x, prec, scale);
}
+ template <database_type_id ID, typename T>
+ static ref_bind_typed<T, ID>
+ _ref (const T& x, unsigned short prec = 0xFFF, short scale = 0xFFF)
+ {
+ return ref_bind_typed<T, ID> (x, prec, scale);
+ }
+
public:
query_base&
operator+= (const query_base&);
@@ -263,6 +349,17 @@ namespace odb
return *this;
}
+ template <typename T, database_type_id ID>
+ query_base&
+ operator+= (val_bind_typed<T, ID> v)
+ {
+ // We are not using default type_traits so no default conversion
+ // either.
+ //
+ append<T, ID> (v, 0);
+ return *this;
+ }
+
template <typename T>
query_base&
operator+= (ref_bind<T> r)
@@ -272,6 +369,17 @@ namespace odb
return *this;
}
+ template <typename T, database_type_id ID>
+ query_base&
+ operator+= (ref_bind_typed<T, ID> r)
+ {
+ // We are not using default type_traits so no default conversion
+ // either.
+ //
+ append<T, ID> (r, 0);
+ return *this;
+ }
+
// Implementation details.
//
public:
@@ -333,16 +441,26 @@ namespace odb
template <typename T>
inline query_base
- operator+ (const query_base& q, ref_bind<T> b)
+ operator+ (val_bind<T> b, const query_base& q)
+ {
+ query_base r;
+ r += b;
+ r += q;
+ return r;
+ }
+
+ template <typename T, database_type_id ID>
+ inline query_base
+ operator+ (const query_base& q, val_bind_typed<T, ID> b)
{
query_base r (q);
r += b;
return r;
}
- template <typename T>
+ template <typename T, database_type_id ID>
inline query_base
- operator+ (val_bind<T> b, const query_base& q)
+ operator+ (val_bind_typed<T, ID> b, const query_base& q)
{
query_base r;
r += b;
@@ -352,6 +470,15 @@ namespace odb
template <typename T>
inline query_base
+ operator+ (const query_base& q, ref_bind<T> b)
+ {
+ query_base r (q);
+ r += b;
+ return r;
+ }
+
+ template <typename T>
+ inline query_base
operator+ (ref_bind<T> b, const query_base& q)
{
query_base r;
@@ -360,6 +487,25 @@ namespace odb
return r;
}
+ template <typename T, database_type_id ID>
+ inline query_base
+ operator+ (const query_base& q, ref_bind_typed<T, ID> b)
+ {
+ query_base r (q);
+ r += b;
+ return r;
+ }
+
+ template <typename T, database_type_id ID>
+ inline query_base
+ operator+ (ref_bind_typed<T, ID> b, const query_base& q)
+ {
+ query_base r;
+ r += b;
+ r += q;
+ return r;
+ }
+
inline query_base
operator+ (const query_base& q, const std::string& s)
{
@@ -387,16 +533,26 @@ namespace odb
template <typename T>
inline query_base
- operator+ (const std::string& s, ref_bind<T> b)
+ operator+ (val_bind<T> b, const std::string& s)
+ {
+ query_base r;
+ r += b;
+ r += s;
+ return r;
+ }
+
+ template <typename T, database_type_id ID>
+ inline query_base
+ operator+ (const std::string& s, val_bind_typed<T, ID> b)
{
query_base r (s);
r += b;
return r;
}
- template <typename T>
+ template <typename T, database_type_id ID>
inline query_base
- operator+ (val_bind<T> b, const std::string& s)
+ operator+ (val_bind_typed<T, ID> b, const std::string& s)
{
query_base r;
r += b;
@@ -406,6 +562,15 @@ namespace odb
template <typename T>
inline query_base
+ operator+ (const std::string& s, ref_bind<T> b)
+ {
+ query_base r (s);
+ r += b;
+ return r;
+ }
+
+ template <typename T>
+ inline query_base
operator+ (ref_bind<T> b, const std::string& s)
{
query_base r;
@@ -414,6 +579,25 @@ namespace odb
return r;
}
+ template <typename T, database_type_id ID>
+ inline query_base
+ operator+ (const std::string& s, ref_bind_typed<T, ID> b)
+ {
+ query_base r (s);
+ r += b;
+ return r;
+ }
+
+ template <typename T, database_type_id ID>
+ inline query_base
+ operator+ (ref_bind_typed<T, ID> b, const std::string& s)
+ {
+ query_base r;
+ r += b;
+ r += s;
+ return r;
+ }
+
LIBODB_ORACLE_EXPORT query_base
operator&& (const query_base& x, const query_base& y);
@@ -481,23 +665,11 @@ namespace odb
short scale_;
};
- template <typename T, typename T2>
- class copy_bind: public val_bind<T>
- {
- public:
- explicit
- copy_bind (const T2& v): val_bind<T> (val), val (v) {}
-
- const T val;
- };
-
- template <typename T>
- const T&
- type_instance ();
-
template <typename T, database_type_id ID>
struct query_column: query_column_base
{
+ typedef typename decay_traits<T>::type decayed_type;
+
// Note that we keep shalow copies of the table, column, and conversion
// expression. The latter can be NULL.
//
@@ -540,16 +712,17 @@ namespace odb
//
public:
query_base
- in (const T&, const T&) const;
+ in (decayed_type, decayed_type) const;
query_base
- in (const T&, const T&, const T&) const;
+ in (decayed_type, decayed_type, decayed_type) const;
query_base
- in (const T&, const T&, const T&, const T&) const;
+ in (decayed_type, decayed_type, decayed_type, decayed_type) const;
query_base
- in (const T&, const T&, const T&, const T&, const T&) const;
+ in (decayed_type, decayed_type, decayed_type, decayed_type,
+ decayed_type) const;
template <typename I>
query_base
@@ -559,7 +732,7 @@ namespace odb
//
public:
query_base
- equal (const T& v) const
+ equal (decayed_type v) const
{
return equal (val_bind<T> (v));
}
@@ -580,8 +753,7 @@ namespace odb
query_base
equal (val_bind<T2> v) const
{
- copy_bind<T, T2> c (v.val);
- return equal (c);
+ return equal (val_bind<T> (decayed_type (v.val)));
}
query_base
@@ -597,13 +769,13 @@ namespace odb
}
friend query_base
- operator== (const query_column& c, const T& v)
+ operator== (const query_column& c, decayed_type v)
{
return c.equal (v);
}
friend query_base
- operator== (const T& v, const query_column& c)
+ operator== (decayed_type v, const query_column& c)
{
return c.equal (v);
}
@@ -650,7 +822,7 @@ namespace odb
//
public:
query_base
- unequal (const T& v) const
+ unequal (decayed_type v) const
{
return unequal (val_bind<T> (v));
}
@@ -671,8 +843,7 @@ namespace odb
query_base
unequal (val_bind<T2> v) const
{
- copy_bind<T, T2> c (v.val);
- return unequal (c);
+ return unequal (val_bind<T> (decayed_type (v.val)));
}
query_base
@@ -688,13 +859,13 @@ namespace odb
}
friend query_base
- operator!= (const query_column& c, const T& v)
+ operator!= (const query_column& c, decayed_type v)
{
return c.unequal (v);
}
friend query_base
- operator!= (const T& v, const query_column& c)
+ operator!= (decayed_type v, const query_column& c)
{
return c.unequal (v);
}
@@ -741,7 +912,7 @@ namespace odb
//
public:
query_base
- less (const T& v) const
+ less (decayed_type v) const
{
return less (val_bind<T> (v));
}
@@ -762,8 +933,7 @@ namespace odb
query_base
less (val_bind<T2> v) const
{
- copy_bind<T, T2> c (v.val);
- return less (c);
+ return less (val_bind<T> (decayed_type (v.val)));
}
query_base
@@ -779,13 +949,13 @@ namespace odb
}
friend query_base
- operator< (const query_column& c, const T& v)
+ operator< (const query_column& c, decayed_type v)
{
return c.less (v);
}
friend query_base
- operator< (const T& v, const query_column& c)
+ operator< (decayed_type v, const query_column& c)
{
return c.greater (v);
}
@@ -832,7 +1002,7 @@ namespace odb
//
public:
query_base
- greater (const T& v) const
+ greater (decayed_type v) const
{
return greater (val_bind<T> (v));
}
@@ -853,8 +1023,7 @@ namespace odb
query_base
greater (val_bind<T2> v) const
{
- copy_bind<T, T2> c (v.val);
- return greater (c);
+ return greater (val_bind<T> (decayed_type (v.val)));
}
query_base
@@ -870,13 +1039,13 @@ namespace odb
}
friend query_base
- operator> (const query_column& c, const T& v)
+ operator> (const query_column& c, decayed_type v)
{
return c.greater (v);
}
friend query_base
- operator> (const T& v, const query_column& c)
+ operator> (decayed_type v, const query_column& c)
{
return c.less (v);
}
@@ -923,7 +1092,7 @@ namespace odb
//
public:
query_base
- less_equal (const T& v) const
+ less_equal (decayed_type v) const
{
return less_equal (val_bind<T> (v));
}
@@ -944,8 +1113,7 @@ namespace odb
query_base
less_equal (val_bind<T2> v) const
{
- copy_bind<T, T2> c (v.val);
- return less_equal (c);
+ return less_equal (val_bind<T> (decayed_type (v.val)));
}
query_base
@@ -961,13 +1129,13 @@ namespace odb
}
friend query_base
- operator<= (const query_column& c, const T& v)
+ operator<= (const query_column& c, decayed_type v)
{
return c.less_equal (v);
}
friend query_base
- operator<= (const T& v, const query_column& c)
+ operator<= (decayed_type v, const query_column& c)
{
return c.greater_equal (v);
}
@@ -1014,7 +1182,7 @@ namespace odb
//
public:
query_base
- greater_equal (const T& v) const
+ greater_equal (decayed_type v) const
{
return greater_equal (val_bind<T> (v));
}
@@ -1035,8 +1203,7 @@ namespace odb
query_base
greater_equal (val_bind<T2> v) const
{
- copy_bind<T, T2> c (v.val);
- return greater_equal (c);
+ return greater_equal (val_bind<T> (decayed_type (v.val)));
}
query_base
@@ -1052,13 +1219,13 @@ namespace odb
}
friend query_base
- operator>= (const query_column& c, const T& v)
+ operator>= (const query_column& c, decayed_type v)
{
return c.greater_equal (v);
}
friend query_base
- operator>= (const T& v, const query_column& c)
+ operator>= (decayed_type v, const query_column& c)
{
return c.less_equal (v);
}
@@ -1110,7 +1277,8 @@ namespace odb
{
// We can compare columns only if we can compare their C++ types.
//
- (void) (sizeof (type_instance<T> () == type_instance<T2> ()));
+ (void) (sizeof (decay_traits<T>::instance () ==
+ decay_traits<T2>::instance ()));
query_base q (table_, column_);
q += "=";
@@ -1124,7 +1292,8 @@ namespace odb
{
// We can compare columns only if we can compare their C++ types.
//
- (void) (sizeof (type_instance<T> () != type_instance<T2> ()));
+ (void) (sizeof (decay_traits<T>::instance () !=
+ decay_traits<T2>::instance ()));
query_base q (table_, column_);
q += "!=";
@@ -1138,7 +1307,8 @@ namespace odb
{
// We can compare columns only if we can compare their C++ types.
//
- (void) (sizeof (type_instance<T> () < type_instance<T2> ()));
+ (void) (sizeof (decay_traits<T>::instance () <
+ decay_traits<T2>::instance ()));
query_base q (table_, column_);
q += "<";
@@ -1152,7 +1322,8 @@ namespace odb
{
// We can compare columns only if we can compare their C++ types.
//
- (void) (sizeof (type_instance<T> () > type_instance<T2> ()));
+ (void) (sizeof (decay_traits<T>::instance () >
+ decay_traits<T2>::instance ()));
query_base q (table_, column_);
q += ">";
@@ -1166,7 +1337,8 @@ namespace odb
{
// We can compare columns only if we can compare their C++ types.
//
- (void) (sizeof (type_instance<T> () <= type_instance<T2> ()));
+ (void) (sizeof (decay_traits<T>::instance () <=
+ decay_traits<T2>::instance ()));
query_base q (table_, column_);
q += "<=";
@@ -1180,7 +1352,8 @@ namespace odb
{
// We can compare columns only if we can compare their C++ types.
//
- (void) (sizeof (type_instance<T> () >= type_instance<T2> ()));
+ (void) (sizeof (decay_traits<T>::instance () >=
+ decay_traits<T2>::instance ()));
query_base q (table_, column_);
q += ">=";
@@ -1317,7 +1490,7 @@ namespace odb
template <typename T>
struct query_param_impl<T, id_int32>: query_param
{
- query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (ref_bind<T> r) : query_param (r.ptr ()) {}
query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
virtual bool
@@ -1338,7 +1511,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
value_traits<T, id_int32>::set_image (image_, is_null, v);
@@ -1353,7 +1526,7 @@ namespace odb
template <typename T>
struct query_param_impl<T, id_int64>: query_param
{
- query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (ref_bind<T> r) : query_param (r.ptr ()) {}
query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
virtual bool
@@ -1374,7 +1547,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
value_traits<T, id_int64>::set_image (image_, is_null, v);
@@ -1389,7 +1562,7 @@ namespace odb
template <typename T>
struct query_param_impl<T, id_big_int>: query_param
{
- query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (ref_bind<T> r) : query_param (r.ptr ()) {}
query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
virtual bool
@@ -1410,7 +1583,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
std::size_t size (0);
@@ -1428,7 +1601,7 @@ namespace odb
template <typename T>
struct query_param_impl<T, id_float>: query_param
{
- query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (ref_bind<T> r) : query_param (r.ptr ()) {}
query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
virtual bool
@@ -1449,7 +1622,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
value_traits<T, id_float>::set_image (image_, is_null, v);
@@ -1464,7 +1637,7 @@ namespace odb
template <typename T>
struct query_param_impl<T, id_double>: query_param
{
- query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (ref_bind<T> r) : query_param (r.ptr ()) {}
query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
virtual bool
@@ -1485,7 +1658,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
value_traits<T, id_double>::set_image (image_, is_null, v);
@@ -1500,7 +1673,7 @@ namespace odb
template <typename T>
struct query_param_impl<T, id_big_float>: query_param
{
- query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (ref_bind<T> r) : query_param (r.ptr ()) {}
query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
virtual bool
@@ -1521,7 +1694,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
std::size_t size (0);
@@ -1539,7 +1712,7 @@ namespace odb
template <typename T>
struct query_param_impl<T, id_date>: query_param
{
- query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (ref_bind<T> r) : query_param (r.ptr ()) {}
query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
virtual bool
@@ -1560,7 +1733,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
value_traits<T, id_date>::set_image (image_, is_null, v);
@@ -1576,7 +1749,7 @@ namespace odb
struct query_param_impl<T, id_timestamp>: query_param
{
query_param_impl (ref_bind<T> r)
- : query_param (&r.ref),
+ : query_param (r.ptr ()),
image_ (descriptor_cache) // Cache, don't free.
{
}
@@ -1606,7 +1779,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
value_traits<T, id_timestamp>::set_image (image_, is_null, v);
@@ -1622,7 +1795,7 @@ namespace odb
struct query_param_impl<T, id_interval_ym>: query_param
{
query_param_impl (ref_bind<T> r)
- : query_param (&r.ref),
+ : query_param (r.ptr ()),
image_ (descriptor_cache) // Cache, don't free.
{
}
@@ -1652,7 +1825,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
value_traits<T, id_interval_ym>::set_image (image_, is_null, v);
@@ -1668,7 +1841,7 @@ namespace odb
struct query_param_impl<T, id_interval_ds>: query_param
{
query_param_impl (ref_bind<T> r)
- : query_param (&r.ref),
+ : query_param (r.ptr ()),
image_ (descriptor_cache) // Cache, don't free.
{
}
@@ -1699,7 +1872,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
value_traits<T, id_interval_ds>::set_image (image_, is_null, v);
@@ -1715,7 +1888,7 @@ namespace odb
struct query_param_impl<T, id_string>: query_param
{
query_param_impl (ref_bind<T> r)
- : query_param (&r.ref),
+ : query_param (r.ptr ()),
// Default to max (4000).
buf_ (r.prec != 0xFFF ? r.prec : 4000)
{
@@ -1748,7 +1921,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
std::size_t size (0);
@@ -1768,7 +1941,7 @@ namespace odb
struct query_param_impl<T, id_nstring>: query_param
{
query_param_impl (ref_bind<T> r)
- : query_param (&r.ref),
+ : query_param (r.ptr ()),
// Default to max (4000).
buf_ (r.prec != 0xFFF ? r.prec : 4000)
{
@@ -1801,7 +1974,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
std::size_t size (0);
@@ -1821,7 +1994,7 @@ namespace odb
struct query_param_impl<T, id_raw>: query_param
{
query_param_impl (ref_bind<T> r)
- : query_param (&r.ref),
+ : query_param (r.ptr ()),
// Default to max (2000).
buf_ (r.prec != 0xFFF ? r.prec : 2000)
{
@@ -1854,7 +2027,7 @@ namespace odb
private:
void
- init (const T& v)
+ init (typename decay_traits<T>::type v)
{
bool is_null (false); // Can't be NULL.
std::size_t size (0);
diff --git a/odb/oracle/query.txx b/odb/oracle/query.txx
index 5921efe..879072b 100644
--- a/odb/oracle/query.txx
+++ b/odb/oracle/query.txx
@@ -27,7 +27,7 @@ namespace odb
//
template <typename T, database_type_id ID>
query_base query_column<T, ID>::
- in (const T& v1, const T& v2) const
+ in (decayed_type v1, decayed_type v2) const
{
query_base q (table_, column_);
q += "IN (";
@@ -40,7 +40,7 @@ namespace odb
template <typename T, database_type_id ID>
query_base query_column<T, ID>::
- in (const T& v1, const T& v2, const T& v3) const
+ in (decayed_type v1, decayed_type v2, decayed_type v3) const
{
query_base q (table_, column_);
q += "IN (";
@@ -55,7 +55,8 @@ namespace odb
template <typename T, database_type_id ID>
query_base query_column<T, ID>::
- in (const T& v1, const T& v2, const T& v3, const T& v4) const
+ in (decayed_type v1, decayed_type v2, decayed_type v3,
+ decayed_type v4) const
{
query_base q (table_, column_);
q += "IN (";
@@ -72,7 +73,8 @@ namespace odb
template <typename T, database_type_id ID>
query_base query_column<T, ID>::
- in (const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) const
+ in (decayed_type v1, decayed_type v2, decayed_type v3, decayed_type v4,
+ decayed_type v5) const
{
query_base q (table_, column_);
q += "IN (";
diff --git a/odb/oracle/traits.cxx b/odb/oracle/traits.cxx
index 6927f65..5ab0d1e 100644
--- a/odb/oracle/traits.cxx
+++ b/odb/oracle/traits.cxx
@@ -11,9 +11,54 @@ namespace odb
namespace oracle
{
//
- // string_lob_value_traits
+ // c_array_value_traits_base
//
+ void c_array_value_traits_base::
+ set_value (char* const& v,
+ const char* b,
+ size_t n,
+ bool is_null,
+ size_t N)
+ {
+ if (!is_null)
+ {
+ n = n < N ? n : N;
+
+ if (n != 0)
+ memcpy (v, b, n);
+ }
+ else
+ n = 0;
+
+ if (n != N) // Append '\0' if there is space.
+ v[n] = '\0';
+ }
+
+ void c_array_value_traits_base::
+ set_image (char* b,
+ size_t c,
+ size_t& n,
+ bool& is_null,
+ const char* v,
+ size_t N)
+ {
+ is_null = false;
+ // Figure out the length. We cannot use strlen since it may
+ // not be 0-terminated (strnlen is not standard).
+ //
+ for (n = 0; n != N && v[n] != '\0'; ++n);
+
+ if (n > c)
+ n = c;
+
+ if (n != 0)
+ memcpy (b, v, n);
+ }
+
+ //
+ // string_lob_value_traits
+ //
bool string_lob_value_traits::
result_callback (void* c, ub4*, void* b, ub4 s, chunk_position p)
{
@@ -58,31 +103,8 @@ namespace odb
}
//
- // c_string_lob_value_traits
- //
-
- bool c_string_lob_value_traits::
- param_callback (const void* c,
- ub4*,
- const void** b,
- ub4* s,
- chunk_position* p,
- void*,
- ub4)
- {
- const char* v (static_cast<const char*> (c));
-
- *p = chunk_one;
- *s = static_cast<ub4> (strlen (v));
- *b = v;
-
- return true;
- }
-
- //
// default_value_traits<std::vector<char>, id_blob>
//
-
bool default_value_traits<std::vector<char>, id_blob>::
result_callback (void* c, ub4*, void* b, ub4 s, chunk_position p)
{
@@ -131,7 +153,6 @@ namespace odb
//
// default_value_traits<std::vector<unsigned char>, id_blob>
//
-
bool default_value_traits<std::vector<unsigned char>, id_blob>::
result_callback (void* c, ub4*, void* b, ub4 s, chunk_position p)
{
diff --git a/odb/oracle/traits.hxx b/odb/oracle/traits.hxx
index 2cbce04..13bb1dc 100644
--- a/odb/oracle/traits.hxx
+++ b/odb/oracle/traits.hxx
@@ -546,7 +546,7 @@ namespace odb
{
};
- // const char* specialization.
+ // char*/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
@@ -577,45 +577,151 @@ namespace odb
};
template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<char*, id_string>:
+ c_string_value_traits {};
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<char*, id_nstring>:
+ c_string_value_traits {};
+
+ template <>
struct LIBODB_ORACLE_EXPORT default_value_traits<const char*, id_string>:
- c_string_value_traits
- {
- typedef const char* query_type;
- };
+ c_string_value_traits {};
template <>
struct LIBODB_ORACLE_EXPORT default_value_traits<const char*, id_nstring>:
- c_string_value_traits
+ c_string_value_traits {};
+
+ // char[N] specializations.
+ //
+ struct LIBODB_ORACLE_EXPORT c_array_value_traits_base
{
- typedef const char* query_type;
+ static void
+ set_value (char* const& v,
+ const char* b,
+ std::size_t n,
+ bool is_null,
+ std::size_t N);
+
+ static void
+ set_image (char* b,
+ std::size_t c,
+ std::size_t& n,
+ bool& is_null,
+ const char* v,
+ std::size_t N);
};
template <std::size_t N>
- struct default_value_traits<char[N], id_string>: c_string_value_traits
+ struct c_array_value_traits
{
+ typedef char* value_type;
typedef char query_type[N];
+ typedef details::buffer image_type;
+
+ static void
+ set_value (char* const& v,
+ const char* b,
+ std::size_t n,
+ bool is_null)
+ {
+ c_array_value_traits_base::set_value (v, b, n, is_null, N);
+ }
+
+ static void
+ set_image (char* b,
+ std::size_t c,
+ std::size_t& n,
+ bool& is_null,
+ const char* v)
+ {
+ c_array_value_traits_base::set_image (b, c, n, is_null, v, N);
+ }
};
template <std::size_t N>
- struct default_value_traits<const char[N], id_string>:
- c_string_value_traits
- {
- typedef const char query_type[N];
- };
+ struct default_value_traits<char[N], id_string>:
+ c_array_value_traits<N> {};
template <std::size_t N>
- struct default_value_traits<char[N], id_nstring>: c_string_value_traits
+ struct default_value_traits<char[N], id_nstring>:
+ c_array_value_traits<N> {};
+
+ // std::array<char, N> (string) specialization.
+ //
+#ifdef ODB_CXX11
+ template <std::size_t N>
+ struct std_array_value_traits
{
- typedef char query_type[N];
+ typedef std::array<char, N> value_type;
+ typedef std::array<char, N> query_type;
+ typedef details::buffer image_type;
+
+ static void
+ set_value (value_type& v,
+ const char* b,
+ std::size_t n,
+ bool is_null)
+ {
+ c_array_value_traits_base::set_value (v.data (), b, n, is_null, N);
+ }
+
+ static void
+ set_image (char* b,
+ std::size_t c,
+ std::size_t& n,
+ bool& is_null,
+ const value_type& v)
+ {
+ c_array_value_traits_base::set_image (b, c, n, is_null, v.data (), N);
+ }
};
template <std::size_t N>
- struct default_value_traits<const char[N], id_nstring>:
- c_string_value_traits
+ struct default_value_traits<std::array<char, N>, id_string>:
+ std_array_value_traits<N> {};
+
+ template <std::size_t N>
+ struct default_value_traits<std::array<char, N>, id_nstring>:
+ std_array_value_traits<N> {};
+#endif
+
+ // char specialization.
+ //
+ struct LIBODB_ORACLE_EXPORT char_value_traits
{
- typedef const char query_type[N];
+ typedef char value_type;
+ typedef char query_type;
+ typedef details::buffer image_type;
+
+ static void
+ set_value (char& v,
+ const char* b,
+ std::size_t n,
+ bool is_null)
+ {
+ c_array_value_traits_base::set_value (&v, b, n, is_null, 1);
+ }
+
+ static void
+ set_image (char* b,
+ std::size_t c,
+ std::size_t& n,
+ bool& is_null,
+ char v)
+ {
+ c_array_value_traits_base::set_image (b, c, n, is_null, &v, 1);
+ }
};
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<char, id_string>:
+ char_value_traits {};
+
+ template <>
+ struct LIBODB_ORACLE_EXPORT default_value_traits<char, id_nstring>:
+ char_value_traits {};
+
// std::vector<char> (buffer) specialization for RAW.
//
template <>
@@ -892,81 +998,6 @@ namespace odb
{
};
- // 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 pass such values to the queries.
- //
- class LIBODB_ORACLE_EXPORT c_string_lob_value_traits
- {
- public:
- typedef const char* value_type;
- typedef lob_callback image_type;
-
- static void
- set_image (param_callback_type& cb,
- const void*& context,
- bool& is_null,
- const char* v)
- {
- is_null = false;
- cb = &param_callback;
- context = v;
- }
-
- static bool
- param_callback (const void* context,
- ub4* position_context,
- const 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
- {
- typedef const char* query_type;
- };
-
- template <>
- struct LIBODB_ORACLE_EXPORT default_value_traits<const char*, id_nclob>:
- c_string_lob_value_traits
- {
- typedef const char* query_type;
- };
-
- template <std::size_t N>
- struct default_value_traits<char[N], id_clob>:
- c_string_lob_value_traits
- {
- typedef char query_type[N];
- };
-
- template <std::size_t N>
- struct default_value_traits<const char[N], id_clob>:
- c_string_lob_value_traits
- {
- typedef const char query_type[N];
- };
-
- template <std::size_t N>
- struct default_value_traits<char[N], id_nclob>:
- c_string_lob_value_traits
- {
- typedef char query_type[N];
- };
-
- template <std::size_t N>
- struct default_value_traits<const char[N], id_nclob>:
- c_string_lob_value_traits
- {
- typedef const char query_type[N];
- };
-
// std::vector<char> (buffer) specialization for BLOBs.
//
template <>
@@ -1392,6 +1423,12 @@ namespace odb
};
template <>
+ struct default_type_traits<char*>
+ {
+ 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;
@@ -1403,37 +1440,44 @@ namespace odb
static const database_type_id db_type_id = id_string;
};
- template <std::size_t N>
- struct default_type_traits<const char[N]>
+ template <>
+ struct default_type_traits<char>
{
static const database_type_id db_type_id = id_string;
};
- // Binary types. Assume BLOB.
+ // Binary types. Assume RAW since LOBs cannot be compared in
+ // Oracle and this is only used in queries.
//
+ template <std::size_t N>
+ struct default_type_traits<unsigned char[N]>
+ {
+ static const database_type_id db_type_id = id_raw;
+ };
+
template <>
struct default_type_traits<std::vector<char> >
{
- static const database_type_id db_type_id = id_blob;
+ static const database_type_id db_type_id = id_raw;
};
template <>
struct default_type_traits<std::vector<unsigned char> >
{
- static const database_type_id db_type_id = id_blob;
+ static const database_type_id db_type_id = id_raw;
};
#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_blob;
+ static const database_type_id db_type_id = id_raw;
};
template <std::size_t N>
struct default_type_traits<std::array<unsigned char, N> >
{
- static const database_type_id db_type_id = id_blob;
+ static const database_type_id db_type_id = id_raw;
};
#endif
}