From 6e71fee5bdb0fe338c7b9c3259a07d317ba36679 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 9 Nov 2011 14:09:52 +0200 Subject: Avoid copying statement text if it is statically allocated --- odb/pgsql/container-statements.hxx | 7 +- odb/pgsql/object-statements.hxx | 16 ++-- odb/pgsql/statement.cxx | 174 +++++++++++++++++++++++++++++++------ odb/pgsql/statement.hxx | 81 ++++++++++++++--- 4 files changed, 234 insertions(+), 44 deletions(-) diff --git a/odb/pgsql/container-statements.hxx b/odb/pgsql/container-statements.hxx index a8d15d8..79c6e6b 100644 --- a/odb/pgsql/container-statements.hxx +++ b/odb/pgsql/container-statements.hxx @@ -188,6 +188,7 @@ namespace odb insert_one_count_, data_image_binding_, data_image_native_binding_, + false, false)); } @@ -208,7 +209,8 @@ namespace odb select_all_count_, cond_image_binding_, cond_image_native_binding_, - data_image_binding_)); + data_image_binding_, + false)); } return *select_all_; @@ -227,7 +229,8 @@ namespace odb delete_all_types_, delete_all_count_, cond_image_binding_, - cond_image_native_binding_)); + cond_image_native_binding_, + false)); } return *delete_all_; diff --git a/odb/pgsql/object-statements.hxx b/odb/pgsql/object-statements.hxx index 040f7bd..8a806a8 100644 --- a/odb/pgsql/object-statements.hxx +++ b/odb/pgsql/object-statements.hxx @@ -309,7 +309,8 @@ namespace odb insert_column_count, insert_image_binding_, insert_image_native_binding_, - object_traits::auto_id)); + object_traits::auto_id, + false)); } return *persist_; @@ -329,7 +330,8 @@ namespace odb id_column_count, id_image_binding_, id_image_native_binding_, - select_image_binding_)); + select_image_binding_, + false)); } return *find_; @@ -348,7 +350,8 @@ namespace odb object_traits::update_statement_types, update_column_count + id_column_count, update_image_binding_, - update_image_native_binding_)); + update_image_native_binding_, + false)); } return *update_; @@ -367,7 +370,8 @@ namespace odb object_traits::erase_statement_types, id_column_count, id_image_binding_, - id_image_native_binding_)); + id_image_native_binding_, + false)); } return *erase_; @@ -386,7 +390,8 @@ namespace odb object_traits::optimistic_erase_statement_types, id_column_count + managed_optimistic_column_count, od_.id_image_binding_, - od_.id_image_native_binding_)); + od_.id_image_native_binding_, + false)); } return *od_.erase_; @@ -602,6 +607,7 @@ namespace odb insert_column_count, insert_image_binding_, insert_image_native_binding_, + false, false)); } diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx index 8a20456..026c419 100644 --- a/odb/pgsql/statement.cxx +++ b/odb/pgsql/statement.cxx @@ -93,10 +93,51 @@ namespace odb const Oid* types, size_t types_count) : conn_ (conn), - name_ (name), - text_ (text), + name_copy_ (name), name_ (name_copy_.c_str ()), + text_copy_ (text), text_ (text_copy_.c_str ()), deallocated_ (false) { + init (types, types_count); + + // + // If any code after this line throws, the statement will be leaked + // (on the server) since deallocate() won't be called for it. + // + } + + statement:: + statement (connection& conn, + const char* name, + const char* text, + bool copy, + const Oid* types, + size_t types_count) + : conn_ (conn), deallocated_ (false) + { + if (copy) + { + name_copy_ = name; + name_ = name_copy_.c_str (); + text_copy_ = text; + text_ = text_copy_.c_str (); + } + else + { + name_ = name; + text_ = text; + } + + init (types, types_count); + + // + // If any code after this line throws, the statement will be leaked + // (on the server) since deallocate() won't be called for it. + // + } + + void statement:: + init (const Oid* types, size_t types_count) + { { odb::tracer* t; if ((t = conn_.transaction_tracer ()) || @@ -107,8 +148,8 @@ namespace odb auto_handle h ( PQprepare (conn_.handle (), - name_.c_str (), - text_.c_str (), + name_, + text_, static_cast (types_count), types)); @@ -124,7 +165,7 @@ namespace odb const char* statement:: text () const { - return text_.c_str (); + return text_; } void statement:: @@ -355,13 +396,13 @@ namespace odb select_statement:: select_statement (connection& conn, const std::string& name, - const std::string& stmt, + const std::string& text, const Oid* types, std::size_t types_count, binding& param, native_binding& native_param, binding& result) - : statement (conn, name, stmt, types, types_count), + : statement (conn, name, text, types, types_count), param_ (¶m), native_param_ (&native_param), result_ (result), @@ -372,14 +413,16 @@ namespace odb select_statement:: select_statement (connection& conn, - const std::string& name, - const std::string& stmt, + const char* name, + const char* text, const Oid* types, std::size_t types_count, + binding& param, native_binding& native_param, - binding& result) - : statement (conn, name, stmt, types, types_count), - param_ (0), + binding& result, + bool copy) + : statement (conn, name, text, copy, types, types_count), + param_ (¶m), native_param_ (&native_param), result_ (result), row_count_ (0), @@ -390,9 +433,9 @@ namespace odb select_statement:: select_statement (connection& conn, const std::string& name, - const std::string& stmt, + const std::string& text, binding& result) - : statement (conn, name, stmt, 0, 0), + : statement (conn, name, text, 0, 0), param_ (0), native_param_ (0), result_ (result), @@ -401,6 +444,38 @@ namespace odb { } + select_statement:: + select_statement (connection& conn, + const char* name, + const char* text, + binding& result, + bool copy) + : statement (conn, name, text, copy, 0, 0), + param_ (0), + native_param_ (0), + result_ (result), + row_count_ (0), + current_row_ (0) + { + } + + select_statement:: + select_statement (connection& conn, + const std::string& name, + const std::string& text, + const Oid* types, + std::size_t types_count, + native_binding& native_param, + binding& result) + : statement (conn, name, text, types, types_count), + param_ (0), + native_param_ (&native_param), + result_ (result), + row_count_ (0), + current_row_ (0) + { + } + void select_statement:: execute () { @@ -421,7 +496,7 @@ namespace odb handle_.reset ( PQexecPrepared (conn_.handle (), - name_.c_str (), + name_, in ? native_param_->count : 0, in ? native_param_->values : 0, in ? native_param_->lengths : 0, @@ -493,13 +568,30 @@ namespace odb insert_statement:: insert_statement (connection& conn, const string& name, - const string& stmt, + const string& text, const Oid* types, size_t types_count, binding& param, native_binding& native_param, bool returning) - : statement (conn, name, stmt, types, types_count), + : statement (conn, name, text, types, types_count), + param_ (param), + native_param_ (native_param), + returning_ (returning) + { + } + + insert_statement:: + insert_statement (connection& conn, + const char* name, + const char* text, + const Oid* types, + size_t types_count, + binding& param, + native_binding& native_param, + bool returning, + bool copy) + : statement (conn, name, text, copy, types, types_count), param_ (param), native_param_ (native_param), returning_ (returning) @@ -521,7 +613,7 @@ namespace odb auto_handle h ( PQexecPrepared (conn_.handle (), - name_.c_str (), + name_, native_param_.count, native_param_.values, native_param_.lengths, @@ -595,12 +687,27 @@ namespace odb update_statement:: update_statement (connection& conn, const string& name, - const string& stmt, + const string& text, const Oid* types, size_t types_count, binding& param, native_binding& native_param) - : statement (conn, name, stmt, types, types_count), + : statement (conn, name, text, types, types_count), + param_ (param), + native_param_ (native_param) + { + } + + update_statement:: + update_statement (connection& conn, + const char* name, + const char* text, + const Oid* types, + size_t types_count, + binding& param, + native_binding& native_param, + bool copy) + : statement (conn, name, text, copy, types, types_count), param_ (param), native_param_ (native_param) { @@ -621,7 +728,7 @@ namespace odb auto_handle h ( PQexecPrepared (conn_.handle (), - name_.c_str (), + name_, native_param_.count, native_param_.values, native_param_.lengths, @@ -646,12 +753,27 @@ namespace odb delete_statement:: delete_statement (connection& conn, const string& name, - const string& stmt, + const string& text, const Oid* types, size_t types_count, binding& param, native_binding& native_param) - : statement (conn, name, stmt, types, types_count), + : statement (conn, name, text, types, types_count), + param_ (¶m), + native_param_ (native_param) + { + } + + delete_statement:: + delete_statement (connection& conn, + const char* name, + const char* text, + const Oid* types, + size_t types_count, + binding& param, + native_binding& native_param, + bool copy) + : statement (conn, name, text, copy, types, types_count), param_ (¶m), native_param_ (native_param) { @@ -660,11 +782,11 @@ namespace odb delete_statement:: delete_statement (connection& conn, const string& name, - const string& stmt, + const string& text, const Oid* types, size_t types_count, native_binding& native_param) - : statement (conn, name, stmt, types, types_count), + : statement (conn, name, text, types, types_count), param_ (0), native_param_ (native_param) { @@ -686,7 +808,7 @@ namespace odb auto_handle h ( PQexecPrepared (conn_.handle (), - name_.c_str (), + name_, native_param_.count, native_param_.values, native_param_.lengths, diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx index 3230bb2..5620ac0 100644 --- a/odb/pgsql/statement.hxx +++ b/odb/pgsql/statement.hxx @@ -36,7 +36,7 @@ namespace odb const char* name () const { - return name_.c_str (); + return name_; } virtual const char* @@ -69,10 +69,25 @@ namespace odb const Oid* types, std::size_t types_count); + statement (connection&, + const char* name, + const char* text, + bool copy_name_text, + const Oid* types, + std::size_t types_count); + + private: + void + init (const Oid* types, std::size_t types_count); + protected: connection& conn_; - std::string name_; - std::string text_; + + std::string name_copy_; + const char* name_; + + std::string text_copy_; + const char* text_; private: bool deallocated_; @@ -86,7 +101,7 @@ namespace odb select_statement (connection& conn, const std::string& name, - const std::string& stmt, + const std::string& text, const Oid* types, std::size_t types_count, binding& param, @@ -94,16 +109,32 @@ namespace odb binding& result); select_statement (connection& conn, - const std::string& name, - const std::string& stmt, + const char* name, + const char* stmt, const Oid* types, std::size_t types_count, + binding& param, native_binding& native_param, + binding& result, + bool copy_name_text = true); + + select_statement (connection& conn, + const std::string& name, + const std::string& text, binding& result); select_statement (connection& conn, + const char* name, + const char* text, + binding& result, + bool copy_name_text = true); + + select_statement (connection& conn, const std::string& name, - const std::string& stmt, + const std::string& text, + const Oid* types, + std::size_t types_count, + native_binding& native_param, binding& result); // Common select interface expected by the generated code. @@ -187,13 +218,23 @@ namespace odb insert_statement (connection& conn, const std::string& name, - const std::string& stmt, + const std::string& text, const Oid* types, std::size_t types_count, binding& param, native_binding& native_param, bool returning); + insert_statement (connection& conn, + const char* name, + const char* text, + const Oid* types, + std::size_t types_count, + binding& param, + native_binding& native_param, + bool returning, + bool copy_name_text = true); + // Return true if successful and false if the row is a duplicate. // All other errors are reported by throwing exceptions. // @@ -226,12 +267,21 @@ namespace odb update_statement (connection& conn, const std::string& name, - const std::string& stmt, + const std::string& text, const Oid* types, std::size_t types_count, binding& param, native_binding& native_param); + update_statement (connection& conn, + const char* name, + const char* text, + const Oid* types, + std::size_t types_count, + binding& param, + native_binding& native_param, + bool copy_name_text = true); + unsigned long long execute (); @@ -252,15 +302,24 @@ namespace odb delete_statement (connection& conn, const std::string& name, - const std::string& stmt, + const std::string& text, const Oid* types, std::size_t types_count, binding& param, native_binding& native_param); delete_statement (connection& conn, + const char* name, + const char* text, + const Oid* types, + std::size_t types_count, + binding& param, + native_binding& native_param, + bool copy_name_text = true); + + delete_statement (connection& conn, const std::string& name, - const std::string& stmt, + const std::string& text, const Oid* types, std::size_t types_count, native_binding& native_param); -- cgit v1.1