diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-01-18 11:21:02 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-01-18 11:23:53 +0200 |
commit | a86cf1e87af6808dbe042b571e41bff918030e61 (patch) | |
tree | 0e84516ea5e317bcf6ad91681e70d1f54326c5c6 | |
parent | d1fea829e1381a0ef382176fe2050933609bfc8e (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.cxx | 47 | ||||
-rw-r--r-- | odb/mysql/database.hxx | 4 |
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 (); |