// Prepare returns a prepared statement, bound to this connection func (c *connection) Prepare(query string) (driver.Stmt, error) { // Allocate the statement handle var stmtHandle odbc.SQLHandle ret := odbc.SQLAllocHandle(odbc.SQL_HANDLE_STMT, c.handle, &stmtHandle) if isError(ret) { return nil, errorConnection(c.handle) } // Set the query timeout ret = odbc.SQLSetStmtAttr(stmtHandle, odbc.SQL_ATTR_QUERY_TIMEOUT, odbc.SQLPOINTER(queryTimeout.Seconds()), odbc.SQL_IS_INTEGER) if isError(ret) { return nil, errorStatement(stmtHandle, query) } // Get the statement descriptor table var stmtDescHandle odbc.SQLHandle ret = odbc.SQLGetStmtAttr(stmtHandle, odbc.SQL_ATTR_APP_PARAM_DESC, uintptr(unsafe.Pointer(&stmtDescHandle)), 0, nil) if isError(ret) { return nil, errorConnection(c.handle) } // Parse query options queryOptions, err := parseQueryOptions(query) if err != nil { return nil, err } // Remove query options from SQL query query = removeOptions(query) // Create new statement stmt := &statement{handle: stmtHandle, stmtDescHandle: stmtDescHandle, sqlStmt: query, conn: c, queryOptions: queryOptions} // Add to map of statements owned by the connection c.statements[stmt] = true //Add a finalizer runtime.SetFinalizer(stmt, (*statement).Close) return stmt, nil }
// Returns a new connection to the database func (d *lodbcDriver) Open(name string) (driver.Conn, error) { // Allocate the connection handle var connHandle odbc.SQLHandle ret := odbc.SQLAllocHandle(odbc.SQL_HANDLE_DBC, envHandle, &connHandle) if isError(ret) { return nil, errorEnvironment(envHandle) } // Establish the connection with the database nameSqlPtr := (*odbc.SQLCHAR)(unsafe.Pointer(syscall.StringToUTF16Ptr(name))) ret = odbc.SQLDriverConnect(connHandle, 0, nameSqlPtr, odbc.SQLSMALLINT(odbc.SQL_NTS), nil, 0, nil, odbc.SQL_DRIVER_NOPROMPT) if isError(ret) { return nil, errorConnection(connHandle) } // Create new connection var conn = &connection{handle: connHandle, isTransactionActive: false, statements: make(map[driver.Stmt]bool, 0)} //Add a finalizer runtime.SetFinalizer(conn, (*connection).Close) return conn, nil }
// Allocates shared environment func init() { // Set environment handle for connection pooling ret := odbc.SQLSetEnvAttr(envHandle, odbc.SQL_ATTR_CONNECTION_POOLING, odbc.SQL_CP_ONE_PER_DRIVER, 0) if isError(ret) { panic(errorEnvironment(envHandle)) } // Allocate the environment handle ret = odbc.SQLAllocHandle(odbc.SQL_HANDLE_ENV, 0, &envHandle) if isError(ret) { panic(errorEnvironment(envHandle)) } // Set the environment handle to use ODBC v3 ret = odbc.SQLSetEnvAttr(envHandle, odbc.SQL_ATTR_ODBC_VERSION, odbc.SQL_OV_ODBC3, 0) if isError(ret) { panic(errorEnvironment(envHandle)) } // Register with the SQL package d := &lodbcDriver{} sql.Register("lodbc", d) }