From 9fce9a7250f63a2a3cceeb0aac7b22d5dd7e6915 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 30 Aug 2011 16:10:02 +0200 Subject: Implement uniform handle management across all databases Also use the auto_handle template instead of the raw handle in connection, statement, and result classes. This removes a lot of brittle "exception safety guarantee" code that we had in those classes. --- odb/pgsql/statement.cxx | 128 +++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 72 deletions(-) (limited to 'odb/pgsql/statement.cxx') diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx index 26ae475..7e5b5aa 100644 --- a/odb/pgsql/statement.cxx +++ b/odb/pgsql/statement.cxx @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include @@ -53,7 +53,7 @@ namespace odb s += name_; s += "\""; - result_ptr r (PQexec (conn_.handle (), s.c_str ())); + auto_handle h (PQexec (conn_.handle (), s.c_str ())); deallocated_ = true; } @@ -67,14 +67,20 @@ namespace odb name_ (name), deallocated_ (false) { - result_ptr r (PQprepare (conn_.handle (), - name_.c_str (), - stmt.c_str (), - static_cast (types_count), - types)); - - if (!is_good_result (r.get ())) - translate_error (conn_, r.get ()); + auto_handle h ( + PQprepare (conn_.handle (), + name_.c_str (), + stmt.c_str (), + static_cast (types_count), + types)); + + if (!is_good_result (h)) + translate_error (conn_, h); + + // + // 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:: @@ -295,8 +301,6 @@ namespace odb select_statement:: ~select_statement () { - if (result_ != 0) - PQclear (result_); } select_statement:: @@ -312,10 +316,8 @@ namespace odb cond_ (&cond), native_cond_ (native_cond), data_ (data), - result_ (0), row_count_ (0), current_row_ (0) - { } @@ -331,55 +333,39 @@ namespace odb cond_ (0), native_cond_ (native_cond), data_ (data), - result_ (0), row_count_ (0), current_row_ (0) - { } void select_statement:: execute () { - if (result_ != 0) - { - PQclear (result_); - result_ = 0; - } + result_.reset (); if (cond_ != 0) bind_param (native_cond_, *cond_); - // Use temporary result_ptr to guarantee exception safety. - // - result_ptr r (PQexecPrepared (conn_.handle (), - name_.c_str (), - native_cond_.count, - native_cond_.values, - native_cond_.lengths, - native_cond_.formats, - 1)); + result_.reset ( + PQexecPrepared (conn_.handle (), + name_.c_str (), + native_cond_.count, + native_cond_.values, + native_cond_.lengths, + native_cond_.formats, + 1)); - PGresult* h (r.get ()); + if (!is_good_result (result_)) + translate_error (conn_, result_); - if (!is_good_result (h)) - translate_error (conn_, h); - - row_count_ = static_cast (PQntuples (h)); + row_count_ = static_cast (PQntuples (result_)); current_row_ = 0; - - result_ = r.release (); } void select_statement:: free_result () { - if (result_ != 0) - { - PQclear (result_); - result_ = 0; - } - + result_.reset (); row_count_ = 0; current_row_ = 0; } @@ -450,14 +436,15 @@ namespace odb bind_param (native_data_, data_); - result_ptr r (PQexecPrepared (conn_.handle (), - name_.c_str (), - native_data_.count, - native_data_.values, - native_data_.lengths, - native_data_.formats, - 1)); - PGresult* h (r.get ()); + auto_handle h ( + PQexecPrepared (conn_.handle (), + name_.c_str (), + native_data_.count, + native_data_.values, + native_data_.lengths, + native_data_.formats, + 1)); + ExecStatusType stat (PGRES_FATAL_ERROR); if (!is_good_result (h, &stat)) @@ -482,10 +469,8 @@ namespace odb if (id_cached_) return id_; - result_ptr r (PQexecParams (conn_.handle (), - "select lastval ()", - 0, 0, 0, 0, 0, 1)); - PGresult* h (r.get ()); + auto_handle h ( + PQexecParams (conn_.handle (), "select lastval ()", 0, 0, 0, 0, 0, 1)); if (!is_good_result (h)) translate_error (conn_, h); @@ -534,15 +519,14 @@ namespace odb bind_param (native_data_, data_); bind_param (native_cond_, cond_); - result_ptr r (PQexecPrepared (conn_.handle (), - name_.c_str (), - native_data_.count + native_cond_.count, - native_data_.values, - native_data_.lengths, - native_data_.formats, - 1)); - - PGresult* h (r.get ()); + auto_handle h ( + PQexecPrepared (conn_.handle (), + name_.c_str (), + native_data_.count + native_cond_.count, + native_data_.values, + native_data_.lengths, + native_data_.formats, + 1)); if (!is_good_result (h)) translate_error (conn_, h); @@ -596,14 +580,14 @@ namespace odb if (cond_ != 0) bind_param (native_cond_, *cond_); - result_ptr r (PQexecPrepared (conn_.handle (), - name_.c_str (), - native_cond_.count, - native_cond_.values, - native_cond_.lengths, - native_cond_.formats, - 1)); - PGresult* h (r.get ()); + auto_handle h ( + PQexecPrepared (conn_.handle (), + name_.c_str (), + native_cond_.count, + native_cond_.values, + native_cond_.lengths, + native_cond_.formats, + 1)); if (!is_good_result (h)) translate_error (conn_, h); -- cgit v1.1