func (rc *OCI8Rows) Next(dest []driver.Value) error { rv := C.OCIStmtFetch( (*C.OCIStmt)(rc.s.s), (*C.OCIError)(rc.s.c.err), 1, C.OCI_FETCH_NEXT, C.OCI_DEFAULT) if rv == C.OCI_ERROR { err := ociGetError(rc.s.c.err) if err.Error()[:9] != "ORA-01405" { return err } } if rv == C.OCI_NO_DATA { return io.EOF } for i := range dest { if rc.cols[i].ind == -1 { //Null dest[i] = nil continue } buf := rc.cols[i].pbuf switch rc.cols[i].kind { case C.SQLT_DAT: //TODO Handle BCE dates (http://docs.oracle.com/cd/B12037_01/appdev.101/b10779/oci03typ.htm#438305) //TODO Handle timezones (http://docs.oracle.com/cd/B12037_01/appdev.101/b10779/oci03typ.htm#443601) dest[i] = time.Date(((int(buf[0])-100)*100)+(int(buf[1])-100), time.Month(int(buf[2])), int(buf[3]), int(buf[4])-1, int(buf[5])-1, int(buf[6])-1, 0, rc.s.c.location) case C.SQLT_CHR, C.SQLT_AFC, C.SQLT_AVC: switch { case rc.cols[i].ind == 0: //Normal dest[i] = string(buf)[0:rc.cols[i].rlen] case rc.cols[i].ind == -2 || //Field longer than type (truncated) rc.cols[i].ind > 0: //Field longer than type (truncated). Value is original length. dest[i] = string(buf) default: return errors.New(fmt.Sprintf("Unknown column indicator: %d", rc.cols[i].ind)) } default: return errors.New(fmt.Sprintf("Unhandled column type: %d", rc.cols[i].kind)) } } return nil }
// Performs the actual fetch from Oracle. func (cur *Cursor) internalFetch(numRows uint) error { if cur.fetchVariables == nil { return errors.New("query not executed") } debug("fetchVars=%v", cur.fetchVariables) var err error for _, v := range cur.fetchVariables { if CTrace { ctrace("fetchvar %d=%s", v.internalFetchNum, v) ctrace("typ=%v", v.typ) } v.internalFetchNum++ // debug("typ=%s", v.typ) // debug("preFetch=%s", v.typ.preFetch) if v.typ.preFetch != nil { if err = v.typ.preFetch(v); err != nil { return err } } } // debug("StmtFetch numRows=%d", numRows) // Py_BEGIN_ALLOW_THREADS if CTrace { ctrace("OCIStmtFetch(cur=%p, env=%p, numRows=%d, FETCH_NEXT, DEFAULT)", cur.handle, cur.environment.errorHandle, numRows) } if err = cur.environment.CheckStatus( C.OCIStmtFetch(cur.handle, cur.environment.errorHandle, C.ub4(numRows), C.OCI_FETCH_NEXT, C.OCI_DEFAULT), "internalFetch(): fetch"); err != nil && err != NoDataFound { return err } // debug("fetched, getting row count") var rowCount int if _, err = cur.environment.AttrGet(unsafe.Pointer(cur.handle), C.OCI_HTYPE_STMT, C.OCI_ATTR_ROW_COUNT, unsafe.Pointer(&rowCount), "internalFetch(): row count"); err != nil { return err } // debug("row count = %d", rowCount) cur.actualRows = rowCount - cur.rowCount cur.rowNum = 0 return nil }
func (rc *OCI8Rows) Next(dest []driver.Value) error { rv := C.OCIStmtFetch( (*C.OCIStmt)(rc.s.s), (*C.OCIError)(rc.s.c.err), 1, C.OCI_FETCH_NEXT, C.OCI_DEFAULT) if rv == C.OCI_ERROR { return ociGetError(rc.s.c.err) } if rv == C.OCI_NO_DATA { return io.EOF } for i := range dest { dest[i] = string(rc.cols[i].pbuf) } return nil }
func (rc *OCI8Rows) Next(dest []driver.Value) error { rv := C.OCIStmtFetch( (*C.OCIStmt)(rc.s.s), (*C.OCIError)(rc.s.c.err), 1, C.OCI_FETCH_NEXT, OCI_MODE) if rv == C.OCI_ERROR { err := ociGetError(rc.s.c.err) if err.Error()[:9] != "ORA-01405" { return err } } if rv == C.OCI_NO_DATA { return io.EOF } for i := range dest { dest[i] = strings.TrimSpace(string(rc.cols[i].pbuf)) } return nil }
func (rc *OCI8Rows) Next(dest []driver.Value) error { rv := C.OCIStmtFetch( (*C.OCIStmt)(rc.s.s), (*C.OCIError)(rc.s.c.err), 1, C.OCI_FETCH_NEXT, C.OCI_DEFAULT) if rv == C.OCI_NO_DATA { return io.EOF } else if rv != C.OCI_SUCCESS { return ociGetError(rc.s.c.err) } for i := range dest { // TODO: switch rc.cols[i].ind if rc.cols[i].ind == -1 { // Null dest[i] = nil continue } else if rc.cols[i].ind != 0 { return errors.New(fmt.Sprintf("Unknown column indicator: %d, col %s", rc.cols[i].ind, rc.cols[i].name)) } switch rc.cols[i].kind { case C.SQLT_DAT: // for test, date are return as timestamp buf := (*[1 << 30]byte)(unsafe.Pointer(rc.cols[i].pbuf))[0:rc.cols[i].rlen] // TODO: Handle BCE dates (http://docs.oracle.com/cd/B12037_01/appdev.101/b10779/oci03typ.htm#438305) // TODO: Handle timezones (http://docs.oracle.com/cd/B12037_01/appdev.101/b10779/oci03typ.htm#443601) dest[i] = time.Date( (int(buf[0])-100)*100+(int(buf[1])-100), time.Month(int(buf[2])), int(buf[3]), int(buf[4])-1, int(buf[5])-1, int(buf[6])-1, 0, rc.s.c.location) case C.SQLT_BLOB, C.SQLT_CLOB: ptmp := unsafe.Pointer(uintptr(rc.cols[i].pbuf) + unsafe.Sizeof(unsafe.Pointer(nil))) bamt := (*C.ub4)(ptmp) *bamt = 0 ptmp = unsafe.Pointer(uintptr(rc.cols[i].pbuf) + unsafe.Sizeof(C.ub4(0)) + unsafe.Sizeof(unsafe.Pointer(nil))) b := (*[1 << 30]byte)(ptmp)[0:blobBufSize] var buf []byte again: rv = C.OCILobRead( (*C.OCISvcCtx)(rc.s.c.svc), (*C.OCIError)(rc.s.c.err), *(**C.OCILobLocator)(rc.cols[i].pbuf), bamt, 1, ptmp, C.ub4(blobBufSize), nil, nil, 0, C.SQLCS_IMPLICIT) if rv == C.OCI_NEED_DATA { buf = append(buf, b[:int(*bamt)]...) goto again } if rv != C.OCI_SUCCESS { return ociGetError(rc.s.c.err) } if rc.cols[i].kind == C.SQLT_BLOB { dest[i] = append(buf, b[:int(*bamt)]...) } else { dest[i] = string(append(buf, b[:int(*bamt)]...)) } case C.SQLT_CHR, C.SQLT_AFC, C.SQLT_AVC: buf := (*[1 << 30]byte)(unsafe.Pointer(rc.cols[i].pbuf))[0:rc.cols[i].rlen] switch { case rc.cols[i].ind == 0: // Normal dest[i] = string(buf) case rc.cols[i].ind == -2 || // Field longer than type (truncated) rc.cols[i].ind > 0: // Field longer than type (truncated). Value is original length. dest[i] = string(buf) default: return errors.New(fmt.Sprintf("Unknown column indicator: %d", rc.cols[i].ind)) } case C.SQLT_BIN: // RAW buf := (*[1 << 30]byte)(unsafe.Pointer(rc.cols[i].pbuf))[0:rc.cols[i].rlen] dest[i] = buf case C.SQLT_NUM: // NUMBER buf := (*[21]byte)(unsafe.Pointer(rc.cols[i].pbuf)) dest[i] = buf case C.SQLT_VNU: // VARNUM buf := (*[22]byte)(unsafe.Pointer(rc.cols[i].pbuf)) dest[i] = buf case C.SQLT_INT: // INT buf := (*[1 << 30]byte)(unsafe.Pointer(rc.cols[i].pbuf))[0:rc.cols[i].rlen] dest[i] = buf case C.SQLT_LNG: // LONG buf := (*[1 << 30]byte)(unsafe.Pointer(rc.cols[i].pbuf))[0:rc.cols[i].rlen] dest[i] = buf case C.SQLT_IBDOUBLE, C.SQLT_IBFLOAT: colsize := rc.cols[i].size buf := (*[1 << 30]byte)(unsafe.Pointer(rc.cols[i].pbuf))[0:colsize] if colsize == 4 { v := uint32(buf[3]) v |= uint32(buf[2]) << 8 v |= uint32(buf[1]) << 16 v |= uint32(buf[0]) << 24 // Don't know why bits are inverted that way, but it works if buf[0]&0x80 == 0 { v ^= 0xffffffff } else { v &= 0x7fffffff } dest[i] = math.Float32frombits(v) } else if colsize == 8 { v := uint64(buf[7]) v |= uint64(buf[6]) << 8 v |= uint64(buf[5]) << 16 v |= uint64(buf[4]) << 24 v |= uint64(buf[3]) << 32 v |= uint64(buf[2]) << 40 v |= uint64(buf[1]) << 48 v |= uint64(buf[0]) << 56 // Don't know why bits are inverted that way, but it works if buf[0]&0x80 == 0 { v ^= 0xffffffffffffffff } else { v &= 0x7fffffffffffffff } dest[i] = math.Float64frombits(v) } else { return errors.New(fmt.Sprintf("Unhandled binary float size: %d", colsize)) } case C.SQLT_TIMESTAMP: if rv := C.WrapOCIDateTimeGetDateTime( (*C.OCIEnv)(rc.s.c.env), (*C.OCIError)(rc.s.c.err), *(**C.OCIDateTime)(rc.cols[i].pbuf), ); rv.rv != C.OCI_SUCCESS { return ociGetError(rc.s.c.err) } else { dest[i] = time.Date( int(rv.y), time.Month(rv.m), int(rv.d), int(rv.hh), int(rv.mm), int(rv.ss), int(rv.ff), rc.s.c.location) } case C.SQLT_TIMESTAMP_TZ, C.SQLT_TIMESTAMP_LTZ: tptr := *(**C.OCIDateTime)(rc.cols[i].pbuf) rv := C.WrapOCIDateTimeGetDateTime( (*C.OCIEnv)(rc.s.c.env), (*C.OCIError)(rc.s.c.err), tptr) if rv.rv != C.OCI_SUCCESS { return ociGetError(rc.s.c.err) } rvz := C.WrapOCIDateTimeGetTimeZoneNameOffset( (*C.OCIEnv)(rc.s.c.env), (*C.OCIError)(rc.s.c.err), tptr) if rvz.rv != C.OCI_SUCCESS { return ociGetError(rc.s.c.err) } nnn := C.GoStringN((*C.char)((unsafe.Pointer)(&rvz.zone[0])), C.int(rvz.zlen)) loc, err := time.LoadLocation(nnn) if err != nil { // TODO: reuse locations loc = time.FixedZone(nnn, int(rvz.h)*60*60+int(rvz.m)*60) } dest[i] = time.Date( int(rv.y), time.Month(rv.m), int(rv.d), int(rv.hh), int(rv.mm), int(rv.ss), int(rv.ff), loc) case C.SQLT_INTERVAL_DS: iptr := *(**C.OCIInterval)(rc.cols[i].pbuf) rv := C.WrapOCIIntervalGetDaySecond( (*C.OCIEnv)(rc.s.c.env), (*C.OCIError)(rc.s.c.err), iptr) if rv.rv != C.OCI_SUCCESS { return ociGetError(rc.s.c.err) } dest[i] = int64(time.Duration(rv.d)*time.Hour*24 + time.Duration(rv.hh)*time.Hour + time.Duration(rv.mm)*time.Minute + time.Duration(rv.ss)*time.Second + time.Duration(rv.ff)) case C.SQLT_INTERVAL_YM: iptr := *(**C.OCIInterval)(rc.cols[i].pbuf) rv := C.WrapOCIIntervalGetYearMonth( (*C.OCIEnv)(rc.s.c.env), (*C.OCIError)(rc.s.c.err), iptr) if rv.rv != C.OCI_SUCCESS { return ociGetError(rc.s.c.err) } dest[i] = int64(rv.y)*12 + int64(rv.m) default: return errors.New(fmt.Sprintf("Unhandled column type: %d", rc.cols[i].kind)) } } return nil }
func (rc *OCI8Rows) Next(dest []driver.Value) error { rv := C.OCIStmtFetch( (*C.OCIStmt)(rc.s.s), (*C.OCIError)(rc.s.c.err), 1, C.OCI_FETCH_NEXT, C.OCI_DEFAULT) if rv == C.OCI_ERROR { err := ociGetError(rc.s.c.err) if err.Error()[:9] != "ORA-01405" { return err } } if rv == C.OCI_NO_DATA { return io.EOF } var err error for i := range dest { if rc.cols[i].ind == -1 { //Null dest[i] = nil continue } switch rc.cols[i].kind { case C.SQLT_DAT: buf := (*[1 << 30]byte)(unsafe.Pointer(rc.cols[i].pbuf))[0:rc.cols[i].rlen] //TODO Handle BCE dates (http://docs.oracle.com/cd/B12037_01/appdev.101/b10779/oci03typ.htm#438305) //TODO Handle timezones (http://docs.oracle.com/cd/B12037_01/appdev.101/b10779/oci03typ.htm#443601) datestr := fmt.Sprintf(dateStrFmt, ((int(buf[0])-100)*100)+(int(buf[1])-100), int(buf[2]), int(buf[3]), int(buf[4])-1, int(buf[5])-1, int(buf[6])-1) dest[i], err = time.ParseInLocation(dateFmt, datestr, rc.s.c.location) if err != nil { return fmt.Errorf("Unknown date format:", err) } case C.SQLT_BLOB, C.SQLT_CLOB: var bamt C.ub4 b := make([]byte, rc.cols[i].size) rv = C.OCILobRead( (*C.OCISvcCtx)(rc.s.c.svc), (*C.OCIError)(rc.s.c.err), (*C.OCILobLocator)(rc.cols[i].pbuf), &bamt, 1, unsafe.Pointer(&b[0]), C.ub4(rc.cols[i].size), nil, nil, 0, C.SQLCS_IMPLICIT) if rv == C.OCI_ERROR { return ociGetError(rc.s.c.err) } dest[i] = b case C.SQLT_CHR, C.SQLT_AFC, C.SQLT_AVC: buf := (*[1 << 30]byte)(unsafe.Pointer(rc.cols[i].pbuf))[0:rc.cols[i].rlen] switch { case rc.cols[i].ind == 0: //Normal dest[i] = string(buf) case rc.cols[i].ind == -2 || //Field longer than type (truncated) rc.cols[i].ind > 0: //Field longer than type (truncated). Value is original length. dest[i] = string(buf) default: return errors.New(fmt.Sprintf("Unknown column indicator: %d", rc.cols[i].ind)) } default: return errors.New(fmt.Sprintf("Unhandled column type: %d", rc.cols[i].kind)) } } return nil }