Skip to content

Commit 1e8d7c5

Browse files
committed
Initial Result Set code
1 parent e4a84b5 commit 1e8d7c5

14 files changed

+816
-34
lines changed

binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"src/njs/src/njsOracle.cpp",
77
"src/njs/src/njsPool.cpp",
88
"src/njs/src/njsConnection.cpp",
9+
"src/njs/src/njsResultSet.cpp",
910
"src/njs/src/njsMessages.cpp",
1011
"src/dpi/src/dpiEnv.cpp",
1112
"src/dpi/src/dpiEnvImpl.cpp",

src/dpi/include/dpiStmt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ class Stmt
146146
// properties
147147
virtual DpiStmtType stmtType() const = 0;
148148

149+
virtual void prefetchRows ( int prefetchRows ) = 0;
150+
149151
virtual bool isDML() const = 0 ;
150152

151153
virtual bool isReturning() = 0 ;

src/dpi/src/dpiStmtImpl.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,34 @@ unsigned int StmtImpl::numCols ()
196196
}
197197

198198

199+
/*****************************************************************************/
200+
/*
201+
DESCRIPTION
202+
Prefetch Rows set on statement handle
203+
204+
PARAMETERS
205+
prefetchRows count
206+
207+
RETURNS
208+
NONE
209+
210+
*/
211+
void StmtImpl::prefetchRows (int prefetchRows)
212+
{
213+
ociCall(OCIAttrSet(stmth_, OCI_HTYPE_STMT, &prefetchRows, 0,
214+
OCI_ATTR_PREFETCH_ROWS, errh_), errh_);
215+
}
216+
217+
199218

200219

201220
/*****************************************************************************/
202221
/*
203222
DESCRIPTION
204-
bind the variable(s) by pdpition
223+
bind the variable(s) by position
205224
206225
PARAMETERS
207-
pos - pdpition of the variable 1 based
226+
pos - position of the variable 1 based
208227
type - Data type
209228
buf (IN/OUT) - data buffer for the variable's value
210229
bufSize - size of the buffer

src/dpi/src/dpiStmtImpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class StmtImpl : public Stmt
6666
virtual DpiStmtType stmtType () const;
6767
virtual DPI_SZ_TYPE rowsAffected () const;
6868
virtual unsigned int numCols() ;
69+
virtual void prefetchRows( int prefetchRows ) ;
6970
virtual unsigned int rowsFetched () const ;
7071

7172
// Methods

src/njs/src/njsConnection.cpp

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
*****************************************************************************/
5050

5151
#include "njsConnection.h"
52+
#include "njsResultSet.h"
5253
#include <stdlib.h>
5354
#include <iostream>
5455
using namespace std;
@@ -340,10 +341,12 @@ NAN_METHOD(Connection::Execute)
340341
NJSString (executeBaton->sql, sql);
341342

342343
executeBaton->maxRows = connection->oracledb_->getMaxRows();
344+
executeBaton->prefetchRows = connection->oracledb_->getPrefetchRows();
343345
executeBaton->outFormat = connection->oracledb_->getOutFormat();
344346
executeBaton->autoCommit = connection->oracledb_->getAutoCommit();
345347
executeBaton->dpienv = connection->oracledb_->getDpiEnv();
346348
executeBaton->dpiconn = connection->dpiconn_;
349+
executeBaton->njsconn = connection;
347350

