From 057c8299fb1fec24338404b28f2b33473e547bc8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 24 Jan 2013 15:10:21 +0200 Subject: Add support for mapping char[N] to CHAR/VARCHAR database types Also improve query support for arrays (decaying). --- odb/mssql/query.hxx | 418 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 295 insertions(+), 123 deletions(-) (limited to 'odb/mssql/query.hxx') diff --git a/odb/mssql/query.hxx b/odb/mssql/query.hxx index d9a84e4..3a82932 100644 --- a/odb/mssql/query.hxx +++ b/odb/mssql/query.hxx @@ -38,39 +38,96 @@ namespace odb // 0. As a result, for scale, the not specific special value will // be 0xFFFF (USHORT_MAX). // - template - class val_bind + struct val_bind { - public: + typedef const T& type; + explicit - val_bind (const T& v, unsigned short p = 0, unsigned short s = 0xFFFF) - : val (v), prec (p), scale (s) - { - } + val_bind (type v, unsigned short p = 0, unsigned short s = 0xFFFF) + : val (v), prec (p), scale (s) {} - const T& val; + type val; + + unsigned short prec; + unsigned short scale; + }; + + template + struct val_bind + { + typedef const T* type; + + explicit + val_bind (type v, unsigned short p = 0, unsigned short s = 0xFFFF) + : val (v), prec (p), scale (s) {} + + type val; unsigned short prec; unsigned short scale; }; template - class ref_bind + struct ref_bind { - public: + typedef const T& type; + explicit - ref_bind (const T& r, unsigned short p = 0, unsigned short s = 0xFFFF) - : ref (r) , prec (p), scale (s) - { - } + ref_bind (type r, unsigned short p = 0, unsigned short s = 0xFFFF) + : ref (r), prec (p), scale (s) {} + + const void* + ptr () const {return &ref;} + + type ref; + + unsigned short prec; + unsigned short scale; + }; - const T& ref; + template + struct ref_bind + { + typedef const T* type; + + explicit + ref_bind (type r, unsigned short p = 0, unsigned short s = 0xFFFF) + : ref (r), prec (p), scale (s) {} + + // Allow implicit conversion from decayed ref_bind's. + // + ref_bind (ref_bind r): ref (r.ref), prec (r.prec), scale (r.scale) {} + ref_bind (ref_bind r) + : ref (r.ref), prec (r.prec), scale (r.scale) {} + + const void* + ptr () const {return ref;} + + type ref; unsigned short prec; unsigned short scale; }; + template + struct val_bind_typed: val_bind + { + explicit + val_bind_typed (typename val_bind::type v, + unsigned short p = 0, + unsigned short s = 0xFFFF): val_bind (v, p, s) {} + }; + + template + struct ref_bind_typed: ref_bind + { + explicit + ref_bind_typed (typename ref_bind::type r, + unsigned short p = 0, + unsigned short s = 0xFFFF): ref_bind (r, p, s) {} + }; + struct LIBODB_MSSQL_EXPORT query_param: details::shared_base { typedef mssql::bind bind_type; @@ -166,8 +223,15 @@ namespace odb query_base (val_bind v) : binding_ (0, 0) { - append::db_type_id> ( - v, details::conversion::to ()); + *this += v; + } + + template + explicit + query_base (val_bind_typed v) + : binding_ (0, 0) + { + *this += v; } template @@ -175,8 +239,15 @@ namespace odb query_base (ref_bind r) : binding_ (0, 0) { - append::db_type_id> ( - r, details::conversion::to ()); + *this += r; + } + + template + explicit + query_base (ref_bind_typed r) + : binding_ (0, 0) + { + *this += r; } template @@ -237,6 +308,13 @@ namespace odb return val_bind (x, prec, scale); } + template + static val_bind_typed + _val (const T& x, unsigned short prec = 0, unsigned short scale = 0xFFFF) + { + return val_bind_typed (x, prec, scale); + } + template static ref_bind _ref (const T& x, unsigned short prec = 0, unsigned short scale = 0xFFFF) @@ -244,6 +322,13 @@ namespace odb return ref_bind (x, prec, scale); } + template + static ref_bind_typed + _ref (const T& x, unsigned short prec = 0, unsigned short scale = 0xFFFF) + { + return ref_bind_typed (x, prec, scale); + } + public: query_base& operator+= (const query_base&); @@ -264,6 +349,17 @@ namespace odb return *this; } + template + query_base& + operator+= (val_bind_typed v) + { + // We are not using default type_traits so no default conversion + // either. + // + append (v, 0); + return *this; + } + template query_base& operator+= (ref_bind r) @@ -273,6 +369,17 @@ namespace odb return *this; } + template + query_base& + operator+= (ref_bind_typed r) + { + // We are not using default type_traits so no default conversion + // either. + // + append (r, 0); + return *this; + } + // Implementation details. // public: @@ -334,16 +441,26 @@ namespace odb template inline query_base - operator+ (const query_base& q, ref_bind b) + operator+ (val_bind b, const query_base& q) + { + query_base r; + r += b; + r += q; + return r; + } + + template + inline query_base + operator+ (const query_base& q, val_bind_typed b) { query_base r (q); r += b; return r; } - template + template inline query_base - operator+ (val_bind b, const query_base& q) + operator+ (val_bind_typed b, const query_base& q) { query_base r; r += b; @@ -353,6 +470,15 @@ namespace odb template inline query_base + operator+ (const query_base& q, ref_bind b) + { + query_base r (q); + r += b; + return r; + } + + template + inline query_base operator+ (ref_bind b, const query_base& q) { query_base r; @@ -361,6 +487,25 @@ namespace odb return r; } + template + inline query_base + operator+ (const query_base& q, ref_bind_typed b) + { + query_base r (q); + r += b; + return r; + } + + template + inline query_base + operator+ (ref_bind_typed 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) { @@ -388,16 +533,26 @@ namespace odb template inline query_base - operator+ (const std::string& s, ref_bind b) + operator+ (val_bind b, const std::string& s) + { + query_base r; + r += b; + r += s; + return r; + } + + template + inline query_base + operator+ (const std::string& s, val_bind_typed b) { query_base r (s); r += b; return r; } - template + template inline query_base - operator+ (val_bind b, const std::string& s) + operator+ (val_bind_typed b, const std::string& s) { query_base r; r += b; @@ -407,6 +562,15 @@ namespace odb template inline query_base + operator+ (const std::string& s, ref_bind b) + { + query_base r (s); + r += b; + return r; + } + + template + inline query_base operator+ (ref_bind b, const std::string& s) { query_base r; @@ -415,6 +579,25 @@ namespace odb return r; } + template + inline query_base + operator+ (const std::string& s, ref_bind_typed b) + { + query_base r (s); + r += b; + return r; + } + + template + inline query_base + operator+ (ref_bind_typed b, const std::string& s) + { + query_base r; + r += b; + r += s; + return r; + } + LIBODB_MSSQL_EXPORT query_base operator&& (const query_base& x, const query_base& y); @@ -482,23 +665,11 @@ namespace odb unsigned short scale_; }; - template - class copy_bind: public val_bind - { - public: - explicit - copy_bind (const T2& v): val_bind (val), val (v) {} - - const T val; - }; - - template - const T& - type_instance (); - template struct query_column: query_column_base { + typedef typename decay_traits::type decayed_type; + // Note that we keep shalow copies of the table, column, and conversion // expression. The latter can be NULL. // @@ -541,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 query_base @@ -560,7 +732,7 @@ namespace odb // public: query_base - equal (const T& v) const + equal (decayed_type v) const { return equal (val_bind (v)); } @@ -581,8 +753,7 @@ namespace odb query_base equal (val_bind v) const { - copy_bind c (v.val); - return equal (c); + return equal (val_bind (decayed_type (v.val)));; } query_base @@ -598,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); } @@ -651,7 +822,7 @@ namespace odb // public: query_base - unequal (const T& v) const + unequal (decayed_type v) const { return unequal (val_bind (v)); } @@ -672,8 +843,7 @@ namespace odb query_base unequal (val_bind v) const { - copy_bind c (v.val); - return unequal (c); + return unequal (val_bind (decayed_type (v.val))); } query_base @@ -689,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); } @@ -742,7 +912,7 @@ namespace odb // public: query_base - less (const T& v) const + less (decayed_type v) const { return less (val_bind (v)); } @@ -763,8 +933,7 @@ namespace odb query_base less (val_bind v) const { - copy_bind c (v.val); - return less (c); + return less (val_bind (decayed_type (v.val))); } query_base @@ -780,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); } @@ -833,7 +1002,7 @@ namespace odb // public: query_base - greater (const T& v) const + greater (decayed_type v) const { return greater (val_bind (v)); } @@ -854,8 +1023,7 @@ namespace odb query_base greater (val_bind v) const { - copy_bind c (v.val); - return greater (c); + return greater (val_bind (decayed_type (v.val))); } query_base @@ -871,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); } @@ -924,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 (v)); } @@ -945,8 +1113,7 @@ namespace odb query_base less_equal (val_bind v) const { - copy_bind c (v.val); - return less_equal (c); + return less_equal (val_bind (decayed_type (v.val))); } query_base @@ -962,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); } @@ -1015,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 (v)); } @@ -1036,8 +1203,7 @@ namespace odb query_base greater_equal (val_bind v) const { - copy_bind c (v.val); - return greater_equal (c); + return greater_equal (val_bind (decayed_type (v.val))); } query_base @@ -1053,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); } @@ -1111,7 +1277,8 @@ namespace odb { // We can compare columns only if we can compare their C++ types. // - (void) (sizeof (type_instance () == type_instance ())); + (void) (sizeof (decay_traits::instance () == + decay_traits::instance ())); query_base q (table_, column_); q += "="; @@ -1125,7 +1292,8 @@ namespace odb { // We can compare columns only if we can compare their C++ types. // - (void) (sizeof (type_instance () != type_instance ())); + (void) (sizeof (decay_traits::instance () != + decay_traits::instance ())); query_base q (table_, column_); q += "!="; @@ -1139,7 +1307,8 @@ namespace odb { // We can compare columns only if we can compare their C++ types. // - (void) (sizeof (type_instance () < type_instance ())); + (void) (sizeof (decay_traits::instance () < + decay_traits::instance ())); query_base q (table_, column_); q += "<"; @@ -1153,7 +1322,8 @@ namespace odb { // We can compare columns only if we can compare their C++ types. // - (void) (sizeof (type_instance () > type_instance ())); + (void) (sizeof (decay_traits::instance () > + decay_traits::instance ())); query_base q (table_, column_); q += ">"; @@ -1167,7 +1337,8 @@ namespace odb { // We can compare columns only if we can compare their C++ types. // - (void) (sizeof (type_instance () <= type_instance ())); + (void) (sizeof (decay_traits::instance () <= + decay_traits::instance ())); query_base q (table_, column_); q += "<="; @@ -1181,7 +1352,8 @@ namespace odb { // We can compare columns only if we can compare their C++ types. // - (void) (sizeof (type_instance () >= type_instance ())); + (void) (sizeof (decay_traits::instance () >= + decay_traits::instance ())); query_base q (table_, column_); q += ">="; @@ -1239,7 +1411,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -1259,7 +1431,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1276,7 +1448,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -1296,7 +1468,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1313,7 +1485,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -1333,7 +1505,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1350,7 +1522,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -1370,7 +1542,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1387,7 +1559,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -1407,7 +1579,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1425,7 +1597,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), prec_ (r.prec != 0 ? r.prec : 18), // Default is 18. scale_ (r.scale != 0xFFFF ? r.scale : 0) // Default is 0. { @@ -1459,7 +1631,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1479,7 +1651,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -1499,7 +1671,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1516,7 +1688,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -1536,7 +1708,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1554,7 +1726,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), prec_ (r.prec != 0 ? r.prec : 24) { } @@ -1584,7 +1756,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1603,7 +1775,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), prec_ (r.prec != 0 ? r.prec : 53) { } @@ -1633,7 +1805,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -1652,7 +1824,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), // Default to short data max (1024). buf_ (r.prec != 0 ? r.prec : 1024) { @@ -1686,7 +1858,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. std::size_t size (0); @@ -1706,7 +1878,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), // Precision is in 2-byte chars. Default to short data max (1024). buf_ (r.prec != 0 ? r.prec * 2 : 1024) { @@ -1740,7 +1912,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. std::size_t size (0); @@ -1764,7 +1936,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), // Default to short data max (1024). buf_ (r.prec != 0 ? r.prec : 1024) { @@ -1796,7 +1968,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. std::size_t size (0); @@ -1838,7 +2010,7 @@ namespace odb long_query_param_impl { query_param_impl (ref_bind r) - : query_param (&r.ref), prec_ (r.prec) + : query_param (r.ptr ()), prec_ (r.prec) { } @@ -1889,7 +2061,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image ( @@ -1911,7 +2083,7 @@ namespace odb long_query_param_impl { query_param_impl (ref_bind r) - : query_param (&r.ref), prec_ (r.prec) + : query_param (r.ptr ()), prec_ (r.prec) { } @@ -1962,7 +2134,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image ( @@ -1984,7 +2156,7 @@ namespace odb long_query_param_impl { query_param_impl (ref_bind r) - : query_param (&r.ref), prec_ (r.prec) + : query_param (r.ptr ()), prec_ (r.prec) { } @@ -2033,7 +2205,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image ( @@ -2053,7 +2225,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -2073,7 +2245,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -2091,7 +2263,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), scale_ (r.scale != 0xFFFF ? r.scale : 7) // Default is 7. { } @@ -2121,7 +2293,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, scale_, is_null, v); @@ -2140,7 +2312,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), scale_ (r.scale != 0xFFFF ? r.scale : 7) // Default to datetime2/7. { } @@ -2170,7 +2342,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, scale_, is_null, v); @@ -2189,7 +2361,7 @@ namespace odb struct query_param_impl: query_param { query_param_impl (ref_bind r) - : query_param (&r.ref), + : query_param (r.ptr ()), scale_ (r.scale != 0xFFFF ? r.scale : 7) // Default is 7. { } @@ -2219,7 +2391,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image ( @@ -2238,7 +2410,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -2258,7 +2430,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); @@ -2275,7 +2447,7 @@ namespace odb template struct query_param_impl: query_param { - query_param_impl (ref_bind r) : query_param (&r.ref) {} + query_param_impl (ref_bind r) : query_param (r.ptr ()) {} query_param_impl (val_bind v) : query_param (0) {init (v.val);} virtual bool @@ -2295,7 +2467,7 @@ namespace odb private: void - init (const T& v) + init (typename decay_traits::type v) { bool is_null (false); // Can't be NULL. value_traits::set_image (image_, is_null, v); -- cgit v1.1