Add REF CURSOR support. Result Set tidy ups. Renumber constants.
This commit is contained in:
parent
322e447324
commit
bc6b88eefe
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -414,7 +414,6 @@ Stmt* ConnImpl::getStmt (const string &sql)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
|
|
@ -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_)
|
||||
|
|
|
@ -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.
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ Persistent<FunctionTemplate> 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<v8::Value> Connection::GetRows (eBaton* executeBaton)
|
|||
Local<Array> row = NanNew<v8::Array>(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<v8::Value> 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<v8::String>(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<v8::Value> 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<Value> 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<Value> Connection::GetValueRefCursor ( eBaton *executeBaton,
|
||||
Bind *bind )
|
||||
{
|
||||
NanEscapableScope();
|
||||
Handle<Object> resultSet;
|
||||
Handle<Value> value;
|
||||
|
||||
if(bind->ind[0] != -1)
|
||||
{
|
||||
resultSet = NanNew(ResultSet::resultSetTemplate_s)->
|
||||
GetFunction() ->NewInstance();
|
||||
(ObjectWrap::Unwrap<ResultSet> (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<v8::Value> Connection::GetRows (eBaton* executeBaton)
|
|||
RETURNS:
|
||||
Handle
|
||||
*/
|
||||
v8::Handle<v8::Value> Connection::GetValue ( short ind, unsigned short type,
|
||||
void* val, DPI_BUFLEN_TYPE len,
|
||||
DPI_SZ_TYPE maxSize)
|
||||
Handle<Value> Connection::GetValueCommon ( short ind,
|
||||
unsigned short type,
|
||||
void* val, DPI_BUFLEN_TYPE len )
|
||||
{
|
||||
NanEscapableScope();
|
||||
Handle<Value> value;
|
||||
|
@ -1422,17 +1545,12 @@ v8::Handle<v8::Value> 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<v8::Value> Connection::GetOutBinds (eBaton* executeBaton)
|
|||
RETURNS:
|
||||
Outbinds array
|
||||
*/
|
||||
v8::Handle<v8::Value> Connection::GetOutBindArray ( std::vector<Bind*> &binds,
|
||||
unsigned int outCount,
|
||||
bool isDMLReturning,
|
||||
unsigned long rowcount )
|
||||
v8::Handle<v8::Value> Connection::GetOutBindArray ( eBaton *executeBaton )
|
||||
{
|
||||
NanEscapableScope();
|
||||
|
||||
Local<Array> arrayBinds = NanNew<v8::Array>( outCount );
|
||||
std::vector<Bind*>binds = executeBaton->binds;
|
||||
|
||||
Local<Array> arrayBinds = NanNew<v8::Array>( executeBaton->numOutBinds );
|
||||
|
||||
unsigned int it = 0;
|
||||
for(unsigned int index = 0; index < binds.size(); index++)
|
||||
|
@ -1464,20 +1581,7 @@ v8::Handle<v8::Value> Connection::GetOutBindArray ( std::vector<Bind*> &binds,
|
|||
if(binds[index]->isOut)
|
||||
{
|
||||
Handle<Value> 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<v8::Value> Connection::GetOutBindArray ( std::vector<Bind*> &binds,
|
|||
RETURNS:
|
||||
Outbinds object
|
||||
*/
|
||||
v8::Handle<v8::Value> Connection::GetOutBindObject ( std::vector<Bind*> &binds,
|
||||
bool isDMLReturning,
|
||||
unsigned long rowcount )
|
||||
v8::Handle<v8::Value> Connection::GetOutBindObject ( eBaton *executeBaton )
|
||||
{
|
||||
std::vector<Bind*>binds = executeBaton->binds;
|
||||
|
||||
NanEscapableScope();
|
||||
Local<Object> objectBinds = NanNew<v8::Object>();
|
||||
for(unsigned int index = 0; index < binds.size(); index++)
|
||||
|
@ -1510,21 +1614,7 @@ v8::Handle<v8::Value> Connection::GetOutBindObject ( std::vector<Bind*> &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<v8::String> ( binds[index]->key.c_str(),
|
||||
(int) binds[index]->key.length() ),
|
||||
val );
|
||||
|
|
|
@ -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<v8::Value> GetOutBinds (eBaton* executeBaton);
|
||||
static v8::Handle<v8::Value> GetOutBindArray ( std::vector<Bind*> &binds,
|
||||
unsigned int outCount,
|
||||
bool bDMLReturn = false,
|
||||
unsigned long rowcount = 1);
|
||||
static v8::Handle<v8::Value> GetOutBindObject (std::vector<Bind*> &binds,
|
||||
bool bDMLReturn = false,
|
||||
unsigned long rowcount = 1);
|
||||
static v8::Handle<v8::Value> GetOutBindArray (eBaton* executeBaton);
|
||||
static v8::Handle<v8::Value> GetOutBindObject (eBaton* executeBaton);
|
||||
static v8::Handle<v8::Value> GetArrayValue (Bind *bind, unsigned long count);
|
||||
static v8::Handle<v8::Value> 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<v8::Value> GetValue (eBaton *executeBaton,
|
||||
bool isQuery,
|
||||
unsigned int index,
|
||||
unsigned int row = 0);
|
||||
// for primitive types (Number, String and Date)
|
||||
static v8::Handle<v8::Value> GetValueCommon (short ind,
|
||||
unsigned short type,
|
||||
void* val, DPI_BUFLEN_TYPE len);
|
||||
// for refcursor
|
||||
static v8::Handle<v8::Value> GetValueRefCursor (eBaton *executeBaton,
|
||||
Bind *bind);
|
||||
static void UpdateDateValue ( eBaton *executeBaton );
|
||||
static void v8Date2OraDate ( v8::Handle<v8::Value>, Bind *bind);
|
||||
|
||||
|
@ -302,7 +309,6 @@ private:
|
|||
|
||||
dpi::Conn* dpiconn_;
|
||||
bool isValid_;
|
||||
Oracledb* oracledb_;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ using namespace node;
|
|||
using namespace v8;
|
||||
//peristent ResultSet class handle
|
||||
Persistent<FunctionTemplate> ResultSet::resultSetTemplate_s;
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
@ -71,14 +70,14 @@ Persistent<FunctionTemplate> 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:
|
||||
|
|
|
@ -101,8 +101,9 @@ public:
|
|||
|
||||
static void Init(Handle<Object> 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<FunctionTemplate> resultSetTemplate_s ;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue