From 2c44802ec25744ba351536a41f3ffc28d56282be Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 11 Oct 2011 16:52:45 +0200 Subject: Split 'in' binding into insert/update pair; rename 'out' to select Also add the initial infrastructure for the readonly members support. Right now the split insert/update bindings allows us to avoid sending object id in UPDATE statements. It will also allows us to support readonly members. --- odb/pgsql/forward.hxx | 7 ++ odb/pgsql/object-result.txx | 18 ++-- odb/pgsql/object-statements.hxx | 184 +++++++++++++++++++++------------------- odb/pgsql/object-statements.txx | 50 ++++++----- 4 files changed, 143 insertions(+), 116 deletions(-) diff --git a/odb/pgsql/forward.hxx b/odb/pgsql/forward.hxx index 0e1fb10..2ec44ec 100644 --- a/odb/pgsql/forward.hxx +++ b/odb/pgsql/forward.hxx @@ -23,6 +23,13 @@ namespace odb // Implementation details. // + enum statement_kind + { + statement_select, + statement_insert, + statement_update + }; + class binding; class select_statement; diff --git a/odb/pgsql/object-result.txx b/odb/pgsql/object-result.txx index f4ee961..b10afe4 100644 --- a/odb/pgsql/object-result.txx +++ b/odb/pgsql/object-result.txx @@ -93,11 +93,11 @@ namespace odb // 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 ()); - object_traits::bind (b.bind, im, true); - statements_.out_image_version (im.version); + binding& b (statements_.select_image_binding ()); + object_traits::bind (b.bind, im, statement_select); + statements_.select_image_version (im.version); b.version++; } @@ -105,14 +105,14 @@ namespace odb 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++; - if (im.version != statements_.out_image_version ()) + if (im.version != statements_.select_image_version ()) { - binding& b (statements_.out_image_binding ()); - object_traits::bind (b.bind, im, true); - statements_.out_image_version (im.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 (); } diff --git a/odb/pgsql/object-statements.hxx b/odb/pgsql/object-statements.hxx index dc3c0db..912c864 100644 --- a/odb/pgsql/object-statements.hxx +++ b/odb/pgsql/object-statements.hxx @@ -101,10 +101,10 @@ namespace odb typename object_traits::container_statement_cache_type container_statement_cache_type; - typedef pgsql::insert_statement persist_statement_type; - typedef pgsql::select_statement find_statement_type; + typedef pgsql::insert_statement insert_statement_type; + typedef pgsql::select_statement select_statement_type; typedef pgsql::update_statement update_statement_type; - typedef pgsql::delete_statement erase_statement_type; + typedef pgsql::delete_statement delete_statement_type; // Automatic lock. // @@ -176,115 +176,94 @@ namespace odb // Object image. // image_type& - image () - { - return image_; - } - - std::size_t - in_image_version () const - { - return in_image_version_; - } + image () {return image_;} + // Insert binding. + // std::size_t - out_image_version () const - { - return out_image_version_; - } + insert_image_version () const { return insert_image_version_;} void - in_image_version (std::size_t v) - { - in_image_version_ = v; - } + insert_image_version (std::size_t v) {insert_image_version_ = v;} + + binding& + insert_image_binding () {return insert_image_binding_;} + + // Update binding. + // + std::size_t + update_image_version () const { return update_image_version_;} void - out_image_version (std::size_t v) - { - out_image_version_ = v; - } + update_image_version (std::size_t v) {update_image_version_ = v;} binding& - in_image_binding () - { - return in_image_binding_; - } + update_image_binding () {return update_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& - out_image_binding () - { - return out_image_binding_; - } + select_image_binding () {return select_image_binding_;} bool* - out_image_truncated () - { - return out_image_truncated_; - } + select_image_truncated () {return select_image_truncated_;} - // Object id image. + // Object id image and binding. // id_image_type& - id_image () - { - return id_image_; - } + id_image () {return id_image_;} std::size_t - id_image_version () const - { - return id_image_version_; - } + id_image_version () const {return id_image_version_;} void - id_image_version (std::size_t v) - { - id_image_version_ = v; - } + id_image_version (std::size_t v) {id_image_version_ = v;} binding& - id_image_binding () - { - return id_image_binding_; - } + id_image_binding () {return id_image_binding_;} // Statements. // - persist_statement_type& + insert_statement_type& persist_statement () { if (persist_ == 0) { persist_.reset ( - new (details::shared) persist_statement_type ( + new (details::shared) insert_statement_type ( conn_, object_traits::persist_statement_name, object_traits::persist_statement, object_traits::persist_statement_types, - object_traits::in_column_count, - in_image_binding_, - in_image_native_binding_)); + insert_column_count, + insert_image_binding_, + insert_image_native_binding_)); } return *persist_; } - find_statement_type& + select_statement_type& find_statement () { if (find_ == 0) { find_.reset ( - new (details::shared) find_statement_type ( + new (details::shared) select_statement_type ( conn_, object_traits::find_statement_name, object_traits::find_statement, object_traits::find_statement_types, - 1, + id_column_count, id_image_binding_, id_image_native_binding_, - out_image_binding_)); + select_image_binding_)); } return *find_; @@ -301,28 +280,28 @@ namespace odb object_traits::update_statement_name, object_traits::update_statement, object_traits::update_statement_types, - object_traits::in_column_count + 1, + update_column_count + id_column_count, id_image_binding_, id_image_native_binding_, - in_image_binding_, - in_image_native_binding_)); + update_image_binding_, + update_image_native_binding_)); } return *update_; } - erase_statement_type& + delete_statement_type& erase_statement () { if (erase_ == 0) { erase_.reset ( - new (details::shared) erase_statement_type ( + new (details::shared) delete_statement_type ( conn_, object_traits::erase_statement_name, object_traits::erase_statement, object_traits::erase_statement_types, - 1, + id_column_count, id_image_binding_, id_image_native_binding_)); } @@ -350,38 +329,67 @@ namespace odb clear_delayed_ (); private: + // select = total + // insert = total - inverse + // update = total - inverse - 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; + + static const std::size_t update_column_count = insert_column_count - + object_traits::id_column_count - object_traits::readonly_column_count; + + static const std::size_t id_column_count = + object_traits::id_column_count; + + private: container_statement_cache_type container_statement_cache_; image_type image_; - // In (send) binding. The last element is the id parameter. - // - std::size_t in_image_version_; - binding in_image_binding_; - bind in_image_bind_[object_traits::in_column_count + 1]; - native_binding in_image_native_binding_; - char* in_image_values_[object_traits::in_column_count + 1]; - int in_image_lengths_[object_traits::in_column_count + 1]; - int in_image_formats_[object_traits::in_column_count + 1]; - - // Out (receive) binding. + // Select binding. // - std::size_t out_image_version_; - binding out_image_binding_; - bind out_image_bind_[object_traits::out_column_count]; - bool out_image_truncated_[object_traits::out_column_count]; + std::size_t select_image_version_; + binding select_image_binding_; + bind select_image_bind_[select_column_count]; + bool select_image_truncated_[select_column_count]; - // Id image binding (only in). + // Insert binding. + // + std::size_t insert_image_version_; + binding insert_image_binding_; + bind insert_image_bind_[insert_column_count]; + native_binding insert_image_native_binding_; + char* insert_image_values_[insert_column_count]; + int insert_image_lengths_[insert_column_count]; + int insert_image_formats_[insert_column_count]; + + // Update binding. The suffix of the bind array is object id. we + // do it this way for consistency with other databases. + // + std::size_t update_image_version_; + binding update_image_binding_; + bind update_image_bind_[update_column_count + id_column_count]; + native_binding update_image_native_binding_; + char* update_image_values_[update_column_count + id_column_count]; + int update_image_lengths_[update_column_count + id_column_count]; + int update_image_formats_[update_column_count + id_column_count]; + + // Id image binding (only used as a parameter). Uses the suffix in + // the update bind. // id_image_type id_image_; std::size_t id_image_version_; binding id_image_binding_; native_binding id_image_native_binding_; - details::shared_ptr persist_; - details::shared_ptr find_; + details::shared_ptr persist_; + details::shared_ptr find_; details::shared_ptr update_; - details::shared_ptr erase_; + details::shared_ptr erase_; // Delayed loading. // diff --git a/odb/pgsql/object-statements.txx b/odb/pgsql/object-statements.txx index c204ae6..409ed22 100644 --- a/odb/pgsql/object-statements.txx +++ b/odb/pgsql/object-statements.txx @@ -27,33 +27,45 @@ namespace odb object_statements (connection_type& conn) : object_statements_base (conn), container_statement_cache_ (conn), - in_image_binding_ (in_image_bind_, object_traits::in_column_count), - in_image_native_binding_ (in_image_values_, - in_image_lengths_, - in_image_formats_, - object_traits::in_column_count), - out_image_binding_ (out_image_bind_, - object_traits::out_column_count), - id_image_binding_ (in_image_bind_ + object_traits::in_column_count, - 1), + // select + select_image_binding_ (select_image_bind_, select_column_count), + // insert + insert_image_binding_ (insert_image_bind_, insert_column_count), + insert_image_native_binding_ (insert_image_values_, + insert_image_lengths_, + insert_image_formats_, + insert_column_count), + // update + update_image_binding_ (update_image_bind_, update_column_count), + update_image_native_binding_ (update_image_values_, + update_image_lengths_, + update_image_formats_, + update_column_count), + // id + id_image_binding_ (update_image_bind_ + update_column_count, + id_column_count), id_image_native_binding_ ( - in_image_values_ + object_traits::in_column_count, - in_image_lengths_ + object_traits::in_column_count, - in_image_formats_ + object_traits::in_column_count, 1) + update_image_values_ + update_column_count, + update_image_lengths_ + update_column_count, + update_image_formats_ + update_column_count, + id_column_count) { image_.version = 0; - in_image_version_ = 0; - out_image_version_ = 0; + select_image_version_ = 0; + insert_image_version_ = 0; + update_image_version_ = 0; id_image_.version = 0; id_image_version_ = 0; - std::memset (in_image_bind_, 0, sizeof (in_image_bind_)); - std::memset (out_image_bind_, 0, sizeof (out_image_bind_)); - std::memset (out_image_truncated_, 0, sizeof (out_image_truncated_)); + std::memset (insert_image_bind_, 0, sizeof (insert_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_truncated_, 0, sizeof (select_image_truncated_)); - for (std::size_t i (0); i < object_traits::out_column_count; ++i) - out_image_bind_[i].truncated = out_image_truncated_ + i; + for (std::size_t i (0); i < select_column_count; ++i) + select_image_bind_[i].truncated = select_image_truncated_ + i; } template -- cgit v1.1