348351
if(args.Length() > 2)
349352
{
@@ -411,8 +414,12 @@ void Connection::ProcessOptions (_NAN_METHOD_ARGS, unsigned int index,
411414
options = args[index]->ToObject();
412415
NJS_GET_UINT_FROM_JSON ( executeBaton->maxRows, executeBaton->error,
413416
options, "maxRows", 2, exitProcessOptions );
417+
NJS_GET_UINT_FROM_JSON ( executeBaton->prefetchRows, executeBaton->error,
418+
options, "prefetchRows", 2, exitProcessOptions );
414419
NJS_GET_UINT_FROM_JSON ( executeBaton->outFormat, executeBaton->error,
415420
options, "outFormat", 2, exitProcessOptions );
421+
NJS_GET_BOOL_FROM_JSON ( executeBaton->getRS, executeBaton->error,
422+
options, "resultSet", 2, exitProcessOptions );
416423
NJS_GET_BOOL_FROM_JSON ( executeBaton->autoCommit, executeBaton->error,
417424
options, "autoCommit", 2, exitProcessOptions );
418425
}
@@ -731,10 +738,22 @@ void Connection::Async_Execute (uv_work_t *req)
731738
if (executeBaton->st == DpiStmtSelect)
732739
{
733740
executeBaton->dpistmt->execute(0, executeBaton->autoCommit);
734-
Connection::GetDefines(executeBaton);
741+
const dpi::MetaData* meta = executeBaton->dpistmt->getMetaData();
742+
executeBaton->numCols = executeBaton->dpistmt->numCols();
743+
executeBaton->columnNames = new std::string[executeBaton->numCols];
744+
Connection::metaData( executeBaton->columnNames, meta,
745+
executeBaton->numCols );
746+
if( executeBaton->getRS ) goto exitAsyncExecute;
747+
Connection::GetDefines(executeBaton, meta, executeBaton->numCols);
735748
}
736749
else
737750
{
751+
if( executeBaton->getRS )
752+
{
753+
executeBaton->error = NJSMessages::getErrorMsg(
754+
errInvalidNonQueryExecution );
755+
goto exitAsyncExecute;
756+
}
738757
executeBaton->dpistmt->execute(1, executeBaton->autoCommit);
739758
executeBaton->rowsAffected = executeBaton->dpistmt->rowsAffected();
740759

@@ -797,7 +816,7 @@ void Connection::Async_Execute (uv_work_t *req)
797816
// In Case of DML Returning, if the buffer is small, and if the callback
798817
// is called multiple times, an ORA error 24343 was reported. Converting
799818
// that error to errInsufficientBufferForBinds.
800-
if ( !executeBaton->stmtIsReturning &&
819+
if ( !executeBaton->stmtIsReturning &&
801820
(e.errnum() != 24343) )
802821
{
803822
executeBaton->error = std::string(e.what ());
@@ -826,6 +845,9 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
826845
executeBaton->st = executeBaton->dpistmt->stmtType ();
827846
executeBaton->stmtIsReturning = executeBaton->dpistmt->isReturning ();
828847

848+
if(executeBaton->getRS && executeBaton->prefetchRows > -1)
849+
executeBaton->dpistmt->prefetchRows(executeBaton->prefetchRows);
850+
829851
if(!executeBaton->binds.empty())
830852
{
831853
if(!executeBaton->binds[0]->key.empty())
@@ -930,6 +952,24 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
930952
}
931953
}
932954

955+
/*****************************************************************************/
956+
/*
957+
DESCRIPTION
958+
get meta data into baton
959+
960+
PARAMETERS:
961+
string arrat, metaData, numCols
962+
*/
963+
void Connection::metaData ( std::string* names, const dpi::MetaData* meta,
964+
unsigned int numCols )
965+
{
966+
for (unsigned int i = 0; i < numCols; i++)
967+
{
968+
names[i] = std::string( (const char*)meta[i].colName,
969+
meta[i].colNameLen );
970+
}
971+
}
972+
933973
/*****************************************************************************/
934974
/*
935975
DESCRIPTION
@@ -939,19 +979,13 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
939979
PARAMETERS:
940980
eBaton struct
941981
*/
942-
void Connection::GetDefines (eBaton* executeBaton)
982+
void Connection::GetDefines ( eBaton* executeBaton, const dpi::MetaData* meta,
983+
unsigned int numCols )
943984
{
944-
unsigned int numCols = executeBaton->dpistmt->numCols();
945985
Define *defines = new Define[numCols];
946-
const dpi::MetaData* meta = executeBaton->dpistmt->getMetaData();
947-
executeBaton->columnNames = new std::string[numCols];
948986

949987
for (unsigned int i = 0; i < numCols; i++)
950988
{
951-
952-
executeBaton->columnNames[i] = std::string((const char*)meta[i].colName,
953-
meta[i].colNameLen );
954-
955989
switch(meta[i].dbType)
956990
{
957991
case dpi::DpiNumber :
@@ -993,8 +1027,22 @@ void Connection::GetDefines (eBaton* executeBaton)
9931027
executeBaton->defines = defines;
9941028
executeBaton->numCols = numCols;
9951029
executeBaton->rowsFetched = executeBaton->dpistmt->rowsFetched();
1030+
Connection::descr2Dbl (executeBaton->defines, numCols,
1031+
executeBaton->rowsFetched,
1032+
executeBaton->getRS);
1033+
}
1034+
1035+
/*****************************************************************************/
1036+
/*
1037+
DESCRIPTION
1038+
Special processing for datetime, as it is obtained as descriptors
9961039
997-
/* Special processing for datetime, as it is obtained as descriptors */
1040+
PARAMETERS:
1041+
Define struct, numCols
1042+
*/
1043+
void Connection::descr2Dbl( Define* defines, unsigned int numCols,
1044+
unsigned int rowsFetched, bool getRS )
1045+
{
9981046
for (unsigned int col = 0; col < numCols; col ++ )
9991047
{
10001048
if ( defines[col].dttmarr )
@@ -1003,15 +1051,18 @@ void Connection::GetDefines (eBaton* executeBaton)
10031051

10041052
defines[col].buf =
10051053
dblArr = (long double *)malloc ( sizeof ( long double ) *
1006-
executeBaton->rowsFetched );
1054+
rowsFetched );
10071055

1008-
for ( int row = 0; row < (int) executeBaton->rowsFetched; row ++ )
1056+
for ( int row = 0; row < (int) rowsFetched; row ++ )
10091057
{
10101058
dblArr[row] = defines[col].dttmarr->getDateTime (row) * NJS_DAY2MS;
10111059
}
10121060
defines[col].buf = (void *) dblArr;
1013-
defines[col].dttmarr->release ();
1014-
defines[col].extbuf = NULL;
1061+
if ( !getRS )
1062+
{
1063+
defines[col].dttmarr->release ();
1064+
defines[col].extbuf = NULL;
1065+
}
10151066
}
10161067
}
10171068

@@ -1055,7 +1106,23 @@ void Connection::Async_AfterExecute(uv_work_t *req)
10551106
argv[1] = NanUndefined();
10561107
goto exitAsyncAfterExecute;
10571108
}
1058-
result->Set(NanNew<v8::String>("rows"), rowArray);//, v8::ReadOnly);
1109+
if( executeBaton->getRS )
1110+
{
1111+
result->Set(NanNew<v8::String>("rows"), NanUndefined());
1112+
Handle<Object> resultSet = NanNew(ResultSet::resultSetTemplate_s)->
1113+
GetFunction() ->NewInstance();
1114+
(ObjectWrap::Unwrap<ResultSet> (resultSet))->
1115+
setResultSet( executeBaton->dpistmt,
1116+
executeBaton->dpienv,
1117+
executeBaton->njsconn,
1118+
executeBaton->outFormat );
1119+
result->Set(NanNew<v8::String>("resultSet"), resultSet );
1120+
}
1121+
else
1122+
{
1123+
result->Set(NanNew<v8::String>("rows"), rowArray);
1124+
result->Set(NanNew<v8::String>("resultSet"), NanUndefined());
1125+
}
10591126
result->Set(NanNew<v8::String>("outBinds"),NanUndefined());
10601127
result->Set(NanNew<v8::String>("rowsAffected"), NanUndefined());
10611128
result->Set(NanNew<v8::String>("metaData"), Connection::GetMetaData(

src/njs/src/njsConnection.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ using namespace v8;
6363
using namespace node;
6464
using namespace dpi;
6565

66+
67+
class Connection;
6668
/**
6769
* Structure used for binds
6870
**/
@@ -113,8 +115,11 @@ typedef struct eBaton
113115
std::string error;
114116
dpi::Env* dpienv;
115117
dpi::Conn* dpiconn;
118+
Connection *njsconn;
116119
DPI_SZ_TYPE rowsAffected;
117120
unsigned int maxRows;
121+
int prefetchRows;
122+
bool getRS;
118123
bool autoCommit;
119124
unsigned int rowsFetched;
120125
unsigned int outFormat;
@@ -128,9 +133,10 @@ typedef struct eBaton
128133
Define *defines;
129134
Persistent<Function> cb;
130135

131-
eBaton() : sql(""), error(""), dpienv(NULL), dpiconn(NULL),
132-
rowsAffected(0), maxRows(0), autoCommit(false),
133-
rowsFetched(0), outFormat(0), numCols(0), dpistmt(NULL),
136+
eBaton() : sql(""), error(""), dpienv(NULL), dpiconn(NULL), njsconn(NULL),
137+
rowsAffected(0), maxRows(0), prefetchRows(0),
138+
getRS(false), autoCommit(false), rowsFetched(0),
139+
outFormat(0), numCols(0), dpistmt(NULL),
134140
st(DpiStmtUnknown), stmtIsReturning (false), numOutBinds(0),
135141
columnNames(NULL), defines(NULL)
136142
{}
@@ -171,7 +177,7 @@ typedef struct eBaton
171177
}
172178
if( columnNames )
173179
delete [] columnNames;
174-
if( defines )
180+
if( defines && !getRS )
175181
{
176182
for( unsigned int i=0; i<numCols; i++ )
177183
{
@@ -192,6 +198,15 @@ class Connection: public ObjectWrap
192198
// Define Connection Constructor
193199
static Persistent<FunctionTemplate> connectionTemplate_s;
194200
static void Init (Handle<Object> target);
201+
static Handle<Value> GetRows (eBaton* executeBaton);
202+
static Handle<Value> GetMetaData (std::string* columnNames,
203+
unsigned int numCols);
204+
static void GetDefines ( eBaton* executeBaton, const dpi::MetaData*,
205+
unsigned int numCols );
206+
static void metaData ( std::string*, const dpi::MetaData*, unsigned int );
207+
static void descr2Dbl ( Define* defines, unsigned int numCols,
208+
unsigned int rowsFetched, bool getRS );
209+
bool getIsValid() { return isValid_; }
195210

196211
private:
197212
static NAN_METHOD(New);
@@ -241,7 +256,6 @@ class Connection: public ObjectWrap
241256

242257

243258
static void PrepareAndBind (eBaton* executeBaton);
244-
static void GetDefines (eBaton* executeBaton);
245259
static void ProcessBinds (_NAN_METHOD_ARGS, unsigned int index,
246260
eBaton* executeBaton);
247261
static void ProcessOptions (_NAN_METHOD_ARGS, unsigned int index,
@@ -266,9 +280,6 @@ class Connection: public ObjectWrap
266280
static v8::Handle<v8::Value> GetOutBindObject (std::vector<Bind*> &binds,
267281
bool bDMLReturn = false,
268282
unsigned long rowcount = 1);
269-
static v8::Handle<v8::Value> GetRows (eBaton* executeBaton);
270-
static v8::Handle<v8::Value> GetMetaData (std::string* columnNames,
271-
unsigned int numCols);
272283
static v8::Handle<v8::Value> GetArrayValue (Bind *bind, unsigned long count);
273284
static v8::Handle<v8::Value> GetValue (short ind, unsigned short type, void* val,
274285
DPI_BUFLEN_TYPE len,

src/njs/src/njsMessages.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ static const char *errMsg[] =
5050
"NJS-013: invalid bind direction",
5151
"NJS-014: %s is a read-only property",
5252
"NJS-015: %s is a write-only property",
53-
"NJS-016: Buffer is too small for OUT binds"
53+
"NJS-016: buffer is too small for OUT binds",
54+
"NJS-017: concurrent operations on resultSet are not allowed",
55+
"NJS-018: invalid result set",
56+
"NJS-019: getResultSet set for non-query execution",
5457
};
5558

5659
string NJSMessages::getErrorMsg ( NJSErrorType err, ... )

src/njs/src/njsMessages.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ typedef enum
5050
errReadOnly,
5151
errWriteOnly,
5252
errInsufficientBufferForBinds,
53+
errBusyResultSet,
54+
errInvalidResultSet,
55+
errInvalidNonQueryExecution,
5356

5457
// New ones should be added here
5558

0 commit comments

Comments
 (0)