| container-statements.hxx | | container-statements.hxx | |
| | | | |
| skipping to change at line 13 | | skipping to change at line 13 | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #ifndef ODB_PGSQL_CONTAINER_STATEMENTS_HXX | | #ifndef ODB_PGSQL_CONTAINER_STATEMENTS_HXX | |
| #define ODB_PGSQL_CONTAINER_STATEMENTS_HXX | | #define ODB_PGSQL_CONTAINER_STATEMENTS_HXX | |
| | | | |
| #include <odb/pre.hxx> | | #include <odb/pre.hxx> | |
| | | | |
| #include <cstddef> // std::size_t | | #include <cstddef> // std::size_t | |
| | | | |
| #include <odb/forward.hxx> | | #include <odb/forward.hxx> | |
|
| | | #include <odb/schema-version.hxx> | |
| #include <odb/traits.hxx> | | #include <odb/traits.hxx> | |
| | | | |
| #include <odb/pgsql/version.hxx> | | #include <odb/pgsql/version.hxx> | |
| #include <odb/pgsql/binding.hxx> | | #include <odb/pgsql/binding.hxx> | |
| #include <odb/pgsql/statement.hxx> | | #include <odb/pgsql/statement.hxx> | |
| #include <odb/pgsql/pgsql-fwd.hxx> // Oid | | #include <odb/pgsql/pgsql-fwd.hxx> // Oid | |
| #include <odb/pgsql/details/export.hxx> | | #include <odb/pgsql/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| | | | |
| skipping to change at line 64 | | skipping to change at line 65 | |
| } | | } | |
| | | | |
| // Functions. | | // Functions. | |
| // | | // | |
| functions_type& | | functions_type& | |
| functions () | | functions () | |
| { | | { | |
| return functions_; | | return functions_; | |
| } | | } | |
| | | | |
|
| | | // Schema version. | |
| | | // | |
| | | const schema_version_migration& | |
| | | version_migration () const {return *svm_;} | |
| | | | |
| | | void | |
| | | version_migration (const schema_version_migration& svm) {svm_ = &svm; | |
| | | } | |
| | | | |
| // Id image binding (external). | | // Id image binding (external). | |
| // | | // | |
| const binding& | | const binding& | |
| id_binding () | | id_binding () | |
| { | | { | |
| return id_binding_; | | return id_binding_; | |
| } | | } | |
| | | | |
| // Data image. The image is split into the id (that comes as a | | // Data image. The image is split into the id (that comes as a | |
| // binding) and index/key plus value which are in data_image_type. | | // binding) and index/key plus value which are in data_image_type. | |
| | | | |
| skipping to change at line 124 | | skipping to change at line 133 | |
| | | | |
| insert_statement_type& | | insert_statement_type& | |
| insert_statement () | | insert_statement () | |
| { | | { | |
| if (insert_ == 0) | | if (insert_ == 0) | |
| insert_.reset ( | | insert_.reset ( | |
| new (details::shared) insert_statement_type ( | | new (details::shared) insert_statement_type ( | |
| conn_, | | conn_, | |
| insert_name_, | | insert_name_, | |
| insert_text_, | | insert_text_, | |
|
| | | versioned_, // Process if versioned. | |
| insert_types_, | | insert_types_, | |
| insert_count_, | | insert_count_, | |
| insert_image_binding_, | | insert_image_binding_, | |
| insert_image_native_binding_, | | insert_image_native_binding_, | |
| false, | | false, | |
| false)); | | false)); | |
| | | | |
| return *insert_; | | return *insert_; | |
| } | | } | |
| | | | |
| select_statement_type& | | select_statement_type& | |
| select_statement () | | select_statement () | |
| { | | { | |
| if (select_ == 0) | | if (select_ == 0) | |
| select_.reset ( | | select_.reset ( | |
| new (details::shared) select_statement_type ( | | new (details::shared) select_statement_type ( | |
| conn_, | | conn_, | |
| select_name_, | | select_name_, | |
| select_text_, | | select_text_, | |
|
| | | versioned_, // Process if versioned. | |
| | | false, // Don't optimize. | |
| id_types_, | | id_types_, | |
| id_binding_.count, | | id_binding_.count, | |
| id_binding_, | | id_binding_, | |
| id_native_binding_, | | id_native_binding_, | |
| select_image_binding_, | | select_image_binding_, | |
| false)); | | false)); | |
| | | | |
| return *select_; | | return *select_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 204 | | skipping to change at line 216 | |
| const char* insert_text_; | | const char* insert_text_; | |
| const Oid* insert_types_; | | const Oid* insert_types_; | |
| std::size_t insert_count_; | | std::size_t insert_count_; | |
| | | | |
| const char* select_name_; | | const char* select_name_; | |
| const char* select_text_; | | const char* select_text_; | |
| | | | |
| const char* delete_name_; | | const char* delete_name_; | |
| const char* delete_text_; | | const char* delete_text_; | |
| | | | |
|
| | | bool versioned_; | |
| | | const schema_version_migration* svm_; | |
| | | | |
| details::shared_ptr<insert_statement_type> insert_; | | details::shared_ptr<insert_statement_type> insert_; | |
| details::shared_ptr<select_statement_type> select_; | | details::shared_ptr<select_statement_type> select_; | |
| details::shared_ptr<delete_statement_type> delete_; | | details::shared_ptr<delete_statement_type> delete_; | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| class smart_container_statements: public container_statements<T> | | class smart_container_statements: public container_statements<T> | |
| { | | { | |
| public: | | public: | |
| typedef T traits; | | typedef T traits; | |
| | | | |
| skipping to change at line 316 | | skipping to change at line 331 | |
| | | | |
| 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 ( | |
| this->conn_, | | this->conn_, | |
| update_name_, | | update_name_, | |
| update_text_, | | update_text_, | |
|
| | | this->versioned_, // Process if versioned. | |
| update_types_, | | update_types_, | |
| update_count_, | | update_count_, | |
| update_image_binding_, | | update_image_binding_, | |
| update_image_native_binding_, | | update_image_native_binding_, | |
| false)); | | false)); | |
| | | | |
| return *update_; | | return *update_; | |
| } | | } | |
| | | | |
| protected: | | protected: | |
| | | | |
End of changes. 6 change blocks. |
| 0 lines changed or deleted | | 17 lines changed or added | |
|
| no-id-object-result.txx | | no-id-object-result.txx | |
| | | | |
| skipping to change at line 38 | | skipping to change at line 38 | |
| this->end_ = true; | | this->end_ = true; | |
| } | | } | |
| | | | |
| statement_.reset (); | | statement_.reset (); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| no_id_object_result_impl<T>:: | | no_id_object_result_impl<T>:: | |
| no_id_object_result_impl (const query_base&, | | no_id_object_result_impl (const query_base&, | |
| details::shared_ptr<select_statement> stateme
nt, | | details::shared_ptr<select_statement> stateme
nt, | |
|
| statements_type& statements) | | statements_type& statements, | |
| | | const schema_version_migration* svm) | |
| : base_type (statements.connection ()), | | : base_type (statements.connection ()), | |
| statement_ (statement), | | statement_ (statement), | |
| statements_ (statements), | | statements_ (statements), | |
|
| | | tc_ (svm), | |
| count_ (0) | | count_ (0) | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void no_id_object_result_impl<T>:: | | void no_id_object_result_impl<T>:: | |
| load (object_type& obj) | | load (object_type& obj) | |
| { | | { | |
| // 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_.select_image_version ()) | | if (im.version != statements_.select_image_version ()) | |
| { | | { | |
| binding& b (statements_.select_image_binding ()); | | binding& b (statements_.select_image_binding ()); | |
|
| object_traits::bind (b.bind, im, statement_select); | | tc_.bind (b.bind, im, statement_select); | |
| statements_.select_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_.select_image_truncated ())
) | | if (tc_.grow (im, statements_.select_image_truncated ())) | |
| im.version++; | | im.version++; | |
| | | | |
| if (im.version != statements_.select_image_version ()) | | if (im.version != statements_.select_image_version ()) | |
| { | | { | |
| binding& b (statements_.select_image_binding ()); | | binding& b (statements_.select_image_binding ()); | |
|
| object_traits::bind (b.bind, im, statement_select); | | tc_.bind (b.bind, im, statement_select); | |
| statements_.select_image_version (im.version); | | statements_.select_image_version (im.version); | |
| b.version++; | | b.version++; | |
| statement_->reload (); | | statement_->reload (); | |
| } | | } | |
| } | | } | |
| | | | |
| object_traits::callback (this->db_, obj, callback_event::pre_load); | | object_traits::callback (this->db_, obj, callback_event::pre_load); | |
|
| object_traits::init (obj, im, &this->db_); | | tc_.init (obj, im, &this->db_); | |
| object_traits::callback (this->db_, obj, callback_event::post_load); | | object_traits::callback (this->db_, obj, callback_event::post_load); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void no_id_object_result_impl<T>:: | | void no_id_object_result_impl<T>:: | |
| next () | | next () | |
| { | | { | |
| this->current (pointer_type ()); | | this->current (pointer_type ()); | |
| | | | |
| if (statement_->next ()) | | if (statement_->next ()) | |
| | | | |
End of changes. 6 change blocks. |
| 5 lines changed or deleted | | 7 lines changed or added | |
|
| polymorphic-object-result.txx | | polymorphic-object-result.txx | |
| | | | |
| skipping to change at line 41 | | skipping to change at line 41 | |
| this->end_ = true; | | this->end_ = true; | |
| } | | } | |
| | | | |
| statement_.reset (); | | statement_.reset (); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| polymorphic_object_result_impl<T>:: | | polymorphic_object_result_impl<T>:: | |
| polymorphic_object_result_impl (const query_base&, | | polymorphic_object_result_impl (const query_base&, | |
| details::shared_ptr<select_statement> s
t, | | details::shared_ptr<select_statement> s
t, | |
|
| statements_type& sts) | | statements_type& sts, | |
| | | const schema_version_migration* svm) | |
| : base_type (sts.connection ()), | | : base_type (sts.connection ()), | |
| statement_ (st), | | statement_ (st), | |
| statements_ (sts), | | statements_ (sts), | |
|
| | | tc_ (svm), | |
| count_ (0) | | count_ (0) | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void polymorphic_object_result_impl<T>:: | | void polymorphic_object_result_impl<T>:: | |
| load (object_type* pobj, bool fetch) | | load (object_type* pobj, bool fetch) | |
| { | | { | |
| if (fetch) | | if (fetch) | |
| load_image (); | | load_image (); | |
| | | | |
| skipping to change at line 124 | | skipping to change at line 126 | |
| const info_type& dpi (root_traits::map->find (typeid (*pobj))); | | const info_type& dpi (root_traits::map->find (typeid (*pobj))); | |
| | | | |
| if (&dpi != &pi && dpi.derived (pi)) | | if (&dpi != &pi && dpi.derived (pi)) | |
| throw object_not_persistent (); // @@ type_mismatch ? | | throw object_not_persistent (); // @@ type_mismatch ? | |
| } | | } | |
| } | | } | |
| | | | |
| callback_event ce (callback_event::pre_load); | | callback_event ce (callback_event::pre_load); | |
| pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); | | pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); | |
| | | | |
|
| object_traits::init (*pobj, i, &this->db_); | | tc_.init (*pobj, i, &this->db_); | |
| | | | |
| // Initialize the id image and binding and load the rest of the objec
t | | // Initialize the id image and binding and load the rest of the objec
t | |
| // (containers, dynamic part, etc). | | // (containers, dynamic part, etc). | |
| // | | // | |
| typename object_traits::id_image_type& idi (statements_.id_image ()); | | typename object_traits::id_image_type& idi (statements_.id_image ()); | |
| root_traits::init (idi, id); | | root_traits::init (idi, id); | |
| | | | |
| binding& idb (statements_.id_image_binding ()); | | binding& idb (statements_.id_image_binding ()); | |
| if (idi.version != statements_.id_image_version () || idb.version ==
0) | | if (idi.version != statements_.id_image_version () || idb.version ==
0) | |
| { | | { | |
| object_traits::bind (idb.bind, idi); | | object_traits::bind (idb.bind, idi); | |
| statements_.id_image_version (idi.version); | | statements_.id_image_version (idi.version); | |
| idb.version++; | | idb.version++; | |
| } | | } | |
| | | | |
|
| object_traits::load_ (statements_, *pobj); | | tc_.load_ (statements_, *pobj, false); | |
| | | | |
| // Load the dynamic part of the object unless static and dynamic | | // Load the dynamic part of the object unless static and dynamic | |
| // types are the same. | | // types are the same. | |
| // | | // | |
| if (&pi != &object_traits::info) | | if (&pi != &object_traits::info) | |
| { | | { | |
| std::size_t d (object_traits::depth); | | std::size_t d (object_traits::depth); | |
| pi.dispatch (info_type::call_load, this->db_, pobj, &d); | | pi.dispatch (info_type::call_load, this->db_, pobj, &d); | |
| }; | | }; | |
| | | | |
|
| rsts.load_delayed (); | | rsts.load_delayed (tc_.version ()); | |
| l.unlock (); | | l.unlock (); | |
| | | | |
| ce = callback_event::post_load; | | ce = callback_event::post_load; | |
| pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); | | pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); | |
| object_traits::pointer_cache_traits::load (ig.position ()); | | object_traits::pointer_cache_traits::load (ig.position ()); | |
| ig.release (); | | ig.release (); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename polymorphic_object_result_impl<T>::id_type | | typename polymorphic_object_result_impl<T>::id_type | |
| | | | |
| skipping to change at line 202 | | skipping to change at line 204 | |
| } | | } | |
| | | | |
| template <typename T, typename R> | | template <typename T, typename R> | |
| struct polymorphic_image_rebind | | struct polymorphic_image_rebind | |
| { | | { | |
| // Derived type version. | | // Derived type version. | |
| // | | // | |
| typedef object_traits_impl<T, id_pgsql> traits; | | typedef object_traits_impl<T, id_pgsql> traits; | |
| | | | |
| static bool | | static bool | |
|
| rebind (typename traits::statements_type& sts) | | rebind (typename traits::statements_type& sts, | |
| | | const schema_version_migration* svm) | |
| { | | { | |
| typename traits::image_type& im (sts.image ()); | | typename traits::image_type& im (sts.image ()); | |
| | | | |
| if (traits::check_version (sts.select_image_versions (), im)) | | if (traits::check_version (sts.select_image_versions (), im)) | |
| { | | { | |
| binding& b (sts.select_image_binding (traits::depth)); | | binding& b (sts.select_image_binding (traits::depth)); | |
|
| traits::bind (b.bind, 0, 0, im, statement_select); | | object_traits_calls<T> tc (svm); | |
| | | tc.bind (b.bind, 0, 0, im, statement_select); | |
| traits::update_version ( | | traits::update_version ( | |
| sts.select_image_versions (), im, sts.select_image_bindings ())
; | | sts.select_image_versions (), im, sts.select_image_bindings ())
; | |
| return true; | | return true; | |
| } | | } | |
| | | | |
| return false; | | return false; | |
| } | | } | |
| }; | | }; | |
| | | | |
| template <typename R> | | template <typename R> | |
| struct polymorphic_image_rebind<R, R> | | struct polymorphic_image_rebind<R, R> | |
| { | | { | |
| // Root type version. | | // Root type version. | |
| // | | // | |
| typedef object_traits_impl<R, id_pgsql> traits; | | typedef object_traits_impl<R, id_pgsql> traits; | |
| | | | |
| static bool | | static bool | |
|
| rebind (typename traits::statements_type& sts) | | rebind (typename traits::statements_type& sts, | |
| | | const schema_version_migration* svm) | |
| { | | { | |
| typename traits::image_type& im (sts.image ()); | | typename traits::image_type& im (sts.image ()); | |
| | | | |
| if (im.version != sts.select_image_version ()) | | if (im.version != sts.select_image_version ()) | |
| { | | { | |
| binding& b (sts.select_image_binding ()); | | binding& b (sts.select_image_binding ()); | |
|
| traits::bind (b.bind, im, statement_select); | | object_traits_calls<R> tc (svm); | |
| | | tc.bind (b.bind, im, statement_select); | |
| sts.select_image_version (im.version); | | sts.select_image_version (im.version); | |
| b.version++; | | b.version++; | |
| return true; | | return true; | |
| } | | } | |
| | | | |
| return false; | | return false; | |
| } | | } | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| void polymorphic_object_result_impl<T>:: | | void polymorphic_object_result_impl<T>:: | |
| load_image () | | load_image () | |
| { | | { | |
| typedef polymorphic_image_rebind<object_type, root_type> image_rebind
; | | typedef polymorphic_image_rebind<object_type, root_type> image_rebind
; | |
| | | | |
| // 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. | |
| // | | // | |
|
| image_rebind::rebind (statements_); | | image_rebind::rebind (statements_, tc_.version ()); | |
| | | | |
| select_statement::result r (statement_->load ()); | | select_statement::result r (statement_->load ()); | |
| | | | |
| if (r == select_statement::truncated) | | if (r == select_statement::truncated) | |
| { | | { | |
| typename object_traits::image_type& im (statements_.image ()); | | typename object_traits::image_type& im (statements_.image ()); | |
| | | | |
|
| if (object_traits::grow (im, statements_.select_image_truncated ())
) | | if (tc_.grow (im, statements_.select_image_truncated ())) | |
| im.version++; | | im.version++; | |
| | | | |
|
| if (image_rebind::rebind (statements_)) | | if (image_rebind::rebind (statements_, tc_.version ())) | |
| statement_->reload (); | | statement_->reload (); | |
| } | | } | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void polymorphic_object_result_impl<T>:: | | void polymorphic_object_result_impl<T>:: | |
| cache () | | cache () | |
| { | | { | |
| } | | } | |
| | | | |
| | | | |
End of changes. 12 change blocks. |
| 11 lines changed or deleted | | 17 lines changed or added | |
|
| polymorphic-object-statements.hxx | | polymorphic-object-statements.hxx | |
| | | | |
| skipping to change at line 113 | | skipping to change at line 113 | |
| // | | // | |
| select_statement_type& | | select_statement_type& | |
| find_discriminator_statement () | | find_discriminator_statement () | |
| { | | { | |
| if (find_discriminator_ == 0) | | if (find_discriminator_ == 0) | |
| find_discriminator_.reset ( | | find_discriminator_.reset ( | |
| new (details::shared) select_statement_type ( | | new (details::shared) select_statement_type ( | |
| this->conn_, | | this->conn_, | |
| object_traits::find_discriminator_statement_name, | | object_traits::find_discriminator_statement_name, | |
| object_traits::find_discriminator_statement, | | object_traits::find_discriminator_statement, | |
|
| | | false, // Doesn't need to be processed. | |
| | | false, // Don't optimize. | |
| object_traits::find_statement_types, // The same as find (id)
. | | object_traits::find_statement_types, // The same as find (id)
. | |
| id_column_count, | | id_column_count, | |
| discriminator_id_image_binding_, | | discriminator_id_image_binding_, | |
| discriminator_id_image_native_binding_, | | discriminator_id_image_native_binding_, | |
| discriminator_image_binding_, | | discriminator_image_binding_, | |
| false)); | | false)); | |
| | | | |
| return *find_discriminator_; | | return *find_discriminator_; | |
| } | | } | |
| | | | |
| public: | | public: | |
| polymorphic_root_object_statements (connection_type&); | | polymorphic_root_object_statements (connection_type&); | |
| | | | |
| virtual | | virtual | |
| ~polymorphic_root_object_statements (); | | ~polymorphic_root_object_statements (); | |
| | | | |
|
| | | // Static "override" (statements type). | |
| | | // | |
| | | void | |
| | | load_delayed (const schema_version_migration* svm) | |
| | | { | |
| | | assert (this->locked ()); | |
| | | | |
| | | if (!this->delayed_.empty ()) | |
| | | this->template load_delayed_<polymorphic_root_object_statements> | |
| | | ( | |
| | | svm); | |
| | | } | |
| | | | |
| public: | | public: | |
| static const std::size_t id_column_count = | | static const std::size_t id_column_count = | |
| object_statements<T>::id_column_count; | | object_statements<T>::id_column_count; | |
| | | | |
| static const std::size_t discriminator_column_count = | | static const std::size_t discriminator_column_count = | |
| object_traits::discriminator_column_count; | | object_traits::discriminator_column_count; | |
| | | | |
| static const std::size_t managed_optimistic_column_count = | | static const std::size_t managed_optimistic_column_count = | |
| object_traits::managed_optimistic_column_count; | | object_traits::managed_optimistic_column_count; | |
| | | | |
| | | | |
| skipping to change at line 186 | | skipping to change at line 200 | |
| typedef | | typedef | |
| polymorphic_root_object_statements<root_type> | | polymorphic_root_object_statements<root_type> | |
| root_statements_type; | | root_statements_type; | |
| | | | |
| typedef typename object_traits::base_type base_type; | | typedef typename object_traits::base_type base_type; | |
| typedef | | typedef | |
| typename object_traits::base_traits::statements_type | | typename object_traits::base_traits::statements_type | |
| base_statements_type; | | base_statements_type; | |
| | | | |
| typedef | | typedef | |
|
| typename object_traits::container_statement_cache_type | | typename object_traits::extra_statement_cache_type | |
| container_statement_cache_type; | | extra_statement_cache_type; | |
| | | | |
| typedef pgsql::insert_statement insert_statement_type; | | typedef pgsql::insert_statement insert_statement_type; | |
| typedef pgsql::select_statement select_statement_type; | | typedef pgsql::select_statement select_statement_type; | |
| typedef pgsql::update_statement update_statement_type; | | typedef pgsql::update_statement update_statement_type; | |
| typedef pgsql::delete_statement delete_statement_type; | | typedef pgsql::delete_statement delete_statement_type; | |
| | | | |
| typedef typename root_statements_type::auto_lock auto_lock; | | typedef typename root_statements_type::auto_lock auto_lock; | |
| | | | |
| public: | | public: | |
| polymorphic_derived_object_statements (connection_type&); | | polymorphic_derived_object_statements (connection_type&); | |
| | | | |
| virtual | | virtual | |
| ~polymorphic_derived_object_statements (); | | ~polymorphic_derived_object_statements (); | |
| | | | |
| public: | | public: | |
| // Delayed loading. | | // Delayed loading. | |
| // | | // | |
| static void | | static void | |
|
| delayed_loader (odb::database&, const id_type&, root_type&); | | delayed_loader (odb::database&, | |
| | | const id_type&, | |
| | | root_type&, | |
| | | const schema_version_migration*); | |
| public: | | public: | |
| // Root and immediate base statements. | | // Root and immediate base statements. | |
| // | | // | |
| root_statements_type& | | root_statements_type& | |
| root_statements () | | root_statements () | |
| { | | { | |
| return root_statements_; | | return root_statements_; | |
| } | | } | |
| | | | |
| base_statements_type& | | base_statements_type& | |
| | | | |
| skipping to change at line 297 | | skipping to change at line 313 | |
| | | | |
| std::size_t | | std::size_t | |
| id_image_version () const {return root_statements_.id_image_version (
);} | | id_image_version () const {return root_statements_.id_image_version (
);} | |
| | | | |
| void | | void | |
| id_image_version (std::size_t v) {root_statements_.id_image_version (
v);} | | id_image_version (std::size_t v) {root_statements_.id_image_version (
v);} | |
| | | | |
| binding& | | binding& | |
| id_image_binding () {return root_statements_.id_image_binding ();} | | id_image_binding () {return root_statements_.id_image_binding ();} | |
| | | | |
|
| | | binding& | |
| | | optimistic_id_image_binding () { | |
| | | return root_statements_.optimistic_id_image_binding ();} | |
| | | | |
| // Statements. | | // Statements. | |
| // | | // | |
| insert_statement_type& | | insert_statement_type& | |
| persist_statement () | | persist_statement () | |
| { | | { | |
| if (persist_ == 0) | | if (persist_ == 0) | |
| persist_.reset ( | | persist_.reset ( | |
| new (details::shared) insert_statement_type ( | | new (details::shared) insert_statement_type ( | |
| conn_, | | conn_, | |
| object_traits::persist_statement_name, | | object_traits::persist_statement_name, | |
| object_traits::persist_statement, | | object_traits::persist_statement, | |
|
| | | object_traits::versioned, // Process if versioned. | |
| object_traits::persist_statement_types, | | object_traits::persist_statement_types, | |
| insert_column_count, | | insert_column_count, | |
| insert_image_binding_, | | insert_image_binding_, | |
| insert_image_native_binding_, | | insert_image_native_binding_, | |
| object_traits::auto_id, | | object_traits::auto_id, | |
| false)); | | false)); | |
| | | | |
| return *persist_; | | return *persist_; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 330 | | skipping to change at line 351 | |
| { | | { | |
| std::size_t i (object_traits::depth - d); | | std::size_t i (object_traits::depth - d); | |
| details::shared_ptr<select_statement_type>& p (find_[i]); | | details::shared_ptr<select_statement_type>& p (find_[i]); | |
| | | | |
| if (p == 0) | | if (p == 0) | |
| p.reset ( | | p.reset ( | |
| new (details::shared) select_statement_type ( | | new (details::shared) select_statement_type ( | |
| conn_, | | conn_, | |
| object_traits::find_statement_names[i], | | object_traits::find_statement_names[i], | |
| object_traits::find_statements[i], | | object_traits::find_statements[i], | |
|
| | | object_traits::versioned, // Process if versioned. | |
| | | false, // Don't optimize. | |
| object_traits::find_statement_types, | | object_traits::find_statement_types, | |
| id_column_count, | | id_column_count, | |
| root_statements_.id_image_binding (), | | root_statements_.id_image_binding (), | |
| root_statements_.id_image_native_binding (), | | root_statements_.id_image_native_binding (), | |
| select_image_bindings_[i], | | select_image_bindings_[i], | |
| false)); | | false)); | |
| | | | |
| return *p; | | return *p; | |
| } | | } | |
| | | | |
| 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_name, | | object_traits::update_statement_name, | |
| object_traits::update_statement, | | object_traits::update_statement, | |
|
| | | object_traits::versioned, // Process if versioned. | |
| object_traits::update_statement_types, | | object_traits::update_statement_types, | |
| update_column_count + id_column_count, | | update_column_count + id_column_count, | |
| update_image_binding_, | | update_image_binding_, | |
| update_image_native_binding_, | | update_image_native_binding_, | |
| false)); | | false)); | |
| | | | |
| return *update_; | | return *update_; | |
| } | | } | |
| | | | |
| delete_statement_type& | | delete_statement_type& | |
| | | | |
| skipping to change at line 376 | | skipping to change at line 400 | |
| object_traits::erase_statement, | | object_traits::erase_statement, | |
| object_traits::find_statement_types, // The same as find (id)
. | | object_traits::find_statement_types, // The same as find (id)
. | |
| id_column_count, | | id_column_count, | |
| root_statements_.id_image_binding (), | | root_statements_.id_image_binding (), | |
| root_statements_.id_image_native_binding (), | | root_statements_.id_image_native_binding (), | |
| false)); | | false)); | |
| | | | |
| return *erase_; | | return *erase_; | |
| } | | } | |
| | | | |
|
| // Container statement cache. | | // Extra (container, section) statement cache. | |
| // | | // | |
|
| container_statement_cache_type& | | extra_statement_cache_type& | |
| container_statment_cache () | | extra_statement_cache () | |
| { | | { | |
|
| return container_statement_cache_.get ( | | return extra_statement_cache_.get ( | |
| conn_, | | conn_, | |
|
| root_statements_.id_image_binding (), | | image_, | |
| | | id_image_binding (), | |
| | | &id_image_binding (), // Note, not id+version. | |
| root_statements_.id_image_native_binding (), | | root_statements_.id_image_native_binding (), | |
| object_traits::find_statement_types); | | object_traits::find_statement_types); | |
| } | | } | |
| | | | |
| public: | | public: | |
|
| // select = total - id + base::select | | // select = total - id - separate_load + base::select | |
| // insert = total - inverse | | // insert = total - inverse | |
|
| // update = total - inverse - id - readonly | | // update = total - inverse - id - readonly - separate_update | |
| // | | // | |
| static const std::size_t id_column_count = | | static const std::size_t id_column_count = | |
| object_traits::id_column_count; | | object_traits::id_column_count; | |
| | | | |
| static const std::size_t select_column_count = | | static const std::size_t select_column_count = | |
|
| object_traits::column_count - id_column_count + | | object_traits::column_count - | |
| | | id_column_count - | |
| | | object_traits::separate_load_column_count + | |
| base_statements_type::select_column_count; | | base_statements_type::select_column_count; | |
| | | | |
| static const std::size_t insert_column_count = | | static const std::size_t insert_column_count = | |
|
| object_traits::column_count - object_traits::inverse_column_count; | | object_traits::column_count - | |
| | | object_traits::inverse_column_count; | |
| | | | |
|
| static const std::size_t update_column_count = insert_column_count - | | static const std::size_t update_column_count = | |
| object_traits::id_column_count - object_traits::readonly_column_cou | | insert_column_count - | |
| nt; | | object_traits::id_column_count - | |
| | | object_traits::readonly_column_count - | |
| | | object_traits::separate_update_column_count; | |
| | | | |
| private: | | private: | |
| polymorphic_derived_object_statements ( | | polymorphic_derived_object_statements ( | |
| const polymorphic_derived_object_statements&); | | const polymorphic_derived_object_statements&); | |
| | | | |
| polymorphic_derived_object_statements& | | polymorphic_derived_object_statements& | |
| operator= (const polymorphic_derived_object_statements&); | | operator= (const polymorphic_derived_object_statements&); | |
| | | | |
| private: | | private: | |
| root_statements_type& root_statements_; | | root_statements_type& root_statements_; | |
| base_statements_type& base_statements_; | | base_statements_type& base_statements_; | |
| | | | |
|
| container_statement_cache_ptr<container_statement_cache_type> | | extra_statement_cache_ptr<extra_statement_cache_type, image_type> | |
| container_statement_cache_; | | extra_statement_cache_; | |
| | | | |
| image_type image_; | | image_type image_; | |
| | | | |
| // Select binding. Here we are have an array of statements/bindings | | // Select binding. Here we are have an array of statements/bindings | |
| // one for each depth. In other words, if we have classes root, base, | | // one for each depth. In other words, if we have classes root, base, | |
| // and derived, then we have the following array of statements: | | // and derived, then we have the following array of statements: | |
| // | | // | |
| // [0] d + b + r | | // [0] d + b + r | |
| // [1] d + b | | // [1] d + b | |
| // [2] d | | // [2] d | |
| | | | |
End of changes. 18 change blocks. |
| 18 lines changed or deleted | | 50 lines changed or added | |
|
| polymorphic-object-statements.txx | | polymorphic-object-statements.txx | |
| | | | |
| skipping to change at line 13 | | skipping to change at line 13 | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #include <cstring> // std::memset | | #include <cstring> // std::memset | |
| | | | |
| #include <odb/callback.hxx> | | #include <odb/callback.hxx> | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| | | | |
| #include <odb/pgsql/connection.hxx> | | #include <odb/pgsql/connection.hxx> | |
| #include <odb/pgsql/transaction.hxx> | | #include <odb/pgsql/transaction.hxx> | |
| #include <odb/pgsql/statement-cache.hxx> | | #include <odb/pgsql/statement-cache.hxx> | |
|
| | | #include <odb/pgsql/traits-calls.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace pgsql | | namespace pgsql | |
| { | | { | |
| // | | // | |
| // polymorphic_root_object_statements | | // polymorphic_root_object_statements | |
| // | | // | |
| | | | |
| template <typename T> | | template <typename T> | |
| | | | |
| skipping to change at line 127 | | skipping to change at line 128 | |
| std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | | std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | |
| std::memset ( | | std::memset ( | |
| select_image_truncated_, 0, sizeof (select_image_truncated_)); | | select_image_truncated_, 0, sizeof (select_image_truncated_)); | |
| | | | |
| for (std::size_t i (0); i < select_column_count; ++i) | | for (std::size_t i (0); i < select_column_count; ++i) | |
| select_image_bind_[i].truncated = select_image_truncated_ + i; | | select_image_bind_[i].truncated = select_image_truncated_ + i; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void polymorphic_derived_object_statements<T>:: | | void polymorphic_derived_object_statements<T>:: | |
|
| delayed_loader (odb::database& db, const id_type& id, root_type& robj) | | delayed_loader (odb::database& db, | |
| | | const id_type& id, | |
| | | root_type& robj, | |
| | | const schema_version_migration* svm) | |
| { | | { | |
| connection_type& conn (transaction::current ().connection ()); | | connection_type& conn (transaction::current ().connection ()); | |
| polymorphic_derived_object_statements& sts ( | | polymorphic_derived_object_statements& sts ( | |
| conn.statement_cache ().find_object<object_type> ()); | | conn.statement_cache ().find_object<object_type> ()); | |
| root_statements_type& rsts (sts.root_statements ()); | | root_statements_type& rsts (sts.root_statements ()); | |
| | | | |
| object_type& obj (static_cast<object_type&> (robj)); | | object_type& obj (static_cast<object_type&> (robj)); | |
| | | | |
| // The same code as in object_statements::load_delayed_(). | | // The same code as in object_statements::load_delayed_(). | |
| // | | // | |
|
| if (!object_traits::find_ (sts, &id)) | | object_traits_calls<T> tc (svm); | |
| | | | |
| | | if (!tc.find_ (sts, &id)) | |
| throw object_not_persistent (); | | throw object_not_persistent (); | |
| | | | |
| object_traits::callback (db, obj, callback_event::pre_load); | | object_traits::callback (db, obj, callback_event::pre_load); | |
|
| object_traits::init (obj, sts.image (), &db); | | tc.init (obj, sts.image (), &db); | |
| object_traits::load_ (sts, obj); // Load containers, etc. | | tc.load_ (sts, obj, false); // Load containers, etc. | |
| | | | |
|
| rsts.load_delayed (); | | rsts.load_delayed (svm); | |
| | | | |
| { | | { | |
| typename root_statements_type::auto_unlock u (rsts); | | typename root_statements_type::auto_unlock u (rsts); | |
| object_traits::callback (db, obj, callback_event::post_load); | | object_traits::callback (db, obj, callback_event::post_load); | |
| } | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 5 change blocks. |
| 5 lines changed or deleted | | 11 lines changed or added | |
|
| query.txx | | query.txx | |
| // file : odb/pgsql/query.txx | | // file : odb/pgsql/query.txx | |
| // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | | // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace pgsql | | namespace pgsql | |
| { | | { | |
|
| | | // | |
| // query_base | | // query_base | |
| // | | // | |
| | | | |
| template <database_type_id ID> | | template <database_type_id ID> | |
| query_base:: | | query_base:: | |
| query_base (const query_column<bool, ID>& c) | | query_base (const query_column<bool, ID>& c) | |
| : binding_ (0, 0), native_binding_ (0, 0, 0, 0) | | : binding_ (0, 0), native_binding_ (0, 0, 0, 0) | |
| { | | { | |
| // Cannot use IS TRUE here since database type can be a non- | | // Cannot use IS TRUE here since database type can be a non- | |
| // integral type. | | // integral type. | |
| // | | // | |
| append (c.table (), c.column ()); | | append (c.table (), c.column ()); | |
| append ("="); | | append ("="); | |
| append<bool, ID> (val_bind<bool> (true), c.conversion ()); | | append<bool, ID> (val_bind<bool> (true), c.conversion ()); | |
| } | | } | |
| | | | |
|
| | | // | |
| // query_column | | // query_column | |
| // | | // | |
|
| | | | |
| | | // in | |
| | | // | |
| template <typename T, database_type_id ID> | | template <typename T, database_type_id ID> | |
| query_base query_column<T, ID>:: | | query_base query_column<T, ID>:: | |
| in (decayed_type v1, decayed_type v2) const | | in (decayed_type v1, decayed_type v2) const | |
| { | | { | |
| query_base q (table_, column_); | | query_base q (table_, column_); | |
| q += "IN ("; | | q += "IN ("; | |
| q.append<T, ID> (val_bind<T> (v1), conversion_); | | q.append<T, ID> (val_bind<T> (v1), conversion_); | |
| q += ","; | | q += ","; | |
| q.append<T, ID> (val_bind<T> (v2), conversion_); | | q.append<T, ID> (val_bind<T> (v2), conversion_); | |
| q += ")"; | | q += ")"; | |
| | | | |
| skipping to change at line 112 | | skipping to change at line 117 | |
| { | | { | |
| if (i != begin) | | if (i != begin) | |
| q += ","; | | q += ","; | |
| | | | |
| q.append<T, ID> (val_bind<T> (*i), conversion_); | | q.append<T, ID> (val_bind<T> (*i), conversion_); | |
| } | | } | |
| | | | |
| q += ")"; | | q += ")"; | |
| return q; | | return q; | |
| } | | } | |
|
| | | | |
| | | // like | |
| | | // | |
| | | template <typename T, database_type_id ID> | |
| | | query_base query_column<T, ID>:: | |
| | | like (val_bind<T> p) const | |
| | | { | |
| | | query_base q (table_, column_); | |
| | | q += "LIKE"; | |
| | | q.append<T, ID> (p, conversion_); | |
| | | return q; | |
| | | } | |
| | | | |
| | | template <typename T, database_type_id ID> | |
| | | query_base query_column<T, ID>:: | |
| | | like (ref_bind<T> p) const | |
| | | { | |
| | | query_base q (table_, column_); | |
| | | q += "LIKE"; | |
| | | q.append<T, ID> (p, conversion_); | |
| | | return q; | |
| | | } | |
| | | | |
| | | template <typename T, database_type_id ID> | |
| | | query_base query_column<T, ID>:: | |
| | | like (val_bind<T> p, decayed_type e) const | |
| | | { | |
| | | query_base q (table_, column_); | |
| | | q += "LIKE"; | |
| | | q.append<T, ID> (p, conversion_); | |
| | | q += "ESCAPE"; | |
| | | q.append<T, ID> (val_bind<T> (e), conversion_); | |
| | | return q; | |
| | | } | |
| | | | |
| | | template <typename T, database_type_id ID> | |
| | | query_base query_column<T, ID>:: | |
| | | like (ref_bind<T> p, decayed_type e) const | |
| | | { | |
| | | query_base q (table_, column_); | |
| | | q += "LIKE"; | |
| | | q.append<T, ID> (p, conversion_); | |
| | | q += "ESCAPE"; | |
| | | q.append<T, ID> (val_bind<T> (e), conversion_); | |
| | | return q; | |
| | | } | |
| } | | } | |
| } | | } | |
| | | | |
End of changes. 4 change blocks. |
| 0 lines changed or deleted | | 51 lines changed or added | |
|
| simple-object-result.txx | | simple-object-result.txx | |
| | | | |
| skipping to change at line 40 | | skipping to change at line 40 | |
| this->end_ = true; | | this->end_ = true; | |
| } | | } | |
| | | | |
| statement_.reset (); | | statement_.reset (); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| object_result_impl<T>:: | | object_result_impl<T>:: | |
| object_result_impl (const query_base&, | | object_result_impl (const query_base&, | |
| details::shared_ptr<select_statement> statement, | | details::shared_ptr<select_statement> statement, | |
|
| statements_type& statements) | | statements_type& statements, | |
| | | const schema_version_migration* svm) | |
| : base_type (statements.connection ()), | | : base_type (statements.connection ()), | |
| statement_ (statement), | | statement_ (statement), | |
| statements_ (statements), | | statements_ (statements), | |
|
| | | tc_ (svm), | |
| count_ (0) | | count_ (0) | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void object_result_impl<T>:: | | void object_result_impl<T>:: | |
| load (object_type& obj, bool fetch) | | load (object_type& obj, bool fetch) | |
| { | | { | |
| if (fetch) | | if (fetch) | |
| load_image (); | | 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 statements_type::auto_lock l (statements_); | | typename statements_type::auto_lock l (statements_); | |
| | | | |
| object_traits::callback (this->db_, obj, callback_event::pre_load); | | object_traits::callback (this->db_, obj, callback_event::pre_load); | |
| | | | |
| typename object_traits::image_type& i (statements_.image ()); | | typename object_traits::image_type& i (statements_.image ()); | |
|
| object_traits::init (obj, i, &this->db_); | | tc_.init (obj, i, &this->db_); | |
| | | | |
| // Initialize the id image and binding and load the rest of the objec
t | | // Initialize the id image and binding and load the rest of the objec
t | |
| // (containers, etc). | | // (containers, etc). | |
| // | | // | |
| typename object_traits::id_image_type& idi (statements_.id_image ()); | | typename object_traits::id_image_type& idi (statements_.id_image ()); | |
| object_traits::init (idi, object_traits::id (i)); | | object_traits::init (idi, object_traits::id (i)); | |
| | | | |
| binding& idb (statements_.id_image_binding ()); | | binding& idb (statements_.id_image_binding ()); | |
| if (idi.version != statements_.id_image_version () || idb.version ==
0) | | if (idi.version != statements_.id_image_version () || idb.version ==
0) | |
| { | | { | |
| object_traits::bind (idb.bind, idi); | | object_traits::bind (idb.bind, idi); | |
| statements_.id_image_version (idi.version); | | statements_.id_image_version (idi.version); | |
| idb.version++; | | idb.version++; | |
| } | | } | |
| | | | |
|
| object_traits::load_ (statements_, obj); | | tc_.load_ (statements_, obj, false); | |
| statements_.load_delayed (); | | statements_.load_delayed (tc_.version ()); | |
| l.unlock (); | | l.unlock (); | |
| object_traits::callback (this->db_, obj, callback_event::post_load); | | object_traits::callback (this->db_, obj, callback_event::post_load); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| typename object_result_impl<T>::id_type | | typename object_result_impl<T>::id_type | |
| object_result_impl<T>:: | | object_result_impl<T>:: | |
| load_id () | | load_id () | |
| { | | { | |
| load_image (); | | load_image (); | |
| | | | |
| skipping to change at line 121 | | skipping to change at line 123 | |
| 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_.select_image_version ()) | | if (im.version != statements_.select_image_version ()) | |
| { | | { | |
| binding& b (statements_.select_image_binding ()); | | binding& b (statements_.select_image_binding ()); | |
|
| object_traits::bind (b.bind, im, statement_select); | | tc_.bind (b.bind, im, statement_select); | |
| statements_.select_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_.select_image_truncated ())
) | | if (tc_.grow (im, statements_.select_image_truncated ())) | |
| im.version++; | | im.version++; | |
| | | | |
| if (im.version != statements_.select_image_version ()) | | if (im.version != statements_.select_image_version ()) | |
| { | | { | |
| binding& b (statements_.select_image_binding ()); | | binding& b (statements_.select_image_binding ()); | |
|
| object_traits::bind (b.bind, im, statement_select); | | tc_.bind (b.bind, im, statement_select); | |
| statements_.select_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 object_result_impl<T>:: | | void object_result_impl<T>:: | |
| cache () | | cache () | |
| | | | |
End of changes. 7 change blocks. |
| 7 lines changed or deleted | | 9 lines changed or added | |
|
| simple-object-statements.hxx | | simple-object-statements.hxx | |
| | | | |
| skipping to change at line 32 | | skipping to change at line 32 | |
| #include <odb/pgsql/binding.hxx> | | #include <odb/pgsql/binding.hxx> | |
| #include <odb/pgsql/statement.hxx> | | #include <odb/pgsql/statement.hxx> | |
| #include <odb/pgsql/statements-base.hxx> | | #include <odb/pgsql/statements-base.hxx> | |
| | | | |
| #include <odb/pgsql/details/export.hxx> | | #include <odb/pgsql/details/export.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace pgsql | | namespace pgsql | |
| { | | { | |
|
| // The container_statement_cache class is only defined (and used) in | | // The extra_statement_cache class is only defined (and used) in | |
| // the generated source file. However, object_statements may be | | // the generated source file. However, object_statements may be | |
| // referenced from another source file in the case of a polymorphic | | // referenced from another source file in the case of a polymorphic | |
|
| // hierarchy (though in this case the container statement cache is | | // hierarchy (though in this case the extra statement cache is | |
| // not used). As a result, we cannot have a by-value member and | | // not used). As a result, we cannot have a by-value member and | |
| // instead will store a pointer and lazily allocate the cache if | | // instead will store a pointer and lazily allocate the cache if | |
| // and when needed. We will also need to store a pointer to the | | // and when needed. We will also need to store a pointer to the | |
| // deleter function which will be initialized during allocation | | // deleter function which will be initialized during allocation | |
| // (at that point we know that the cache class is defined). | | // (at that point we know that the cache class is defined). | |
| // | | // | |
|
| template <typename T> | | template <typename T, typename I> | |
| struct container_statement_cache_ptr | | struct extra_statement_cache_ptr | |
| { | | { | |
|
| | | typedef I image_type; | |
| typedef pgsql::connection connection_type; | | typedef pgsql::connection connection_type; | |
| | | | |
|
| container_statement_cache_ptr (): p_ (0) {} | | extra_statement_cache_ptr (): p_ (0) {} | |
| ~container_statement_cache_ptr () | | ~extra_statement_cache_ptr () | |
| { | | { | |
| if (p_ != 0) | | if (p_ != 0) | |
|
| (this->*deleter_) (0, 0, 0, 0); | | (this->*deleter_) (0, 0, 0, 0, 0, 0); | |
| } | | } | |
| | | | |
| T& | | T& | |
| get (connection_type& c, | | get (connection_type& c, | |
|
| binding& id, native_binding& idn, const Oid* idt) | | image_type& im, | |
| | | binding& id, | |
| | | binding* idv, | |
| | | native_binding& idn, | |
| | | const Oid* idt) | |
| { | | { | |
| if (p_ == 0) | | if (p_ == 0) | |
|
| allocate (&c, &id, &idn, idt); | | allocate (&c, &im, &id, (idv != 0 ? idv : &id), &idn, idt); | |
| | | | |
| return *p_; | | return *p_; | |
| } | | } | |
| | | | |
| private: | | private: | |
| void | | void | |
|
| allocate (connection_type*, binding*, native_binding*, const Oid*); | | allocate (connection_type*, | |
| | | image_type*, | |
| | | binding*, binding*, native_binding*, const Oid*); | |
| | | | |
| private: | | private: | |
| T* p_; | | T* p_; | |
|
| void (container_statement_cache_ptr::*deleter_) ( | | void (extra_statement_cache_ptr::*deleter_) ( | |
| connection_type*, binding*, native_binding*, const Oid*); | | connection_type*, | |
| | | image_type*, | |
| | | binding*, binding*, native_binding*, const Oid*); | |
| }; | | }; | |
| | | | |
|
| template <typename T> | | template <typename T, typename I> | |
| void container_statement_cache_ptr<T>:: | | void extra_statement_cache_ptr<T, I>:: | |
| allocate (connection_type* c, | | allocate (connection_type* c, | |
|
| binding* id, native_binding* idn, const Oid* idt) | | image_type* im, | |
| | | binding* id, binding* idv, native_binding* idn, const Oid* id | |
| | | t) | |
| { | | { | |
| // To reduce object code size, this function acts as both allocator | | // To reduce object code size, this function acts as both allocator | |
| // and deleter. | | // and deleter. | |
| // | | // | |
| if (p_ == 0) | | if (p_ == 0) | |
| { | | { | |
|
| p_ = new T (*c, *id, *idn, idt); | | p_ = new T (*c, *im, *id, *idv, *idn, idt); | |
| deleter_ = &container_statement_cache_ptr<T>::allocate; | | deleter_ = &extra_statement_cache_ptr<T, I>::allocate; | |
| } | | } | |
| else | | else | |
| delete p_; | | delete p_; | |
| } | | } | |
| | | | |
| // | | // | |
| // Implementation for objects with object id. | | // Implementation for objects with object id. | |
| // | | // | |
| | | | |
| class LIBODB_PGSQL_EXPORT object_statements_base: public statements_bas
e | | class LIBODB_PGSQL_EXPORT object_statements_base: public statements_bas
e | |
| | | | |
| skipping to change at line 161 | | skipping to change at line 171 | |
| struct optimistic_data; | | struct optimistic_data; | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct optimistic_data<T, true> | | struct optimistic_data<T, true> | |
| { | | { | |
| typedef T object_type; | | typedef T object_type; | |
| typedef object_traits_impl<object_type, id_pgsql> object_traits; | | typedef object_traits_impl<object_type, id_pgsql> object_traits; | |
| | | | |
| optimistic_data (bind*, char** nv, int* nl, int* nf); | | optimistic_data (bind*, char** nv, int* nl, int* nf); | |
| | | | |
|
| | | binding* | |
| | | id_image_binding () {return &id_image_binding_;} | |
| | | | |
| | | native_binding* | |
| | | id_image_native_binding () {return &id_image_native_binding_;} | |
| | | | |
| | | const Oid* | |
| | | id_image_types () | |
| | | {return object_traits::optimistic_erase_statement_types;} | |
| | | | |
| // The id + optimistic column binding. | | // The id + optimistic column binding. | |
| // | | // | |
|
| std::size_t id_image_version_; | | | |
| binding id_image_binding_; | | binding id_image_binding_; | |
| native_binding id_image_native_binding_; | | native_binding id_image_native_binding_; | |
| | | | |
| details::shared_ptr<delete_statement> erase_; | | details::shared_ptr<delete_statement> erase_; | |
| }; | | }; | |
| | | | |
| template <typename T> | | template <typename T> | |
| struct optimistic_data<T, false> | | struct optimistic_data<T, false> | |
| { | | { | |
| optimistic_data (bind*, char**, int*, int*) {} | | optimistic_data (bind*, char**, int*, int*) {} | |
|
| | | | |
| | | binding* | |
| | | id_image_binding () {return 0;} | |
| | | | |
| | | native_binding* | |
| | | id_image_native_binding () {return 0;} | |
| | | | |
| | | const Oid* | |
| | | id_image_types () {return 0;} | |
| }; | | }; | |
| | | | |
| 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 object_traits_impl<object_type, id_pgsql> object_traits; | | typedef object_traits_impl<object_type, id_pgsql> 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 | | typedef | |
| typename object_traits::pointer_cache_traits | | typename object_traits::pointer_cache_traits | |
| pointer_cache_traits; | | pointer_cache_traits; | |
| | | | |
| typedef | | typedef | |
|
| typename object_traits::container_statement_cache_type | | typename object_traits::extra_statement_cache_type | |
| container_statement_cache_type; | | extra_statement_cache_type; | |
| | | | |
| typedef pgsql::insert_statement insert_statement_type; | | typedef pgsql::insert_statement insert_statement_type; | |
| typedef pgsql::select_statement select_statement_type; | | typedef pgsql::select_statement select_statement_type; | |
| typedef pgsql::update_statement update_statement_type; | | typedef pgsql::update_statement update_statement_type; | |
| typedef pgsql::delete_statement delete_statement_type; | | typedef pgsql::delete_statement delete_statement_type; | |
| | | | |
| // Automatic lock. | | // Automatic lock. | |
| // | | // | |
| struct auto_lock | | struct auto_lock | |
| { | | { | |
| | | | |
| skipping to change at line 243 | | skipping to change at line 271 | |
| }; | | }; | |
| | | | |
| public: | | public: | |
| object_statements (connection_type&); | | object_statements (connection_type&); | |
| | | | |
| virtual | | virtual | |
| ~object_statements (); | | ~object_statements (); | |
| | | | |
| // Delayed loading. | | // Delayed loading. | |
| // | | // | |
|
| typedef void (*loader_function) ( | | typedef void (*loader_function) (odb::database&, | |
| odb::database&, const id_type&, object_type&); | | const id_type&, | |
| | | object_type&, | |
| | | const schema_version_migration*); | |
| void | | void | |
| delay_load (const id_type& id, | | delay_load (const id_type& id, | |
| object_type& obj, | | object_type& obj, | |
| const typename pointer_cache_traits::position_type& p, | | const typename pointer_cache_traits::position_type& p, | |
| loader_function l = 0) | | loader_function l = 0) | |
| { | | { | |
| delayed_.push_back (delayed_load (id, obj, p, l)); | | delayed_.push_back (delayed_load (id, obj, p, l)); | |
| } | | } | |
| | | | |
| void | | void | |
|
| load_delayed () | | load_delayed (const schema_version_migration* svm) | |
| { | | { | |
| assert (locked ()); | | assert (locked ()); | |
| | | | |
| if (!delayed_.empty ()) | | if (!delayed_.empty ()) | |
|
| load_delayed_ (); | | load_delayed_<object_statements> (svm); | |
| } | | } | |
| | | | |
| void | | void | |
| clear_delayed () | | clear_delayed () | |
| { | | { | |
| if (!delayed_.empty ()) | | if (!delayed_.empty ()) | |
| clear_delayed_ (); | | clear_delayed_ (); | |
| } | | } | |
| | | | |
| // Object image. | | // Object image. | |
| | | | |
| skipping to change at line 332 | | skipping to change at line 361 | |
| | | | |
| std::size_t | | std::size_t | |
| id_image_version () const {return id_image_version_;} | | id_image_version () const {return id_image_version_;} | |
| | | | |
| void | | void | |
| id_image_version (std::size_t v) {id_image_version_ = v;} | | id_image_version (std::size_t v) {id_image_version_ = v;} | |
| | | | |
| binding& | | binding& | |
| id_image_binding () {return id_image_binding_;} | | id_image_binding () {return id_image_binding_;} | |
| | | | |
|
| // Optimistic id + managed column image binding. | | // Optimistic id + managed column image binding. It points to | |
| | | // the same suffix as id binding and they are always updated | |
| | | // at the same time. | |
| // | | // | |
|
| 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& | | binding& | |
| optimistic_id_image_binding () {return od_.id_image_binding_;} | | optimistic_id_image_binding () {return od_.id_image_binding_;} | |
| | | | |
| // Statements. | | // Statements. | |
| // | | // | |
| insert_statement_type& | | insert_statement_type& | |
| persist_statement () | | persist_statement () | |
| { | | { | |
| if (persist_ == 0) | | if (persist_ == 0) | |
| persist_.reset ( | | persist_.reset ( | |
| new (details::shared) insert_statement_type ( | | new (details::shared) insert_statement_type ( | |
| conn_, | | conn_, | |
| object_traits::persist_statement_name, | | object_traits::persist_statement_name, | |
| object_traits::persist_statement, | | object_traits::persist_statement, | |
|
| | | object_traits::versioned, // Process if versioned. | |
| object_traits::persist_statement_types, | | object_traits::persist_statement_types, | |
| insert_column_count, | | insert_column_count, | |
| insert_image_binding_, | | insert_image_binding_, | |
| insert_image_native_binding_, | | insert_image_native_binding_, | |
| object_traits::auto_id, | | object_traits::auto_id, | |
| false)); | | false)); | |
| | | | |
| return *persist_; | | return *persist_; | |
| } | | } | |
| | | | |
| select_statement_type& | | select_statement_type& | |
| find_statement () | | find_statement () | |
| { | | { | |
| if (find_ == 0) | | if (find_ == 0) | |
| find_.reset ( | | find_.reset ( | |
| new (details::shared) select_statement_type ( | | new (details::shared) select_statement_type ( | |
| conn_, | | conn_, | |
| object_traits::find_statement_name, | | object_traits::find_statement_name, | |
| object_traits::find_statement, | | object_traits::find_statement, | |
|
| | | object_traits::versioned, // Process if versioned. | |
| | | false, // Don't optimize. | |
| object_traits::find_statement_types, | | object_traits::find_statement_types, | |
| id_column_count, | | id_column_count, | |
| id_image_binding_, | | id_image_binding_, | |
| id_image_native_binding_, | | id_image_native_binding_, | |
| select_image_binding_, | | select_image_binding_, | |
| false)); | | false)); | |
| | | | |
| 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_name, | | object_traits::update_statement_name, | |
| object_traits::update_statement, | | object_traits::update_statement, | |
|
| | | object_traits::versioned, // Process if versioned. | |
| object_traits::update_statement_types, | | object_traits::update_statement_types, | |
| update_column_count + id_column_count, | | update_column_count + id_column_count, | |
| update_image_binding_, | | update_image_binding_, | |
| update_image_native_binding_, | | update_image_native_binding_, | |
| false)); | | false)); | |
| | | | |
| return *update_; | | return *update_; | |
| } | | } | |
| | | | |
| delete_statement_type& | | delete_statement_type& | |
| | | | |
| skipping to change at line 437 | | skipping to change at line 466 | |
| object_traits::optimistic_erase_statement, | | object_traits::optimistic_erase_statement, | |
| object_traits::optimistic_erase_statement_types, | | object_traits::optimistic_erase_statement_types, | |
| id_column_count + managed_optimistic_column_count, | | id_column_count + managed_optimistic_column_count, | |
| od_.id_image_binding_, | | od_.id_image_binding_, | |
| od_.id_image_native_binding_, | | od_.id_image_native_binding_, | |
| false)); | | false)); | |
| | | | |
| return *od_.erase_; | | return *od_.erase_; | |
| } | | } | |
| | | | |
|
| // Container statement cache. | | // Extra (container, section) statement cache. | |
| // | | // | |
|
| container_statement_cache_type& | | extra_statement_cache_type& | |
| container_statment_cache () | | extra_statement_cache () | |
| { | | { | |
|
| return container_statement_cache_.get ( | | return extra_statement_cache_.get ( | |
| conn_, | | conn_, | |
|
| | | image_, | |
| id_image_binding_, | | id_image_binding_, | |
|
| | | od_.id_image_binding (), | |
| id_image_native_binding_, | | id_image_native_binding_, | |
| object_traits::find_statement_types); | | object_traits::find_statement_types); | |
| } | | } | |
| | | | |
| public: | | public: | |
|
| // select = total | | // select = total - separate_load | |
| // insert = total - inverse - managed_optimistic - auto_id | | // insert = total - inverse - managed_optimistic - auto_id | |
|
| // update = total - inverse - managed_optimistic - id - readonly | | // update = total - inverse - managed_optimistic - id - readonly - | |
| | | // separate_update | |
| // | | // | |
| static const std::size_t select_column_count = | | static const std::size_t select_column_count = | |
|
| object_traits::column_count; | | object_traits::column_count - | |
| | | object_traits::separate_load_column_count; | |
| | | | |
| static const std::size_t id_column_count = | | static const std::size_t id_column_count = | |
| object_traits::id_column_count; | | object_traits::id_column_count; | |
| | | | |
| static const std::size_t insert_column_count = | | static const std::size_t insert_column_count = | |
|
| object_traits::column_count - object_traits::inverse_column_count - | | object_traits::column_count - | |
| | | object_traits::inverse_column_count - | |
| object_traits::managed_optimistic_column_count - | | object_traits::managed_optimistic_column_count - | |
| (object_traits::auto_id ? id_column_count : 0); | | (object_traits::auto_id ? id_column_count : 0); | |
| | | | |
|
| static const std::size_t update_column_count = insert_column_count - | | static const std::size_t update_column_count = | |
| | | insert_column_count - | |
| (object_traits::auto_id ? 0 : id_column_count) - | | (object_traits::auto_id ? 0 : id_column_count) - | |
|
| object_traits::readonly_column_count; | | object_traits::readonly_column_count - | |
| | | object_traits::separate_update_column_count; | |
| | | | |
| static const std::size_t managed_optimistic_column_count = | | static const std::size_t managed_optimistic_column_count = | |
| object_traits::managed_optimistic_column_count; | | object_traits::managed_optimistic_column_count; | |
| | | | |
| 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: | | protected: | |
| | | template <typename STS> | |
| void | | void | |
|
| load_delayed_ (); | | load_delayed_ (const schema_version_migration*); | |
| | | | |
| void | | void | |
| clear_delayed_ (); | | clear_delayed_ (); | |
| | | | |
| protected: | | protected: | |
|
| container_statement_cache_ptr<container_statement_cache_type> | | template <typename T1> | |
| container_statement_cache_; | | friend class polymorphic_derived_object_statements; | |
| | | | |
| | | extra_statement_cache_ptr<extra_statement_cache_type, image_type> | |
| | | extra_statement_cache_; | |
| | | | |
| image_type image_; | | image_type image_; | |
| | | | |
| // Select binding. | | // Select binding. | |
| // | | // | |
| std::size_t select_image_version_; | | std::size_t select_image_version_; | |
| binding select_image_binding_; | | binding select_image_binding_; | |
| bind select_image_bind_[select_column_count]; | | bind select_image_bind_[select_column_count]; | |
| bool select_image_truncated_[select_column_count]; | | bool select_image_truncated_[select_column_count]; | |
| | | | |
| | | | |
End of changes. 39 change blocks. |
| 47 lines changed or deleted | | 87 lines changed or added | |
|
| simple-object-statements.txx | | simple-object-statements.txx | |
| // file : odb/pgsql/simple-object-statements.txx | | // file : odb/pgsql/simple-object-statements.txx | |
| // copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC | | // copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC | |
| // license : GNU GPL v2; see accompanying LICENSE file | | // license : GNU GPL v2; see accompanying LICENSE file | |
| | | | |
| #include <cstring> // std::memset | | #include <cstring> // std::memset | |
| | | | |
| #include <odb/callback.hxx> | | #include <odb/callback.hxx> | |
| #include <odb/exceptions.hxx> | | #include <odb/exceptions.hxx> | |
| | | | |
| #include <odb/pgsql/connection.hxx> | | #include <odb/pgsql/connection.hxx> | |
|
| | | #include <odb/pgsql/traits-calls.hxx> | |
| | | | |
| namespace odb | | namespace odb | |
| { | | { | |
| namespace pgsql | | namespace pgsql | |
| { | | { | |
| // | | // | |
| // optimistic_data | | // optimistic_data | |
| // | | // | |
| | | | |
| template <typename T> | | template <typename T> | |
| | | | |
| skipping to change at line 32 | | skipping to change at line 33 | |
| optimistic_data (bind* b, char** nv, int* nl, int* nf) | | optimistic_data (bind* b, char** nv, int* nl, int* nf) | |
| : id_image_binding_ ( | | : id_image_binding_ ( | |
| b, | | b, | |
| object_traits::id_column_count + | | object_traits::id_column_count + | |
| object_traits::managed_optimistic_column_count), | | object_traits::managed_optimistic_column_count), | |
| id_image_native_binding_ ( | | id_image_native_binding_ ( | |
| nv, nl, nf, | | nv, nl, nf, | |
| object_traits::id_column_count + | | object_traits::id_column_count + | |
| object_traits::managed_optimistic_column_count) | | object_traits::managed_optimistic_column_count) | |
| { | | { | |
|
| id_image_version_ = 0; | | | |
| } | | } | |
| | | | |
| // | | // | |
| // object_statements | | // object_statements | |
| // | | // | |
| | | | |
| template <typename T> | | template <typename T> | |
| object_statements<T>:: | | object_statements<T>:: | |
| ~object_statements () | | ~object_statements () | |
| { | | { | |
| | | | |
| skipping to change at line 100 | | skipping to change at line 100 | |
| std::memset (update_image_bind_, 0, sizeof (update_image_bind_)); | | std::memset (update_image_bind_, 0, sizeof (update_image_bind_)); | |
| std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | | std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | |
| std::memset ( | | std::memset ( | |
| select_image_truncated_, 0, sizeof (select_image_truncated_)); | | select_image_truncated_, 0, sizeof (select_image_truncated_)); | |
| | | | |
| for (std::size_t i (0); i < select_column_count; ++i) | | for (std::size_t i (0); i < select_column_count; ++i) | |
| select_image_bind_[i].truncated = select_image_truncated_ + i; | | select_image_bind_[i].truncated = select_image_truncated_ + i; | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
|
| | | template <typename STS> | |
| void object_statements<T>:: | | void object_statements<T>:: | |
|
| load_delayed_ () | | load_delayed_ (const schema_version_migration* svm) | |
| { | | { | |
| database& db (connection ().database ()); | | database& db (connection ().database ()); | |
| | | | |
| delayed_loads dls; | | delayed_loads dls; | |
| swap_guard sg (*this, dls); | | swap_guard sg (*this, dls); | |
| | | | |
| while (!dls.empty ()) | | while (!dls.empty ()) | |
| { | | { | |
| delayed_load l (dls.back ()); | | delayed_load l (dls.back ()); | |
| typename pointer_cache_traits::insert_guard ig (l.pos); | | typename pointer_cache_traits::insert_guard ig (l.pos); | |
| dls.pop_back (); | | dls.pop_back (); | |
| | | | |
| if (l.loader == 0) | | if (l.loader == 0) | |
| { | | { | |
|
| if (!object_traits::find_ (*this, &l.id)) | | object_traits_calls<T> tc (svm); | |
| | | | |
| | | if (!tc.find_ (static_cast<STS&> (*this), &l.id)) | |
| throw object_not_persistent (); | | throw object_not_persistent (); | |
| | | | |
| object_traits::callback (db, *l.obj, callback_event::pre_load); | | object_traits::callback (db, *l.obj, callback_event::pre_load); | |
| | | | |
| // Our calls to init/load below can result in additional delayed | | // Our calls to init/load below can result in additional delayed | |
| // loads being added to the delayed_ vector. We need to process | | // loads being added to the delayed_ vector. We need to process | |
| // those before we call the post callback. | | // those before we call the post callback. | |
| // | | // | |
|
| object_traits::init (*l.obj, image (), &db); | | tc.init (*l.obj, image (), &db); | |
| object_traits::load_ (*this, *l.obj); // Load containers, etc. | | | |
| | | // Load containers, etc. | |
| | | // | |
| | | tc.load_ (static_cast<STS&> (*this), *l.obj, false); | |
| | | | |
| if (!delayed_.empty ()) | | if (!delayed_.empty ()) | |
|
| load_delayed_ (); | | load_delayed_<STS> (svm); | |
| | | | |
| // Temporarily unlock the statement for the post_load call so tha
t | | // Temporarily unlock the statement for the post_load call so tha
t | |
| // it can load objects of this type recursively. This is safe to
do | | // it can load objects of this type recursively. This is safe to
do | |
| // because we have completely loaded the current object. Also the | | // because we have completely loaded the current object. Also the | |
| // delayed_ list is clear before the unlock and should be clear o
n | | // delayed_ list is clear before the unlock and should be clear o
n | |
| // re-lock (since a callback can only call public API functions | | // re-lock (since a callback can only call public API functions | |
| // which will make sure all the delayed loads are processed befor
e | | // which will make sure all the delayed loads are processed befor
e | |
| // returning). | | // returning). | |
| // | | // | |
| { | | { | |
| auto_unlock u (*this); | | auto_unlock u (*this); | |
| object_traits::callback (db, *l.obj, callback_event::post_load)
; | | object_traits::callback (db, *l.obj, callback_event::post_load)
; | |
| } | | } | |
| } | | } | |
| else | | else | |
|
| l.loader (db, l.id, *l.obj); | | l.loader (db, l.id, *l.obj, svm); | |
| | | | |
| pointer_cache_traits::load (ig.position ()); | | pointer_cache_traits::load (ig.position ()); | |
| ig.release (); | | ig.release (); | |
| } | | } | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| void object_statements<T>:: | | void object_statements<T>:: | |
| clear_delayed_ () | | clear_delayed_ () | |
| { | | { | |
| | | | |
End of changes. 8 change blocks. |
| 7 lines changed or deleted | | 13 lines changed or added | |
|
| statement.hxx | | statement.hxx | |
| | | | |
| skipping to change at line 53 | | skipping to change at line 53 | |
| | | | |
| virtual const char* | | virtual const char* | |
| text () const; | | text () const; | |
| | | | |
| virtual connection_type& | | virtual connection_type& | |
| connection () | | connection () | |
| { | | { | |
| return conn_; | | return conn_; | |
| } | | } | |
| | | | |
|
| | | // A statement can be empty. This is used to handle situations | |
| | | // where a SELECT or UPDATE statement ends up not having any | |
| | | // columns after processing. An empty statement cannot be | |
| | | // executed. | |
| | | // | |
| | | bool | |
| | | empty () const | |
| | | { | |
| | | return *text_ == '\0'; | |
| | | } | |
| | | | |
| void | | void | |
| deallocate (); | | deallocate (); | |
| | | | |
| // Adapt an ODB binding to a native PostgreSQL parameter binding. | | // Adapt an ODB binding to a native PostgreSQL parameter binding. | |
| // | | // | |
| static void | | static void | |
| bind_param (native_binding&, const binding&); | | bind_param (native_binding&, const binding&); | |
| | | | |
| // Populate an ODB binding given a PostgreSQL result. If the truncate
d | | // Populate an ODB binding given a PostgreSQL result. If the truncate
d | |
| // argument is true, then only truncated columns are extracted. Retur
n | | // argument is true, then only truncated columns are extracted. Retur
n | |
| | | | |
| skipping to change at line 74 | | skipping to change at line 85 | |
| // more columns were truncated. | | // more columns were truncated. | |
| // | | // | |
| static bool | | static bool | |
| bind_result (bind*, | | bind_result (bind*, | |
| std::size_t count, | | std::size_t count, | |
| PGresult*, | | PGresult*, | |
| std::size_t row, | | std::size_t row, | |
| bool truncated = false); | | bool truncated = false); | |
| | | | |
| protected: | | protected: | |
|
| | | // We keep two versions to take advantage of std::string COW. | |
| | | // | |
| statement (connection_type&, | | statement (connection_type&, | |
| const std::string& name, | | const std::string& name, | |
| const std::string& text, | | const std::string& text, | |
|
| | | statement_kind, | |
| | | const binding* process, | |
| | | bool optimize, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count); | | std::size_t types_count); | |
| | | | |
| statement (connection_type&, | | statement (connection_type&, | |
| const char* name, | | const char* name, | |
| const char* text, | | const char* text, | |
|
| | | statement_kind, | |
| | | const binding* process, | |
| | | bool optimize, | |
| bool copy_name_text, | | bool copy_name_text, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count); | | std::size_t types_count); | |
| | | | |
| private: | | private: | |
| void | | void | |
|
| init (const Oid* types, std::size_t types_count); | | init (statement_kind, | |
| | | const binding* process, | |
| | | bool optimize, | |
| | | const Oid* types, | |
| | | std::size_t types_count); | |
| | | | |
| protected: | | protected: | |
| connection_type& conn_; | | connection_type& conn_; | |
| | | | |
| std::string name_copy_; | | std::string name_copy_; | |
| const char* name_; | | const char* name_; | |
| | | | |
| std::string text_copy_; | | std::string text_copy_; | |
| const char* text_; | | const char* text_; | |
| | | | |
| | | | |
| skipping to change at line 113 | | skipping to change at line 136 | |
| | | | |
| class LIBODB_PGSQL_EXPORT select_statement: public statement | | class LIBODB_PGSQL_EXPORT select_statement: public statement | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
| ~select_statement (); | | ~select_statement (); | |
| | | | |
| select_statement (connection_type& conn, | | select_statement (connection_type& conn, | |
| const std::string& name, | | const std::string& name, | |
| const std::string& text, | | const std::string& text, | |
|
| | | bool process_text, | |
| | | bool optimize_text, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count, | | std::size_t types_count, | |
| binding& param, | | binding& param, | |
| native_binding& native_param, | | native_binding& native_param, | |
| binding& result); | | binding& result); | |
| | | | |
| select_statement (connection_type& conn, | | select_statement (connection_type& conn, | |
| const char* name, | | const char* name, | |
| const char* stmt, | | const char* stmt, | |
|
| | | bool process_text, | |
| | | bool optimize_text, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count, | | std::size_t types_count, | |
| binding& param, | | binding& param, | |
| native_binding& native_param, | | native_binding& native_param, | |
| binding& result, | | binding& result, | |
| bool copy_name_text = true); | | bool copy_name_text = true); | |
| | | | |
| select_statement (connection_type& conn, | | select_statement (connection_type& conn, | |
| const std::string& name, | | const std::string& name, | |
| const std::string& text, | | const std::string& text, | |
|
| | | bool process_text, | |
| | | bool optimize_text, | |
| binding& result); | | binding& result); | |
| | | | |
| select_statement (connection_type& conn, | | select_statement (connection_type& conn, | |
| const char* name, | | const char* name, | |
| const char* text, | | const char* text, | |
|
| | | bool process_text, | |
| | | bool optimize_text, | |
| binding& result, | | binding& result, | |
| bool copy_name_text = true); | | bool copy_name_text = true); | |
| | | | |
| select_statement (connection_type& conn, | | select_statement (connection_type& conn, | |
| const std::string& name, | | const std::string& name, | |
| const std::string& text, | | const std::string& text, | |
|
| | | bool process_text, | |
| | | bool optimize_text, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count, | | std::size_t types_count, | |
| native_binding& native_param, | | native_binding& native_param, | |
| binding& result); | | binding& result); | |
| | | | |
| // Common select interface expected by the generated code. | | // Common select interface expected by the generated code. | |
| // | | // | |
| public: | | public: | |
| enum result | | enum result | |
| { | | { | |
| | | | |
| skipping to change at line 243 | | skipping to change at line 276 | |
| | | | |
| class LIBODB_PGSQL_EXPORT insert_statement: public statement | | class LIBODB_PGSQL_EXPORT insert_statement: public statement | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
| ~insert_statement (); | | ~insert_statement (); | |
| | | | |
| insert_statement (connection_type& conn, | | insert_statement (connection_type& conn, | |
| const std::string& name, | | const std::string& name, | |
| const std::string& text, | | const std::string& text, | |
|
| | | bool process_text, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count, | | std::size_t types_count, | |
| binding& param, | | binding& param, | |
| native_binding& native_param, | | native_binding& native_param, | |
| bool returning); | | bool returning); | |
| | | | |
| insert_statement (connection_type& conn, | | insert_statement (connection_type& conn, | |
| const char* name, | | const char* name, | |
| const char* text, | | const char* text, | |
|
| | | bool process_text, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count, | | std::size_t types_count, | |
| binding& param, | | binding& param, | |
| native_binding& native_param, | | native_binding& native_param, | |
| bool returning, | | bool returning, | |
| bool copy_name_text = true); | | bool copy_name_text = true); | |
| | | | |
| // 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. | |
| // | | // | |
| | | | |
| skipping to change at line 292 | | skipping to change at line 327 | |
| | | | |
| class LIBODB_PGSQL_EXPORT update_statement: public statement | | class LIBODB_PGSQL_EXPORT update_statement: public statement | |
| { | | { | |
| public: | | public: | |
| virtual | | virtual | |
| ~update_statement (); | | ~update_statement (); | |
| | | | |
| update_statement (connection_type& conn, | | update_statement (connection_type& conn, | |
| const std::string& name, | | const std::string& name, | |
| const std::string& text, | | const std::string& text, | |
|
| | | bool process_text, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count, | | std::size_t types_count, | |
| binding& param, | | binding& param, | |
| native_binding& native_param); | | native_binding& native_param); | |
| | | | |
| update_statement (connection_type& conn, | | update_statement (connection_type& conn, | |
| const char* name, | | const char* name, | |
| const char* text, | | const char* text, | |
|
| | | bool process_text, | |
| const Oid* types, | | const Oid* types, | |
| std::size_t types_count, | | std::size_t types_count, | |
| binding& param, | | binding& param, | |
| native_binding& native_param, | | native_binding& native_param, | |
| bool copy_name_text = true); | | bool copy_name_text = true); | |
| | | | |
| unsigned long long | | unsigned long long | |
| execute (); | | execute (); | |
| | | | |
| private: | | private: | |
| | | | |
End of changes. 14 change blocks. |
| 1 lines changed or deleted | | 38 lines changed or added | |
|