aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-01-18 11:21:02 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-01-18 11:23:53 +0200
commita86cf1e87af6808dbe042b571e41bff918030e61 (patch)
tree0e84516ea5e317bcf6ad91681e70d1f54326c5c6
parentd1fea829e1381a0ef382176fe2050933609bfc8e (diff)
Add support for native SQL statement execution
New test: mysql/native. New manual section: 3.9, "Executing Native SQL Statements".
-rw-r--r--odb/mysql/database.cxx47
-rw-r--r--odb/mysql/database.hxx4
2 files changed, 48 insertions, 3 deletions
diff --git a/odb/mysql/database.cxx b/odb/mysql/database.cxx
index 88899b5..da19ab5 100644
--- a/odb/mysql/database.cxx
+++ b/odb/mysql/database.cxx
@@ -5,9 +5,10 @@
#include <sstream>
-#include <odb/transaction.hxx>
-
+#include <odb/mysql/mysql.hxx>
#include <odb/mysql/database.hxx>
+#include <odb/mysql/transaction.hxx>
+#include <odb/mysql/connection.hxx>
#include <odb/mysql/connection-factory.hxx>
#include <odb/mysql/exceptions.hxx>
@@ -209,10 +210,50 @@ namespace odb
details::options::print_usage (os);
}
+ unsigned long long database::
+ execute (const char* s, std::size_t n)
+ {
+ if (!transaction::has_current ())
+ throw not_in_transaction ();
+
+ connection_type& c (transaction::current ().connection ());
+ 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);
+ }
+
+ // 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().
+ //
+ unsigned long long r (0);
+
+ if (mysql_field_count (h) == 0)
+ r = static_cast<unsigned long long> (mysql_affected_rows (h));
+ else
+ {
+ if (MYSQL_RES* rs = mysql_store_result (h))
+ {
+ r = static_cast<unsigned long long> (mysql_num_rows (rs));
+ mysql_free_result (rs);
+ }
+ else
+ throw database_exception (h);
+ }
+
+ return r;
+ }
+
transaction_impl* database::
begin ()
{
- if (odb::transaction::has_current ())
+ if (transaction::has_current ())
throw already_in_transaction ();
return new transaction_impl (*this);
diff --git a/odb/mysql/database.hxx b/odb/mysql/database.hxx
index 6449d23..81f2892 100644
--- a/odb/mysql/database.hxx
+++ b/odb/mysql/database.hxx
@@ -159,6 +159,10 @@ namespace odb
}
public:
+ virtual unsigned long long
+ execute (const char* statement, std::size_t length);
+
+ public:
virtual transaction_impl*
begin ();