src/Connection.cpp
branchv_0
changeset 46 85e6dc1853ee
parent 43 7f396cdb9628
equal deleted inserted replaced
45:225e294ad1db 46:85e6dc1853ee
    27 namespace relpipe {
    27 namespace relpipe {
    28 namespace tr {
    28 namespace tr {
    29 namespace sql {
    29 namespace sql {
    30 
    30 
    31 Connection::Connection(void* db) : connection(db) {
    31 Connection::Connection(void* db) : connection(db) {
    32 	// TODO: transaction control
    32 	setAutoCommit(false);
    33 }
    33 }
    34 
    34 
    35 Connection::~Connection() {
    35 Connection::~Connection() {
       
    36 	// If an exception was thrown somewhere, there might be a transaction in progress, so we will cancel this transaction.
       
    37 	// If there was no exception, commit() has already been called and this rollback() will not affect any (desired) transaction.
       
    38 	// Without this rollback(), SQLDisconnect() will fail and then will fail also freeHandle() which will throw exception.
       
    39 	// And throwing exception while throwing exception will lead to a catastrophic failure: SIGABRT, core dump.
       
    40 	rollback();
    36 	SQLRETURN result = SQLDisconnect(connection);
    41 	SQLRETURN result = SQLDisconnect(connection);
    37 	// TODO: log warning if disconnection failed?
       
    38 	OdbcCommon::freeHandle(SQL_HANDLE_DBC, connection);
    42 	OdbcCommon::freeHandle(SQL_HANDLE_DBC, connection);
    39 }
    43 }
    40 
    44 
    41 PreparedStatement* Connection::prepareStatement(relpipe::reader::string_t sql) {
    45 PreparedStatement* Connection::prepareStatement(relpipe::reader::string_t sql) {
    42 	SQLHSTMT statement = OdbcCommon::allocateHandle(SQL_HANDLE_STMT, connection);
    46 	SQLHSTMT statement = OdbcCommon::allocateHandle(SQL_HANDLE_STMT, connection);
    44 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to prepare statement", result, SQL_HANDLE_STMT, statement, true);
    48 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to prepare statement", result, SQL_HANDLE_STMT, statement, true);
    45 	return new PreparedStatement(statement);
    49 	return new PreparedStatement(statement);
    46 }
    50 }
    47 
    51 
    48 bool Connection::getAutoCommit() {
    52 bool Connection::getAutoCommit() {
    49 	// TODO: transaction control
    53 	SQLULEN autoCommit = SQL_AUTOCOMMIT_DEFAULT;
    50 	return false;
    54 	SQLRETURN result = SQLGetConnectOption(connection, SQL_AUTOCOMMIT, &autoCommit);
       
    55 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to get auto-commit status", result, SQL_HANDLE_DBC, connection);
       
    56 
       
    57 	if (autoCommit == SQL_AUTOCOMMIT_ON) return true;
       
    58 	else if (autoCommit == SQL_AUTOCOMMIT_OFF) return false;
       
    59 	else throw SqlException(L"Unexpected value of auto-commit status");
    51 }
    60 }
    52 
    61 
    53 void Connection::setAutoCommit(bool autoCommit) {
    62 void Connection::setAutoCommit(bool autoCommit) {
    54 	// TODO: transaction control
    63 	SQLRETURN result = SQLSetConnectOption(connection, SQL_AUTOCOMMIT, autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
       
    64 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(std::wstring(L"Unable to set auto-commit to ") + (autoCommit ? L"enabled" : L"disabled"), result, SQL_HANDLE_DBC, connection);
    55 }
    65 }
    56 
    66 
    57 void Connection::commit() {
    67 void Connection::commit() {
    58 	SQLRETURN result = SQLEndTran(SQL_HANDLE_DBC, connection, SQL_COMMIT);
    68 	SQLRETURN result = SQLEndTran(SQL_HANDLE_DBC, connection, SQL_COMMIT);
    59 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to COMMIT: " + std::to_wstring(result));
    69 	if (OdbcCommon::isNotSuccessful(result)) throw SqlException(L"Unable to COMMIT: " + std::to_wstring(result));