aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-02-18 17:56:53 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-02-18 17:56:53 +0200
commit4acabe57939ff37bad0a8aabc5164b6d5add449b (patch)
tree1211cf34b447014671effc59770f06f1cc0e3bb8
parenta534bbdabe677b67687c9d0093cba4a800b6b766 (diff)
Factor out MySQL error to exception translation into separate function
-rw-r--r--odb/mysql/connection.cxx14
-rw-r--r--odb/mysql/database.cxx12
-rw-r--r--odb/mysql/error.cxx60
-rw-r--r--odb/mysql/error.hxx36
-rw-r--r--odb/mysql/exceptions.cxx37
-rw-r--r--odb/mysql/exceptions.hxx7
-rw-r--r--odb/mysql/makefile1
-rw-r--r--odb/mysql/statement.cxx88
-rw-r--r--odb/mysql/transaction-impl.cxx20
9 files changed, 148 insertions, 127 deletions
diff --git a/odb/mysql/connection.cxx b/odb/mysql/connection.cxx
index e77c04d..1395592 100644
--- a/odb/mysql/connection.cxx
+++ b/odb/mysql/connection.cxx
@@ -4,6 +4,7 @@
// license : GNU GPL v2; see accompanying LICENSE file
#include <new> // std::bad_alloc
+#include <string>
#include <odb/mysql/database.hxx>
#include <odb/mysql/connection.hxx>
@@ -40,9 +41,18 @@ namespace odb
db.socket (),
db.client_flags () | CLIENT_FOUND_ROWS) == 0)
{
- database_exception e (handle_);
+ // We cannot use translate_error() here since there is no connection
+ // yet.
+ //
+ unsigned int e (mysql_errno (handle_));
+ string sqlstate (mysql_sqlstate (handle_));
+ string message (mysql_error (handle_));
mysql_close (handle_);
- throw e;
+
+ if (e == CR_OUT_OF_MEMORY)
+ throw bad_alloc ();
+
+ throw database_exception (e, sqlstate, message);
}
}
diff --git a/odb/mysql/database.cxx b/odb/mysql/database.cxx
index da19ab5..72b18d8 100644
--- a/odb/mysql/database.cxx
+++ b/odb/mysql/database.cxx
@@ -10,6 +10,7 @@
#include <odb/mysql/transaction.hxx>
#include <odb/mysql/connection.hxx>
#include <odb/mysql/connection-factory.hxx>
+#include <odb/mysql/error.hxx>
#include <odb/mysql/exceptions.hxx>
#include <odb/mysql/details/options.hxx>
@@ -220,14 +221,7 @@ namespace odb
MYSQL* h (c.handle ());
if (mysql_real_query (h, s, static_cast<unsigned long> (n)))
- {
- unsigned int e (mysql_errno (h));
-
- if (e == ER_LOCK_DEADLOCK)
- throw deadlock ();
- else
- throw database_exception (h);
- }
+ translate_error (c);
// Get the affected row count, if any. If the statement has a result
// set (e.g., SELECT), we first need to call mysql_store_result().
@@ -244,7 +238,7 @@ namespace odb
mysql_free_result (rs);
}
else
- throw database_exception (h);
+ translate_error (c);
}
return r;
diff --git a/odb/mysql/error.cxx b/odb/mysql/error.cxx
new file mode 100644
index 0000000..460816a
--- /dev/null
+++ b/odb/mysql/error.cxx
@@ -0,0 +1,60 @@
+// file : odb/mysql/errors.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#include <new> // std::bad_alloc
+
+#include <odb/mysql/mysql.hxx>
+#include <odb/mysql/connection.hxx>
+#include <odb/mysql/exceptions.hxx>
+
+using namespace std;
+
+namespace odb
+{
+ namespace mysql
+ {
+ void
+ translate_error (connection&,
+ unsigned int e,
+ const std::string& sqlstate,
+ const std::string& message)
+ {
+ switch (e)
+ {
+ case CR_OUT_OF_MEMORY:
+ {
+ throw bad_alloc ();
+ }
+ case ER_LOCK_DEADLOCK:
+ {
+ throw deadlock ();
+ }
+ default:
+ {
+ throw database_exception (e, sqlstate, message);
+ }
+ }
+ }
+
+ void
+ translate_error (connection& c)
+ {
+ MYSQL* h (c.handle ());
+ translate_error (c,
+ mysql_errno (h),
+ mysql_sqlstate (h),
+ mysql_error (h));
+ }
+
+ void
+ translate_error (connection& c, MYSQL_STMT* h)
+ {
+ translate_error (c,
+ mysql_stmt_errno (h),
+ mysql_stmt_sqlstate (h),
+ mysql_stmt_error (h));
+ }
+ }
+}
diff --git a/odb/mysql/error.hxx b/odb/mysql/error.hxx
new file mode 100644
index 0000000..6aeec0d
--- /dev/null
+++ b/odb/mysql/error.hxx
@@ -0,0 +1,36 @@
+// file : odb/mysql/errors.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_MYSQL_ERRORS_HXX
+#define ODB_MYSQL_ERRORS_HXX
+
+#include <odb/pre.hxx>
+
+#include <odb/mysql/mysql.hxx>
+#include <odb/mysql/version.hxx>
+
+#include <odb/mysql/details/export.hxx>
+
+namespace odb
+{
+ namespace mysql
+ {
+ class connection;
+
+ // Translate MySQL error and throw an appropriate exception. Also,
+ // if the error code indicates that the connection is no longer
+ // usable, mark it as failed.
+ //
+ LIBODB_MYSQL_EXPORT void
+ translate_error (connection&);
+
+ LIBODB_MYSQL_EXPORT void
+ translate_error (connection&, MYSQL_STMT*);
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_MYSQL_ERRORS_HXX
diff --git a/odb/mysql/exceptions.cxx b/odb/mysql/exceptions.cxx
index d87b6c2..dd9e199 100644
--- a/odb/mysql/exceptions.cxx
+++ b/odb/mysql/exceptions.cxx
@@ -3,10 +3,8 @@
// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
-#include <new> // std::bad_alloc
#include <sstream>
-#include <odb/mysql/mysql.hxx>
#include <odb/mysql/exceptions.hxx>
using namespace std;
@@ -25,47 +23,12 @@ namespace odb
}
database_exception::
- database_exception (MYSQL* h)
- : error_ (mysql_errno (h))
- {
- if (error_ == CR_OUT_OF_MEMORY)
- throw bad_alloc ();
-
- sqlstate_ = mysql_sqlstate (h);
- message_ = mysql_error (h);
-
- init ();
- }
-
- database_exception::
- database_exception (MYSQL_STMT* h)
- : error_ (mysql_stmt_errno (h))
- {
- if (error_ == CR_OUT_OF_MEMORY)
- throw bad_alloc ();
-
- sqlstate_ = mysql_stmt_sqlstate (h);
- message_ = mysql_stmt_error (h);
-
- init ();
- }
-
- database_exception::
database_exception (unsigned int e, const string& s, const string& m)
: error_ (e)
{
- if (error_ == CR_OUT_OF_MEMORY)
- throw bad_alloc ();
-
sqlstate_ = s;
message_ = m;
- init ();
- }
-
- void database_exception::
- init ()
- {
ostringstream ostr;
ostr << error_ << " (" << sqlstate_ << "): " << message_;
what_ = ostr.str ();
diff --git a/odb/mysql/exceptions.hxx b/odb/mysql/exceptions.hxx
index 12af4c4..f0c17e4 100644
--- a/odb/mysql/exceptions.hxx
+++ b/odb/mysql/exceptions.hxx
@@ -12,7 +12,6 @@
#include <odb/exceptions.hxx>
-#include <odb/mysql/mysql.hxx>
#include <odb/mysql/version.hxx>
#include <odb/mysql/details/export.hxx>
@@ -23,8 +22,6 @@ namespace odb
{
struct LIBODB_MYSQL_EXPORT database_exception: odb::database_exception
{
- database_exception (MYSQL*);
- database_exception (MYSQL_STMT*);
database_exception (unsigned int,
const std::string& sqlstate,
const std::string& message);
@@ -53,10 +50,6 @@ namespace odb
what () const throw ();
private:
- void
- init ();
-
- private:
unsigned int error_;
std::string sqlstate_;
std::string message_;
diff --git a/odb/mysql/makefile b/odb/mysql/makefile
index d56f67a..024b14f 100644
--- a/odb/mysql/makefile
+++ b/odb/mysql/makefile
@@ -9,6 +9,7 @@ cxx := \
connection.cxx \
connection-factory.cxx \
database.cxx \
+error.cxx \
exceptions.cxx \
object-statements.cxx \
transaction.cxx \
diff --git a/odb/mysql/statement.cxx b/odb/mysql/statement.cxx
index 8dbdc30..e1516f2 100644
--- a/odb/mysql/statement.cxx
+++ b/odb/mysql/statement.cxx
@@ -6,6 +6,7 @@
#include <odb/mysql/mysql.hxx>
#include <odb/mysql/statement.hxx>
#include <odb/mysql/connection.hxx>
+#include <odb/mysql/error.hxx>
#include <odb/mysql/exceptions.hxx>
using namespace std;
@@ -71,7 +72,7 @@ namespace odb
a->cancel ();
if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
}
void select_statement::
@@ -87,12 +88,12 @@ namespace odb
rows_ = 0;
if (mysql_stmt_reset (stmt_))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
if (cond_version_ != cond_.version)
{
if (mysql_stmt_bind_param (stmt_, cond_.bind))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
cond_version_ = cond_.version;
}
@@ -100,20 +101,13 @@ namespace odb
if (data_version_ != data_.version)
{
if (mysql_stmt_bind_result (stmt_, data_.bind))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
data_version_ = data_.version;
}
if (mysql_stmt_execute (stmt_))
- {
- unsigned int e (mysql_stmt_errno (stmt_));
-
- if (e == ER_LOCK_DEADLOCK)
- throw deadlock ();
- else
- throw database_exception (stmt_);
- }
+ translate_error (conn_, stmt_);
conn_.active (this);
}
@@ -126,7 +120,7 @@ namespace odb
if (!end_)
{
if (mysql_stmt_store_result (stmt_))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
// mysql_stmt_num_rows() returns the number of rows that have been
// fetched by store_result.
@@ -149,7 +143,7 @@ namespace odb
if (cached_ && data_version_ != data_.version)
{
if (mysql_stmt_bind_result (stmt_, data_.bind))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
data_version_ = data_.version;
}
@@ -175,7 +169,8 @@ namespace odb
}
default:
{
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
+ return no_data; // Never reaches.
}
}
}
@@ -193,7 +188,7 @@ namespace odb
if (mysql_stmt_fetch_column (
stmt_, data_.bind + i, static_cast<unsigned int> (i), 0))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
}
}
}
@@ -206,7 +201,7 @@ namespace odb
rows_ = 0;
if (mysql_stmt_free_result (stmt_))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
if (conn_.active () == this)
conn_.active (0);
@@ -239,7 +234,7 @@ namespace odb
a->cancel ();
if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
}
bool insert_statement::
@@ -249,33 +244,22 @@ namespace odb
a->cancel ();
if (mysql_stmt_reset (stmt_))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
if (data_version_ != data_.version)
{
if (mysql_stmt_bind_param (stmt_, data_.bind))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
data_version_ = data_.version;
}
if (mysql_stmt_execute (stmt_))
{
- switch (mysql_stmt_errno (stmt_))
- {
- case ER_DUP_ENTRY:
- {
- return false;
- }
- case ER_LOCK_DEADLOCK:
- {
- throw deadlock ();
- }
- default:
- {
- throw database_exception (stmt_);
- }
- }
+ if (mysql_stmt_errno (stmt_) == ER_DUP_ENTRY)
+ return false;
+ else
+ translate_error (conn_, stmt_);
}
return true;
@@ -304,7 +288,7 @@ namespace odb
a->cancel ();
if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
}
void update_statement::
@@ -314,7 +298,7 @@ namespace odb
a->cancel ();
if (mysql_stmt_reset (stmt_))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
if (image_version_ != image_.version || id_version_ != id_.version)
{
@@ -322,21 +306,14 @@ namespace odb
// id parameter.
//
if (mysql_stmt_bind_param (stmt_, image_.bind))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
id_version_ = id_.version;
image_version_ = image_.version;
}
if (mysql_stmt_execute (stmt_))
- {
- unsigned int e (mysql_stmt_errno (stmt_));
-
- if (e == ER_LOCK_DEADLOCK)
- throw deadlock ();
- else
- throw database_exception (stmt_);
- }
+ translate_error (conn_, stmt_);
my_ulonglong r (mysql_stmt_affected_rows (stmt_));
@@ -346,7 +323,7 @@ namespace odb
if (r == 0)
throw object_not_persistent ();
else
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
}
// delete_statement
@@ -365,7 +342,7 @@ namespace odb
a->cancel ();
if (mysql_stmt_prepare (stmt_, s.c_str (), s.size ()) != 0)
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
}
unsigned long long delete_statement::
@@ -375,30 +352,23 @@ namespace odb
a->cancel ();
if (mysql_stmt_reset (stmt_))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
if (cond_version_ != cond_.version)
{
if (mysql_stmt_bind_param (stmt_, cond_.bind))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
cond_version_ = cond_.version;
}
if (mysql_stmt_execute (stmt_))
- {
- unsigned int e (mysql_stmt_errno (stmt_));
-
- if (e == ER_LOCK_DEADLOCK)
- throw deadlock ();
- else
- throw database_exception (stmt_);
- }
+ translate_error (conn_, stmt_);
my_ulonglong r (mysql_stmt_affected_rows (stmt_));
if (r == static_cast<my_ulonglong> (-1))
- throw database_exception (stmt_);
+ translate_error (conn_, stmt_);
return static_cast<unsigned long long> (r);
}
diff --git a/odb/mysql/transaction-impl.cxx b/odb/mysql/transaction-impl.cxx
index 73011b4..b523568 100644
--- a/odb/mysql/transaction-impl.cxx
+++ b/odb/mysql/transaction-impl.cxx
@@ -7,7 +7,7 @@
#include <odb/mysql/database.hxx>
#include <odb/mysql/connection.hxx>
#include <odb/mysql/statement.hxx>
-#include <odb/mysql/exceptions.hxx>
+#include <odb/mysql/error.hxx>
#include <odb/mysql/transaction-impl.hxx>
namespace odb
@@ -18,10 +18,8 @@ namespace odb
transaction_impl (database_type& db)
: odb::transaction_impl (db), connection_ (db.connection ())
{
- MYSQL* h (connection_->handle ());
-
- if (mysql_real_query (h, "begin", 5) != 0)
- throw database_exception (h);
+ if (mysql_real_query (connection_->handle (), "begin", 5) != 0)
+ translate_error (*connection_);
}
transaction_impl::
@@ -35,10 +33,8 @@ namespace odb
if (statement* a = connection_->active ())
a->cancel ();
- MYSQL* h (connection_->handle ());
-
- if (mysql_real_query (h, "commit", 6) != 0)
- throw database_exception (h);
+ if (mysql_real_query (connection_->handle (), "commit", 6) != 0)
+ translate_error (*connection_);
// Release the connection.
//
@@ -51,10 +47,8 @@ namespace odb
if (statement* a = connection_->active ())
a->cancel ();
- MYSQL* h (connection_->handle ());
-
- if (mysql_real_query (h, "rollback", 8) != 0)
- throw database_exception (h);
+ if (mysql_real_query (connection_->handle (), "rollback", 8) != 0)
+ translate_error (*connection_);
// Release the connection.
//