func (conn *Connection) Prepare(sql string, params ...interface{}) (*Statement, *ODBCError) { wsql := StringToUTF16Ptr(sql) stmt, err := conn.newStmt() if err != nil { return nil, err } ret := C.SQLPrepareW(C.SQLHSTMT(stmt.handle), (*C.SQLWCHAR)(unsafe.Pointer(wsql)), C.SQLINTEGER(len(sql))) if !Success(ret) { err := FormatError(C.SQL_HANDLE_STMT, stmt.handle) stmt.Close() return nil, err } stmt.prepared = true return stmt, nil }
func SQLPrepare(statementHandle SQLHSTMT, statementText *SQLWCHAR, textLength SQLINTEGER) (ret SQLRETURN) { r := C.SQLPrepareW(C.SQLHSTMT(statementHandle), (*C.SQLWCHAR)(unsafe.Pointer(statementText)), C.SQLINTEGER(textLength)) return SQLRETURN(r) }
func SQLSetConnectAttr(connectionHandle SQLHDBC, attribute SQLINTEGER, valuePtr SQLPOINTER, stringLength SQLINTEGER) (ret SQLRETURN) { r := C.SQLSetConnectAttrW(C.SQLHDBC(connectionHandle), C.SQLINTEGER(attribute), C.SQLPOINTER(valuePtr), C.SQLINTEGER(stringLength)) return SQLRETURN(r) }
func SQLSetEnvAttr(environmentHandle SQLHENV, attribute SQLINTEGER, valuePtr SQLPOINTER, stringLength SQLINTEGER) (ret SQLRETURN) { r := C.SQLSetEnvAttr(C.SQLHENV(environmentHandle), C.SQLINTEGER(attribute), C.SQLPOINTER(valuePtr), C.SQLINTEGER(stringLength)) return SQLRETURN(r) }
func initEnv() (err *ODBCError) { ret := C.SQLAllocHandle(C.SQL_HANDLE_ENV, nil, &Genv) if !Success(ret) { err := FormatError(C.SQL_HANDLE_ENV, Genv) return err } ret = C.SQLSetEnvAttr(C.SQLHENV(Genv), C.SQL_ATTR_ODBC_VERSION, C.SQLPOINTER(unsafe.Pointer(uintptr(C.SQL_OV_ODBC3))), C.SQLINTEGER(0)) if !Success(ret) { err := FormatError(C.SQL_HANDLE_ENV, Genv) return err } return nil }
func (stmt *Statement) BindParam(index int, param interface{}) *ODBCError { var ValueType C.SQLSMALLINT var ParameterType C.SQLSMALLINT var ColumnSize C.SQLULEN var DecimalDigits C.SQLSMALLINT var ParameterValuePtr C.SQLPOINTER var BufferLength C.SQLLEN var StrLen_or_IndPt C.SQLLEN v := reflect.ValueOf(param) if param == nil { ft, _, _, _, err := stmt.GetParamType(index) if err != nil { return err } ParameterType = C.SQLSMALLINT(ft) if ParameterType == C.SQL_UNKNOWN_TYPE { ParameterType = C.SQL_VARCHAR } ValueType = C.SQL_C_DEFAULT StrLen_or_IndPt = C.SQL_NULL_DATA ColumnSize = 1 } else { switch v.Kind() { case reflect.Bool: ParameterType = C.SQL_BIT ValueType = C.SQL_C_BIT var b [1]byte if v.Bool() { b[0] = 1 } else { b[0] = 0 } ParameterValuePtr = C.SQLPOINTER(unsafe.Pointer(&b[0])) BufferLength = 1 StrLen_or_IndPt = 0 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: switch v.Type().Kind() { case reflect.Int: case reflect.Int8, reflect.Int16, reflect.Int32: ParameterType = C.SQL_INTEGER ValueType = C.SQL_C_LONG var l C.long = C.long(v.Int()) ParameterValuePtr = C.SQLPOINTER(unsafe.Pointer(&l)) BufferLength = 4 StrLen_or_IndPt = 0 case reflect.Int64: ParameterType = C.SQL_BIGINT ValueType = C.SQL_C_SBIGINT var ll C.longlong = C.longlong(v.Int()) ParameterValuePtr = C.SQLPOINTER(unsafe.Pointer(&ll)) BufferLength = 8 StrLen_or_IndPt = 0 } case reflect.Float32, reflect.Float64: ParameterType = C.SQL_DOUBLE ValueType = C.SQL_C_DOUBLE var d C.double = C.double(v.Float()) ParameterValuePtr = C.SQLPOINTER(unsafe.Pointer(&d)) BufferLength = 8 StrLen_or_IndPt = 0 case reflect.Complex64, reflect.Complex128: case reflect.String: var slen C.SQLUINTEGER = C.SQLUINTEGER(len(v.String())) ParameterType = C.SQL_VARCHAR ValueType = C.SQL_C_CHAR s := []byte(v.String()) ParameterValuePtr = C.SQLPOINTER(unsafe.Pointer(&s[0])) ColumnSize = slen BufferLength = C.SQLINTEGER(slen + 1) StrLen_or_IndPt = C.SQLINTEGER(slen) default: debugPrint("Not support type", v) } } ret := C.SQLBindParameter(C.SQLHSTMT(stmt.handle), C.SQLUSMALLINT(index), C.SQL_PARAM_INPUT, ValueType, ParameterType, ColumnSize, DecimalDigits, ParameterValuePtr, BufferLength, &StrLen_or_IndPt) if !Success(ret) { err := FormatError(C.SQL_HANDLE_STMT, stmt.handle, int(ret)) debugPrint("SQLBindParameter Error", err) return err } return nil }
func (stmt *Statement) GetField(field_index int) (v interface{}, ftype int, flen int, err *ODBCError) { var field_type C.SQLINTEGER var field_len C.SQLINTEGER var ll C.SQLSMALLINT ret := C.SQLColAttribute(C.SQLHSTMT(stmt.handle), C.SQLUSMALLINT(field_index+1), C.SQL_DESC_CONCISE_TYPE, C.SQLPOINTER(unsafe.Pointer(uintptr(0))), C.SQLSMALLINT(0), &ll, &field_type) if !Success(ret) { debugPrint("GetFiled type Error") } ret = C.SQLColAttribute(C.SQLHSTMT(stmt.handle), C.SQLUSMALLINT(field_index+1), C.SQL_DESC_LENGTH, C.SQLPOINTER(unsafe.Pointer(uintptr(0))), C.SQLSMALLINT(0), &ll, &field_len) if !Success(ret) { debugPrint("GetFiled len Error") } var fl C.SQLLEN = C.SQLLEN(field_len) switch int(field_type) { case C.SQL_BIT, C.SQL_INTEGER, C.SQL_SMALLINT, C.SQL_TINYINT: var value C.HANDLE ret = C.SQLGetData(C.SQLHSTMT(stmt.handle), C.SQLUSMALLINT(field_index+1), C.SQL_C_LONG, C.SQLPOINTER(unsafe.Pointer(&value)), 0, &fl) if fl == -1 { v = nil } else { v = value } case C.SQL_FLOAT, C.SQL_REAL: var value C.double ret = C.SQLGetData(C.SQLHSTMT(stmt.handle), C.SQLUSMALLINT(field_index+1), C.SQL_C_DOUBLE, C.SQLPOINTER(unsafe.Pointer(&value)), 0, &fl) if fl == -1 { v = nil } else { v = value } case C.SQL_WCHAR, C.SQL_WVARCHAR, C.SQL_WLONGVARCHAR: value := make([]uint16, int(field_len)+8) ret = C.SQLGetData(C.SQLHSTMT(stmt.handle), C.SQLUSMALLINT(field_index+1), C.SQL_C_WCHAR, C.SQLPOINTER(unsafe.Pointer(&value[0])), C.SQLINTEGER(int(field_len)+4), &fl) s := UTF16ToString(value) v = s default: value := make([]byte, int(fl)+2) ret = C.SQLGetData(C.SQLHSTMT(stmt.handle), C.SQLUSMALLINT(field_index+1), C.SQL_C_CHAR, C.SQLPOINTER(unsafe.Pointer(&value[0])), C.SQLINTEGER(int(field_len)+4), &fl) s := string(value[0:]) v = s debugPrint("default type", value, fl, s) } if !Success(ret) { err = FormatError(C.SQL_HANDLE_STMT, stmt.handle, int(ret)) debugPrint("GetFiled Data Error", err) } return v, int(field_type), int(fl), err }
func SQLSetConnectUIntPtrAttr(connectionHandle SQLHDBC, attribute SQLINTEGER, valuePtr uintptr, stringLength SQLINTEGER) (ret SQLRETURN) { r := C.sqlSetConnectUIntPtrAttr(C.SQLHDBC(connectionHandle), C.SQLINTEGER(attribute), C.uintptr_t(valuePtr), C.SQLINTEGER(stringLength)) return SQLRETURN(r) }
func SQLSetEnvUIntPtrAttr(environmentHandle SQLHENV, attribute SQLINTEGER, valuePtr uintptr, stringLength SQLINTEGER) (ret SQLRETURN) { r := C.sqlSetEnvUIntPtrAttr(C.SQLHENV(environmentHandle), C.SQLINTEGER(attribute), C.uintptr_t(valuePtr), C.SQLINTEGER(stringLength)) return SQLRETURN(r) }