diff options
Diffstat (limited to 'odb/mssql/connection.cxx')
-rw-r--r-- | odb/mssql/connection.cxx | 116 |
1 files changed, 109 insertions, 7 deletions
diff --git a/odb/mssql/connection.cxx b/odb/mssql/connection.cxx index 0d09461..3ba10ba 100644 --- a/odb/mssql/connection.cxx +++ b/odb/mssql/connection.cxx @@ -5,7 +5,7 @@ //@@ disabled functionality -//#include <string> +#include <string> #include <odb/mssql/mssql.hxx> #include <odb/mssql/database.hxx> @@ -47,7 +47,7 @@ namespace odb r = SQLSetConnectAttr (handle_, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, - SQL_IS_UINTEGER); + 0); if (!SQL_SUCCEEDED (r)) // Still use the handle version of translate_error since there @@ -107,12 +107,114 @@ namespace odb } unsigned long long connection:: - execute (const char* /*s*/, std::size_t /*n*/) + execute (const char* s, std::size_t n) { - //@@ - //generic_statement st (*this, string (s, n)); - //return st.execute (); - return 0; + /* + @@ + { + odb::tracer* t; + if ((t = transaction_tracer ()) || + (t = tracer ()) || + (t = database ().tracer ())) + { + string str (s, n); + t->execute (*this, str.c_str ()); + } + } + */ + + SQLRETURN r; + + // Allocate the statement if necessary. + // + if (direct_stmt_ == 0) + { + SQLHANDLE h; + r = SQLAllocHandle (SQL_HANDLE_STMT, handle_, &h); + + if (!SQL_SUCCEEDED (r)) + translate_error (r, *this); + + direct_stmt_.reset (h); + + // Disable escape sequences. + // + r = SQLSetStmtAttr (direct_stmt_, + SQL_ATTR_NOSCAN, + (SQLPOINTER) SQL_NOSCAN_OFF, + 0); + + if (!SQL_SUCCEEDED (r)) + translate_error (r, *this, direct_stmt_); + + // Disable data retrieval for SELECT statements. + // + r = SQLSetStmtAttr (direct_stmt_, + SQL_ATTR_RETRIEVE_DATA, + (SQLPOINTER) SQL_RD_OFF, + 0); + + if (!SQL_SUCCEEDED (r)) + translate_error (r, *this, direct_stmt_); + } + + // Execute. + // + r = SQLExecDirect (direct_stmt_, (SQLCHAR*) s, (SQLINTEGER) n); + + // SQL_NO_DATA indicates that a DML statement hasn't affected + // any rows. + // + if (r == SQL_NO_DATA) + return 0; + + if (!SQL_SUCCEEDED (r)) + translate_error (r, *this, direct_stmt_); + + // Get the number of affected/returned rows. + // + SQLLEN rows; + + // See if this is a select statement. + // + SQLSMALLINT cols; + r = SQLNumResultCols (direct_stmt_, &cols); + + if (!SQL_SUCCEEDED (r)) + translate_error (r, *this, direct_stmt_); + + if (cols != 0) + { + for (rows = 0;; ++rows) + { + r = SQLFetch (direct_stmt_); + + if (r == SQL_NO_DATA) + break; + else if (!SQL_SUCCEEDED (r)) + translate_error (r, *this, direct_stmt_); + } + + r = SQLCloseCursor (direct_stmt_); + + if (!SQL_SUCCEEDED (r)) + translate_error (r, *this, direct_stmt_); + } + else + { + r = SQLRowCount (direct_stmt_, &rows); + + if (!SQL_SUCCEEDED (r)) + translate_error (r, *this, direct_stmt_); + + // -1 means the row count is not available. In particular, the + // Native Client ODBC driver returns this value for DDL statements. + // + if (rows == -1) + rows = 0; + } + + return static_cast<unsigned long long> (rows); } } } |