| query.hxx | | query.hxx | |
| // file : odb/mysql/query.hxx | | // file : odb/mysql/query.hxx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_MYSQL_QUERY_HXX | | #ifndef ODB_MYSQL_QUERY_HXX | |
| #define ODB_MYSQL_QUERY_HXX | | #define ODB_MYSQL_QUERY_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <string> | | #include <string> | |
| #include <vector> | | #include <vector> | |
| #include <cstddef> // std::size_t | | #include <cstddef> // std::size_t | |
| | | | |
| #include <odb/query.hxx> | | #include <odb/query.hxx> | |
| | | | |
| #include <odb/mysql/mysql.hxx> | | #include <odb/mysql/mysql.hxx> | |
| #include <odb/mysql/version.hxx> | | #include <odb/mysql/version.hxx> | |
| #include <odb/mysql/forward.hxx> | | #include <odb/mysql/forward.hxx> | |
| #include <odb/mysql/traits.hxx> | | #include <odb/mysql/traits.hxx> | |
|
| | | #include <odb/mysql/binding.hxx> | |
| | | | |
| #include <odb/details/buffer.hxx> | | #include <odb/details/buffer.hxx> | |
| #include <odb/details/shared-ptr.hxx> | | #include <odb/details/shared-ptr.hxx> | |
| | | | |
| #include <odb/mysql/details/export.hxx> | | #include <odb/mysql/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace mysql | | namespace mysql | |
| { | | { | |
| | | | |
| skipping to change at line 62 | | skipping to change at line 63 | |
| { | | { | |
| virtual | | virtual | |
| ~query_param (); | | ~query_param (); | |
| | | | |
| bool | | bool | |
| reference () const | | reference () const | |
| { | | { | |
| return value_ != 0; | | return value_ != 0; | |
| } | | } | |
| | | | |
|
| virtual void | | virtual bool | |
| init () = 0; | | init () = 0; | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND*) = 0; | | bind (MYSQL_BIND*) = 0; | |
| | | | |
| protected: | | protected: | |
| query_param (const void* value) | | query_param (const void* value) | |
| : value_ (value) | | : value_ (value) | |
| { | | { | |
| } | | } | |
| | | | |
| skipping to change at line 87 | | skipping to change at line 88 | |
| | | | |
| // | | // | |
| // | | // | |
| template <typename T, database_type_id ID> | | template <typename T, database_type_id ID> | |
| struct query_column; | | struct query_column; | |
| | | | |
| class LIBODB_MYSQL_EXPORT query | | class LIBODB_MYSQL_EXPORT query | |
| { | | { | |
| public: | | public: | |
| query () | | query () | |
|
| | | : binding_ (0, 0) | |
| { | | { | |
| } | | } | |
| | | | |
| explicit | | explicit | |
| query (const std::string& q) | | query (const std::string& q) | |
|
| : clause_ (q) | | : clause_ (q), binding_ (0, 0) | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| explicit | | explicit | |
| query (val_bind<T> v) | | query (val_bind<T> v) | |
|
| | | : binding_ (0, 0) | |
| { | | { | |
| append<T, type_traits<T>::db_type_id> (v); | | append<T, type_traits<T>::db_type_id> (v); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| explicit | | explicit | |
| query (ref_bind<T> r) | | query (ref_bind<T> r) | |
|
| | | : binding_ (0, 0) | |
| { | | { | |
| append<T, type_traits<T>::db_type_id> (r); | | append<T, type_traits<T>::db_type_id> (r); | |
| } | | } | |
| | | | |
| template <database_type_id ID> | | template <database_type_id ID> | |
| query (const query_column<bool, ID>&); | | query (const query_column<bool, ID>&); | |
| | | | |
| query (const query&); | | query (const query&); | |
| | | | |
| query& | | query& | |
| operator= (const query&); | | operator= (const query&); | |
| | | | |
| public: | | public: | |
|
| MYSQL_BIND* | | binding& | |
| parameters () const; | | parameters () const; | |
| | | | |
| std::string | | std::string | |
| clause () const; | | clause () const; | |
| | | | |
| public: | | public: | |
| template <typename T> | | template <typename T> | |
| static val_bind<T> | | static val_bind<T> | |
| _val (const T& x) | | _val (const T& x) | |
| { | | { | |
| | | | |
| skipping to change at line 190 | | skipping to change at line 194 | |
| | | | |
| private: | | private: | |
| void | | void | |
| add (details::shared_ptr<query_param>); | | add (details::shared_ptr<query_param>); | |
| | | | |
| private: | | private: | |
| typedef std::vector<details::shared_ptr<query_param> > parameters_typ
e; | | typedef std::vector<details::shared_ptr<query_param> > parameters_typ
e; | |
| | | | |
| std::string clause_; | | std::string clause_; | |
| parameters_type parameters_; | | parameters_type parameters_; | |
|
| std::vector<MYSQL_BIND> binding_; | | mutable std::vector<MYSQL_BIND> bind_; | |
| | | mutable binding binding_; | |
| }; | | }; | |
| | | | |
| inline query | | inline query | |
| operator+ (const query& x, const query& y) | | operator+ (const query& x, const query& y) | |
| { | | { | |
| query r (x); | | query r (x); | |
| r += y; | | r += y; | |
| return r; | | return r; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1008 | | skipping to change at line 1013 | |
| struct query_param_impl; | | struct query_param_impl; | |
| | | | |
| // TINY | | // TINY | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_tiny>: query_param | | struct query_param_impl<T, id_tiny>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_TINY; | | b->buffer_type = MYSQL_TYPE_TINY; | |
| b->is_unsigned = false; | | b->is_unsigned = false; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1040 | | skipping to change at line 1046 | |
| private: | | private: | |
| signed char image_; | | signed char image_; | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_utiny>: query_param | | struct query_param_impl<T, id_utiny>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_TINY; | | b->buffer_type = MYSQL_TYPE_TINY; | |
| b->is_unsigned = true; | | b->is_unsigned = true; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1074 | | skipping to change at line 1081 | |
| }; | | }; | |
| | | | |
| // SHORT | | // SHORT | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_short>: query_param | | struct query_param_impl<T, id_short>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_SHORT; | | b->buffer_type = MYSQL_TYPE_SHORT; | |
| b->is_unsigned = false; | | b->is_unsigned = false; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1106 | | skipping to change at line 1114 | |
| private: | | private: | |
| short image_; | | short image_; | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_ushort>: query_param | | struct query_param_impl<T, id_ushort>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_SHORT; | | b->buffer_type = MYSQL_TYPE_SHORT; | |
| b->is_unsigned = true; | | b->is_unsigned = true; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1141 | | skipping to change at line 1150 | |
| }; | | }; | |
| | | | |
| // LONG | | // LONG | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_long>: query_param | | struct query_param_impl<T, id_long>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_LONG; | | b->buffer_type = MYSQL_TYPE_LONG; | |
| b->is_unsigned = false; | | b->is_unsigned = false; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1173 | | skipping to change at line 1183 | |
| private: | | private: | |
| int image_; | | int image_; | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_ulong>: query_param | | struct query_param_impl<T, id_ulong>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_LONG; | | b->buffer_type = MYSQL_TYPE_LONG; | |
| b->is_unsigned = true; | | b->is_unsigned = true; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1207 | | skipping to change at line 1218 | |
| }; | | }; | |
| | | | |
| // LONGLONG | | // LONGLONG | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_longlong>: query_param | | struct query_param_impl<T, id_longlong>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_LONGLONG; | | b->buffer_type = MYSQL_TYPE_LONGLONG; | |
| b->is_unsigned = false; | | b->is_unsigned = false; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1239 | | skipping to change at line 1251 | |
| private: | | private: | |
| long long image_; | | long long image_; | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_ulonglong>: query_param | | struct query_param_impl<T, id_ulonglong>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_LONGLONG; | | b->buffer_type = MYSQL_TYPE_LONGLONG; | |
| b->is_unsigned = true; | | b->is_unsigned = true; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1274 | | skipping to change at line 1287 | |
| }; | | }; | |
| | | | |
| // FLOAT | | // FLOAT | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_float>: query_param | | 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.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_FLOAT; | | b->buffer_type = MYSQL_TYPE_FLOAT; | |
| b->is_unsigned = false; | | b->is_unsigned = false; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1308 | | skipping to change at line 1322 | |
| }; | | }; | |
| | | | |
| // DOUBLE | | // DOUBLE | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_double>: query_param | | 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.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_DOUBLE; | | b->buffer_type = MYSQL_TYPE_DOUBLE; | |
| b->is_unsigned = false; | | b->is_unsigned = false; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1342 | | skipping to change at line 1357 | |
| }; | | }; | |
| | | | |
| // DECIMAL | | // DECIMAL | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_decimal>: query_param | | struct query_param_impl<T, id_decimal>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
|
| init (*static_cast<const T*> (value_)); | | return init (*static_cast<const T*> (value_)); | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_NEWDECIMAL; | | b->buffer_type = MYSQL_TYPE_NEWDECIMAL; | |
| b->buffer = buffer_.data (); | | b->buffer = buffer_.data (); | |
| b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | | b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | |
| b->length = &size_; | | b->length = &size_; | |
| } | | } | |
| | | | |
| private: | | private: | |
|
| void | | bool | |
| init (const T& v) | | init (const T& v) | |
| { | | { | |
| bool dummy; | | bool dummy; | |
|
| std::size_t size; | | std::size_t size, cap (buffer_.capacity ()); | |
| value_traits<T, details::buffer, id_decimal>::set_image ( | | value_traits<T, details::buffer, id_decimal>::set_image ( | |
| buffer_, size, dummy, v); | | buffer_, size, dummy, v); | |
| size_ = static_cast<unsigned long> (size); | | size_ = static_cast<unsigned long> (size); | |
|
| | | return cap != buffer_.capacity (); | |
| } | | } | |
| | | | |
| private: | | private: | |
| details::buffer buffer_; | | details::buffer buffer_; | |
| unsigned long size_; | | unsigned long size_; | |
| }; | | }; | |
| | | | |
| // DATE | | // DATE | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_date>: query_param | | 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.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_DATE; | | b->buffer_type = MYSQL_TYPE_DATE; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| private: | | private: | |
| | | | |
| skipping to change at line 1414 | | skipping to change at line 1431 | |
| }; | | }; | |
| | | | |
| // TIME | | // TIME | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_time>: query_param | | struct query_param_impl<T, id_time>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_TIME; | | b->buffer_type = MYSQL_TYPE_TIME; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| private: | | private: | |
| | | | |
| skipping to change at line 1447 | | skipping to change at line 1465 | |
| }; | | }; | |
| | | | |
| // DATETIME | | // DATETIME | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_datetime>: query_param | | struct query_param_impl<T, id_datetime>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_DATETIME; | | b->buffer_type = MYSQL_TYPE_DATETIME; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| private: | | private: | |
| | | | |
| skipping to change at line 1480 | | skipping to change at line 1499 | |
| }; | | }; | |
| | | | |
| // TIMESTAMP | | // TIMESTAMP | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_timestamp>: query_param | | struct query_param_impl<T, id_timestamp>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_TIMESTAMP; | | b->buffer_type = MYSQL_TYPE_TIMESTAMP; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| private: | | private: | |
| | | | |
| skipping to change at line 1514 | | skipping to change at line 1534 | |
| }; | | }; | |
| | | | |
| // YEAR | | // YEAR | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_year>: query_param | | struct query_param_impl<T, id_year>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_SHORT; | | b->buffer_type = MYSQL_TYPE_SHORT; | |
| b->is_unsigned = false; | | b->is_unsigned = false; | |
| b->buffer = &image_; | | b->buffer = &image_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1548 | | skipping to change at line 1569 | |
| }; | | }; | |
| | | | |
| // STRING | | // STRING | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_string>: query_param | | struct query_param_impl<T, id_string>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
|
| init (*static_cast<const T*> (value_)); | | return init (*static_cast<const T*> (value_)); | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_STRING; | | b->buffer_type = MYSQL_TYPE_STRING; | |
| b->buffer = buffer_.data (); | | b->buffer = buffer_.data (); | |
| b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | | b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | |
| b->length = &size_; | | b->length = &size_; | |
| } | | } | |
| | | | |
| private: | | private: | |
|
| void | | bool | |
| init (const T& v) | | init (const T& v) | |
| { | | { | |
| bool dummy; | | bool dummy; | |
|
| std::size_t size; | | std::size_t size, cap (buffer_.capacity ()); | |
| value_traits<T, details::buffer, id_string>::set_image ( | | value_traits<T, details::buffer, id_string>::set_image ( | |
| buffer_, size, dummy, v); | | buffer_, size, dummy, v); | |
| size_ = static_cast<unsigned long> (size); | | size_ = static_cast<unsigned long> (size); | |
|
| | | return cap != buffer_.capacity (); | |
| } | | } | |
| | | | |
| private: | | private: | |
| details::buffer buffer_; | | details::buffer buffer_; | |
| unsigned long size_; | | unsigned long size_; | |
| }; | | }; | |
| | | | |
| // BLOB | | // BLOB | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_blob>: query_param | | struct query_param_impl<T, id_blob>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
|
| init (*static_cast<const T*> (value_)); | | return init (*static_cast<const T*> (value_)); | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_BLOB; | | b->buffer_type = MYSQL_TYPE_BLOB; | |
| b->buffer = buffer_.data (); | | b->buffer = buffer_.data (); | |
| b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | | b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | |
| b->length = &size_; | | b->length = &size_; | |
| } | | } | |
| | | | |
| private: | | private: | |
|
| void | | bool | |
| init (const T& v) | | init (const T& v) | |
| { | | { | |
| bool dummy; | | bool dummy; | |
|
| std::size_t size; | | std::size_t size, cap (buffer_.capacity ()); | |
| value_traits<T, details::buffer, id_blob>::set_image ( | | value_traits<T, details::buffer, id_blob>::set_image ( | |
| buffer_, size, dummy, v); | | buffer_, size, dummy, v); | |
| size_ = static_cast<unsigned long> (size); | | size_ = static_cast<unsigned long> (size); | |
|
| | | return cap != buffer_.capacity (); | |
| } | | } | |
| | | | |
| private: | | private: | |
| details::buffer buffer_; | | details::buffer buffer_; | |
| unsigned long size_; | | unsigned long size_; | |
| }; | | }; | |
| | | | |
| // BIT | | // BIT | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_bit>: query_param | | struct query_param_impl<T, id_bit>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
| init (*static_cast<const T*> (value_)); | | init (*static_cast<const T*> (value_)); | |
|
| | | return false; | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_BLOB; | | b->buffer_type = MYSQL_TYPE_BLOB; | |
| b->buffer = buffer_; | | b->buffer = buffer_; | |
| b->buffer_length = static_cast<unsigned long> (sizeof (buffer_)); | | b->buffer_length = static_cast<unsigned long> (sizeof (buffer_)); | |
| b->length = &size_; | | b->length = &size_; | |
| } | | } | |
| | | | |
| skipping to change at line 1667 | | skipping to change at line 1691 | |
| }; | | }; | |
| | | | |
| // ENUM | | // ENUM | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_enum>: query_param | | struct query_param_impl<T, id_enum>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
|
| init (*static_cast<const T*> (value_)); | | return init (*static_cast<const T*> (value_)); | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_STRING; | | b->buffer_type = MYSQL_TYPE_STRING; | |
| b->buffer = buffer_.data (); | | b->buffer = buffer_.data (); | |
| b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | | b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | |
| b->length = &size_; | | b->length = &size_; | |
| } | | } | |
| | | | |
| private: | | private: | |
|
| void | | bool | |
| init (const T& v) | | init (const T& v) | |
| { | | { | |
| bool dummy; | | bool dummy; | |
|
| std::size_t size; | | std::size_t size, cap (buffer_.capacity ()); | |
| value_traits<T, details::buffer, id_enum>::set_image ( | | value_traits<T, details::buffer, id_enum>::set_image ( | |
| buffer_, size, dummy, v); | | buffer_, size, dummy, v); | |
| size_ = static_cast<unsigned long> (size); | | size_ = static_cast<unsigned long> (size); | |
|
| | | return cap != buffer_.capacity (); | |
| } | | } | |
| | | | |
| private: | | private: | |
| details::buffer buffer_; | | details::buffer buffer_; | |
| unsigned long size_; | | unsigned long size_; | |
| }; | | }; | |
| | | | |
| // SET | | // SET | |
| // | | // | |
| template <typename T> | | template <typename T> | |
| struct query_param_impl<T, id_set>: query_param | | struct query_param_impl<T, id_set>: query_param | |
| { | | { | |
| query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | | query_param_impl (ref_bind<T> r) : query_param (&r.ref) {} | |
| query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | | query_param_impl (val_bind<T> v) : query_param (0) {init (v.val);} | |
| | | | |
|
| virtual void | | virtual bool | |
| init () | | init () | |
| { | | { | |
|
| init (*static_cast<const T*> (value_)); | | return init (*static_cast<const T*> (value_)); | |
| } | | } | |
| | | | |
| virtual void | | virtual void | |
| bind (MYSQL_BIND* b) | | bind (MYSQL_BIND* b) | |
| { | | { | |
| b->buffer_type = MYSQL_TYPE_STRING; | | b->buffer_type = MYSQL_TYPE_STRING; | |
| b->buffer = buffer_.data (); | | b->buffer = buffer_.data (); | |
| b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | | b->buffer_length = static_cast<unsigned long> (buffer_.capacity ())
; | |
| b->length = &size_; | | b->length = &size_; | |
| } | | } | |
| | | | |
| private: | | private: | |
|
| void | | bool | |
| init (const T& v) | | init (const T& v) | |
| { | | { | |
| bool dummy; | | bool dummy; | |
|
| std::size_t size; | | std::size_t size, cap (buffer_.capacity ()); | |
| value_traits<T, details::buffer, id_set>::set_image ( | | value_traits<T, details::buffer, id_set>::set_image ( | |
| buffer_, size, dummy, v); | | buffer_, size, dummy, v); | |
| size_ = static_cast<unsigned long> (size); | | size_ = static_cast<unsigned long> (size); | |
|
| | | return cap != buffer_.capacity (); | |
| } | | } | |
| | | | |
| private: | | private: | |
| details::buffer buffer_; | | details::buffer buffer_; | |
| unsigned long size_; | | unsigned long size_; | |
| }; | | }; | |
| } | | } | |
| } | | } | |
| | | | |
| // odb::query specialization for MySQL. | | // odb::query specialization for MySQL. | |
| | | | |
End of changes. 66 change blocks. |
| 41 lines changed or deleted | | 67 lines changed or added | |
|
| result.txx | | result.txx | |
| // file : odb/mysql/result.txx | | // file : odb/mysql/result.txx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
|
| | | #include <odb/exceptions.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace mysql | | namespace mysql | |
| { | | { | |
| template <typename T> | | template <typename T> | |
| result_impl<T>:: | | result_impl<T>:: | |
| ~result_impl () | | ~result_impl () | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| result_impl<T>:: | | result_impl<T>:: | |
|
| result_impl (details::shared_ptr<query_statement> statement, | | result_impl (details::shared_ptr<select_statement> statement, | |
| object_statements<T>& statements) | | object_statements<object_type>& statements) | |
| : statement_ (statement), statements_ (statements) | | : odb::result_impl<T> (statements.connection ().database ()), | |
| | | statement_ (statement), | |
| | | statements_ (statements), | |
| | | count_ (0) | |
| { | | { | |
|
| next (); | | | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void result_impl<T>:: | | void result_impl<T>:: | |
|
| current () | | load (object_type& obj) | |
| { | | { | |
|
| if (!this->end_) | | if (count_ > statement_->fetched ()) | |
| { | | fetch (); | |
| pointer_type p (traits::create ()); | | | |
| current (p); | | // This is a top-level call so the statements cannot be locked. | |
| traits::init (pointer_traits::get_ref (p), statements_.image ()); | | // | |
| } | | assert (!statements_.locked ()); | |
| | | typename object_statements<object_type>::auto_lock l (statements_); | |
| | | | |
| | | typename object_traits::image_type& im (statements_.image ()); | |
| | | object_traits::init (obj, im, this->database ()); | |
| | | | |
| | | // Initialize the id image and load the rest of the object | |
| | | // (containers, etc). | |
| | | // | |
| | | object_traits::init (statements_.id_image (), object_traits::id (im)) | |
| | | ; | |
| | | object_traits::load_ (statements_, obj); | |
| | | | |
| | | statements_.load_delayed (); | |
| | | l.unlock (); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| void result_impl<T>:: | | typename result_impl<T>::id_type result_impl<T>:: | |
| current (T& x) | | load_id () | |
| { | | { | |
|
| if (!this->end_) | | if (count_ > statement_->fetched ()) | |
| traits::init (x, statements_.image ()); | | fetch (); | |
| | | | |
| | | return object_traits::id (statements_.image ()); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void result_impl<T>:: | | void result_impl<T>:: | |
| next () | | next () | |
| { | | { | |
| this->current (pointer_type ()); | | this->current (pointer_type ()); | |
|
| query_statement::result r (statement_->fetch ()); | | | |
| | | | |
|
| switch (r) | | // If we are cached, simply increment the position and | |
| | | // postpone the actual row fetching until later. This way | |
| | | // if the same object is loaded in between iteration, the | |
| | | // image won't be messed up. | |
| | | // | |
| | | count_++; | |
| | | | |
| | | if (statement_->cached ()) | |
| | | this->end_ = count_ > statement_->result_size (); | |
| | | else | |
| | | fetch (); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | void result_impl<T>:: | |
| | | fetch () | |
| | | { | |
| | | // If the result is cached, the image can grow between calls | |
| | | // to fetch() as a result of other statements execution. | |
| | | // | |
| | | if (statement_->cached ()) | |
| { | | { | |
|
| case query_statement::truncated: | | typename object_traits::image_type& im (statements_.image ()); | |
| { | | | |
| typename traits::image_type& i (statements_.image ()); | | | |
| | | | |
|
| if (traits::grow (i, statements_.image_error ())) | | if (im.version != statements_.out_image_version ()) | |
| { | | | |
| traits::bind (statements_.image_binding (), i); | | | |
| statement_->refetch (); | | | |
| } | | | |
| // Fall throught. | | | |
| } | | | |
| case query_statement::success: | | | |
| { | | { | |
|
| break; | | binding& b (statements_.out_image_binding ()); | |
| | | object_traits::bind (b.bind, im, true); | |
| | | statements_.out_image_version (im.version); | |
| | | b.version++; | |
| } | | } | |
|
| case query_statement::no_data: | | } | |
| | | | |
| | | while (count_ > statement_->fetched ()) | |
| | | { | |
| | | select_statement::result r (statement_->fetch ()); | |
| | | | |
| | | switch (r) | |
| { | | { | |
|
| this->end_ = true; | | case select_statement::truncated: | |
| break; | | { | |
| | | // Don't re-fetch data we are skipping. | |
| | | // | |
| | | if (count_ != statement_->fetched ()) | |
| | | continue; | |
| | | | |
| | | typename object_traits::image_type& im (statements_.image ()); | |
| | | object_traits::grow (im, statements_.out_image_error ()); | |
| | | | |
| | | if (im.version != statements_.out_image_version ()) | |
| | | { | |
| | | binding& b (statements_.out_image_binding ()); | |
| | | object_traits::bind (b.bind, im, true); | |
| | | statements_.out_image_version (im.version); | |
| | | b.version++; | |
| | | statement_->refetch (); | |
| | | } | |
| | | // Fall throught. | |
| | | } | |
| | | case select_statement::success: | |
| | | { | |
| | | break; | |
| | | } | |
| | | case select_statement::no_data: | |
| | | { | |
| | | this->end_ = true; | |
| | | break; | |
| | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void result_impl<T>:: | | void result_impl<T>:: | |
| cache () | | cache () | |
| { | | { | |
|
| statement_->cache (); | | if (!statement_->cached ()) | |
| | | { | |
| | | statement_->cache (); | |
| | | | |
| | | if (count_ >= statement_->result_size ()) | |
| | | this->end_ = true; | |
| | | } | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| std::size_t result_impl<T>:: | | std::size_t result_impl<T>:: | |
| size () | | size () | |
| { | | { | |
|
| | | if (!statement_->cached ()) | |
| | | throw result_not_cached (); | |
| | | | |
| return statement_->result_size (); | | return statement_->result_size (); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 17 change blocks. |
| 34 lines changed or deleted | | 109 lines changed or added | |
|
| statement.hxx | | statement.hxx | |
| // file : odb/mysql/statement.hxx | | // file : odb/mysql/statement.hxx | |
| // author : Boris Kolpackov <boris@codesynthesis.com> | | // author : Boris Kolpackov <boris@codesynthesis.com> | |
|
| // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC | | // copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_MYSQL_STATEMENT_HXX | | #ifndef ODB_MYSQL_STATEMENT_HXX | |
| #define ODB_MYSQL_STATEMENT_HXX | | #define ODB_MYSQL_STATEMENT_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
|
| #include <map> | | | |
| #include <string> | | #include <string> | |
| #include <cstddef> // std::size_t | | #include <cstddef> // std::size_t | |
|
| #include <typeinfo> | | | |
| | | | |
| #include <odb/forward.hxx> | | #include <odb/forward.hxx> | |
|
| #include <odb/traits.hxx> | | | |
| | | | |
| #include <odb/mysql/mysql.hxx> | | #include <odb/mysql/mysql.hxx> | |
| #include <odb/mysql/version.hxx> | | #include <odb/mysql/version.hxx> | |
|
| | | #include <odb/mysql/binding.hxx> | |
| | | | |
| #include <odb/details/shared-ptr.hxx> | | #include <odb/details/shared-ptr.hxx> | |
| | | | |
| #include <odb/mysql/details/export.hxx> | | #include <odb/mysql/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace mysql | | namespace mysql | |
| { | | { | |
| class connection; | | class connection; | |
| | | | |
|
| class LIBODB_MYSQL_EXPORT binding | | | |
| { | | | |
| public: | | | |
| binding (MYSQL_BIND* b, std::size_t n) | | | |
| : bind (b), count (n), version (0) | | | |
| { | | | |
| } | | | |
| | | | |
| MYSQL_BIND* bind; | | | |
| std::size_t count; | | | |
| std::size_t version; | | | |
| | | | |
| private: | | | |
| binding (const binding&); | | | |
| binding& operator= (const binding&); | | | |
| }; | | | |
| | | | |
| class LIBODB_MYSQL_EXPORT statement: public details::shared_base | | class LIBODB_MYSQL_EXPORT statement: public details::shared_base | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
| ~statement () = 0; | | ~statement () = 0; | |
| | | | |
| // Cancel the statement execution (e.g., result fetching) so | | // Cancel the statement execution (e.g., result fetching) so | |
| // that another statement can be executed on the connection. | | // that another statement can be executed on the connection. | |
| // | | // | |
| virtual void | | virtual void | |
| cancel (); | | cancel (); | |
| | | | |
| protected: | | protected: | |
| statement (connection&); | | statement (connection&); | |
| | | | |
| protected: | | protected: | |
| connection& conn_; | | connection& conn_; | |
| MYSQL_STMT* stmt_; | | MYSQL_STMT* stmt_; | |
| }; | | }; | |
| | | | |
|
| class LIBODB_MYSQL_EXPORT query_statement: public statement | | class LIBODB_MYSQL_EXPORT select_statement: public statement | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
|
| ~query_statement (); | | ~select_statement (); | |
| | | | |
|
| query_statement (connection& conn, | | select_statement (connection& conn, | |
| const std::string& statement, | | const std::string& statement, | |
| binding& image, | | binding& cond, | |
| MYSQL_BIND* parameters); | | binding& data); | |
| enum result | | enum result | |
| { | | { | |
| success, | | success, | |
| no_data, | | no_data, | |
| truncated | | truncated | |
| }; | | }; | |
| | | | |
| void | | void | |
| execute (); | | execute (); | |
| | | | |
| void | | void | |
| cache (); | | cache (); | |
| | | | |
|
| | | bool | |
| | | cached () const | |
| | | { | |
| | | return cached_; | |
| | | } | |
| | | | |
| | | // Can only be called on a cached result. | |
| | | // | |
| std::size_t | | std::size_t | |
|
| result_size (); | | result_size () const | |
| | | { | |
| | | return size_; | |
| | | } | |
| | | | |
| | | // Number of rows already fetched. | |
| | | // | |
| | | std::size_t | |
| | | fetched () const | |
| | | { | |
| | | return rows_; | |
| | | } | |
| | | | |
| result | | result | |
| fetch (); | | fetch (); | |
| | | | |
| void | | void | |
| refetch (); | | refetch (); | |
| | | | |
| void | | void | |
| free_result (); | | free_result (); | |
| | | | |
| virtual void | | virtual void | |
| cancel (); | | cancel (); | |
| | | | |
| private: | | private: | |
|
| query_statement (const query_statement&); | | select_statement (const select_statement&); | |
| query_statement& operator= (const query_statement&); | | select_statement& operator= (const select_statement&); | |
| | | | |
| private: | | private: | |
| bool end_; | | bool end_; | |
| bool cached_; | | bool cached_; | |
| std::size_t rows_; | | std::size_t rows_; | |
|
| | | std::size_t size_; | |
| | | | |
|
| binding& image_; | | binding& cond_; | |
| std::size_t image_version_; | | std::size_t cond_version_; | |
| | | | |
|
| MYSQL_BIND* parameters_; | | binding& data_; | |
| | | std::size_t data_version_; | |
| }; | | }; | |
| | | | |
|
| class LIBODB_MYSQL_EXPORT persist_statement: public statement | | class LIBODB_MYSQL_EXPORT insert_statement: public statement | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
|
| ~persist_statement (); | | ~insert_statement (); | |
| | | | |
|
| persist_statement (connection& conn, | | insert_statement (connection& conn, | |
| const std::string& statement, | | const std::string& statement, | |
| binding& image); | | binding& data); | |
| | | | |
|
| void | | // Return true if successful and false if the row is a duplicate. | |
| execute (); | | // All other errors are reported by throwing exceptions. | |
| | | // | |
| | | bool | |
| | | execute (); | |
| | | | |
| unsigned long long | | unsigned long long | |
| id () | | id () | |
| { | | { | |
|
| return mysql_stmt_insert_id (stmt_); | | return static_cast<unsigned long long> ( | |
| | | mysql_stmt_insert_id (stmt_)); | |
| } | | } | |
| | | | |
| private: | | private: | |
|
| persist_statement (const persist_statement&); | | insert_statement (const insert_statement&); | |
| persist_statement& operator= (const persist_statement&); | | insert_statement& operator= (const insert_statement&); | |
| | | | |
| private: | | private: | |
|
| binding& image_; | | binding& data_; | |
| std::size_t version_; | | std::size_t data_version_; | |
| }; | | | |
| | | | |
| class LIBODB_MYSQL_EXPORT find_statement: public statement | | | |
| { | | | |
| public: | | | |
| virtual | | | |
| ~find_statement (); | | | |
| | | | |
| find_statement (connection& conn, | | | |
| const std::string& statement, | | | |
| binding& id, | | | |
| binding& image); | | | |
| enum result | | | |
| { | | | |
| success, | | | |
| no_data, | | | |
| truncated | | | |
| }; | | | |
| | | | |
| // You are expected to call free_result() if this function | | | |
| // returns success or truncated. | | | |
| // | | | |
| result | | | |
| execute (); | | | |
| | | | |
| void | | | |
| refetch (); | | | |
| | | | |
| void | | | |
| free_result (); | | | |
| | | | |
| void | | | |
| cancel (); | | | |
| | | | |
| private: | | | |
| find_statement (const find_statement&); | | | |
| find_statement& operator= (const find_statement&); | | | |
| | | | |
| private: | | | |
| binding& id_; | | | |
| std::size_t id_version_; | | | |
| | | | |
| binding& image_; | | | |
| std::size_t image_version_; | | | |
| }; | | }; | |
| | | | |
| class LIBODB_MYSQL_EXPORT update_statement: public statement | | class LIBODB_MYSQL_EXPORT update_statement: public statement | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
| ~update_statement (); | | ~update_statement (); | |
| | | | |
| update_statement (connection& conn, | | update_statement (connection& conn, | |
| const std::string& statement, | | const std::string& statement, | |
| | | | |
| skipping to change at line 219 | | skipping to change at line 181 | |
| update_statement& operator= (const update_statement&); | | update_statement& operator= (const update_statement&); | |
| | | | |
| private: | | private: | |
| binding& id_; | | binding& id_; | |
| std::size_t id_version_; | | std::size_t id_version_; | |
| | | | |
| binding& image_; | | binding& image_; | |
| std::size_t image_version_; | | std::size_t image_version_; | |
| }; | | }; | |
| | | | |
|
| class LIBODB_MYSQL_EXPORT erase_statement: public statement | | class LIBODB_MYSQL_EXPORT delete_statement: public statement | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
|
| ~erase_statement (); | | ~delete_statement (); | |
| | | | |
|
| erase_statement (connection& conn, | | delete_statement (connection& conn, | |
| const std::string& statement, | | const std::string& statement, | |
| binding& id); | | binding& cond); | |
| | | | |
|
| void | | unsigned long long | |
| execute (); | | execute (); | |
| | | | |
| private: | | private: | |
|
| erase_statement (const erase_statement&); | | delete_statement (const delete_statement&); | |
| erase_statement& operator= (const erase_statement&); | | delete_statement& operator= (const delete_statement&); | |
| | | | |
| private: | | | |
| binding& id_; | | | |
| std::size_t version_; | | | |
| }; | | | |
| | | | |
| // Statement cache. | | | |
| // | | | |
| | | | |
| class LIBODB_MYSQL_EXPORT object_statements_base: | | | |
| public details::shared_base | | | |
| { | | | |
| public: | | | |
| virtual | | | |
| ~object_statements_base (); | | | |
| | | | |
| protected: | | | |
| object_statements_base (connection& conn) | | | |
| : conn_ (conn) | | | |
| { | | | |
| } | | | |
| | | | |
| protected: | | | |
| connection& conn_; | | | |
| }; | | | |
| | | | |
| template <typename T> | | | |
| class object_statements: public object_statements_base | | | |
| { | | | |
| public: | | | |
| typedef odb::object_traits<T> object_traits; | | | |
| typedef typename object_traits::image_type image_type; | | | |
| typedef typename object_traits::id_image_type id_image_type; | | | |
| | | | |
| typedef mysql::persist_statement persist_statement_type; | | | |
| typedef mysql::find_statement find_statement_type; | | | |
| typedef mysql::update_statement update_statement_type; | | | |
| typedef mysql::erase_statement erase_statement_type; | | | |
| | | | |
| object_statements (connection&); | | | |
| | | | |
| image_type& | | | |
| image () | | | |
| { | | | |
| return image_; | | | |
| } | | | |
| | | | |
| binding& | | | |
| image_binding () | | | |
| { | | | |
| return image_binding_; | | | |
| } | | | |
| | | | |
| my_bool* | | | |
| image_error () | | | |
| { | | | |
| return image_error_; | | | |
| } | | | |
| | | | |
| id_image_type& | | | |
| id_image () | | | |
| { | | | |
| return id_image_; | | | |
| } | | | |
| | | | |
| binding& | | | |
| id_image_binding () | | | |
| { | | | |
| return id_image_binding_; | | | |
| } | | | |
| | | | |
| persist_statement_type& | | | |
| persist_statement () | | | |
| { | | | |
| if (persist_ == 0) | | | |
| persist_.reset ( | | | |
| new (details::shared) persist_statement_type ( | | | |
| conn_, object_traits::persist_statement, image_binding_)); | | | |
| | | | |
| return *persist_; | | | |
| } | | | |
| | | | |
| find_statement_type& | | | |
| find_statement () | | | |
| { | | | |
| if (find_ == 0) | | | |
| find_.reset ( | | | |
| new (details::shared) find_statement_type ( | | | |
| conn_, | | | |
| object_traits::find_statement, | | | |
| id_image_binding_, | | | |
| image_binding_)); | | | |
| | | | |
| return *find_; | | | |
| } | | | |
| | | | |
| update_statement_type& | | | |
| update_statement () | | | |
| { | | | |
| if (update_ == 0) | | | |
| update_.reset ( | | | |
| new (details::shared) update_statement_type ( | | | |
| conn_, | | | |
| object_traits::update_statement, | | | |
| id_image_binding_, | | | |
| image_binding_)); | | | |
| | | | |
| return *update_; | | | |
| } | | | |
| | | | |
| erase_statement_type& | | | |
| erase_statement () | | | |
| { | | | |
| if (erase_ == 0) | | | |
| erase_.reset ( | | | |
| new (details::shared) erase_statement_type ( | | | |
| conn_, | | | |
| object_traits::erase_statement, | | | |
| id_image_binding_)); | | | |
| | | | |
| return *erase_; | | | |
| } | | | |
| | | | |
| private: | | | |
| object_statements (const object_statements&); | | | |
| object_statements& operator= (const object_statements&); | | | |
| | | | |
| private: | | | |
| // The last element is the id parameter. The update statement | | | |
| // depends on this being one contiguous arrays. | | | |
| // | | | |
| MYSQL_BIND image_bind_[object_traits::column_count + 1]; | | | |
| | | | |
| image_type image_; | | | |
| my_bool image_error_[object_traits::column_count]; | | | |
| binding image_binding_; | | | |
| | | | |
| id_image_type id_image_; | | | |
| binding id_image_binding_; | | | |
| | | | |
| details::shared_ptr<persist_statement_type> persist_; | | | |
| details::shared_ptr<find_statement_type> find_; | | | |
| details::shared_ptr<update_statement_type> update_; | | | |
| details::shared_ptr<erase_statement_type> erase_; | | | |
| }; | | | |
| | | | |
| struct LIBODB_MYSQL_EXPORT type_info_comparator | | | |
| { | | | |
| bool | | | |
| operator() (const std::type_info* x, const std::type_info* y) const | | | |
| { | | | |
| // XL C++ on AIX has buggy type_info::before() in that | | | |
| // it returns true for two different type_info objects | | | |
| // that happened to be for the same type. | | | |
| // | | | |
| #if defined(__xlC__) && defined(_AIX) | | | |
| return *x != *y && x->before (*y); | | | |
| #else | | | |
| return x->before (*y); | | | |
| #endif | | | |
| } | | | |
| }; | | | |
| | | | |
| class LIBODB_MYSQL_EXPORT statement_cache | | | |
| { | | | |
| public: | | | |
| statement_cache (connection& conn) | | | |
| : conn_ (conn) | | | |
| { | | | |
| } | | | |
| | | | |
| template <typename T> | | | |
| object_statements<T>& | | | |
| find () | | | |
| { | | | |
| map::iterator i (map_.find (&typeid (T))); | | | |
| | | | |
| if (i != map_.end ()) | | | |
| return static_cast<object_statements<T>&> (*i->second); | | | |
| | | | |
| details::shared_ptr<object_statements<T> > p ( | | | |
| new (details::shared) object_statements<T> (conn_)); | | | |
| | | | |
| map_.insert (map::value_type (&typeid (T), p)); | | | |
| return *p; | | | |
| } | | | |
| | | | |
| private: | | private: | |
|
| typedef std::map<const std::type_info*, | | binding& cond_; | |
| details::shared_ptr<object_statements_base>, | | std::size_t cond_version_; | |
| type_info_comparator> map; | | | |
| | | | |
| connection& conn_; | | | |
| map map_; | | | |
| }; | | }; | |
| } | | } | |
| } | | } | |
| | | | |
|
| #include <odb/mysql/statement.txx> | | | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_MYSQL_STATEMENT_HXX | | #endif // ODB_MYSQL_STATEMENT_HXX | |
| | | | |
End of changes. 29 change blocks. |
| 291 lines changed or deleted | | 61 lines changed or added | |
|