| object-result.hxx | | object-result.hxx | |
| | | | |
| skipping to change at line 25 | | skipping to change at line 25 | |
| #include <odb/sqlite/version.hxx> | | #include <odb/sqlite/version.hxx> | |
| #include <odb/sqlite/forward.hxx> // query, object_statements | | #include <odb/sqlite/forward.hxx> // query, object_statements | |
| #include <odb/sqlite/result.hxx> | | #include <odb/sqlite/result.hxx> | |
| #include <odb/sqlite/statement.hxx> | | #include <odb/sqlite/statement.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace sqlite | | namespace sqlite | |
| { | | { | |
| template <typename T> | | template <typename T> | |
|
| class result_impl<T, class_object>: | | class object_result_impl: public odb::object_result_impl<T>, | |
| public odb::result_impl<T, class_object>, | | public result_impl_base | |
| public result_impl_base | | | |
| { | | { | |
| public: | | public: | |
|
| typedef odb::result_impl<T, class_object> base_type; | | typedef odb::object_result_impl<T> base_type; | |
| | | | |
| typedef typename base_type::object_traits object_traits; | | typedef typename base_type::object_traits object_traits; | |
| typedef typename base_type::object_type object_type; | | typedef typename base_type::object_type object_type; | |
| typedef typename base_type::id_type id_type; | | typedef typename base_type::id_type id_type; | |
| | | | |
| typedef typename base_type::pointer_type pointer_type; | | typedef typename base_type::pointer_type pointer_type; | |
| typedef typename base_type::pointer_traits pointer_traits; | | typedef typename base_type::pointer_traits pointer_traits; | |
| | | | |
| virtual | | virtual | |
|
| ~result_impl (); | | ~object_result_impl (); | |
| | | | |
|
| result_impl (const query&, | | object_result_impl (const query&, | |
| details::shared_ptr<select_statement>, | | details::shared_ptr<select_statement>, | |
| object_statements<object_type>&); | | object_statements<object_type>&); | |
| | | | |
| virtual void | | virtual void | |
|
| load (object_type&); | | load (object_type&, bool fetch); | |
| | | | |
| virtual id_type | | virtual id_type | |
| load_id (); | | load_id (); | |
| | | | |
| virtual void | | virtual void | |
| next (); | | next (); | |
| | | | |
| virtual void | | virtual void | |
| cache (); | | cache (); | |
| | | | |
| | | | |
| skipping to change at line 70 | | skipping to change at line 69 | |
| | | | |
| using base_type::current; | | using base_type::current; | |
| | | | |
| private: | | private: | |
| void | | void | |
| load_image (); | | load_image (); | |
| | | | |
| private: | | private: | |
| object_statements<object_type>& statements_; | | object_statements<object_type>& statements_; | |
| }; | | }; | |
|
| | | | |
| | | template <typename T> | |
| | | class object_result_impl_no_id: public odb::object_result_impl_no_id<T> | |
| | | , | |
| | | public result_impl_base | |
| | | { | |
| | | public: | |
| | | typedef odb::object_result_impl_no_id<T> base_type; | |
| | | | |
| | | typedef typename base_type::object_traits object_traits; | |
| | | typedef typename base_type::object_type object_type; | |
| | | | |
| | | typedef typename base_type::pointer_type pointer_type; | |
| | | typedef typename base_type::pointer_traits pointer_traits; | |
| | | | |
| | | virtual | |
| | | ~object_result_impl_no_id (); | |
| | | | |
| | | object_result_impl_no_id (const query&, | |
| | | details::shared_ptr<select_statement>, | |
| | | object_statements_no_id<object_type>&); | |
| | | | |
| | | virtual void | |
| | | load (object_type&); | |
| | | | |
| | | virtual void | |
| | | next (); | |
| | | | |
| | | virtual void | |
| | | cache (); | |
| | | | |
| | | virtual std::size_t | |
| | | size (); | |
| | | | |
| | | using base_type::current; | |
| | | | |
| | | private: | |
| | | object_statements_no_id<object_type>& statements_; | |
| | | }; | |
| } | | } | |
| } | | } | |
| | | | |
| #include <odb/sqlite/object-result.txx> | | #include <odb/sqlite/object-result.txx> | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_SQLITE_OBJECT_RESULT_HXX | | #endif // ODB_SQLITE_OBJECT_RESULT_HXX | |
| | | | |
End of changes. 6 change blocks. |
| 9 lines changed or deleted | | 47 lines changed or added | |
|
| object-result.txx | | object-result.txx | |
| | | | |
| skipping to change at line 15 | | skipping to change at line 15 | |
| | | | |
| #include <odb/callback.hxx> | | #include <odb/callback.hxx> | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| | | | |
| #include <odb/sqlite/object-statements.hxx> | | #include <odb/sqlite/object-statements.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace sqlite | | namespace sqlite | |
| { | | { | |
|
| | | // | |
| | | // object_result_impl | |
| | | // | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| result_impl<T, class_object>:: | | object_result_impl<T>:: | |
| ~result_impl () | | ~object_result_impl () | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| result_impl<T, class_object>:: | | object_result_impl<T>:: | |
| result_impl (const query& q, | | object_result_impl (const query& q, | |
| details::shared_ptr<select_statement> statement, | | details::shared_ptr<select_statement> statement, | |
| object_statements<object_type>& statements) | | object_statements<object_type>& statements) | |
| : base_type (statements.connection ().database ()), | | : base_type (statements.connection ().database ()), | |
| result_impl_base (q, statement), | | result_impl_base (q, statement), | |
| statements_ (statements) | | statements_ (statements) | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| void result_impl<T, class_object>:: | | void object_result_impl<T>:: | |
| load (object_type& obj) | | load (object_type& obj, bool fetch) | |
| { | | { | |
|
| load_image (); | | if (fetch) | |
| | | load_image (); | |
| | | | |
| // This is a top-level call so the statements cannot be locked. | | // This is a top-level call so the statements cannot be locked. | |
| // | | // | |
| assert (!statements_.locked ()); | | assert (!statements_.locked ()); | |
| typename object_statements<object_type>::auto_lock l (statements_); | | typename object_statements<object_type>::auto_lock l (statements_); | |
| | | | |
| odb::database& db (this->database ()); | | odb::database& db (this->database ()); | |
| object_traits::callback (db, obj, callback_event::pre_load); | | object_traits::callback (db, obj, callback_event::pre_load); | |
| | | | |
| typename object_traits::image_type& i (statements_.image ()); | | typename object_traits::image_type& i (statements_.image ()); | |
| | | | |
| skipping to change at line 70 | | skipping to change at line 75 | |
| idb.version++; | | idb.version++; | |
| } | | } | |
| | | | |
| object_traits::load_ (statements_, obj); | | object_traits::load_ (statements_, obj); | |
| statements_.load_delayed (); | | statements_.load_delayed (); | |
| l.unlock (); | | l.unlock (); | |
| object_traits::callback (db, obj, callback_event::post_load); | | object_traits::callback (db, obj, callback_event::post_load); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| typename result_impl<T, class_object>::id_type | | typename object_result_impl<T>::id_type | |
| result_impl<T, class_object>:: | | object_result_impl<T>:: | |
| load_id () | | load_id () | |
| { | | { | |
| load_image (); | | load_image (); | |
| return object_traits::id (statements_.image ()); | | return object_traits::id (statements_.image ()); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| void result_impl<T, class_object>:: | | void object_result_impl<T>:: | |
| next () | | next () | |
| { | | { | |
| this->current (pointer_type ()); | | this->current (pointer_type ()); | |
| | | | |
| if (!statement_->next ()) | | if (!statement_->next ()) | |
| this->end_ = true; | | this->end_ = true; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| void result_impl<T, class_object>:: | | void object_result_impl<T>:: | |
| load_image () | | load_image () | |
| { | | { | |
| // The image can grow between calls to load() as a result of other | | // The image can grow between calls to load() as a result of other | |
| // statements execution. | | // statements execution. | |
| // | | // | |
| typename object_traits::image_type& im (statements_.image ()); | | typename object_traits::image_type& im (statements_.image ()); | |
| | | | |
|
| if (im.version != statements_.out_image_version ()) | | if (im.version != statements_.select_image_version ()) | |
| { | | { | |
|
| binding& b (statements_.out_image_binding ()); | | binding& b (statements_.select_image_binding ()); | |
| object_traits::bind (b.bind, im, true); | | object_traits::bind (b.bind, im, statement_select); | |
| statements_.out_image_version (im.version); | | statements_.select_image_version (im.version); | |
| b.version++; | | b.version++; | |
| } | | } | |
| | | | |
| select_statement::result r (statement_->load ()); | | select_statement::result r (statement_->load ()); | |
| | | | |
| if (r == select_statement::truncated) | | if (r == select_statement::truncated) | |
| { | | { | |
|
| if (object_traits::grow (im, statements_.out_image_truncated ())) | | if (object_traits::grow (im, statements_.select_image_truncated ())
) | |
| im.version++; | | im.version++; | |
| | | | |
|
| if (im.version != statements_.out_image_version ()) | | if (im.version != statements_.select_image_version ()) | |
| { | | { | |
|
| binding& b (statements_.out_image_binding ()); | | binding& b (statements_.select_image_binding ()); | |
| object_traits::bind (b.bind, im, true); | | object_traits::bind (b.bind, im, statement_select); | |
| statements_.out_image_version (im.version); | | statements_.select_image_version (im.version); | |
| b.version++; | | b.version++; | |
| statement_->reload (); | | statement_->reload (); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| void result_impl<T, class_object>:: | | void object_result_impl<T>:: | |
| | | cache () | |
| | | { | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | std::size_t object_result_impl<T>:: | |
| | | size () | |
| | | { | |
| | | throw result_not_cached (); | |
| | | } | |
| | | | |
| | | // | |
| | | // object_result_impl_no_id | |
| | | // | |
| | | | |
| | | template <typename T> | |
| | | object_result_impl_no_id<T>:: | |
| | | ~object_result_impl_no_id () | |
| | | { | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | object_result_impl_no_id<T>:: | |
| | | object_result_impl_no_id (const query& q, | |
| | | details::shared_ptr<select_statement> stateme | |
| | | nt, | |
| | | object_statements_no_id<object_type>& stateme | |
| | | nts) | |
| | | : base_type (statements.connection ().database ()), | |
| | | result_impl_base (q, statement), | |
| | | statements_ (statements) | |
| | | { | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | void object_result_impl_no_id<T>:: | |
| | | load (object_type& obj) | |
| | | { | |
| | | // The image can grow between calls to load() as a result of other | |
| | | // statements execution. | |
| | | // | |
| | | typename object_traits::image_type& im (statements_.image ()); | |
| | | | |
| | | if (im.version != statements_.select_image_version ()) | |
| | | { | |
| | | binding& b (statements_.select_image_binding ()); | |
| | | object_traits::bind (b.bind, im, statement_select); | |
| | | statements_.select_image_version (im.version); | |
| | | b.version++; | |
| | | } | |
| | | | |
| | | select_statement::result r (statement_->load ()); | |
| | | | |
| | | if (r == select_statement::truncated) | |
| | | { | |
| | | if (object_traits::grow (im, statements_.select_image_truncated ()) | |
| | | ) | |
| | | im.version++; | |
| | | | |
| | | if (im.version != statements_.select_image_version ()) | |
| | | { | |
| | | binding& b (statements_.select_image_binding ()); | |
| | | object_traits::bind (b.bind, im, statement_select); | |
| | | statements_.select_image_version (im.version); | |
| | | b.version++; | |
| | | statement_->reload (); | |
| | | } | |
| | | } | |
| | | | |
| | | odb::database& db (this->database ()); | |
| | | | |
| | | object_traits::callback (db, obj, callback_event::pre_load); | |
| | | object_traits::init (obj, im, db); | |
| | | object_traits::callback (db, obj, callback_event::post_load); | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | void object_result_impl_no_id<T>:: | |
| | | next () | |
| | | { | |
| | | this->current (pointer_type ()); | |
| | | | |
| | | if (!statement_->next ()) | |
| | | this->end_ = true; | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | void object_result_impl_no_id<T>:: | |
| cache () | | cache () | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| std::size_t result_impl<T, class_object>:: | | std::size_t object_result_impl_no_id<T>:: | |
| size () | | size () | |
| { | | { | |
| throw result_not_cached (); | | throw result_not_cached (); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 15 change blocks. |
| 24 lines changed or deleted | | 117 lines changed or added | |
|
| object-statements.hxx | | object-statements.hxx | |
| | | | |
| skipping to change at line 32 | | skipping to change at line 32 | |
| #include <odb/sqlite/binding.hxx> | | #include <odb/sqlite/binding.hxx> | |
| #include <odb/sqlite/statement.hxx> | | #include <odb/sqlite/statement.hxx> | |
| #include <odb/sqlite/statements-base.hxx> | | #include <odb/sqlite/statements-base.hxx> | |
| | | | |
| #include <odb/sqlite/details/export.hxx> | | #include <odb/sqlite/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace sqlite | | namespace sqlite | |
| { | | { | |
|
| | | template <typename T> | |
| | | class object_statements; | |
| | | | |
| | | template <typename T> | |
| | | class object_statements_no_id; | |
| | | | |
| | | template <typename T, typename ID = typename object_traits<T>::id_type> | |
| | | struct object_statements_selector | |
| | | { | |
| | | typedef object_statements<T> type; | |
| | | }; | |
| | | | |
| | | template <typename T> | |
| | | struct object_statements_selector<T, void> | |
| | | { | |
| | | typedef object_statements_no_id<T> type; | |
| | | }; | |
| | | | |
| | | // | |
| | | // Implementation for objects with object id. | |
| | | // | |
| | | | |
| class LIBODB_SQLITE_EXPORT object_statements_base: public statements_ba
se | | class LIBODB_SQLITE_EXPORT object_statements_base: public statements_ba
se | |
| { | | { | |
| public: | | public: | |
| // Locking. | | // Locking. | |
| // | | // | |
| void | | void | |
| lock () | | lock () | |
| { | | { | |
| assert (!locked_); | | assert (!locked_); | |
| locked_ = true; | | locked_ = true; | |
| | | | |
| skipping to change at line 87 | | skipping to change at line 109 | |
| auto_unlock& operator= (const auto_unlock&); | | auto_unlock& operator= (const auto_unlock&); | |
| | | | |
| private: | | private: | |
| object_statements_base& s_; | | object_statements_base& s_; | |
| }; | | }; | |
| | | | |
| protected: | | protected: | |
| bool locked_; | | bool locked_; | |
| }; | | }; | |
| | | | |
|
| | | template <typename T, bool optimistic> | |
| | | struct optimistic_data; | |
| | | | |
| | | template <typename T> | |
| | | struct optimistic_data<T, true> | |
| | | { | |
| | | typedef T object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | | |
| | | optimistic_data (bind*); | |
| | | | |
| | | // The id + optimistic column binding. | |
| | | // | |
| | | std::size_t id_image_version_; | |
| | | binding id_image_binding_; | |
| | | | |
| | | details::shared_ptr<delete_statement> erase_; | |
| | | }; | |
| | | | |
| | | template <typename T> | |
| | | struct optimistic_data<T, false> | |
| | | { | |
| | | optimistic_data (bind*) {} | |
| | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| class object_statements: public object_statements_base | | class object_statements: public object_statements_base | |
| { | | { | |
| public: | | public: | |
| typedef T object_type; | | typedef T object_type; | |
| typedef odb::object_traits<object_type> object_traits; | | typedef odb::object_traits<object_type> object_traits; | |
| typedef typename object_traits::id_type id_type; | | typedef typename object_traits::id_type id_type; | |
| typedef typename object_traits::pointer_type pointer_type; | | typedef typename object_traits::pointer_type pointer_type; | |
| typedef typename object_traits::image_type image_type; | | typedef typename object_traits::image_type image_type; | |
| typedef typename object_traits::id_image_type id_image_type; | | typedef typename object_traits::id_image_type id_image_type; | |
| | | | |
| typedef pointer_cache_traits<pointer_type> object_cache_traits; | | typedef pointer_cache_traits<pointer_type> object_cache_traits; | |
| | | | |
| typedef | | typedef | |
| typename object_traits::container_statement_cache_type | | typename object_traits::container_statement_cache_type | |
| container_statement_cache_type; | | container_statement_cache_type; | |
| | | | |
|
| typedef sqlite::insert_statement persist_statement_type; | | typedef sqlite::insert_statement insert_statement_type; | |
| typedef sqlite::select_statement find_statement_type; | | typedef sqlite::select_statement select_statement_type; | |
| typedef sqlite::update_statement update_statement_type; | | typedef sqlite::update_statement update_statement_type; | |
|
| typedef sqlite::delete_statement erase_statement_type; | | typedef sqlite::delete_statement delete_statement_type; | |
| | | | |
| // Automatic lock. | | // Automatic lock. | |
| // | | // | |
| struct auto_lock | | struct auto_lock | |
| { | | { | |
| // Lock the statements unless they are already locked in which | | // Lock the statements unless they are already locked in which | |
| // case subsequent calls to locked() will return false. | | // case subsequent calls to locked() will return false. | |
| // | | // | |
| auto_lock (object_statements&); | | auto_lock (object_statements&); | |
| | | | |
| | | | |
| skipping to change at line 179 | | skipping to change at line 226 | |
| void | | void | |
| clear_delayed () | | clear_delayed () | |
| { | | { | |
| if (!delayed_.empty ()) | | if (!delayed_.empty ()) | |
| clear_delayed_ (); | | clear_delayed_ (); | |
| } | | } | |
| | | | |
| // Object image. | | // Object image. | |
| // | | // | |
| image_type& | | image_type& | |
|
| image () | | image () {return image_;} | |
| { | | | |
| return image_; | | | |
| } | | | |
| | | | |
|
| | | // Insert binding. | |
| | | // | |
| std::size_t | | std::size_t | |
|
| in_image_version () const | | insert_image_version () const { return insert_image_version_;} | |
| { | | | |
| return in_image_version_; | | void | |
| } | | insert_image_version (std::size_t v) {insert_image_version_ = v;} | |
| | | | |
| | | binding& | |
| | | insert_image_binding () {return insert_image_binding_;} | |
| | | | |
|
| | | // Update binding. | |
| | | // | |
| std::size_t | | std::size_t | |
|
| out_image_version () const | | update_image_version () const { return update_image_version_;} | |
| { | | | |
| return out_image_version_; | | | |
| } | | | |
| | | | |
| void | | void | |
|
| in_image_version (std::size_t v) | | update_image_version (std::size_t v) {update_image_version_ = v;} | |
| { | | | |
| in_image_version_ = v; | | std::size_t | |
| } | | update_id_image_version () const { return update_id_image_version_;} | |
| | | | |
| void | | void | |
|
| out_image_version (std::size_t v) | | update_id_image_version (std::size_t v) {update_id_image_version_ = v | |
| { | | ;} | |
| out_image_version_ = v; | | | |
| } | | | |
| | | | |
| binding& | | binding& | |
|
| in_image_binding () | | update_image_binding () {return update_image_binding_;} | |
| { | | | |
| return in_image_binding_; | | // Select binding. | |
| } | | // | |
| | | std::size_t | |
| | | select_image_version () const { return select_image_version_;} | |
| | | | |
| | | void | |
| | | select_image_version (std::size_t v) {select_image_version_ = v;} | |
| | | | |
| binding& | | binding& | |
|
| out_image_binding () | | select_image_binding () {return select_image_binding_;} | |
| { | | | |
| return out_image_binding_; | | | |
| } | | | |
| | | | |
| bool* | | bool* | |
|
| out_image_truncated () | | select_image_truncated () {return select_image_truncated_;} | |
| { | | | |
| return out_image_truncated_; | | | |
| } | | | |
| | | | |
|
| // Object id image. | | // Object id image and binding. | |
| // | | // | |
| id_image_type& | | id_image_type& | |
|
| id_image () | | id_image () {return id_image_;} | |
| { | | | |
| return id_image_; | | | |
| } | | | |
| | | | |
| std::size_t | | std::size_t | |
|
| id_image_version () const | | id_image_version () const {return id_image_version_;} | |
| { | | | |
| return id_image_version_; | | | |
| } | | | |
| | | | |
| void | | void | |
|
| id_image_version (std::size_t v) | | id_image_version (std::size_t v) {id_image_version_ = v;} | |
| { | | | |
| id_image_version_ = v; | | | |
| } | | | |
| | | | |
| binding& | | binding& | |
|
| id_image_binding () | | id_image_binding () {return id_image_binding_;} | |
| { | | | |
| return id_image_binding_; | | // Optimistic id + managed column image binding. | |
| } | | // | |
| | | std::size_t | |
| | | optimistic_id_image_version () const {return od_.id_image_version_;} | |
| | | | |
| | | void | |
| | | optimistic_id_image_version (std::size_t v) {od_.id_image_version_ = | |
| | | v;} | |
| | | | |
| | | binding& | |
| | | optimistic_id_image_binding () {return od_.id_image_binding_;} | |
| | | | |
| // Statements. | | // Statements. | |
| // | | // | |
|
| persist_statement_type& | | insert_statement_type& | |
| persist_statement () | | persist_statement () | |
| { | | { | |
| if (persist_ == 0) | | if (persist_ == 0) | |
| { | | { | |
| persist_.reset ( | | persist_.reset ( | |
|
| new (details::shared) persist_statement_type ( | | new (details::shared) insert_statement_type ( | |
| conn_, object_traits::persist_statement, in_image_binding_)); | | conn_, | |
| | | object_traits::persist_statement, | |
| | | insert_image_binding_)); | |
| | | | |
| persist_->cached (true); | | persist_->cached (true); | |
| } | | } | |
| | | | |
| return *persist_; | | return *persist_; | |
| } | | } | |
| | | | |
|
| find_statement_type& | | select_statement_type& | |
| find_statement () | | find_statement () | |
| { | | { | |
| if (find_ == 0) | | if (find_ == 0) | |
| { | | { | |
| find_.reset ( | | find_.reset ( | |
|
| new (details::shared) find_statement_type ( | | new (details::shared) select_statement_type ( | |
| conn_, | | conn_, | |
| object_traits::find_statement, | | object_traits::find_statement, | |
| id_image_binding_, | | id_image_binding_, | |
|
| out_image_binding_)); | | select_image_binding_)); | |
| | | | |
| find_->cached (true); | | find_->cached (true); | |
| } | | } | |
| | | | |
| return *find_; | | return *find_; | |
| } | | } | |
| | | | |
| update_statement_type& | | update_statement_type& | |
| update_statement () | | update_statement () | |
| { | | { | |
| if (update_ == 0) | | if (update_ == 0) | |
| { | | { | |
| update_.reset ( | | update_.reset ( | |
| new (details::shared) update_statement_type ( | | new (details::shared) update_statement_type ( | |
| conn_, | | conn_, | |
| object_traits::update_statement, | | object_traits::update_statement, | |
|
| id_image_binding_, | | update_image_binding_)); | |
| in_image_binding_)); | | | |
| | | | |
| update_->cached (true); | | update_->cached (true); | |
| } | | } | |
| | | | |
| return *update_; | | return *update_; | |
| } | | } | |
| | | | |
|
| erase_statement_type& | | delete_statement_type& | |
| erase_statement () | | erase_statement () | |
| { | | { | |
| if (erase_ == 0) | | if (erase_ == 0) | |
| { | | { | |
| erase_.reset ( | | erase_.reset ( | |
|
| new (details::shared) erase_statement_type ( | | new (details::shared) delete_statement_type ( | |
| conn_, | | conn_, | |
| object_traits::erase_statement, | | object_traits::erase_statement, | |
| id_image_binding_)); | | id_image_binding_)); | |
| | | | |
| erase_->cached (true); | | erase_->cached (true); | |
| } | | } | |
| | | | |
| return *erase_; | | return *erase_; | |
| } | | } | |
| | | | |
|
| | | delete_statement_type& | |
| | | optimistic_erase_statement () | |
| | | { | |
| | | if (od_.erase_ == 0) | |
| | | { | |
| | | od_.erase_.reset ( | |
| | | new (details::shared) delete_statement_type ( | |
| | | conn_, | |
| | | object_traits::optimistic_erase_statement, | |
| | | od_.id_image_binding_)); | |
| | | | |
| | | od_.erase_->cached (true); | |
| | | } | |
| | | | |
| | | return *od_.erase_; | |
| | | } | |
| | | | |
| // Container statement cache. | | // Container statement cache. | |
| // | | // | |
| container_statement_cache_type& | | container_statement_cache_type& | |
| container_statment_cache () | | container_statment_cache () | |
| { | | { | |
| return container_statement_cache_; | | return container_statement_cache_; | |
| } | | } | |
| | | | |
| private: | | private: | |
| object_statements (const object_statements&); | | object_statements (const object_statements&); | |
| object_statements& operator= (const object_statements&); | | object_statements& operator= (const object_statements&); | |
| | | | |
| private: | | private: | |
| void | | void | |
| load_delayed_ (); | | load_delayed_ (); | |
| | | | |
| void | | void | |
| clear_delayed_ (); | | clear_delayed_ (); | |
| | | | |
| private: | | private: | |
|
| | | // select = total | |
| | | // insert = total - inverse - managed_optimistic | |
| | | // update = total - inverse - managed_optimistic - id - readonly | |
| | | // | |
| | | static const std::size_t select_column_count = | |
| | | object_traits::column_count; | |
| | | | |
| | | static const std::size_t insert_column_count = | |
| | | object_traits::column_count - object_traits::inverse_column_count - | |
| | | object_traits::managed_optimistic_column_count; | |
| | | | |
| | | static const std::size_t update_column_count = insert_column_count - | |
| | | object_traits::id_column_count - object_traits::readonly_column_cou | |
| | | nt; | |
| | | | |
| | | static const std::size_t id_column_count = | |
| | | object_traits::id_column_count; | |
| | | | |
| | | static const std::size_t managed_optimistic_column_count = | |
| | | object_traits::managed_optimistic_column_count; | |
| | | | |
| | | private: | |
| container_statement_cache_type container_statement_cache_; | | container_statement_cache_type container_statement_cache_; | |
| | | | |
| image_type image_; | | image_type image_; | |
| | | | |
|
| // In (send) binding. The last element is the id parameter. | | // Select binding. | |
| // | | | |
| std::size_t in_image_version_; | | | |
| binding in_image_binding_; | | | |
| bind in_image_bind_[object_traits::in_column_count + 1]; | | | |
| | | | |
| // Out (receive) binding. | | | |
| // | | // | |
|
| std::size_t out_image_version_; | | std::size_t select_image_version_; | |
| binding out_image_binding_; | | binding select_image_binding_; | |
| bind out_image_bind_[object_traits::out_column_count]; | | bind select_image_bind_[select_column_count]; | |
| bool out_image_truncated_[object_traits::out_column_count]; | | bool select_image_truncated_[select_column_count]; | |
| | | | |
| | | // Insert binding. | |
| | | // | |
| | | std::size_t insert_image_version_; | |
| | | binding insert_image_binding_; | |
| | | bind insert_image_bind_[insert_column_count]; | |
| | | | |
| | | // Update binding. Note that the id suffix is bound to id_image_ | |
| | | // below instead of image_ which makes this binding effectively | |
| | | // bound to two images. As a result, we have to track versions | |
| | | // for both of them. If this object uses optimistic concurrency, | |
| | | // then the binding for the managed column (version, timestamp, | |
| | | // etc) comes after the id and the image for such a column is | |
| | | // stored as part of the id image. | |
| | | // | |
| | | std::size_t update_image_version_; | |
| | | std::size_t update_id_image_version_; | |
| | | binding update_image_binding_; | |
| | | bind update_image_bind_[update_column_count + id_column_count + | |
| | | managed_optimistic_column_count]; | |
| | | | |
|
| // Id image binding (only in). | | // Id image binding (only used as a parameter). Uses the suffix in | |
| | | // the update bind. | |
| // | | // | |
| id_image_type id_image_; | | id_image_type id_image_; | |
| std::size_t id_image_version_; | | std::size_t id_image_version_; | |
| binding id_image_binding_; | | binding id_image_binding_; | |
| | | | |
|
| details::shared_ptr<persist_statement_type> persist_; | | // Extra data for objects with optimistic concurrency support. | |
| details::shared_ptr<find_statement_type> find_; | | // | |
| | | optimistic_data<T, managed_optimistic_column_count != 0> od_; | |
| | | | |
| | | details::shared_ptr<insert_statement_type> persist_; | |
| | | details::shared_ptr<select_statement_type> find_; | |
| details::shared_ptr<update_statement_type> update_; | | details::shared_ptr<update_statement_type> update_; | |
|
| details::shared_ptr<erase_statement_type> erase_; | | details::shared_ptr<delete_statement_type> erase_; | |
| | | | |
| // Delayed loading. | | // Delayed loading. | |
| // | | // | |
| struct delayed_load | | struct delayed_load | |
| { | | { | |
| typedef typename object_cache_traits::position_type position_type; | | typedef typename object_cache_traits::position_type position_type; | |
| | | | |
| delayed_load () {} | | delayed_load () {} | |
| delayed_load (const id_type& i, object_type& o, const position_type
& p) | | delayed_load (const id_type& i, object_type& o, const position_type
& p) | |
| : id (i), obj (&o), pos (p) | | : id (i), obj (&o), pos (p) | |
| | | | |
| skipping to change at line 412 | | skipping to change at line 513 | |
| { | | { | |
| os_.clear_delayed (); | | os_.clear_delayed (); | |
| dl_.swap (os_.delayed_); | | dl_.swap (os_.delayed_); | |
| } | | } | |
| | | | |
| private: | | private: | |
| object_statements& os_; | | object_statements& os_; | |
| delayed_loads& dl_; | | delayed_loads& dl_; | |
| }; | | }; | |
| }; | | }; | |
|
| | | | |
| | | // | |
| | | // Implementation for objects without object id. | |
| | | // | |
| | | | |
| | | template <typename T> | |
| | | class object_statements_no_id: public statements_base | |
| | | { | |
| | | public: | |
| | | typedef T object_type; | |
| | | typedef odb::object_traits<object_type> object_traits; | |
| | | typedef typename object_traits::pointer_type pointer_type; | |
| | | typedef typename object_traits::image_type image_type; | |
| | | | |
| | | typedef sqlite::insert_statement insert_statement_type; | |
| | | | |
| | | public: | |
| | | object_statements_no_id (connection_type&); | |
| | | | |
| | | virtual | |
| | | ~object_statements_no_id (); | |
| | | | |
| | | // Object image. | |
| | | // | |
| | | image_type& | |
| | | image () {return image_;} | |
| | | | |
| | | // Insert binding. | |
| | | // | |
| | | std::size_t | |
| | | insert_image_version () const { return insert_image_version_;} | |
| | | | |
| | | void | |
| | | insert_image_version (std::size_t v) {insert_image_version_ = v;} | |
| | | | |
| | | binding& | |
| | | insert_image_binding () {return insert_image_binding_;} | |
| | | | |
| | | // Select binding. | |
| | | // | |
| | | std::size_t | |
| | | select_image_version () const { return select_image_version_;} | |
| | | | |
| | | void | |
| | | select_image_version (std::size_t v) {select_image_version_ = v;} | |
| | | | |
| | | binding& | |
| | | select_image_binding () {return select_image_binding_;} | |
| | | | |
| | | bool* | |
| | | select_image_truncated () {return select_image_truncated_;} | |
| | | | |
| | | // Statements. | |
| | | // | |
| | | insert_statement_type& | |
| | | persist_statement () | |
| | | { | |
| | | if (persist_ == 0) | |
| | | { | |
| | | persist_.reset ( | |
| | | new (details::shared) insert_statement_type ( | |
| | | conn_, | |
| | | object_traits::persist_statement, | |
| | | insert_image_binding_)); | |
| | | | |
| | | persist_->cached (true); | |
| | | } | |
| | | | |
| | | return *persist_; | |
| | | } | |
| | | | |
| | | private: | |
| | | object_statements_no_id (const object_statements_no_id&); | |
| | | object_statements_no_id& operator= (const object_statements_no_id&); | |
| | | | |
| | | private: | |
| | | // select = total | |
| | | // insert = total - inverse; inverse == 0 for object without id | |
| | | // | |
| | | static const std::size_t insert_column_count = | |
| | | object_traits::column_count; | |
| | | | |
| | | static const std::size_t select_column_count = | |
| | | object_traits::column_count; | |
| | | | |
| | | private: | |
| | | image_type image_; | |
| | | | |
| | | // Select binding. | |
| | | // | |
| | | std::size_t select_image_version_; | |
| | | binding select_image_binding_; | |
| | | bind select_image_bind_[select_column_count]; | |
| | | bool select_image_truncated_[select_column_count]; | |
| | | | |
| | | // Insert binding. | |
| | | // | |
| | | std::size_t insert_image_version_; | |
| | | binding insert_image_binding_; | |
| | | bind insert_image_bind_[insert_column_count]; | |
| | | | |
| | | details::shared_ptr<insert_statement_type> persist_; | |
| | | }; | |
| } | | } | |
| } | | } | |
| | | | |
| #include <odb/sqlite/object-statements.ixx> | | #include <odb/sqlite/object-statements.ixx> | |
| #include <odb/sqlite/object-statements.txx> | | #include <odb/sqlite/object-statements.txx> | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_SQLITE_OBJECT_STATEMENTS_HXX | | #endif // ODB_SQLITE_OBJECT_STATEMENTS_HXX | |
| | | | |
End of changes. 35 change blocks. |
| 77 lines changed or deleted | | 284 lines changed or added | |
|
| object-statements.txx | | object-statements.txx | |
| | | | |
| skipping to change at line 19 | | skipping to change at line 19 | |
| #include <odb/session.hxx> | | #include <odb/session.hxx> | |
| #include <odb/callback.hxx> | | #include <odb/callback.hxx> | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| | | | |
| #include <odb/sqlite/connection.hxx> | | #include <odb/sqlite/connection.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace sqlite | | namespace sqlite | |
| { | | { | |
|
| | | // | |
| | | // optimistic_data | |
| | | // | |
| | | | |
| | | template <typename T> | |
| | | optimistic_data<T, true>:: | |
| | | optimistic_data (bind* b) | |
| | | : id_image_binding_ ( | |
| | | b, | |
| | | object_traits::id_column_count + | |
| | | object_traits::managed_optimistic_column_count) | |
| | | { | |
| | | id_image_version_ = 0; | |
| | | } | |
| | | | |
| | | // | |
| | | // object_statements | |
| | | // | |
| | | | |
| template <typename T> | | template <typename T> | |
| object_statements<T>:: | | object_statements<T>:: | |
| ~object_statements () | | ~object_statements () | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| object_statements<T>:: | | object_statements<T>:: | |
| object_statements (connection_type& conn) | | object_statements (connection_type& conn) | |
| : object_statements_base (conn), | | : object_statements_base (conn), | |
| container_statement_cache_ (conn), | | container_statement_cache_ (conn), | |
|
| in_image_binding_ (in_image_bind_, object_traits::in_column_count | | select_image_binding_ (select_image_bind_, select_column_count), | |
| ), | | insert_image_binding_ (insert_image_bind_, insert_column_count), | |
| out_image_binding_ (out_image_bind_, object_traits::out_column_co | | update_image_binding_ (update_image_bind_, | |
| unt), | | update_column_count + id_column_count + | |
| id_image_binding_ (in_image_bind_ + object_traits::in_column_coun | | managed_optimistic_column_count), | |
| t, 1) | | id_image_binding_ (update_image_bind_ + update_column_count, | |
| | | id_column_count), | |
| | | od_ (update_image_bind_ + update_column_count) | |
| { | | { | |
| image_.version = 0; | | image_.version = 0; | |
|
| in_image_version_ = 0; | | select_image_version_ = 0; | |
| out_image_version_ = 0; | | insert_image_version_ = 0; | |
| | | update_image_version_ = 0; | |
| | | update_id_image_version_ = 0; | |
| | | | |
| id_image_.version = 0; | | id_image_.version = 0; | |
| id_image_version_ = 0; | | id_image_version_ = 0; | |
| | | | |
|
| std::memset (in_image_bind_, 0, sizeof (in_image_bind_)); | | std::memset (insert_image_bind_, 0, sizeof (insert_image_bind_)); | |
| std::memset (out_image_bind_, 0, sizeof (out_image_bind_)); | | std::memset (update_image_bind_, 0, sizeof (update_image_bind_)); | |
| std::memset (out_image_truncated_, 0, sizeof (out_image_truncated_)); | | std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | |
| | | std::memset ( | |
| | | select_image_truncated_, 0, sizeof (select_image_truncated_)); | |
| | | | |
|
| for (std::size_t i (0); i < object_traits::out_column_count; ++i) | | for (std::size_t i (0); i < select_column_count; ++i) | |
| out_image_bind_[i].truncated = out_image_truncated_ + i; | | select_image_bind_[i].truncated = select_image_truncated_ + i; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void object_statements<T>:: | | void object_statements<T>:: | |
| load_delayed_ () | | load_delayed_ () | |
| { | | { | |
| database& db (connection ().database ()); | | database& db (connection ().database ()); | |
| | | | |
| delayed_loads dls; | | delayed_loads dls; | |
| swap_guard sg (*this, dls); | | swap_guard sg (*this, dls); | |
| | | | |
| skipping to change at line 113 | | skipping to change at line 141 | |
| { | | { | |
| for (typename delayed_loads::iterator i (delayed_.begin ()), | | for (typename delayed_loads::iterator i (delayed_.begin ()), | |
| e (delayed_.end ()); i != e; ++i) | | e (delayed_.end ()); i != e; ++i) | |
| { | | { | |
| object_cache_traits::erase (i->pos); | | object_cache_traits::erase (i->pos); | |
| } | | } | |
| } | | } | |
| | | | |
| delayed_.clear (); | | delayed_.clear (); | |
| } | | } | |
|
| | | | |
| | | // | |
| | | // object_statements_no_id | |
| | | // | |
| | | | |
| | | template <typename T> | |
| | | object_statements_no_id<T>:: | |
| | | ~object_statements_no_id () | |
| | | { | |
| | | } | |
| | | | |
| | | template <typename T> | |
| | | object_statements_no_id<T>:: | |
| | | object_statements_no_id (connection_type& conn) | |
| | | : statements_base (conn), | |
| | | select_image_binding_ (select_image_bind_, select_column_count), | |
| | | insert_image_binding_ (insert_image_bind_, insert_column_count) | |
| | | { | |
| | | image_.version = 0; | |
| | | select_image_version_ = 0; | |
| | | insert_image_version_ = 0; | |
| | | | |
| | | std::memset (insert_image_bind_, 0, sizeof (insert_image_bind_)); | |
| | | std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | |
| | | std::memset ( | |
| | | select_image_truncated_, 0, sizeof (select_image_truncated_)); | |
| | | | |
| | | for (std::size_t i (0); i < select_column_count; ++i) | |
| | | select_image_bind_[i].truncated = select_image_truncated_ + i; | |
| | | } | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 6 change blocks. |
| 13 lines changed or deleted | | 68 lines changed or added | |
|
| statement-cache.hxx | | statement-cache.hxx | |
| | | | |
| skipping to change at line 38 | | skipping to change at line 38 | |
| { | | { | |
| namespace sqlite | | namespace sqlite | |
| { | | { | |
| class connection; | | class connection; | |
| | | | |
| class LIBODB_SQLITE_EXPORT statement_cache | | class LIBODB_SQLITE_EXPORT statement_cache | |
| { | | { | |
| public: | | public: | |
| statement_cache (connection&); | | statement_cache (connection&); | |
| | | | |
|
| simple_statement& | | generic_statement& | |
| begin_statement () const | | begin_statement () const | |
| { | | { | |
| return *begin_; | | return *begin_; | |
| } | | } | |
| | | | |
|
| simple_statement& | | generic_statement& | |
| begin_immediate_statement () const | | begin_immediate_statement () const | |
| { | | { | |
| if (!begin_immediate_) | | if (!begin_immediate_) | |
| begin_immediate_statement_ (); | | begin_immediate_statement_ (); | |
| | | | |
| return *begin_immediate_; | | return *begin_immediate_; | |
| } | | } | |
| | | | |
|
| simple_statement& | | generic_statement& | |
| begin_exclusive_statement () const | | begin_exclusive_statement () const | |
| { | | { | |
| if (!begin_exclusive_) | | if (!begin_exclusive_) | |
| begin_exclusive_statement_ (); | | begin_exclusive_statement_ (); | |
| | | | |
| return *begin_exclusive_; | | return *begin_exclusive_; | |
| } | | } | |
| | | | |
|
| simple_statement& | | generic_statement& | |
| commit_statement () const | | commit_statement () const | |
| { | | { | |
| return *commit_; | | return *commit_; | |
| } | | } | |
| | | | |
|
| simple_statement& | | generic_statement& | |
| rollback_statement () const | | rollback_statement () const | |
| { | | { | |
| return *rollback_; | | return *rollback_; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| object_statements<T>& | | typename object_statements_selector<T>::type& | |
| find_object () | | find_object () | |
| { | | { | |
|
| | | typedef typename object_statements_selector<T>::type object_stateme | |
| | | nts; | |
| | | | |
| map::iterator i (map_.find (&typeid (T))); | | map::iterator i (map_.find (&typeid (T))); | |
| | | | |
| if (i != map_.end ()) | | if (i != map_.end ()) | |
|
| return static_cast<object_statements<T>&> (*i->second); | | return static_cast<object_statements&> (*i->second); | |
| | | | |
|
| details::shared_ptr<object_statements<T> > p ( | | details::shared_ptr<object_statements> p ( | |
| new (details::shared) object_statements<T> (conn_)); | | new (details::shared) object_statements (conn_)); | |
| | | | |
| map_.insert (map::value_type (&typeid (T), p)); | | map_.insert (map::value_type (&typeid (T), p)); | |
| return *p; | | return *p; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| view_statements<T>& | | view_statements<T>& | |
| find_view () | | find_view () | |
| { | | { | |
| map::iterator i (map_.find (&typeid (T))); | | map::iterator i (map_.find (&typeid (T))); | |
| | | | |
| skipping to change at line 120 | | skipping to change at line 122 | |
| void | | void | |
| begin_exclusive_statement_ () const; | | begin_exclusive_statement_ () const; | |
| | | | |
| private: | | private: | |
| typedef std::map<const std::type_info*, | | typedef std::map<const std::type_info*, | |
| details::shared_ptr<statements_base>, | | details::shared_ptr<statements_base>, | |
| details::type_info_comparator> map; | | details::type_info_comparator> map; | |
| | | | |
| connection& conn_; | | connection& conn_; | |
| | | | |
|
| details::shared_ptr<simple_statement> begin_; | | details::shared_ptr<generic_statement> begin_; | |
| mutable details::shared_ptr<simple_statement> begin_immediate_; | | mutable details::shared_ptr<generic_statement> begin_immediate_; | |
| mutable details::shared_ptr<simple_statement> begin_exclusive_; | | mutable details::shared_ptr<generic_statement> begin_exclusive_; | |
| details::shared_ptr<simple_statement> commit_; | | details::shared_ptr<generic_statement> commit_; | |
| details::shared_ptr<simple_statement> rollback_; | | details::shared_ptr<generic_statement> rollback_; | |
| | | | |
| map map_; | | map map_; | |
| }; | | }; | |
| } | | } | |
| } | | } | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_SQLITE_STATEMENT_CACHE_HXX | | #endif // ODB_SQLITE_STATEMENT_CACHE_HXX | |
| | | | |
End of changes. 10 change blocks. |
| 14 lines changed or deleted | | 17 lines changed or added | |
|
| statement.hxx | | statement.hxx | |
| | | | |
| skipping to change at line 14 | | skipping to change at line 14 | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_SQLITE_STATEMENT_HXX | | #ifndef ODB_SQLITE_STATEMENT_HXX | |
| #define ODB_SQLITE_STATEMENT_HXX | | #define ODB_SQLITE_STATEMENT_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <sqlite3.h> | | #include <sqlite3.h> | |
| | | | |
| #include <string> | | #include <string> | |
|
| #include <cstddef> // std::size_t | | #include <cstddef> // std::size_t | |
| | | #include <cstring> // std::strlen, std::memcpy | |
| #include <cassert> | | #include <cassert> | |
| | | | |
| #include <odb/forward.hxx> | | #include <odb/forward.hxx> | |
|
| #include <odb/details/shared-ptr.hxx> | | #include <odb/statement.hxx> | |
| | | | |
| #include <odb/sqlite/version.hxx> | | #include <odb/sqlite/version.hxx> | |
| #include <odb/sqlite/binding.hxx> | | #include <odb/sqlite/binding.hxx> | |
| #include <odb/sqlite/connection.hxx> | | #include <odb/sqlite/connection.hxx> | |
| #include <odb/sqlite/auto-handle.hxx> | | #include <odb/sqlite/auto-handle.hxx> | |
| | | | |
| #include <odb/sqlite/details/export.hxx> | | #include <odb/sqlite/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace sqlite | | namespace sqlite | |
| { | | { | |
| class connection; | | class connection; | |
| | | | |
|
| class LIBODB_SQLITE_EXPORT statement: public details::shared_base | | class LIBODB_SQLITE_EXPORT statement: public odb::statement | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
| ~statement () = 0; | | ~statement () = 0; | |
| | | | |
| sqlite3_stmt* | | sqlite3_stmt* | |
|
| handle () | | handle () const | |
| { | | { | |
| return stmt_; | | return stmt_; | |
| } | | } | |
| | | | |
|
| | | virtual const char* | |
| | | text () const; | |
| | | | |
| // Cached state (public part). | | // Cached state (public part). | |
| // | | // | |
| public: | | public: | |
| bool | | bool | |
| cached () const | | cached () const | |
| { | | { | |
| return cached_; | | return cached_; | |
| } | | } | |
| | | | |
| void | | void | |
| | | | |
| skipping to change at line 69 | | skipping to change at line 73 | |
| if (!cached_) | | if (!cached_) | |
| { | | { | |
| if (!active_) | | if (!active_) | |
| list_remove (); | | list_remove (); | |
| | | | |
| cached_ = true; | | cached_ = true; | |
| } | | } | |
| } | | } | |
| | | | |
| protected: | | protected: | |
|
| statement (connection& conn, const std::string& statement) | | statement (connection& conn, const std::string& text) | |
| | | : conn_ (conn) | |
| | | { | |
| | | init (text.c_str (), text.size ()); | |
| | | } | |
| | | | |
| | | statement (connection& conn, const char* text) | |
| : conn_ (conn) | | : conn_ (conn) | |
| { | | { | |
|
| init (statement.c_str (), statement.size () + 1); | | init (text, std::strlen (text)); | |
| } | | } | |
| | | | |
|
| statement (connection& conn, const char* statement, std::size_t n) | | statement (connection& conn, const char* text, std::size_t text_size) | |
| : conn_ (conn) | | : conn_ (conn) | |
| { | | { | |
|
| init (statement, n); | | init (text, text_size); | |
| } | | } | |
| | | | |
| protected: | | protected: | |
| void | | void | |
|
| bind_param (const bind*, std::size_t count, std::size_t start_param =
0); | | bind_param (const bind*, std::size_t count); | |
| | | | |
| // Extract row columns into the bound buffers. If the truncated | | // Extract row columns into the bound buffers. If the truncated | |
| // argument is true, then only truncated columns are extracted. | | // argument is true, then only truncated columns are extracted. | |
| // Return true if all the data was extracted successfully and | | // Return true if all the data was extracted successfully and | |
| // false if one or more columns were truncated. | | // false if one or more columns were truncated. | |
| // | | // | |
| bool | | bool | |
| bind_result (const bind*, std::size_t count, bool truncated = false); | | bind_result (const bind*, std::size_t count, bool truncated = false); | |
| | | | |
| // Active state. | | // Active state. | |
| | | | |
| skipping to change at line 133 | | skipping to change at line 143 | |
| list_remove (); | | list_remove (); | |
| | | | |
| active_ = false; | | active_ = false; | |
| } | | } | |
| } | | } | |
| | | | |
| // Cached state (protected part). | | // Cached state (protected part). | |
| // | | // | |
| protected: | | protected: | |
| void | | void | |
|
| finilize () | | finilize (); | |
| { | | | |
| list_remove (); | | | |
| stmt_.reset (); | | | |
| } | | | |
| | | | |
| protected: | | protected: | |
| friend class connection; | | friend class connection; | |
| | | | |
| connection& conn_; | | connection& conn_; | |
| auto_handle<sqlite3_stmt> stmt_; | | auto_handle<sqlite3_stmt> stmt_; | |
| | | | |
| bool active_; | | bool active_; | |
| bool cached_; | | bool cached_; | |
| | | | |
| private: | | private: | |
| void | | void | |
|
| init (const char* statement, std::size_t n); | | init (const char* text, std::size_t text_size); | |
| | | | |
| // Doubly-linked list of active/uncached statements. | | // Doubly-linked list of active/uncached statements. | |
| // | | // | |
| private: | | private: | |
| void list_add () | | void list_add () | |
| { | | { | |
| if (next_ == this) | | if (next_ == this) | |
| { | | { | |
| next_ = conn_.statements_; | | next_ = conn_.statements_; | |
| conn_.statements_ = this; | | conn_.statements_ = this; | |
| | | | |
| skipping to change at line 194 | | skipping to change at line 200 | |
| } | | } | |
| | | | |
| // prev_ == 0 means we are the first element. | | // prev_ == 0 means we are the first element. | |
| // next_ == 0 means we are the last element. | | // next_ == 0 means we are the last element. | |
| // next_ == this means we are not on the list (prev_ should be 0). | | // next_ == this means we are not on the list (prev_ should be 0). | |
| // | | // | |
| statement* prev_; | | statement* prev_; | |
| statement* next_; | | statement* next_; | |
| }; | | }; | |
| | | | |
|
| class LIBODB_SQLITE_EXPORT simple_statement: public statement | | class LIBODB_SQLITE_EXPORT generic_statement: public statement | |
| { | | { | |
| public: | | public: | |
|
| simple_statement (connection&, const std::string& statement); | | generic_statement (connection&, const std::string& text); | |
| simple_statement (connection&, const char* statement, std::size_t n); | | generic_statement (connection&, const char* text); | |
| | | generic_statement (connection&, const char* text, std::size_t text_si | |
| | | ze); | |
| | | | |
| unsigned long long | | unsigned long long | |
| execute (); | | execute (); | |
| | | | |
| private: | | private: | |
|
| simple_statement (const simple_statement&); | | generic_statement (const generic_statement&); | |
| simple_statement& operator= (const simple_statement&); | | generic_statement& operator= (const generic_statement&); | |
| | | | |
| private: | | private: | |
| bool result_set_; | | bool result_set_; | |
| }; | | }; | |
| | | | |
| class LIBODB_SQLITE_EXPORT select_statement: public statement | | class LIBODB_SQLITE_EXPORT select_statement: public statement | |
| { | | { | |
| public: | | public: | |
| select_statement (connection& conn, | | select_statement (connection& conn, | |
|
| const std::string& statement, | | const std::string& text, | |
| binding& cond, | | binding& param, | |
| binding& data); | | binding& result); | |
| | | | |
| | | select_statement (connection& conn, | |
| | | const char* text, | |
| | | binding& param, | |
| | | binding& result); | |
| | | | |
| select_statement (connection& conn, | | select_statement (connection& conn, | |
|
| const std::string& statement, | | const std::string& text, | |
| binding& data); | | binding& result); | |
| | | | |
| | | select_statement (connection& conn, const char* text, binding& result | |
| | | ); | |
| | | | |
| // Common select interface expected by the generated code. | | // Common select interface expected by the generated code. | |
| // | | // | |
| public: | | public: | |
| enum result | | enum result | |
| { | | { | |
| success, | | success, | |
| no_data, | | no_data, | |
| truncated | | truncated | |
| }; | | }; | |
| | | | |
| skipping to change at line 280 | | skipping to change at line 294 | |
| | | | |
| void | | void | |
| reload (); | | reload (); | |
| | | | |
| private: | | private: | |
| select_statement (const select_statement&); | | select_statement (const select_statement&); | |
| select_statement& operator= (const select_statement&); | | select_statement& operator= (const select_statement&); | |
| | | | |
| private: | | private: | |
| bool done_; | | bool done_; | |
|
| binding* cond_; | | binding* param_; | |
| binding& data_; | | binding& result_; | |
| }; | | }; | |
| | | | |
| class LIBODB_SQLITE_EXPORT insert_statement: public statement | | class LIBODB_SQLITE_EXPORT insert_statement: public statement | |
| { | | { | |
| public: | | public: | |
| insert_statement (connection& conn, | | insert_statement (connection& conn, | |
|
| const std::string& statement, | | const std::string& text, | |
| binding& data); | | binding& param); | |
| | | | |
| | | insert_statement (connection& conn, const char* text, binding& param) | |
| | | ; | |
| | | | |
| // Return true if successful and false if the row is a duplicate. | | // Return true if successful and false if the row is a duplicate. | |
| // All other errors are reported by throwing exceptions. | | // All other errors are reported by throwing exceptions. | |
| // | | // | |
| bool | | bool | |
| execute (); | | execute (); | |
| | | | |
| unsigned long long | | unsigned long long | |
| id (); | | id (); | |
| | | | |
| private: | | private: | |
| insert_statement (const insert_statement&); | | insert_statement (const insert_statement&); | |
| insert_statement& operator= (const insert_statement&); | | insert_statement& operator= (const insert_statement&); | |
| | | | |
| private: | | private: | |
|
| binding& data_; | | binding& param_; | |
| }; | | }; | |
| | | | |
| class LIBODB_SQLITE_EXPORT update_statement: public statement | | class LIBODB_SQLITE_EXPORT update_statement: public statement | |
| { | | { | |
| public: | | public: | |
| update_statement (connection& conn, | | update_statement (connection& conn, | |
|
| const std::string& statement, | | const std::string& text, | |
| binding& cond, | | binding& param); | |
| binding& data); | | | |
| void | | update_statement (connection& conn, const char* text, binding& param) | |
| | | ; | |
| | | | |
| | | unsigned long long | |
| execute (); | | execute (); | |
| | | | |
| private: | | private: | |
| update_statement (const update_statement&); | | update_statement (const update_statement&); | |
| update_statement& operator= (const update_statement&); | | update_statement& operator= (const update_statement&); | |
| | | | |
| private: | | private: | |
|
| binding& cond_; | | binding& param_; | |
| binding& data_; | | | |
| }; | | }; | |
| | | | |
| class LIBODB_SQLITE_EXPORT delete_statement: public statement | | class LIBODB_SQLITE_EXPORT delete_statement: public statement | |
| { | | { | |
| public: | | public: | |
| delete_statement (connection& conn, | | delete_statement (connection& conn, | |
|
| const std::string& statement, | | const std::string& text, | |
| binding& cond); | | binding& param); | |
| | | | |
| | | delete_statement (connection& conn, const char* text, binding& param) | |
| | | ; | |
| | | | |
| unsigned long long | | unsigned long long | |
| execute (); | | execute (); | |
| | | | |
| private: | | private: | |
| delete_statement (const delete_statement&); | | delete_statement (const delete_statement&); | |
| delete_statement& operator= (const delete_statement&); | | delete_statement& operator= (const delete_statement&); | |
| | | | |
| private: | | private: | |
|
| binding& cond_; | | binding& param_; | |
| }; | | }; | |
| } | | } | |
| } | | } | |
| | | | |
| #include <odb/post.hxx> | | #include <odb/post.hxx> | |
| | | | |
| #endif // ODB_SQLITE_STATEMENT_HXX | | #endif // ODB_SQLITE_STATEMENT_HXX | |
| | | | |
End of changes. 24 change blocks. |
| 39 lines changed or deleted | | 63 lines changed or added | |
|
| traits.hxx | | traits.hxx | |
| | | | |
| skipping to change at line 14 | | skipping to change at line 14 | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_SQLITE_TRAITS_HXX | | #ifndef ODB_SQLITE_TRAITS_HXX | |
| #define ODB_SQLITE_TRAITS_HXX | | #define ODB_SQLITE_TRAITS_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 <cstring> // std::memcpy, std::memset, std::strlen | |
| | | | |
| #include <odb/traits.hxx> | | #include <odb/traits.hxx> | |
| #include <odb/wrapper-traits.hxx> | | #include <odb/wrapper-traits.hxx> | |
| | | | |
| #include <odb/details/buffer.hxx> | | #include <odb/details/buffer.hxx> | |
| #include <odb/details/wrapper-p.hxx> | | #include <odb/details/wrapper-p.hxx> | |
| | | | |
| #include <odb/sqlite/version.hxx> | | #include <odb/sqlite/version.hxx> | |
| #include <odb/sqlite/details/export.hxx> | | #include <odb/sqlite/details/export.hxx> | |
| | | | |
| | | | |
| skipping to change at line 95 | | skipping to change at line 96 | |
| }; | | }; | |
| | | | |
| // The wrapped_value_traits specializations should be able to handle | | // The wrapped_value_traits specializations should be able to handle | |
| // any value type which means we have to have every possible signature | | // any value type which means we have to have every possible signature | |
| // of the set_value() and set_image() functions. | | // of the set_value() and set_image() functions. | |
| // | | // | |
| template <typename W, database_type_id ID> | | template <typename W, database_type_id ID> | |
| struct wrapped_value_traits<W, ID, false> | | struct wrapped_value_traits<W, ID, false> | |
| { | | { | |
| typedef wrapper_traits<W> wtraits; | | typedef wrapper_traits<W> wtraits; | |
|
| typedef typename wtraits::wrapped_type wrapped_type; | | typedef typename wtraits::unrestricted_wrapped_type wrapped_type; | |
| | | | |
| typedef W value_type; | | typedef W value_type; | |
| typedef wrapped_type query_type; | | typedef wrapped_type query_type; | |
| typedef typename image_traits<ID>::image_type image_type; | | typedef typename image_traits<ID>::image_type image_type; | |
| | | | |
| typedef value_traits<wrapped_type, ID> vtraits; | | typedef value_traits<wrapped_type, ID> vtraits; | |
| | | | |
| static void | | static void | |
| set_value (W& v, const image_type& i, bool is_null) | | set_value (W& v, const image_type& i, bool is_null) | |
| { | | { | |
| | | | |
| skipping to change at line 134 | | skipping to change at line 135 | |
| set_image (details::buffer& b, std::size_t& n, bool& is_null, const W
& v) | | set_image (details::buffer& b, std::size_t& n, bool& is_null, const W
& v) | |
| { | | { | |
| vtraits::set_image (b, n, is_null, wtraits::get_ref (v)); | | vtraits::set_image (b, n, is_null, wtraits::get_ref (v)); | |
| } | | } | |
| }; | | }; | |
| | | | |
| template <typename W, database_type_id ID> | | template <typename W, database_type_id ID> | |
| struct wrapped_value_traits<W, ID, true> | | struct wrapped_value_traits<W, ID, true> | |
| { | | { | |
| typedef wrapper_traits<W> wtraits; | | typedef wrapper_traits<W> wtraits; | |
|
| typedef typename wtraits::wrapped_type wrapped_type; | | typedef typename wtraits::unrestricted_wrapped_type wrapped_type; | |
| | | | |
| typedef W value_type; | | typedef W value_type; | |
| typedef wrapped_type query_type; | | typedef wrapped_type query_type; | |
| typedef typename image_traits<ID>::image_type image_type; | | typedef typename image_traits<ID>::image_type image_type; | |
| | | | |
| typedef value_traits<wrapped_type, ID> vtraits; | | typedef value_traits<wrapped_type, ID> vtraits; | |
| | | | |
| static void | | static void | |
| set_value (W& v, const image_type& i, bool is_null) | | set_value (W& v, const image_type& i, bool is_null) | |
| { | | { | |
| | | | |
| skipping to change at line 271 | | skipping to change at line 272 | |
| }; | | }; | |
| | | | |
| template <std::size_t n> | | template <std::size_t n> | |
| struct default_value_traits<const char[n], id_text>: c_string_value_tra
its | | struct default_value_traits<const char[n], id_text>: c_string_value_tra
its | |
| { | | { | |
| }; | | }; | |
| | | | |
| // std::vector<char> (buffer) specialization. | | // std::vector<char> (buffer) specialization. | |
| // | | // | |
| template <> | | template <> | |
|
| struct LIBODB_SQLITE_EXPORT default_value_traits<std::vector<char>, id_ | | struct LIBODB_SQLITE_EXPORT default_value_traits< | |
| blob> | | std::vector<char>, id_blob> | |
| { | | { | |
| public: | | public: | |
| typedef std::vector<char> value_type; | | typedef std::vector<char> value_type; | |
| typedef std::vector<char> query_type; | | typedef std::vector<char> query_type; | |
| typedef details::buffer image_type; | | typedef details::buffer image_type; | |
| | | | |
| static void | | static void | |
| set_value (value_type& v, | | set_value (value_type& v, | |
| const details::buffer& b, | | const details::buffer& b, | |
| std::size_t n, | | std::size_t n, | |
| | | | |
| skipping to change at line 297 | | skipping to change at line 299 | |
| v.clear (); | | v.clear (); | |
| } | | } | |
| | | | |
| static void | | static void | |
| set_image (details::buffer&, | | set_image (details::buffer&, | |
| std::size_t& n, | | std::size_t& n, | |
| bool& is_null, | | bool& is_null, | |
| const value_type&); | | const value_type&); | |
| }; | | }; | |
| | | | |
|
| | | // std::vector<unsigned char> (buffer) specialization. | |
| | | // | |
| | | template <> | |
| | | struct LIBODB_SQLITE_EXPORT default_value_traits< | |
| | | std::vector<unsigned char>, id_blob> | |
| | | { | |
| | | public: | |
| | | typedef std::vector<unsigned char> value_type; | |
| | | typedef std::vector<unsigned char> query_type; | |
| | | typedef details::buffer image_type; | |
| | | | |
| | | static void | |
| | | set_value (value_type& v, | |
| | | const details::buffer& b, | |
| | | std::size_t n, | |
| | | bool is_null) | |
| | | { | |
| | | if (!is_null) | |
| | | { | |
| | | const unsigned char* d ( | |
| | | reinterpret_cast<const unsigned char*> (b.data ())); | |
| | | v.assign (d, d + n); | |
| | | } | |
| | | else | |
| | | v.clear (); | |
| | | } | |
| | | | |
| | | static void | |
| | | set_image (details::buffer&, | |
| | | std::size_t& n, | |
| | | bool& is_null, | |
| | | const value_type&); | |
| | | }; | |
| | | | |
| | | // char[n] (buffer) specialization. | |
| | | // | |
| | | template <std::size_t N> | |
| | | struct default_value_traits<char[N], id_blob> | |
| | | { | |
| | | public: | |
| | | typedef char* value_type; | |
| | | typedef const char* query_type; | |
| | | typedef details::buffer image_type; | |
| | | | |
| | | static void | |
| | | set_value (char* const& v, | |
| | | const details::buffer& b, | |
| | | std::size_t n, | |
| | | bool is_null) | |
| | | { | |
| | | if (!is_null) | |
| | | std::memcpy (v, b.data (), (n < N ? n : N)); | |
| | | else | |
| | | std::memset (v, 0, N); | |
| | | } | |
| | | | |
| | | static void | |
| | | set_image (details::buffer& b, | |
| | | std::size_t& n, | |
| | | bool& is_null, | |
| | | const char* v) | |
| | | { | |
| | | is_null = false; | |
| | | n = N; | |
| | | | |
| | | if (n > b.capacity ()) | |
| | | b.capacity (n); | |
| | | | |
| | | std::memcpy (b.data (), v, n); | |
| | | } | |
| | | }; | |
| | | | |
| | | // unsigned char[n] (buffer) specialization. | |
| | | // | |
| | | template <std::size_t N> | |
| | | struct default_value_traits<unsigned char[N], id_blob> | |
| | | { | |
| | | public: | |
| | | typedef unsigned char* value_type; | |
| | | typedef const unsigned char* query_type; | |
| | | typedef details::buffer image_type; | |
| | | | |
| | | static void | |
| | | set_value (unsigned char* const& v, | |
| | | const details::buffer& b, | |
| | | std::size_t n, | |
| | | bool is_null) | |
| | | { | |
| | | if (!is_null) | |
| | | std::memcpy (v, b.data (), (n < N ? n : N)); | |
| | | else | |
| | | std::memset (v, 0, N); | |
| | | } | |
| | | | |
| | | static void | |
| | | set_image (details::buffer& b, | |
| | | std::size_t& n, | |
| | | bool& is_null, | |
| | | const unsigned char* v) | |
| | | { | |
| | | is_null = false; | |
| | | n = N; | |
| | | | |
| | | if (n > b.capacity ()) | |
| | | b.capacity (n); | |
| | | | |
| | | std::memcpy (b.data (), v, n); | |
| | | } | |
| | | }; | |
| | | | |
| // | | // | |
| // type_traits | | // type_traits | |
| // | | // | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct default_type_traits; | | struct default_type_traits; | |
| | | | |
| template <typename T> | | template <typename T> | |
| class type_traits: public default_type_traits<T> | | class type_traits: public default_type_traits<T> | |
| { | | { | |
| | | | |
End of changes. 5 change blocks. |
| 4 lines changed or deleted | | 115 lines changed or added | |
|
| view-result.txx | | view-result.txx | |
| | | | |
| skipping to change at line 16 | | skipping to change at line 16 | |
| #include <odb/callback.hxx> | | #include <odb/callback.hxx> | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| | | | |
| #include <odb/sqlite/view-statements.hxx> | | #include <odb/sqlite/view-statements.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace sqlite | | namespace sqlite | |
| { | | { | |
| template <typename T> | | template <typename T> | |
|
| result_impl<T, class_view>:: | | view_result_impl<T>:: | |
| ~result_impl () | | ~view_result_impl () | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| result_impl<T, class_view>:: | | view_result_impl<T>:: | |
| result_impl (const query& q, | | view_result_impl (const query& q, | |
| details::shared_ptr<select_statement> statement, | | details::shared_ptr<select_statement> statement, | |
| view_statements<view_type>& statements) | | view_statements<view_type>& statements) | |
| : base_type (statements.connection ().database ()), | | : base_type (statements.connection ().database ()), | |
| result_impl_base (q, statement), | | result_impl_base (q, statement), | |
| statements_ (statements) | | statements_ (statements) | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| void result_impl<T, class_view>:: | | void view_result_impl<T>:: | |
| load (view_type& view) | | load (view_type& view) | |
| { | | { | |
| // The image can grow between calls to load() as a result of other | | // The image can grow between calls to load() as a result of other | |
| // statements execution. | | // statements execution. | |
| // | | // | |
| typename view_traits::image_type& im (statements_.image ()); | | typename view_traits::image_type& im (statements_.image ()); | |
| | | | |
| if (im.version != statements_.image_version ()) | | if (im.version != statements_.image_version ()) | |
| { | | { | |
| binding& b (statements_.image_binding ()); | | binding& b (statements_.image_binding ()); | |
| | | | |
| skipping to change at line 74 | | skipping to change at line 74 | |
| } | | } | |
| | | | |
| odb::database& db (this->database ()); | | odb::database& db (this->database ()); | |
| | | | |
| view_traits::callback (db, view, callback_event::pre_load); | | view_traits::callback (db, view, callback_event::pre_load); | |
| view_traits::init (view, im, db); | | view_traits::init (view, im, db); | |
| view_traits::callback (db, view, callback_event::post_load); | | view_traits::callback (db, view, callback_event::post_load); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| void result_impl<T, class_view>:: | | void view_result_impl<T>:: | |
| next () | | next () | |
| { | | { | |
| this->current (pointer_type ()); | | this->current (pointer_type ()); | |
| | | | |
| if (!statement_->next ()) | | if (!statement_->next ()) | |
| this->end_ = true; | | this->end_ = true; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| void result_impl<T, class_view>:: | | void view_result_impl<T>:: | |
| cache () | | cache () | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| std::size_t result_impl<T, class_view>:: | | std::size_t view_result_impl<T>:: | |
| size () | | size () | |
| { | | { | |
| throw result_not_cached (); | | throw result_not_cached (); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 6 change blocks. |
| 8 lines changed or deleted | | 8 lines changed or added | |
|