Example #1
0
// Begin starts and returns a new transaction
// Only one transaction is supported at a time for a connection
func (c *connection) Begin() (driver.Tx, error) {
	// Do not allow a  new transaction if one already exists
	if c.isTransactionActive {
		return nil, fmt.Errorf("Transaction already active for connection")
	}

	ret := odbc.SQLSetConnectAttr(c.handle, odbc.SQL_ATTR_AUTOCOMMIT, odbc.SQLPOINTER(odbc.SQL_AUTOCOMMIT_OFF), 0, nil)
	if isError(ret) {
		return nil, errorConnection(c.handle)
	}
	c.isTransactionActive = true

	tx := &transaction{conn: c}
	return tx, nil
}
Example #2
0
// Commit or rollback transaction in consistent manner
func (tx *transaction) completeTransaction(completeType odbc.SQLSMALLINT) error {
	//Complete transaction by either committing or rolling back
	ret := odbc.SQLEndTran(odbc.SQL_HANDLE_DBC, tx.conn.handle, completeType)
	if isError(ret) {
		return errorConnection(tx.conn.handle)
	}

	//Make transaction as finished and turn auto commit back on
	tx.conn.isTransactionActive = false
	ret = odbc.SQLSetConnectAttr(tx.conn.handle, odbc.SQL_ATTR_AUTOCOMMIT, odbc.SQLPOINTER(odbc.SQL_AUTOCOMMIT_ON), 0, nil)
	if isError(ret) {
		return errorConnection(tx.conn.handle)
	}
	return nil
}
Example #3
0
// Close invalidates and potentially stops any current
// prepared statements and transactions, marking this
// connection as no longer in use.
func (c *connection) Close() error {

	// Verify that connHandle is valid
	if c.handle == 0 {
		return nil
	}

	// Verify that connection has not already been closed
	if c.isClosed {
		return nil
	}

	var err error

	// Close all of the statements owned by the connection
	for key, _ := range c.statements {
		// Skip the statement if it is already nil
		if isNil(key) {
			continue
		}
		key.Close()
	}
	c.statements = nil

	// If the transaction is active, roll it back
	if c.isTransactionActive {
		ret := odbc.SQLEndTran(odbc.SQL_HANDLE_DBC, c.handle, odbc.SQL_ROLLBACK)
		if isError(ret) {
			err = errorConnection(c.handle)
		}

		//Turn AutoCommit back on
		ret = odbc.SQLSetConnectAttr(c.handle, odbc.SQL_ATTR_AUTOCOMMIT, odbc.SQLPOINTER(odbc.SQL_AUTOCOMMIT_ON), 0, nil)
		if isError(ret) {
			err = errorConnection(c.handle)
		}
	}

	// Disconnect connection
	ret := odbc.SQLDisconnect(c.handle)
	if isError(ret) {
		err = errorConnection(c.handle)
	}

	// Deallocate connection
	ret = odbc.SQLFreeHandle(odbc.SQL_HANDLE_DBC, c.handle)
	if isError(ret) {
		err = errorConnection(c.handle)
	}

	// Clear the handle
	c.handle = 0

	// Set connection to closed
	c.isClosed = true

	//Clear the finalizer
	runtime.SetFinalizer(c, nil)

	// Return any error
	if err != nil {
		return err
	}

	return nil
}