aboutsummaryrefslogtreecommitdiff
path: root/odb/mysql/query.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-08-10 11:17:52 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-08-10 11:17:52 +0200
commit0a589394a09ce5b3f16d902d657710a2886cc2fc (patch)
tree08f5bfa47a0d07b0dc20352706342e17f277759f /odb/mysql/query.hxx
parentc67f076c75a36877ce142dc43a1ed2292ab8117a (diff)
Add query support
Diffstat (limited to 'odb/mysql/query.hxx')
-rw-r--r--odb/mysql/query.hxx828
1 files changed, 828 insertions, 0 deletions
diff --git a/odb/mysql/query.hxx b/odb/mysql/query.hxx
new file mode 100644
index 0000000..c322c3c
--- /dev/null
+++ b/odb/mysql/query.hxx
@@ -0,0 +1,828 @@
+// file : odb/mysql/query.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_MYSQL_QUERY_HXX
+#define ODB_MYSQL_QUERY_HXX
+
+#include <mysql/mysql.h>
+
+#include <string>
+#include <vector>
+#include <cstddef> // std::size_t
+
+#include <odb/shared-ptr.hxx>
+
+#include <odb/mysql/version.hxx>
+#include <odb/mysql/forward.hxx>
+#include <odb/mysql/traits.hxx>
+
+namespace odb
+{
+ namespace mysql
+ {
+ template <typename T>
+ class val_bind
+ {
+ public:
+ val_bind (const T& v): val (v) {}
+
+ const T& val;
+ };
+
+ template <typename T>
+ class ref_bind
+ {
+ public:
+ ref_bind (const T& r): ref (r) {}
+
+ const T& ref;
+ };
+
+ struct query_param: shared_base
+ {
+ virtual
+ ~query_param ();
+
+ bool
+ reference () const
+ {
+ return value_ != 0;
+ }
+
+ virtual void
+ init () = 0;
+
+ virtual void
+ bind (MYSQL_BIND*) = 0;
+
+ protected:
+ query_param (const void* value)
+ : value_ (value)
+ {
+ }
+
+ protected:
+ const void* value_;
+ };
+
+ class query
+ {
+ public:
+ query ()
+ {
+ }
+
+ explicit
+ query (const std::string& q)
+ : clause_ (q)
+ {
+ }
+
+ query (const query&);
+
+ query&
+ operator= (const query&);
+
+ public:
+ MYSQL_BIND*
+ parameters () const;
+
+ std::string
+ clause () const;
+
+ public:
+ template <typename T>
+ static val_bind<T>
+ _val (const T& x)
+ {
+ return val_bind<T> (x);
+ }
+
+ template <typename T>
+ static ref_bind<T>
+ _ref (const T& x)
+ {
+ return ref_bind<T> (x);
+ }
+
+ public:
+ query&
+ operator+= (const query& q)
+ {
+ clause_ += ' ';
+ clause_ += q.clause_;
+ }
+
+ query&
+ operator+= (const std::string& q)
+ {
+ clause_ += ' ';
+ clause_ += q;
+ }
+
+ template <typename T>
+ query&
+ operator+= (val_bind<T>);
+
+ template <typename T>
+ query&
+ operator+= (ref_bind<T>);
+
+ private:
+ void
+ add (shared_ptr<query_param>);
+
+ private:
+ typedef std::vector<shared_ptr<query_param> > parameters_type;
+
+ std::string clause_;
+ parameters_type parameters_;
+ std::vector<MYSQL_BIND> binding_;
+ };
+
+ inline query
+ operator+ (const query& x, const query& y)
+ {
+ query r (x);
+ r += y;
+ return r;
+ }
+
+ template <typename T>
+ inline query
+ operator+ (const query& q, val_bind<T> b)
+ {
+ query r (q);
+ r += b;
+ return r;
+ }
+
+ template <typename T>
+ inline query
+ operator+ (const query& q, ref_bind<T> b)
+ {
+ query r (q);
+ r += b;
+ return r;
+ }
+
+ template <typename T>
+ inline query
+ operator+ (val_bind<T> b, const query& q)
+ {
+ query r;
+ r += b;
+ r += q;
+ return r;
+ }
+
+ template <typename T>
+ inline query
+ operator+ (ref_bind<T> b, const query& q)
+ {
+ query r;
+ r += b;
+ r += q;
+ return r;
+ }
+
+ inline query
+ operator+ (const query& q, const std::string& s)
+ {
+ query r (q);
+ r += s;
+ return r;
+ }
+
+ inline query
+ operator+ (const std::string& s, const query& q)
+ {
+ query r (s);
+ r += q;
+ return r;
+ }
+
+ template <typename T>
+ inline query
+ operator+ (const std::string& s, val_bind<T> b)
+ {
+ query r (s);
+ r += b;
+ return r;
+ }
+
+ template <typename T>
+ inline query
+ operator+ (const std::string& s, ref_bind<T> b)
+ {
+ query r (s);
+ r += b;
+ return r;
+ }
+
+ template <typename T>
+ inline query
+ operator+ (val_bind<T> b, const std::string& s)
+ {
+ query r;
+ r += b;
+ r += s;
+ return r;
+ }
+
+ template <typename T>
+ inline query
+ operator+ (ref_bind<T> b, const std::string& s)
+ {
+ query r;
+ r += b;
+ r += s;
+ return r;
+ }
+
+ //
+ //
+ template <typename T, image_id_type>
+ struct query_param_impl;
+
+ // TINY
+ //
+ template <typename T>
+ struct query_param_impl<T, id_tiny>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_TINY;
+ b->is_unsigned = false;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ signed char image_;
+ };
+
+ template <typename T>
+ struct query_param_impl<T, id_utiny>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_TINY;
+ b->is_unsigned = true;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ unsigned char image_;
+ };
+
+ // SHORT
+ //
+ template <typename T>
+ struct query_param_impl<T, id_short>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_SHORT;
+ b->is_unsigned = false;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ short image_;
+ };
+
+ template <typename T>
+ struct query_param_impl<T, id_ushort>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_SHORT;
+ b->is_unsigned = true;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ unsigned short image_;
+ };
+
+ // LONG
+ //
+ template <typename T>
+ struct query_param_impl<T, id_long>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_LONG;
+ b->is_unsigned = false;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ int image_;
+ };
+
+ template <typename T>
+ struct query_param_impl<T, id_ulong>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_LONG;
+ b->is_unsigned = true;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ unsigned int image_;
+ };
+
+ // LONGLONG
+ //
+ template <typename T>
+ struct query_param_impl<T, id_longlong>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_LONGLONG;
+ b->is_unsigned = false;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ long long image_;
+ };
+
+ template <typename T>
+ struct query_param_impl<T, id_ulonglong>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_LONGLONG;
+ b->is_unsigned = true;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ unsigned long long image_;
+ };
+
+ // FLOAT
+ //
+ 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 (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_FLOAT;
+ b->is_unsigned = false;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ float image_;
+ };
+
+ // DOUBLE
+ //
+ 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 (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_DOUBLE;
+ b->is_unsigned = false;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ double image_;
+ };
+
+ // DATE
+ //
+ 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 (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_DATE;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ MYSQL_TIME image_;
+ };
+
+ // TIME
+ //
+ template <typename T>
+ struct query_param_impl<T, id_time>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_TIME;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ MYSQL_TIME image_;
+ };
+
+ // DATETIME
+ //
+ template <typename T>
+ struct query_param_impl<T, id_datetime>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_DATETIME;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ MYSQL_TIME image_;
+ };
+
+ // TIMESTAMP
+ //
+ template <typename T>
+ struct query_param_impl<T, id_timestamp>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_TIMESTAMP;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ MYSQL_TIME image_;
+ };
+
+ // YEAR
+ //
+ template <typename T>
+ struct query_param_impl<T, id_year>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_SHORT;
+ b->is_unsigned = false;
+ b->buffer = &image_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ value_traits<T>::set_image (image_, dummy, v);
+ }
+
+ private:
+ short image_;
+ };
+
+ // STRING
+ //
+ template <typename T>
+ struct query_param_impl<T, id_string>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_STRING;
+ b->buffer = buffer_.data ();
+ b->buffer_length = static_cast<unsigned long> (buffer_.capacity ());
+ b->length = &size_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ std::size_t size;
+ value_traits<T>::set_image (buffer_, size, dummy, v);
+ size_ = static_cast<unsigned long> (size);
+ }
+
+ private:
+ buffer buffer_;
+ unsigned long size_;
+ };
+
+ // BLOB
+ //
+ template <typename T>
+ struct query_param_impl<T, id_blob>: query_param
+ {
+ query_param_impl (ref_bind<T> r) : query_param (&r.ref) {}
+ query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);}
+
+ virtual void
+ init ()
+ {
+ init (*static_cast<const T*> (value_));
+ }
+
+ virtual void
+ bind (MYSQL_BIND* b)
+ {
+ b->buffer_type = MYSQL_TYPE_BLOB;
+ b->buffer = buffer_.data ();
+ b->buffer_length = static_cast<unsigned long> (buffer_.capacity ());
+ b->length = &size_;
+ }
+
+ private:
+ void
+ init (const T& v)
+ {
+ bool dummy;
+ std::size_t size;
+ value_traits<T>::set_image (buffer_, size, dummy, v);
+ size_ = static_cast<unsigned long> (size);
+ }
+
+ private:
+ buffer buffer_;
+ unsigned long size_;
+ };
+ }
+}
+
+#include <odb/mysql/query.txx>
+
+#endif // ODB_MYSQL_QUERY_HXX