Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions dpi_bridge/dpi_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,18 @@ type connHandle struct {
tx driver.Tx // active transaction (nil if none)

// Connection parameters (set before login)
host string
port int
user string
password string
schema string
autocommit bool
loginTimeout int
connTimeout int
appName string
txnIsolation int
host string
port int
user string
password string
schema string
autocommit bool
loginTimeout int
connTimeout int
appName string
txnIsolation int
objectDescs map[string]*objDescHandle
objectDescIDs map[string]uintptr

// Post-login info
serverVersion string
Expand All @@ -71,11 +73,13 @@ type connHandle struct {

func newConnHandle(env *envHandle) *connHandle {
return &connHandle{
env: env,
port: DSQL_DEAFAULT_TCPIP_PORT,
autocommit: false,
loginTimeout: 5000,
serverCode: PG_UTF8,
env: env,
port: DSQL_DEAFAULT_TCPIP_PORT,
autocommit: false,
loginTimeout: 5000,
serverCode: PG_UTF8,
objectDescs: make(map[string]*objDescHandle),
objectDescIDs: make(map[string]uintptr),
}
}

Expand Down Expand Up @@ -106,6 +110,9 @@ func dpi_free_con(hcon C.dhcon) C.DPIRETURN {
conn.db = nil
conn.conn = nil
}
for key, id := range conn.objectDescIDs {
freeObjectDescriptor(id, conn.objectDescs[key])
}
conn.mu.Unlock()

id := ptrToHandle(unsafe.Pointer(hcon))
Expand Down
6 changes: 4 additions & 2 deletions dpi_bridge/dpi_desc.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,10 @@ func getRowDescField(stmt *stmtHandle, idx int, fieldID int16, val C.dpointer, v
return DSQL_SUCCESS

case DSQL_DESC_OBJ_DESCRIPTOR:
// Return nil object descriptor
*(*C.dpointer)(val) = nil
if idx < 0 || idx >= len(stmt.columns) {
return DSQL_ERROR
}
*(*C.dpointer)(val) = C.dpointer(handleToPtr(stmt.columns[idx].objectDescID))
return DSQL_SUCCESS

default:
Expand Down
4 changes: 4 additions & 0 deletions dpi_bridge/dpi_diag.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ func getDiagFromHandle(hndlType int16, hndl C.dhandle) *diagInfo {
return h.lastErr
case *descHandle:
return h.lastErr
case *objHandle:
return h.lastErr
case *objDescHandle:
return h.lastErr
}
return nil
}
Expand Down
33 changes: 30 additions & 3 deletions dpi_bridge/dpi_fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef dhandle dhcon;
typedef dhandle dhstmt;
typedef dhandle dhdesc;
typedef dhandle dhloblctr;
typedef dhandle dhobj;

typedef struct {
sdint2 year;
Expand Down Expand Up @@ -342,7 +343,8 @@ func dpi_fetch(hstmt C.dhstmt, rowNum *C.ulength) C.DPIRETURN {
rowBind.actLenPtr = (*C.slength)(unsafe.Pointer(uintptr(unsafe.Pointer(bind.actLenPtr)) + uintptr(fetched)*ei.indStride))
}
}
if err := writeValueToBinding(row[colIdx-1], rowBind, stmt.columns[colIdx-1].sqlType); err != nil {
col := stmt.columns[colIdx-1]
if err := writeValueToBinding(row[colIdx-1], rowBind, col.sqlType, col.objectDesc); err != nil {
stmt.lastErr = diagFromError(err)
return DSQL_ERROR
}
Expand Down Expand Up @@ -401,6 +403,8 @@ func cTypeSize(cType int16) uintptr {
return 19 // DPI_MAX_NUMERIC_LEN(16) + precision + scale + sign
case DSQL_C_INTERVAL_DAY_TO_SECOND:
return unsafe.Sizeof(C.dpi_interval_dt_t{})
case DSQL_C_CLASS, DSQL_C_RECORD, DSQL_C_ARRAY, DSQL_C_SARRAY:
return unsafe.Sizeof(uintptr(0))
default:
return 0 // variable-length (string, binary, etc.)
}
Expand Down Expand Up @@ -444,11 +448,13 @@ func dpi_get_data(hstmt C.dhstmt, icol C.udint2, ctype C.sdint2,
}

sqlType := int16(DSQL_VARCHAR)
var objectDesc *objDescHandle
if idx < len(stmt.columns) {
sqlType = stmt.columns[idx].sqlType
objectDesc = stmt.columns[idx].objectDesc
}

if err := writeValueToBinding(rawVal, bind, sqlType); err != nil {
if err := writeValueToBinding(rawVal, bind, sqlType, objectDesc); err != nil {
stmt.lastErr = diagFromError(err)
return DSQL_ERROR
}
Expand Down Expand Up @@ -515,7 +521,7 @@ func dpi_row_count(hstmt C.dhstmt, rowNum *C.sdint8) C.DPIRETURN {
}

// writeValueToBinding writes a Go value into a C buffer according to the binding info.
func writeValueToBinding(val interface{}, bind bindColInfo, sqlType int16) error {
func writeValueToBinding(val interface{}, bind bindColInfo, sqlType int16, objectDesc *objDescHandle) error {
if val == nil {
if bind.indPtr != nil {
*bind.indPtr = C.slength(DSQL_NULL_DATA)
Expand Down Expand Up @@ -579,6 +585,19 @@ func writeValueToBinding(val interface{}, bind bindColInfo, sqlType int16) error
return writeIntervalDaySecondValue(val, bind)
case DSQL_C_LOB_HANDLE:
writeLobHandleValue(val, bind, sqlType)
case DSQL_C_CLASS, DSQL_C_RECORD:
hobj := *(*C.dhobj)(bind.dataPtr)
if hobj == nil {
id := allocHandle(&objHandle{})
hobj = C.dhobj(handleToPtr(id))
*(*C.dhobj)(bind.dataPtr) = hobj
}
if err := fillObjectHandle(val, unsafe.Pointer(hobj), objectDesc); err != nil {
return err
}
if bind.indPtr != nil {
*bind.indPtr = C.slength(unsafe.Sizeof(hobj))
}
default:
// Default: treat as string
writeStringValue(val, bind)
Expand Down Expand Up @@ -1220,6 +1239,14 @@ func extractBoundValue(bind bindParamInfo) interface{} {
return string(data)
}
return data
case DSQL_C_CLASS, DSQL_C_RECORD:
hobj := *(*C.dhobj)(bind.dataPtr)
value, ok := getHandle(ptrToHandle(unsafe.Pointer(hobj)))
obj, typed := value.(*objHandle)
if !ok || !typed || obj.desc == nil {
return nil
}
return obj.driverValue()
default:
// Treat as string
if bind.indPtr != nil && *bind.indPtr >= 0 {
Expand Down
Loading
Loading