From bc6b88eefe1479d1a810298ae920b6d8e64203d5 Mon Sep 17 00:00:00 2001 From: Christopher Jones Date: Mon, 20 Jul 2015 17:45:32 +1000 Subject: [PATCH] Add REF CURSOR support. Result Set tidy ups. Renumber constants. --- lib/oracledb.js | 17 +-- src/dpi/include/dpiConn.h | 2 +- src/dpi/include/dpiStmt.h | 1 + src/dpi/src/dpiConnImpl.cpp | 1 - src/dpi/src/dpiStmtImpl.cpp | 37 ++++-- src/dpi/src/dpiStmtImpl.h | 2 +- src/njs/src/njsConnection.cpp | 242 +++++++++++++++++++++++----------- src/njs/src/njsConnection.h | 34 +++-- src/njs/src/njsResultSet.cpp | 9 +- src/njs/src/njsResultSet.h | 3 +- src/njs/src/njsUtils.h | 17 +-- 11 files changed, 241 insertions(+), 124 deletions(-) diff --git a/lib/oracledb.js b/lib/oracledb.js index 95588ac2..b6ad4855 100644 --- a/lib/oracledb.js +++ b/lib/oracledb.js @@ -31,15 +31,16 @@ try { var oracledb_ins = new oracledb.Oracledb(); -oracledb_ins.STRING = 1; -oracledb_ins.NUMBER = 2; -oracledb_ins.DATE = 3; +oracledb_ins.STRING = 2001; +oracledb_ins.NUMBER = 2002; +oracledb_ins.DATE = 2003; +oracledb_ins.CURSOR = 2004; -oracledb_ins.ARRAY = 1; -oracledb_ins.OBJECT = 2; +oracledb_ins.BIND_IN = 3001; +oracledb_ins.BIND_INOUT = 3002; +oracledb_ins.BIND_OUT = 3003; -oracledb_ins.BIND_IN = 1; -oracledb_ins.BIND_INOUT = 2; -oracledb_ins.BIND_OUT = 3; +oracledb_ins.ARRAY = 4001; +oracledb_ins.OBJECT = 4002; module.exports = oracledb_ins; diff --git a/src/dpi/include/dpiConn.h b/src/dpi/include/dpiConn.h index f351a597..9e847210 100644 --- a/src/dpi/include/dpiConn.h +++ b/src/dpi/include/dpiConn.h @@ -67,7 +67,7 @@ public: virtual void action(const string &action) = 0; // methods - virtual Stmt* getStmt (const string &sql) = 0; + virtual Stmt* getStmt (const string &sql="") = 0; virtual void commit() = 0; diff --git a/src/dpi/include/dpiStmt.h b/src/dpi/include/dpiStmt.h index b199c0ee..8c5a5c14 100644 --- a/src/dpi/include/dpiStmt.h +++ b/src/dpi/include/dpiStmt.h @@ -86,6 +86,7 @@ typedef enum DpiClob = 112, DpiBlob = 113, DpiBfile = 114, + DpiRSet = 116, DpiYearMonth = 182, /* internal only */ DpiDaySecond = 183, /* internal only */ DpiTimestamp = 187, /* internal only */ diff --git a/src/dpi/src/dpiConnImpl.cpp b/src/dpi/src/dpiConnImpl.cpp index d1000bbf..7af0d9b8 100644 --- a/src/dpi/src/dpiConnImpl.cpp +++ b/src/dpi/src/dpiConnImpl.cpp @@ -414,7 +414,6 @@ Stmt* ConnImpl::getStmt (const string &sql) } - /*****************************************************************************/ /* DESCRIPTION diff --git a/src/dpi/src/dpiStmtImpl.cpp b/src/dpi/src/dpiStmtImpl.cpp index b0f85441..4cc4d031 100644 --- a/src/dpi/src/dpiStmtImpl.cpp +++ b/src/dpi/src/dpiStmtImpl.cpp @@ -88,17 +88,27 @@ StmtImpl::StmtImpl (EnvImpl *env, OCIEnv *envh, ConnImpl *conn, try : conn_(conn), errh_(NULL), svch_(svch), stmth_(NULL), numCols_ (0),meta_(NULL), stmtType_ (DpiStmtUnknown), - isReturning_(false), isReturningSet_(false) + isReturning_(false), isReturningSet_(false), refCursor_(false) { // create an OCIError object for this execution ociCallEnv (OCIHandleAlloc ((void *)envh, (dvoid **)&errh_, OCI_HTYPE_ERROR, 0, (dvoid **)0), envh); - // Prepare OCIStmt object with given sql statement. - ociCall (OCIStmtPrepare2 (svch_, &stmth_, errh_, (oratext *)sql.data(), - (ub4)sql.length(), NULL, 0, OCI_NTV_SYNTAX, - OCI_DEFAULT), - errh_); + if(!sql.empty()) + { + // Prepare OCIStmt object with given sql statement. + ociCall (OCIStmtPrepare2 (svch_, &stmth_, errh_, (oratext *)sql.data(), + (ub4)sql.length(), NULL, 0, OCI_NTV_SYNTAX, + OCI_DEFAULT), + errh_); + } + else + { + // to build empty stmt object used for ref cursors. + ociCall (OCIHandleAlloc ((void *)envh, (dvoid **)&stmth_, + OCI_HTYPE_STMT,0, (dvoid **)0), errh_); + refCursor_ = true; + } } catch (...) { @@ -240,7 +250,9 @@ void StmtImpl::bind (unsigned int pos, unsigned short type, void *buf, OCIBind *b = (OCIBind *)0; ociCall (DPIBINDBYPOS (stmth_, &b, errh_, pos, - (cb ? NULL : buf), bufSize, type, + (cb ? NULL : (type==DpiRSet) ? + (void *)&(((StmtImpl*)buf)->stmth_) : buf), + (type == DpiRSet) ? 0 : bufSize, type, (cb ? NULL : ind), (cb ? NULL : bufLen), NULL, 0, NULL, @@ -285,7 +297,9 @@ void StmtImpl::bind (const unsigned char *name, int nameLen, OCIBind *b = (OCIBind *)0; ociCall (DPIBINDBYNAME (stmth_, &b, errh_, name, nameLen, - (cb ? NULL : buf), bufSize, type, + (cb ? NULL : (type == DpiRSet) ? + (void *)&((StmtImpl*)buf)->stmth_: buf), + (type == DpiRSet) ? 0 : bufSize, type, (cb ? NULL : ind), (cb ? NULL : bufLen), NULL, 0, NULL, @@ -518,7 +532,12 @@ void StmtImpl::cleanup () } if ( stmth_) { - ociCall ( OCIStmtRelease (stmth_, errh_, NULL, 0, OCI_DEFAULT), errh_ ); + // Release not called for ref cursor. + if ( refCursor_ ) + OCIHandleFree ( stmth_, OCI_HTYPE_STMT ); + else + ociCall ( OCIStmtRelease (stmth_, errh_, NULL, 0, OCI_DEFAULT), errh_ ); + stmth_ = NULL; } if ( errh_) diff --git a/src/dpi/src/dpiStmtImpl.h b/src/dpi/src/dpiStmtImpl.h index c80f9903..e1baed09 100644 --- a/src/dpi/src/dpiStmtImpl.h +++ b/src/dpi/src/dpiStmtImpl.h @@ -112,7 +112,6 @@ public: dvoid **bufpp, ub4 **alenp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp ); - private: void cleanup (); @@ -131,6 +130,7 @@ private: DpiStmtType stmtType_; // Statement Type (Query, DML, ... ) bool isReturning_; // Does the stmt has RETURNING INTO clause? bool isReturningSet_; // Has isReturning_ flag queried & set. + bool refCursor_; // refCursor or not. }; diff --git a/src/njs/src/njsConnection.cpp b/src/njs/src/njsConnection.cpp index 6328b4ae..5ea44dfc 100644 --- a/src/njs/src/njsConnection.cpp +++ b/src/njs/src/njsConnection.cpp @@ -59,6 +59,7 @@ Persistent Connection::connectionTemplate_s; #define NJS_MAX_OUT_BIND_SIZE 200 // # of milliseconds in a day. Used to convert from/to v8::Date to Oracle/Date #define NJS_DAY2MS (24.0 * 60.0 * 60.0 * 1000.0 ) +#define NJS_PREFETCH_NON_RESULTSET 2 /*****************************************************************************/ @@ -574,16 +575,20 @@ void Connection::GetOutBindParams (unsigned short dataType, Bind* bind, switch(dataType) { case DATA_STR : - bind->type = dpi::DpiVarChar; + bind->type = dpi::DpiVarChar; break; case DATA_NUM : - bind->type = dpi::DpiDouble; - bind->maxSize = sizeof(double); + bind->type = dpi::DpiDouble; + bind->maxSize = sizeof(double); break; case DATA_DATE : bind->extvalue = (long double *) malloc ( sizeof ( long double ) ); - bind->type = dpi::DpiTimestampLTZ; - bind->maxSize = 0; + bind->type = dpi::DpiTimestampLTZ; + bind->maxSize = 0; + break; + case DATA_CURSOR : + bind->type = dpi::DpiRSet; + bind->maxSize = 0; break; default : executeBaton->error= NJSMessages::getErrorMsg(errInvalidBindDataType,2); @@ -737,6 +742,20 @@ void Connection::Async_Execute (uv_work_t *req) if (executeBaton->st == DpiStmtSelect) { + // set prefetch + if(executeBaton->getRS) + { + // prefetchRows either default or value provided by user + executeBaton->dpistmt->prefetchRows(executeBaton->prefetchRows); + } + else + { + // OCI default prefetchRows value is 1. + // Set default prefetchRows to 2 to cut down on additional + // fetch round-trip for single row non-resultset cases + executeBaton->dpistmt->prefetchRows(NJS_PREFETCH_NON_RESULTSET); + } + executeBaton->dpistmt->execute(0, executeBaton->autoCommit); const dpi::MetaData* meta = executeBaton->dpistmt->getMetaData(); executeBaton->numCols = executeBaton->dpistmt->numCols(); @@ -748,6 +767,10 @@ void Connection::Async_Execute (uv_work_t *req) goto exitAsyncExecute; Connection::DoDefines(executeBaton, meta, executeBaton->numCols); + /* If any errors while creating define structures, bail out */ + if ( !executeBaton->error.empty() ) + goto exitAsyncExecute; + Connection::DoFetch(executeBaton); } else @@ -811,9 +834,9 @@ void Connection::Async_Execute (uv_work_t *req) } } if ( executeBaton->dpistmt ) - { + { executeBaton->dpistmt->release (); - } + } } catch (dpi::Exception& e) { @@ -849,9 +872,6 @@ void Connection::PrepareAndBind (eBaton* executeBaton) executeBaton->st = executeBaton->dpistmt->stmtType (); executeBaton->stmtIsReturning = executeBaton->dpistmt->isReturning (); - // set prefetch - executeBaton->dpistmt->prefetchRows(executeBaton->prefetchRows); - if(!executeBaton->binds.empty()) { if(!executeBaton->binds[0]->key.empty()) @@ -881,6 +901,12 @@ void Connection::PrepareAndBind (eBaton* executeBaton) false, 1 ); } + // Allocate handle for Ref Cursor + if ( executeBaton->binds[index]->type == DpiRSet ) + { + executeBaton->binds[index]->value = executeBaton->dpiconn-> + getStmt(); + } // Convert v8::Date to Oracle DB Type if ( executeBaton->binds[index]->type == DpiTimestampLTZ ) @@ -923,6 +949,13 @@ void Connection::PrepareAndBind (eBaton* executeBaton) return; } + // Allocate handle for Ref Cursor + if ( executeBaton->binds[index]->type == DpiRSet ) + { + executeBaton->binds[index]->value = executeBaton->dpiconn-> + getStmt(); + } + // Allocate for OUT Binds // For DML Returning, allocation happens through callback if ( executeBaton->binds[index]->isOut && @@ -1237,15 +1270,7 @@ v8::Handle Connection::GetRows (eBaton* executeBaton) Local row = NanNew(executeBaton->numCols); for(unsigned int j = 0; j < executeBaton->numCols; j++) { - long double *dblArr = (long double *)executeBaton->defines[j].buf; - row->Set(j, Connection::GetValue( - executeBaton->defines[j].ind[i], - executeBaton->defines[j].fetchType, - (executeBaton->defines[j].fetchType == DpiTimestampLTZ ) ? - (void *) &dblArr[i] : - (void *) ((char *)(executeBaton->defines[j].buf) + - ( i * (executeBaton->defines[j].maxSize ))), - executeBaton->defines[j].len[i])); + row->Set(j, Connection::GetValue(executeBaton, true, j, i)); } rowsArray->Set(i, row); } @@ -1258,24 +1283,17 @@ v8::Handle Connection::GetRows (eBaton* executeBaton) for(unsigned int j = 0; j < executeBaton->numCols; j++) { - long double *dblArr = (long double * )executeBaton->defines[j].buf; row->Set(NanNew(executeBaton->columnNames[j].c_str(), (int) executeBaton->columnNames[j].length()), - Connection::GetValue( - executeBaton->defines[j].ind[i], - executeBaton->defines[j].fetchType, - (executeBaton->defines[j].fetchType == DpiTimestampLTZ ) ? - (void *) &dblArr[i] : - (void *) ((char *)(executeBaton->defines[j].buf) + - ( i * (executeBaton->defines[j].maxSize ))), - executeBaton->defines[j].len[i])); + Connection::GetValue(executeBaton, true, j, i)); } rowsArray->Set(i, row); } break; default : - executeBaton->error = NJSMessages::getErrorMsg(errInvalidPropertyValue, "outFormat"); + executeBaton->error = NJSMessages::getErrorMsg(errInvalidPropertyValue, + "outFormat"); goto exitGetRows; break; } @@ -1288,6 +1306,111 @@ v8::Handle Connection::GetRows (eBaton* executeBaton) DESCRIPTION Method to create handle from C++ value + PARAMETERS: + executeBaton - eBaton struct + isQuery - true if define struct is to be processed + false if bind struct is to be processed + index - column index in define array / + index in binds vector + row - row index in define->buf / + always 0 for bind->value + + RETURNS: + Handle +*/ + +Handle Connection::GetValue ( eBaton *executeBaton, + bool isQuery, + unsigned int index, + unsigned int row ) +{ + NanEscapableScope(); + + if(isQuery) + { + // SELECT queries + Define *define = &(executeBaton->defines[index]); + long double *dblArr = (long double *)define->buf; + return NanEscapeScope( Connection::GetValueCommon( + define->ind[row], + define->fetchType, + (define->fetchType == DpiTimestampLTZ ) ? + (void *) &dblArr[row] : + (void *) ((char *)(define->buf) + + ( row * (define->maxSize ))), + define->len[row] )); + } + else + { + // DML, PL/SQL execution + Bind *bind = executeBaton->binds[index]; + if(executeBaton->stmtIsReturning) + { + return NanEscapeScope(Connection::GetArrayValue ( + executeBaton->binds[index], + (unsigned long)executeBaton->rowsAffected ) ); + } + else if(bind->type == DpiRSet) + { + return NanEscapeScope ( Connection::GetValueRefCursor ( + executeBaton, bind )); + } + else + { + return NanEscapeScope ( Connection::GetValueCommon ( + bind->ind[row], + bind->type, + (bind->type == DpiTimestampLTZ ) ? + bind->extvalue : bind->value, + bind->len[row] )); + } + } +} + +/*****************************************************************************/ +/* + DESCRIPTION + Method to create handle for refcursor + + PARAMETERS: + executeBaton - struct eBaton + bind - struct bind + + RETURNS: + Handle +*/ +Handle Connection::GetValueRefCursor ( eBaton *executeBaton, + Bind *bind ) +{ + NanEscapableScope(); + Handle resultSet; + Handle value; + + if(bind->ind[0] != -1) + { + resultSet = NanNew(ResultSet::resultSetTemplate_s)-> + GetFunction() ->NewInstance(); + (ObjectWrap::Unwrap (resultSet))-> + setResultSet( (dpi::Stmt*)(bind->value), + executeBaton->dpienv, + executeBaton->njsconn, + executeBaton->outFormat ); + // set the prefetch on the cursor object + ((dpi::Stmt*)(bind->value))->prefetchRows(executeBaton->prefetchRows); + value = resultSet; + } + else + { + value = NanNull(); + } + return NanEscapeScope(value); +} + +/*****************************************************************************/ +/* + DESCRIPTION + Method to create handle from C++ value for primitive types + PARAMETERS: ind - to validate the data, type - data type of the value, @@ -1297,9 +1420,9 @@ v8::Handle Connection::GetRows (eBaton* executeBaton) RETURNS: Handle */ -v8::Handle Connection::GetValue ( short ind, unsigned short type, - void* val, DPI_BUFLEN_TYPE len, - DPI_SZ_TYPE maxSize) +Handle Connection::GetValueCommon ( short ind, + unsigned short type, + void* val, DPI_BUFLEN_TYPE len ) { NanEscapableScope(); Handle value; @@ -1422,17 +1545,12 @@ v8::Handle Connection::GetOutBinds (eBaton* executeBaton) if( executeBaton->binds[0]->key.empty() ) { // Binds as JS array - return NanEscapeScope(GetOutBindArray( executeBaton->binds, - executeBaton->numOutBinds, - executeBaton->stmtIsReturning, - (unsigned long)executeBaton->rowsAffected )); + return NanEscapeScope(GetOutBindArray( executeBaton )); } else { // Binds as JS object - return NanEscapeScope(GetOutBindObject( executeBaton->binds, - executeBaton->stmtIsReturning, - (unsigned long)executeBaton->rowsAffected )); + return NanEscapeScope(GetOutBindObject( executeBaton )); } } return NanUndefined(); @@ -1449,14 +1567,13 @@ v8::Handle Connection::GetOutBinds (eBaton* executeBaton) RETURNS: Outbinds array */ -v8::Handle Connection::GetOutBindArray ( std::vector &binds, - unsigned int outCount, - bool isDMLReturning, - unsigned long rowcount ) +v8::Handle Connection::GetOutBindArray ( eBaton *executeBaton ) { NanEscapableScope(); - Local arrayBinds = NanNew( outCount ); + std::vectorbinds = executeBaton->binds; + + Local arrayBinds = NanNew( executeBaton->numOutBinds ); unsigned int it = 0; for(unsigned int index = 0; index < binds.size(); index++) @@ -1464,20 +1581,7 @@ v8::Handle Connection::GetOutBindArray ( std::vector &binds, if(binds[index]->isOut) { Handle val ; - if ( !isDMLReturning ) - { - val = Connection::GetValue ( - binds[index]->ind[0], - binds[index]->type, - (binds[index]->type == DpiTimestampLTZ ) ? - binds[index]->extvalue : - binds[index]->value, - binds[index]->len[0] ) ; - } - else - { - val = Connection::GetArrayValue ( binds[index], rowcount ); - } + val = Connection::GetValue ( executeBaton, false, index ); arrayBinds->Set( it, val ); it ++; } @@ -1496,10 +1600,10 @@ v8::Handle Connection::GetOutBindArray ( std::vector &binds, RETURNS: Outbinds object */ -v8::Handle Connection::GetOutBindObject ( std::vector &binds, - bool isDMLReturning, - unsigned long rowcount ) +v8::Handle Connection::GetOutBindObject ( eBaton *executeBaton ) { + std::vectorbinds = executeBaton->binds; + NanEscapableScope(); Local objectBinds = NanNew(); for(unsigned int index = 0; index < binds.size(); index++) @@ -1510,21 +1614,7 @@ v8::Handle Connection::GetOutBindObject ( std::vector &binds, binds[index]->key.erase(binds[index]->key.begin()); - if ( !isDMLReturning ) - { - val = Connection::GetValue ( - binds[index]->ind[0], - binds[index]->type, - (binds[index]->type == DpiTimestampLTZ ) ? - binds[index]->extvalue : binds[index]->value, - binds[index]->len[0], - binds[index]->maxSize ); - } - else - { - val = Connection::GetArrayValue ( binds[index], rowcount ) ; - } - + val = Connection::GetValue ( executeBaton, false, index ); objectBinds->Set( NanNew ( binds[index]->key.c_str(), (int) binds[index]->key.length() ), val ); diff --git a/src/njs/src/njsConnection.h b/src/njs/src/njsConnection.h index 20ecc6f6..7826d7bd 100644 --- a/src/njs/src/njsConnection.h +++ b/src/njs/src/njsConnection.h @@ -149,15 +149,16 @@ typedef struct eBaton for( unsigned int index = 0 ;index < binds.size(); index++ ) { // donot free date value here, it is done in DateTimeArray functions - if(binds[index]->type != DpiTimestampLTZ ) + if(binds[index]->type != DpiTimestampLTZ ) { - if( binds[index]->value ) + // do not free refcursor type. + if( binds[index]->value && binds[index]->type != DpiRSet ) { free(binds[index]->value); } if ( binds[index]->extvalue ) { - free ( binds[index]->value ); + free ( binds[index]->extvalue ); } if ( binds[index]->ind ) { @@ -208,6 +209,7 @@ public: static void Descr2Double ( Define* defines, unsigned int numCols, unsigned int rowsFetched, bool getRS ); bool isValid() { return isValid_; } + Oracledb* oracledb_; private: static NAN_METHOD(New); @@ -274,17 +276,22 @@ private: static void GetOutBindParams (unsigned short dataType, Bind* bind, eBaton* executeBaton); static v8::Handle GetOutBinds (eBaton* executeBaton); - static v8::Handle GetOutBindArray ( std::vector &binds, - unsigned int outCount, - bool bDMLReturn = false, - unsigned long rowcount = 1); - static v8::Handle GetOutBindObject (std::vector &binds, - bool bDMLReturn = false, - unsigned long rowcount = 1); + static v8::Handle GetOutBindArray (eBaton* executeBaton); + static v8::Handle GetOutBindObject (eBaton* executeBaton); static v8::Handle GetArrayValue (Bind *bind, unsigned long count); - static v8::Handle GetValue (short ind, unsigned short type, void* val, - DPI_BUFLEN_TYPE len, - DPI_SZ_TYPE maxSize = -1); + + // to convert DB value to v8::Value + static v8::Handle GetValue (eBaton *executeBaton, + bool isQuery, + unsigned int index, + unsigned int row = 0); + // for primitive types (Number, String and Date) + static v8::Handle GetValueCommon (short ind, + unsigned short type, + void* val, DPI_BUFLEN_TYPE len); + // for refcursor + static v8::Handle GetValueRefCursor (eBaton *executeBaton, + Bind *bind); static void UpdateDateValue ( eBaton *executeBaton ); static void v8Date2OraDate ( v8::Handle, Bind *bind); @@ -302,7 +309,6 @@ private: dpi::Conn* dpiconn_; bool isValid_; - Oracledb* oracledb_; }; diff --git a/src/njs/src/njsResultSet.cpp b/src/njs/src/njsResultSet.cpp index 1967627b..d4795c50 100644 --- a/src/njs/src/njsResultSet.cpp +++ b/src/njs/src/njsResultSet.cpp @@ -59,7 +59,6 @@ using namespace node; using namespace v8; //peristent ResultSet class handle Persistent ResultSet::resultSetTemplate_s; - /*****************************************************************************/ /* DESCRIPTION @@ -71,14 +70,14 @@ Persistent ResultSet::resultSetTemplate_s; conn - njs connection outFormat - outFormat of the result set */ -void ResultSet::setResultSet ( dpi::Stmt *stmt, dpi::Env *env, +void ResultSet::setResultSet ( dpi::Stmt *stmt, dpi::Env *dpienv, Connection *conn, unsigned int outFormat ) { this->dpistmt_ = stmt; - this->dpienv_ = env; + this->dpienv_ = dpienv; this->njsconn_ = conn; this->meta_ = stmt->getMetaData(); - this->numCols_ = stmt->numCols(); + this->numCols_ = this->dpistmt_->numCols(); this->state_ = INACTIVE; this->outFormat_ = outFormat; this->fetchRowCount_ = 0; @@ -282,8 +281,8 @@ void ResultSet::GetRowsCommon(rsBaton *getRowsBaton) ebaton->columnNames = new std::string[njsRS->numCols_]; ebaton->maxRows = getRowsBaton->numRows; ebaton->dpistmt = njsRS->dpistmt_; - ebaton->dpienv = njsRS->dpienv_; ebaton->getRS = true; + ebaton->dpienv = njsRS->njsconn_->oracledb_->getDpiEnv(); ebaton->outFormat = njsRS->outFormat_; exitGetRowsCommon: diff --git a/src/njs/src/njsResultSet.h b/src/njs/src/njsResultSet.h index b51d5158..2612597c 100644 --- a/src/njs/src/njsResultSet.h +++ b/src/njs/src/njsResultSet.h @@ -101,8 +101,9 @@ public: static void Init(Handle target); - void setResultSet ( dpi::Stmt *dpistmt, dpi::Env *env, + void setResultSet ( dpi::Stmt *dpistmt, dpi::Env *dpienv, Connection* conn, unsigned int outFormat ); + // Define ResultSet Constructor static Persistent resultSetTemplate_s ; diff --git a/src/njs/src/njsUtils.h b/src/njs/src/njsUtils.h index 4be60860..deecedb2 100644 --- a/src/njs/src/njsUtils.h +++ b/src/njs/src/njsUtils.h @@ -61,26 +61,27 @@ typedef enum { DATA_UNKNOWN = -1, - DATA_STR = 1, - DATA_NUM = 2, - DATA_DATE = 3 + DATA_STR = 2001, + DATA_NUM = 2002, + DATA_DATE = 2003, + DATA_CURSOR = 2004 }DataType; // User specified bind types. typedef enum { BIND_UNKNOWN = -1, - BIND_IN = 1, - BIND_INOUT = 2, - BIND_OUT = 3 + BIND_IN = 3001, + BIND_INOUT = 3002, + BIND_OUT = 3003 }BindType; // outFormat types. typedef enum { ROWS_UNKNOWN = -1, - ROWS_ARRAY = 1, - ROWS_OBJECT = 2 + ROWS_ARRAY = 4001, + ROWS_OBJECT = 4002 }RowsType; // states