aboutsummaryrefslogtreecommitdiff
path: root/odb/mssql/connection.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/mssql/connection.cxx')
-rw-r--r--odb/mssql/connection.cxx116
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);
}
}
}