summaryrefslogtreecommitdiff
path: root/libodbcpp/connection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libodbcpp/connection.cpp')
-rw-r--r--libodbcpp/connection.cpp88
1 files changed, 82 insertions, 6 deletions
diff --git a/libodbcpp/connection.cpp b/libodbcpp/connection.cpp
index 4130f08..7fa32fd 100644
--- a/libodbcpp/connection.cpp
+++ b/libodbcpp/connection.cpp
@@ -6,32 +6,39 @@
ODBC::Connection::Connection(const DSN& d) :
DSN(d),
env(0),
- conn(0)
+ conn(0),
+ txDepth(0),
+ txAborted(false)
{
SQLRETURN dberr = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
- if ((dberr != SQL_SUCCESS) && (dberr != SQL_SUCCESS_WITH_INFO)) {
+ if ((dberr != SQL_SUCCESS)) {
throw Error(dberr, SQL_HANDLE_ENV, env, "Allocate handle");
}
dberr = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
- if ((dberr != SQL_SUCCESS) && (dberr != SQL_SUCCESS_WITH_INFO)) {
+ if ((dberr != SQL_SUCCESS)) {
throw Error(dberr, SQL_HANDLE_ENV, env, "Set ODBC version");
}
dberr = SQLAllocHandle(SQL_HANDLE_DBC, env, &conn);
- if ((dberr != SQL_SUCCESS) && (dberr != SQL_SUCCESS_WITH_INFO)) {
+ if ((dberr != SQL_SUCCESS)) {
throw Error(dberr, SQL_HANDLE_ENV, env, "Allocate DBC handle");
}
dberr = SQLSetConnectAttr(conn, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
- if ((dberr != SQL_SUCCESS) && (dberr != SQL_SUCCESS_WITH_INFO)) {
+ if ((dberr != SQL_SUCCESS)) {
throw Error(dberr, SQL_HANDLE_ENV, env, "Set connection attributes");
}
dberr = SQLConnect(conn, dsn, SQL_NTS, username, SQL_NTS, password, SQL_NTS);
- if ((dberr != SQL_SUCCESS) && (dberr != SQL_SUCCESS_WITH_INFO)) {
+ if ((dberr != SQL_SUCCESS)) {
throw Error(dberr, SQL_HANDLE_DBC, conn, "Connect");
}
+
+ dberr = SQLSetConnectOption(conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON);
+ if ((dberr != SQL_SUCCESS)) {
+ throw Error(dberr, SQL_HANDLE_DBC, conn, "Set default auto commit");
+ }
}
ODBC::Connection::~Connection()
@@ -50,3 +57,72 @@ ODBC::Connection::~Connection()
}
}
}
+
+int
+ODBC::Connection::beginTx()
+{
+ SQLRETURN dberr = SQLSetConnectOption(conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF);
+ if ((dberr != SQL_SUCCESS)) {
+ throw Error(dberr, SQL_HANDLE_DBC, conn, "Set default auto commit");
+ }
+ txDepth += 1;
+ return txDepth;
+}
+
+int
+ODBC::Connection::commitTx()
+{
+ if (txDepth > 0) {
+ if (txAborted) {
+ return rollbackTx();
+ }
+ txDepth -= 1;
+ if (txDepth == 0) {
+ SQLRETURN dberr = SQLEndTran(SQL_HANDLE_DBC, conn, SQL_COMMIT);
+ if ((dberr != SQL_SUCCESS)) {
+ throw Error(dberr, SQL_HANDLE_DBC, conn, "SQLEndTran (SQL_COMMIT)");
+ }
+ dberr = SQLSetConnectOption(conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON);
+ if ((dberr != SQL_SUCCESS)) {
+ throw Error(dberr, SQL_HANDLE_DBC, conn, "Enable auto commit");
+ }
+ txAborted = false;
+ }
+ return txDepth;
+ }
+ throw Error("Attempt to commit none existant transaction");
+}
+
+int
+ODBC::Connection::rollbackTx()
+{
+ if (txDepth > 0) {
+ txDepth -= 1;
+ if (txDepth == 0) {
+ SQLRETURN dberr = SQLEndTran(SQL_HANDLE_DBC, conn, SQL_ROLLBACK);
+ if ((dberr != SQL_SUCCESS)) {
+ throw Error(dberr, SQL_HANDLE_DBC, conn, "SQLEndTran (SQL_ROLLBACK)");
+ }
+ dberr = SQLSetConnectOption(conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON);
+ if ((dberr != SQL_SUCCESS)) {
+ throw Error(dberr, SQL_HANDLE_DBC, conn, "Enable auto commit");
+ }
+ txAborted = false;
+ }
+ return txDepth;
+ }
+ throw Error("Attempt to rollback none existant transaction");
+}
+
+void
+ODBC::Connection::abortTx() const
+{
+ txAborted = true;
+}
+
+bool
+ODBC::Connection::txIsAborted() const
+{
+ return txAborted;
+}
+