func (cursor *Cursor) prep() (err error) { var isc_status [20]C.ISC_STATUS if err = cursor.check(); err != nil { return } if err = cursor.connection.check(); err != nil { return } C.isc_dsql_describe(&isc_status[0], &cursor.stmt, 1, cursor.o_sqlda) if err = fbErrorCheck(&isc_status); err != nil { return } cols := cursor.o_sqlda.sqld var offset C.ISC_SHORT = 0 for count := C.ISC_SHORT(0); count < cols; count++ { ovar := C.sqlda_sqlvar(cursor.o_sqlda, count) length, alignment := ovar.sqllen, ovar.sqllen dtp := ovar.sqltype & ^1 if dtp == C.SQL_TEXT { alignment = 1 } else if dtp == C.SQL_VARYING { length += C.SHORT_SIZE alignment = C.SHORT_SIZE } offset = fbAlign(offset, alignment) ovar.sqldata = (*C.ISC_SCHAR)(unsafe.Pointer((uintptr(unsafe.Pointer(cursor.o_buffer)) + uintptr(offset)))) offset += length offset = fbAlign(offset, C.SHORT_SIZE) ovar.sqlind = (*C.ISC_SHORT)(unsafe.Pointer(uintptr(unsafe.Pointer(cursor.o_buffer)) + uintptr(offset))) offset += C.SHORT_SIZE } return }
func (cursor *Cursor) execute2(sql string, args ...interface{}) (rowsAffected int, err error) { const dialect = 1 var isc_status [20]C.ISC_STATUS // prepare query sql2 := C.CString(sql) defer C.free(unsafe.Pointer(sql2)) sql3 := (*C.ISC_SCHAR)(unsafe.Pointer(sql2)) C.isc_dsql_prepare(&isc_status[0], &cursor.connection.transact, &cursor.stmt, 0, sql3, cursor.connection.dialect, cursor.o_sqlda) if err = fbErrorCheck(&isc_status); err != nil { return } // get statement type isc_info_stmt := [...]C.ISC_SCHAR{C.isc_info_sql_stmt_type} var isc_info_buff [16]C.ISC_SCHAR C.isc_dsql_sql_info(&isc_status[0], &cursor.stmt, C.short(unsafe.Sizeof(isc_info_stmt[0])), &isc_info_stmt[0], C.short(unsafe.Sizeof(isc_info_buff[0])*16), &isc_info_buff[0]) if err = fbErrorCheck(&isc_status); err != nil { return } var statement C.long if isc_info_buff[0] == C.isc_info_sql_stmt_type { length := C.isc_vax_integer(&isc_info_buff[1], 2) statement = C.long(C.isc_vax_integer(&isc_info_buff[3], C.short(length))) } else { statement = 0 } // describe input parameters C.isc_dsql_describe_bind(&isc_status[0], &cursor.stmt, dialect, cursor.i_sqlda) if err = fbErrorCheck(&isc_status); err != nil { return } // describe output parameters C.isc_dsql_describe(&isc_status[0], &cursor.stmt, 1, cursor.o_sqlda) if err = fbErrorCheck(&isc_status); err != nil { return } // get number of parameters and reallocate SQLDA in_params := cursor.i_sqlda.sqld if cursor.i_sqlda.sqln < in_params { C.free(unsafe.Pointer(cursor.i_sqlda)) cursor.i_sqlda = C.sqlda_alloc(C.long(in_params)) // describe again C.isc_dsql_describe_bind(&isc_status[0], &cursor.stmt, dialect, cursor.i_sqlda) if err = fbErrorCheck(&isc_status); err != nil { return } } // get size of parameters buffer and reallocate it if in_params > 0 { length := C.calculate_buffsize(cursor.i_sqlda) if length > cursor.i_buffer_size { cursor.i_buffer = (*C.char)(C.realloc(unsafe.Pointer(cursor.i_buffer), C.size_t(length))) cursor.i_buffer_size = length } } if cursor.o_sqlda.sqld != 0 { // open cursor if statement is query // get number of columns and reallocate SQLDA cols := cursor.o_sqlda.sqld if cursor.o_sqlda.sqln < cols { C.free(unsafe.Pointer(cursor.o_sqlda)) cursor.o_sqlda = C.sqlda_alloc(C.long(cols)) // describe again C.isc_dsql_describe(&isc_status[0], &cursor.stmt, 1, cursor.o_sqlda) if err = fbErrorCheck(&isc_status); err != nil { return } } var i_sqlda *C.XSQLDA if in_params > 0 { cursor.setInputParams(args) i_sqlda = cursor.i_sqlda } else { i_sqlda = (*C.XSQLDA)(nil) } // open cursor C.isc_dsql_execute2(&isc_status[0], &cursor.connection.transact, &cursor.stmt, C.SQLDA_VERSION1, i_sqlda, (*C.XSQLDA)(nil)) if err = fbErrorCheck(&isc_status); err != nil { return } cursor.open = true // get size of results buffer and reallocate it length := C.calculate_buffsize(cursor.o_sqlda) if length > cursor.o_buffer_size { cursor.o_buffer = (*C.char)(C.realloc(unsafe.Pointer(cursor.o_buffer), C.size_t(length))) cursor.o_buffer_size = length } // Set the description attributes cursor.Fields = fieldsFromSqlda(cursor.o_sqlda, cursor.connection.database.LowercaseNames) cursor.FieldsMap = fieldsMapFromSlice(cursor.Fields) } else { // execute statement if not query if statement == C.isc_info_sql_stmt_start_trans { panic("use fb.Connection.Transaction()") } else if statement == C.isc_info_sql_stmt_commit { panic("use fb.Connection.Commit()") } else if statement == C.isc_info_sql_stmt_rollback { panic("use fb.Connection.Rollback()") } else if in_params > 0 { cursor.executeWithParams(args) } else { C.isc_dsql_execute2(&isc_status[0], &cursor.connection.transact, &cursor.stmt, C.SQLDA_VERSION1, (*C.XSQLDA)(nil), (*C.XSQLDA)(nil)) if err = fbErrorCheck(&isc_status); err != nil { return } } rowsAffected = cursor.rowsAffected(statement) } return }