Initial Result Set code
This commit is contained in:
parent
e4a84b520d
commit
1e8d7c558c
|
@ -6,6 +6,7 @@
|
|||
"src/njs/src/njsOracle.cpp",
|
||||
"src/njs/src/njsPool.cpp",
|
||||
"src/njs/src/njsConnection.cpp",
|
||||
"src/njs/src/njsResultSet.cpp",
|
||||
"src/njs/src/njsMessages.cpp",
|
||||
"src/dpi/src/dpiEnv.cpp",
|
||||
"src/dpi/src/dpiEnvImpl.cpp",
|
||||
|
|
|
@ -146,6 +146,8 @@ public:
|
|||
// properties
|
||||
virtual DpiStmtType stmtType() const = 0;
|
||||
|
||||
virtual void prefetchRows ( int prefetchRows ) = 0;
|
||||
|
||||
virtual bool isDML() const = 0 ;
|
||||
|
||||
virtual bool isReturning() = 0 ;
|
||||
|
|
|
@ -196,15 +196,34 @@ unsigned int StmtImpl::numCols ()
|
|||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Prefetch Rows set on statement handle
|
||||
|
||||
PARAMETERS
|
||||
prefetchRows count
|
||||
|
||||
RETURNS
|
||||
NONE
|
||||
|
||||
*/
|
||||
void StmtImpl::prefetchRows (int prefetchRows)
|
||||
{
|
||||
ociCall(OCIAttrSet(stmth_, OCI_HTYPE_STMT, &prefetchRows, 0,
|
||||
OCI_ATTR_PREFETCH_ROWS, errh_), errh_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
bind the variable(s) by pdpition
|
||||
bind the variable(s) by position
|
||||
|
||||
PARAMETERS
|
||||
pos - pdpition of the variable 1 based
|
||||
pos - position of the variable 1 based
|
||||
type - Data type
|
||||
buf (IN/OUT) - data buffer for the variable's value
|
||||
bufSize - size of the buffer
|
||||
|
|
|
@ -66,6 +66,7 @@ public:
|
|||
virtual DpiStmtType stmtType () const;
|
||||
virtual DPI_SZ_TYPE rowsAffected () const;
|
||||
virtual unsigned int numCols() ;
|
||||
virtual void prefetchRows( int prefetchRows ) ;
|
||||
virtual unsigned int rowsFetched () const ;
|
||||
|
||||
// Methods
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "njsConnection.h"
|
||||
#include "njsResultSet.h"
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
@ -340,10 +341,12 @@ NAN_METHOD(Connection::Execute)
|
|||
NJSString (executeBaton->sql, sql);
|
||||
|
||||
executeBaton->maxRows = connection->oracledb_->getMaxRows();
|
||||
executeBaton->prefetchRows = connection->oracledb_->getPrefetchRows();
|
||||
executeBaton->outFormat = connection->oracledb_->getOutFormat();
|
||||
executeBaton->autoCommit = connection->oracledb_->getAutoCommit();
|
||||
executeBaton->dpienv = connection->oracledb_->getDpiEnv();
|
||||
executeBaton->dpiconn = connection->dpiconn_;
|
||||
executeBaton->njsconn = connection;
|
||||
|
||||
if(args.Length() > 2)
|
||||
{
|
||||
|
@ -411,8 +414,12 @@ void Connection::ProcessOptions (_NAN_METHOD_ARGS, unsigned int index,
|
|||
options = args[index]->ToObject();
|
||||
NJS_GET_UINT_FROM_JSON ( executeBaton->maxRows, executeBaton->error,
|
||||
options, "maxRows", 2, exitProcessOptions );
|
||||
NJS_GET_UINT_FROM_JSON ( executeBaton->prefetchRows, executeBaton->error,
|
||||
options, "prefetchRows", 2, exitProcessOptions );
|
||||
NJS_GET_UINT_FROM_JSON ( executeBaton->outFormat, executeBaton->error,
|
||||
options, "outFormat", 2, exitProcessOptions );
|
||||
NJS_GET_BOOL_FROM_JSON ( executeBaton->getRS, executeBaton->error,
|
||||
options, "resultSet", 2, exitProcessOptions );
|
||||
NJS_GET_BOOL_FROM_JSON ( executeBaton->autoCommit, executeBaton->error,
|
||||
options, "autoCommit", 2, exitProcessOptions );
|
||||
}
|
||||
|
@ -731,10 +738,22 @@ void Connection::Async_Execute (uv_work_t *req)
|
|||
if (executeBaton->st == DpiStmtSelect)
|
||||
{
|
||||
executeBaton->dpistmt->execute(0, executeBaton->autoCommit);
|
||||
Connection::GetDefines(executeBaton);
|
||||
const dpi::MetaData* meta = executeBaton->dpistmt->getMetaData();
|
||||
executeBaton->numCols = executeBaton->dpistmt->numCols();
|
||||
executeBaton->columnNames = new std::string[executeBaton->numCols];
|
||||
Connection::metaData( executeBaton->columnNames, meta,
|
||||
executeBaton->numCols );
|
||||
if( executeBaton->getRS ) goto exitAsyncExecute;
|
||||
Connection::GetDefines(executeBaton, meta, executeBaton->numCols);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( executeBaton->getRS )
|
||||
{
|
||||
executeBaton->error = NJSMessages::getErrorMsg(
|
||||
errInvalidNonQueryExecution );
|
||||
goto exitAsyncExecute;
|
||||
}
|
||||
executeBaton->dpistmt->execute(1, executeBaton->autoCommit);
|
||||
executeBaton->rowsAffected = executeBaton->dpistmt->rowsAffected();
|
||||
|
||||
|
@ -826,6 +845,9 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
|
|||
executeBaton->st = executeBaton->dpistmt->stmtType ();
|
||||
executeBaton->stmtIsReturning = executeBaton->dpistmt->isReturning ();
|
||||
|
||||
if(executeBaton->getRS && executeBaton->prefetchRows > -1)
|
||||
executeBaton->dpistmt->prefetchRows(executeBaton->prefetchRows);
|
||||
|
||||
if(!executeBaton->binds.empty())
|
||||
{
|
||||
if(!executeBaton->binds[0]->key.empty())
|
||||
|
@ -930,6 +952,24 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
|
|||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
get meta data into baton
|
||||
|
||||
PARAMETERS:
|
||||
string arrat, metaData, numCols
|
||||
*/
|
||||
void Connection::metaData ( std::string* names, const dpi::MetaData* meta,
|
||||
unsigned int numCols )
|
||||
{
|
||||
for (unsigned int i = 0; i < numCols; i++)
|
||||
{
|
||||
names[i] = std::string( (const char*)meta[i].colName,
|
||||
meta[i].colNameLen );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
@ -939,19 +979,13 @@ void Connection::PrepareAndBind (eBaton* executeBaton)
|
|||
PARAMETERS:
|
||||
eBaton struct
|
||||
*/
|
||||
void Connection::GetDefines (eBaton* executeBaton)
|
||||
void Connection::GetDefines ( eBaton* executeBaton, const dpi::MetaData* meta,
|
||||
unsigned int numCols )
|
||||
{
|
||||
unsigned int numCols = executeBaton->dpistmt->numCols();
|
||||
Define *defines = new Define[numCols];
|
||||
const dpi::MetaData* meta = executeBaton->dpistmt->getMetaData();
|
||||
executeBaton->columnNames = new std::string[numCols];
|
||||
|
||||
for (unsigned int i = 0; i < numCols; i++)
|
||||
{
|
||||
|
||||
executeBaton->columnNames[i] = std::string((const char*)meta[i].colName,
|
||||
meta[i].colNameLen );
|
||||
|
||||
switch(meta[i].dbType)
|
||||
{
|
||||
case dpi::DpiNumber :
|
||||
|
@ -993,8 +1027,22 @@ void Connection::GetDefines (eBaton* executeBaton)
|
|||
executeBaton->defines = defines;
|
||||
executeBaton->numCols = numCols;
|
||||
executeBaton->rowsFetched = executeBaton->dpistmt->rowsFetched();
|
||||
Connection::descr2Dbl (executeBaton->defines, numCols,
|
||||
executeBaton->rowsFetched,
|
||||
executeBaton->getRS);
|
||||
}
|
||||
|
||||
/* Special processing for datetime, as it is obtained as descriptors */
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Special processing for datetime, as it is obtained as descriptors
|
||||
|
||||
PARAMETERS:
|
||||
Define struct, numCols
|
||||
*/
|
||||
void Connection::descr2Dbl( Define* defines, unsigned int numCols,
|
||||
unsigned int rowsFetched, bool getRS )
|
||||
{
|
||||
for (unsigned int col = 0; col < numCols; col ++ )
|
||||
{
|
||||
if ( defines[col].dttmarr )
|
||||
|
@ -1003,15 +1051,18 @@ void Connection::GetDefines (eBaton* executeBaton)
|
|||
|
||||
defines[col].buf =
|
||||
dblArr = (long double *)malloc ( sizeof ( long double ) *
|
||||
executeBaton->rowsFetched );
|
||||
rowsFetched );
|
||||
|
||||
for ( int row = 0; row < (int) executeBaton->rowsFetched; row ++ )
|
||||
for ( int row = 0; row < (int) rowsFetched; row ++ )
|
||||
{
|
||||
dblArr[row] = defines[col].dttmarr->getDateTime (row) * NJS_DAY2MS;
|
||||
}
|
||||
defines[col].buf = (void *) dblArr;
|
||||
defines[col].dttmarr->release ();
|
||||
defines[col].extbuf = NULL;
|
||||
if ( !getRS )
|
||||
{
|
||||
defines[col].dttmarr->release ();
|
||||
defines[col].extbuf = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1055,7 +1106,23 @@ void Connection::Async_AfterExecute(uv_work_t *req)
|
|||
argv[1] = NanUndefined();
|
||||
goto exitAsyncAfterExecute;
|
||||
}
|
||||
result->Set(NanNew<v8::String>("rows"), rowArray);//, v8::ReadOnly);
|
||||
if( executeBaton->getRS )
|
||||
{
|
||||
result->Set(NanNew<v8::String>("rows"), NanUndefined());
|
||||
Handle<Object> resultSet = NanNew(ResultSet::resultSetTemplate_s)->
|
||||
GetFunction() ->NewInstance();
|
||||
(ObjectWrap::Unwrap<ResultSet> (resultSet))->
|
||||
setResultSet( executeBaton->dpistmt,
|
||||
executeBaton->dpienv,
|
||||
executeBaton->njsconn,
|
||||
executeBaton->outFormat );
|
||||
result->Set(NanNew<v8::String>("resultSet"), resultSet );
|
||||
}
|
||||
else
|
||||
{
|
||||
result->Set(NanNew<v8::String>("rows"), rowArray);
|
||||
result->Set(NanNew<v8::String>("resultSet"), NanUndefined());
|
||||
}
|
||||
result->Set(NanNew<v8::String>("outBinds"),NanUndefined());
|
||||
result->Set(NanNew<v8::String>("rowsAffected"), NanUndefined());
|
||||
result->Set(NanNew<v8::String>("metaData"), Connection::GetMetaData(
|
||||
|
|
|
@ -63,6 +63,8 @@ using namespace v8;
|
|||
using namespace node;
|
||||
using namespace dpi;
|
||||
|
||||
|
||||
class Connection;
|
||||
/**
|
||||
* Structure used for binds
|
||||
**/
|
||||
|
@ -113,8 +115,11 @@ typedef struct eBaton
|
|||
std::string error;
|
||||
dpi::Env* dpienv;
|
||||
dpi::Conn* dpiconn;
|
||||
Connection *njsconn;
|
||||
DPI_SZ_TYPE rowsAffected;
|
||||
unsigned int maxRows;
|
||||
int prefetchRows;
|
||||
bool getRS;
|
||||
bool autoCommit;
|
||||
unsigned int rowsFetched;
|
||||
unsigned int outFormat;
|
||||
|
@ -128,9 +133,10 @@ typedef struct eBaton
|
|||
Define *defines;
|
||||
Persistent<Function> cb;
|
||||
|
||||
eBaton() : sql(""), error(""), dpienv(NULL), dpiconn(NULL),
|
||||
rowsAffected(0), maxRows(0), autoCommit(false),
|
||||
rowsFetched(0), outFormat(0), numCols(0), dpistmt(NULL),
|
||||
eBaton() : sql(""), error(""), dpienv(NULL), dpiconn(NULL), njsconn(NULL),
|
||||
rowsAffected(0), maxRows(0), prefetchRows(0),
|
||||
getRS(false), autoCommit(false), rowsFetched(0),
|
||||
outFormat(0), numCols(0), dpistmt(NULL),
|
||||
st(DpiStmtUnknown), stmtIsReturning (false), numOutBinds(0),
|
||||
columnNames(NULL), defines(NULL)
|
||||
{}
|
||||
|
@ -171,7 +177,7 @@ typedef struct eBaton
|
|||
}
|
||||
if( columnNames )
|
||||
delete [] columnNames;
|
||||
if( defines )
|
||||
if( defines && !getRS )
|
||||
{
|
||||
for( unsigned int i=0; i<numCols; i++ )
|
||||
{
|
||||
|
@ -192,6 +198,15 @@ public:
|
|||
// Define Connection Constructor
|
||||
static Persistent<FunctionTemplate> connectionTemplate_s;
|
||||
static void Init (Handle<Object> target);
|
||||
static Handle<Value> GetRows (eBaton* executeBaton);
|
||||
static Handle<Value> GetMetaData (std::string* columnNames,
|
||||
unsigned int numCols);
|
||||
static void GetDefines ( eBaton* executeBaton, const dpi::MetaData*,
|
||||
unsigned int numCols );
|
||||
static void metaData ( std::string*, const dpi::MetaData*, unsigned int );
|
||||
static void descr2Dbl ( Define* defines, unsigned int numCols,
|
||||
unsigned int rowsFetched, bool getRS );
|
||||
bool getIsValid() { return isValid_; }
|
||||
|
||||
private:
|
||||
static NAN_METHOD(New);
|
||||
|
@ -241,7 +256,6 @@ private:
|
|||
|
||||
|
||||
static void PrepareAndBind (eBaton* executeBaton);
|
||||
static void GetDefines (eBaton* executeBaton);
|
||||
static void ProcessBinds (_NAN_METHOD_ARGS, unsigned int index,
|
||||
eBaton* executeBaton);
|
||||
static void ProcessOptions (_NAN_METHOD_ARGS, unsigned int index,
|
||||
|
@ -266,9 +280,6 @@ private:
|
|||
static v8::Handle<v8::Value> GetOutBindObject (std::vector<Bind*> &binds,
|
||||
bool bDMLReturn = false,
|
||||
unsigned long rowcount = 1);
|
||||
static v8::Handle<v8::Value> GetRows (eBaton* executeBaton);
|
||||
static v8::Handle<v8::Value> GetMetaData (std::string* columnNames,
|
||||
unsigned int numCols);
|
||||
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,
|
||||
|
|
|
@ -50,7 +50,10 @@ static const char *errMsg[] =
|
|||
"NJS-013: invalid bind direction",
|
||||
"NJS-014: %s is a read-only property",
|
||||
"NJS-015: %s is a write-only property",
|
||||
"NJS-016: Buffer is too small for OUT binds"
|
||||
"NJS-016: buffer is too small for OUT binds",
|
||||
"NJS-017: concurrent operations on resultSet are not allowed",
|
||||
"NJS-018: invalid result set",
|
||||
"NJS-019: getResultSet set for non-query execution",
|
||||
};
|
||||
|
||||
string NJSMessages::getErrorMsg ( NJSErrorType err, ... )
|
||||
|
|
|
@ -50,6 +50,9 @@ typedef enum
|
|||
errReadOnly,
|
||||
errWriteOnly,
|
||||
errInsufficientBufferForBinds,
|
||||
errBusyResultSet,
|
||||
errInvalidResultSet,
|
||||
errInvalidNonQueryExecution,
|
||||
|
||||
// New ones should be added here
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "njsOracle.h"
|
||||
#include "njsConnection.h"
|
||||
#include "njsPool.h"
|
||||
#include "njsResultSet.h"
|
||||
#include "njsMessages.h"
|
||||
//peristent Oracledb class handle
|
||||
Persistent<FunctionTemplate> Oracledb::oracledbTemplate_s;
|
||||
|
@ -63,6 +64,7 @@ Persistent<FunctionTemplate> Oracledb::oracledbTemplate_s;
|
|||
#define POOL_MAX 4
|
||||
#define POOL_INCR 1
|
||||
#define POOL_TIMEOUT 60
|
||||
#define PREFETCH_ROWS -1
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
|
@ -80,6 +82,7 @@ Oracledb::Oracledb()
|
|||
poolMin_ = POOL_MIN;
|
||||
poolIncrement_ = POOL_INCR;
|
||||
poolTimeout_ = POOL_TIMEOUT;
|
||||
prefetchRows_ = PREFETCH_ROWS;
|
||||
connClass_ = "";
|
||||
externalAuth_ = false;
|
||||
}
|
||||
|
@ -356,6 +359,32 @@ NAN_SETTER(Oracledb::SetStmtCacheSize)
|
|||
NJS_SET_PROP_UINT(oracledb->stmtCacheSize_, value, "stmtCacheSize");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Get Accessor of prefetchRows property
|
||||
*/
|
||||
NAN_PROPERTY_GETTER(Oracledb::GetPrefetchRows)
|
||||
{
|
||||
NanScope();
|
||||
Oracledb* oracledb = ObjectWrap::Unwrap<Oracledb>(args.Holder());
|
||||
Local<Integer> value = NanNew<v8::Integer>(oracledb->prefetchRows_);
|
||||
NanReturnValue(value);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Set Accessor of prefetchRows property
|
||||
*/
|
||||
NAN_SETTER(Oracledb::SetPrefetchRows)
|
||||
{
|
||||
NanScope();
|
||||
Oracledb* oracledb = ObjectWrap::Unwrap<Oracledb>(args.Holder());
|
||||
NJS_SET_PROP_UINT(oracledb->prefetchRows_, value, "prefetchRows");
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
@ -769,6 +798,7 @@ extern "C"
|
|||
Oracledb::Init(target);
|
||||
Connection::Init(target);
|
||||
Pool::Init(target);
|
||||
ResultSet::Init(target);
|
||||
}
|
||||
|
||||
NODE_MODULE(oracledb, init)
|
||||
|
|
|
@ -94,6 +94,7 @@ class Oracledb: public ObjectWrap
|
|||
unsigned int getPoolMax () const { return poolMax_; }
|
||||
unsigned int getPoolIncrement () const { return poolIncrement_; }
|
||||
unsigned int getPoolTimeout () const { return poolTimeout_; }
|
||||
unsigned int getPrefetchRows () const { return prefetchRows_; }
|
||||
const std::string& getConnectionClass () const { return connClass_; }
|
||||
|
||||
|
||||
|
@ -126,6 +127,7 @@ private:
|
|||
static NAN_PROPERTY_GETTER(GetVersion);
|
||||
static NAN_PROPERTY_GETTER(GetConnectionClass);
|
||||
static NAN_PROPERTY_GETTER(GetExternalAuth);
|
||||
static NAN_PROPERTY_GETTER(GetPrefetchRows);
|
||||
|
||||
// Define Setter Accessors to Properties
|
||||
static NAN_SETTER(SetPoolMin);
|
||||
|
@ -139,6 +141,7 @@ private:
|
|||
static NAN_SETTER(SetVersion);
|
||||
static NAN_SETTER(SetConnectionClass);
|
||||
static NAN_SETTER(SetExternalAuth);
|
||||
static NAN_SETTER(SetPrefetchRows);
|
||||
|
||||
Oracledb();
|
||||
~Oracledb();
|
||||
|
@ -149,6 +152,7 @@ private:
|
|||
unsigned int maxRows_;
|
||||
|
||||
unsigned int stmtCacheSize_;
|
||||
int prefetchRows_;
|
||||
|
||||
unsigned int poolMin_;
|
||||
unsigned int poolMax_;
|
||||
|
|
|
@ -158,6 +158,8 @@ NAN_METHOD(Pool::New)
|
|||
*/
|
||||
Handle<Value> Pool::getPoolProperty(Pool* njsPool, unsigned int poolProperty)
|
||||
{
|
||||
NanScope();
|
||||
|
||||
if(!njsPool->isValid_)
|
||||
{
|
||||
string msg = NJSMessages::getErrorMsg(errInvalidPool);
|
||||
|
|
|
@ -0,0 +1,486 @@
|
|||
/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* You may not use the identified files except in compliance with the Apache
|
||||
* License, Version 2.0 (the "License.")
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file uses NAN:
|
||||
*
|
||||
* Copyright (c) 2015 NAN contributors
|
||||
*
|
||||
* NAN contributors listed at https://github.com/rvagg/nan#contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* NAME
|
||||
* njsResultSet.cpp
|
||||
*
|
||||
* DESCRIPTION
|
||||
* ResultSet class implementation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include "node.h"
|
||||
#include <string>
|
||||
#include "njsResultSet.h"
|
||||
#include "njsConnection.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace node;
|
||||
using namespace v8;
|
||||
//peristent ResultSet class handle
|
||||
Persistent<FunctionTemplate> ResultSet::resultSetTemplate_s;
|
||||
|
||||
ResultSet::ResultSet(){}
|
||||
ResultSet::~ResultSet(){}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Store the config in pool instance.
|
||||
*/
|
||||
void ResultSet::setResultSet ( dpi::Stmt *stmt, dpi::Env *env,
|
||||
Connection *conn, unsigned int outFormat )
|
||||
{
|
||||
this->dpistmt_ = stmt;
|
||||
this->dpienv_ = env;
|
||||
this->njsconn_ = conn;
|
||||
this->meta_ = stmt->getMetaData();
|
||||
this->numCols_ = stmt->numCols();
|
||||
this->state_ = INACTIVE;
|
||||
this->outFormat_ = outFormat;
|
||||
this->bufferSize_ = 0;
|
||||
this->rsEmpty_ = false;
|
||||
this->fetchBuffers_ = NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Init function of the ResultSet class.
|
||||
Initiates and maps the functions and properties of ResultSet class.
|
||||
*/
|
||||
void ResultSet::Init(Handle<Object> target)
|
||||
{
|
||||
NanScope();
|
||||
Local<FunctionTemplate> temp = NanNew<FunctionTemplate>(New);
|
||||
temp->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
temp->SetClassName(NanNew<v8::String>("ResultSet"));
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(temp, "close", Close);
|
||||
NODE_SET_PROTOTYPE_METHOD(temp, "getRow", GetRows);
|
||||
NODE_SET_PROTOTYPE_METHOD(temp, "getRows", GetRows);
|
||||
|
||||
temp->InstanceTemplate()->SetAccessor(
|
||||
NanNew<v8::String>("metaData"),
|
||||
ResultSet::GetMetaData,
|
||||
ResultSet::SetMetaData );
|
||||
|
||||
NanAssignPersistent( resultSetTemplate_s, temp);
|
||||
target->Set(NanNew<v8::String>("ResultSet"),temp->GetFunction());
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Invoked when new of connection is called from JS
|
||||
*/
|
||||
NAN_METHOD(ResultSet::New)
|
||||
{
|
||||
NanScope();
|
||||
|
||||
ResultSet *resultSet = new ResultSet();
|
||||
resultSet->Wrap(args.This());
|
||||
|
||||
NanReturnValue(args.This());
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Get Accessor of metaData Property
|
||||
*/
|
||||
NAN_PROPERTY_GETTER(ResultSet::GetMetaData)
|
||||
{
|
||||
NanScope();
|
||||
ResultSet* njsResultSet = ObjectWrap::Unwrap<ResultSet>(args.Holder());
|
||||
std::string *columnNames = new std::string[njsResultSet->numCols_];
|
||||
Connection::metaData ( columnNames, njsResultSet->meta_,
|
||||
njsResultSet->numCols_ );
|
||||
Handle<Value> meta;
|
||||
meta = Connection::GetMetaData( columnNames,
|
||||
njsResultSet->numCols_ );
|
||||
NanReturnValue(meta);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Set Accessor of metaData Property - throws error
|
||||
*/
|
||||
NAN_SETTER(ResultSet::SetMetaData)
|
||||
{
|
||||
NanScope();
|
||||
ResultSet* njsResultSet = ObjectWrap::Unwrap<ResultSet>(args.Holder());
|
||||
string msg;
|
||||
if(njsResultSet->state_ == INVALID)
|
||||
msg = NJSMessages::getErrorMsg(errInvalidResultSet);
|
||||
else
|
||||
msg = NJSMessages::getErrorMsg(errReadOnly, "metaData");
|
||||
NJS_SET_EXCEPTION(msg.c_str(), (int) msg.length());
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Get Connection method on Result Set class.
|
||||
|
||||
PARAMETERS:
|
||||
Arguments - Callback
|
||||
*/
|
||||
NAN_METHOD(ResultSet::GetRows)
|
||||
{
|
||||
NanScope();
|
||||
|
||||
Local<Function> callback;
|
||||
NJS_GET_CALLBACK ( callback, args );
|
||||
|
||||
ResultSet *njsResultSet = ObjectWrap::Unwrap<ResultSet>(args.This());
|
||||
rsBaton *getRowsBaton = new rsBaton ();
|
||||
NanAssignPersistent(getRowsBaton->cb, callback );
|
||||
|
||||
NJS_CHECK_NUMBER_OF_ARGS ( getRowsBaton->error, args, 1, 2, exitGetRows );
|
||||
if(args.Length() == 2)
|
||||
{
|
||||
NJS_GET_ARG_V8UINT ( getRowsBaton->numRows, getRowsBaton->error,
|
||||
args, 0, exitGetRows );
|
||||
}
|
||||
else
|
||||
{
|
||||
getRowsBaton->numRows = 1;
|
||||
}
|
||||
|
||||
getRowsBaton->njsRS = njsResultSet;
|
||||
getRowsBaton->ebaton = new eBaton;
|
||||
|
||||
if(!njsResultSet->njsconn_->getIsValid())
|
||||
{
|
||||
getRowsBaton->error = NJSMessages::getErrorMsg ( errInvalidConnection );
|
||||
goto exitGetRows;
|
||||
}
|
||||
if(njsResultSet->state_ == INVALID)
|
||||
{
|
||||
getRowsBaton->error = NJSMessages::getErrorMsg ( errInvalidResultSet );
|
||||
goto exitGetRows;
|
||||
}
|
||||
else if(njsResultSet->state_ == ACTIVE)
|
||||
{
|
||||
getRowsBaton->error = NJSMessages::getErrorMsg ( errBusyResultSet );
|
||||
goto exitGetRows;
|
||||
}
|
||||
|
||||
njsResultSet->state_ = ACTIVE;
|
||||
getRowsBaton->ebaton->columnNames = new std::string[njsResultSet->numCols_];
|
||||
getRowsBaton->ebaton->maxRows = getRowsBaton->numRows;
|
||||
getRowsBaton->ebaton->dpistmt = njsResultSet->dpistmt_;
|
||||
getRowsBaton->ebaton->dpienv = njsResultSet->dpienv_;
|
||||
getRowsBaton->ebaton->getRS = true;
|
||||
|
||||
exitGetRows:
|
||||
getRowsBaton->req.data = (void *)getRowsBaton;
|
||||
|
||||
uv_queue_work(uv_default_loop(), &getRowsBaton->req, Async_GetRows,
|
||||
(uv_after_work_cb)Async_AfterGetRows);
|
||||
|
||||
NanReturnUndefined();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Worker function of Get Rows method
|
||||
|
||||
PARAMETERS:
|
||||
UV queue work block
|
||||
|
||||
NOTES:
|
||||
DPI call execution.
|
||||
*/
|
||||
void ResultSet::Async_GetRows(uv_work_t *req)
|
||||
{
|
||||
rsBaton *getRowsBaton = (rsBaton*)req->data;
|
||||
ResultSet *njsRS = getRowsBaton->njsRS;
|
||||
eBaton *ebaton = getRowsBaton->ebaton;
|
||||
|
||||
if(!(getRowsBaton->error).empty()) goto exitAsyncGetRows;
|
||||
|
||||
if(njsRS->rsEmpty_)
|
||||
{
|
||||
ebaton->rowsFetched = 0;
|
||||
goto exitAsyncGetRows;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Connection::metaData( ebaton->columnNames, njsRS->meta_,
|
||||
njsRS->numCols_ );
|
||||
if( njsRS->fetchBuffers_ == NULL ||
|
||||
njsRS->bufferSize_ < getRowsBaton->numRows )
|
||||
{
|
||||
if(njsRS->fetchBuffers_ != NULL)
|
||||
{
|
||||
ResultSet::nullifyFetchBuffer(njsRS->fetchBuffers_, njsRS->numCols_);
|
||||
}
|
||||
Connection::GetDefines(ebaton, njsRS->meta_, njsRS->numCols_);
|
||||
njsRS->bufferSize_ = getRowsBaton->numRows;
|
||||
njsRS->fetchBuffers_ = ebaton->defines;
|
||||
}
|
||||
else
|
||||
{
|
||||
njsRS->dpistmt_->fetch(getRowsBaton->numRows);
|
||||
ebaton->maxRows = getRowsBaton->numRows;
|
||||
ebaton->outFormat = njsRS->outFormat_;
|
||||
ebaton->defines = njsRS->fetchBuffers_;
|
||||
ebaton->rowsFetched = njsRS->dpistmt_->rowsFetched();
|
||||
ebaton->numCols = njsRS->numCols_;
|
||||
Connection::descr2Dbl ( ebaton->defines, ebaton->numCols,
|
||||
ebaton->rowsFetched, ebaton->getRS );
|
||||
}
|
||||
if(ebaton->rowsFetched != getRowsBaton->numRows)
|
||||
njsRS->rsEmpty_ = true;
|
||||
}
|
||||
catch (dpi::Exception &e)
|
||||
{
|
||||
getRowsBaton->error = std::string (e.what());
|
||||
}
|
||||
exitAsyncGetRows:
|
||||
;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Callback function of Get Connection method
|
||||
|
||||
PARAMETERS:
|
||||
UV queue work block
|
||||
status - expected to be non-zero.
|
||||
|
||||
NOTES:
|
||||
Connection handle is formed and handed over to JS.
|
||||
*/
|
||||
void ResultSet::Async_AfterGetRows(uv_work_t *req)
|
||||
{
|
||||
NanScope();
|
||||
rsBaton *getRowsBaton = (rsBaton*)req->data;
|
||||
v8::TryCatch tc;
|
||||
Handle<Value> argv[2];
|
||||
if(!(getRowsBaton->error).empty())
|
||||
{
|
||||
argv[0] = v8::Exception::Error(NanNew<v8::String>((getRowsBaton->error).c_str()));
|
||||
argv[1] = NanUndefined();
|
||||
}
|
||||
else
|
||||
{
|
||||
getRowsBaton->njsRS->state_ = INACTIVE;
|
||||
argv[0] = NanUndefined();
|
||||
eBaton* ebaton = getRowsBaton->ebaton;
|
||||
ebaton->outFormat = getRowsBaton->njsRS->outFormat_;
|
||||
Handle<Value> rowsArray = v8::Array::New(0),
|
||||
rowsArrayValue = NanNull();
|
||||
if(ebaton->rowsFetched)
|
||||
{
|
||||
rowsArray = Connection::GetRows(ebaton);
|
||||
if(!(ebaton->error).empty())
|
||||
{
|
||||
argv[0] = v8::Exception::Error(NanNew<v8::String>((ebaton->error).c_str()));
|
||||
argv[1] = NanUndefined();
|
||||
goto exitAsyncAfterGetRows;
|
||||
}
|
||||
rowsArrayValue = Handle<Array>::Cast(rowsArray)->Get(0);
|
||||
}
|
||||
argv[1] = (getRowsBaton->numRows > 1) ? rowsArray : rowsArrayValue;
|
||||
}
|
||||
|
||||
exitAsyncAfterGetRows:
|
||||
Local<Function> callback = NanNew(getRowsBaton->cb);
|
||||
NanMakeCallback(NanGetCurrentContext()->Global(),
|
||||
callback, 2, argv);
|
||||
if(tc.HasCaught())
|
||||
{
|
||||
node::FatalException(tc);
|
||||
}
|
||||
delete getRowsBaton;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Close method
|
||||
|
||||
PARAMETERS:
|
||||
Arguments - Callback
|
||||
*/
|
||||
NAN_METHOD(ResultSet::Close)
|
||||
{
|
||||
NanScope();
|
||||
|
||||
Local<Function> callback;
|
||||
NJS_GET_CALLBACK ( callback, args );
|
||||
|
||||
ResultSet *njsResultSet = ObjectWrap::Unwrap<ResultSet>(args.This());
|
||||
rsBaton *closeBaton = new rsBaton ();
|
||||
NanAssignPersistent( closeBaton->cb, callback );
|
||||
|
||||
NJS_CHECK_NUMBER_OF_ARGS ( closeBaton->error, args, 1, 1, exitClose );
|
||||
|
||||
if(!njsResultSet->njsconn_->getIsValid())
|
||||
{
|
||||
closeBaton->error = NJSMessages::getErrorMsg ( errInvalidConnection );
|
||||
goto exitClose;
|
||||
}
|
||||
else if(njsResultSet->state_ == INVALID)
|
||||
{
|
||||
closeBaton->error = NJSMessages::getErrorMsg ( errInvalidResultSet );
|
||||
goto exitClose;
|
||||
}
|
||||
else if(njsResultSet->state_ == ACTIVE)
|
||||
{
|
||||
closeBaton->error = NJSMessages::getErrorMsg ( errBusyResultSet );
|
||||
goto exitClose;
|
||||
}
|
||||
|
||||
closeBaton->njsRS = njsResultSet;
|
||||
|
||||
exitClose:
|
||||
closeBaton->req.data = (void *)closeBaton;
|
||||
|
||||
uv_queue_work(uv_default_loop(), &closeBaton->req, Async_Close,
|
||||
(uv_after_work_cb)Async_AfterClose);
|
||||
|
||||
NanReturnUndefined();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Worker function of close.
|
||||
|
||||
PARAMETERS:
|
||||
UV queue work block
|
||||
|
||||
NOTES:
|
||||
DPI call execution.
|
||||
*/
|
||||
void ResultSet::Async_Close(uv_work_t *req)
|
||||
{
|
||||
rsBaton *closeBaton = (rsBaton*)req->data;
|
||||
if(!closeBaton->error.empty()) goto exitAsyncClose;
|
||||
|
||||
try
|
||||
{
|
||||
closeBaton-> njsRS-> dpistmt_-> release ();
|
||||
Define* fetchBuffers = closeBaton-> njsRS-> fetchBuffers_;
|
||||
unsigned int numCols = closeBaton-> njsRS-> numCols_;
|
||||
ResultSet::nullifyFetchBuffer(fetchBuffers, numCols);
|
||||
}
|
||||
catch(dpi::Exception& e)
|
||||
{
|
||||
closeBaton->error = std::string(e.what());
|
||||
}
|
||||
exitAsyncClose:
|
||||
;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Callback function of close
|
||||
|
||||
PARAMETERS:
|
||||
UV queue work block
|
||||
*/
|
||||
void ResultSet::Async_AfterClose(uv_work_t *req)
|
||||
{
|
||||
NanScope();
|
||||
rsBaton *closeBaton = (rsBaton*)req->data;
|
||||
|
||||
v8::TryCatch tc;
|
||||
|
||||
Handle<Value> argv[1];
|
||||
|
||||
if(!(closeBaton->error).empty())
|
||||
{
|
||||
argv[0] = v8::Exception::Error(NanNew<v8::String>((closeBaton->error).c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
argv[0] = NanUndefined();
|
||||
// pool is not valid after close succeeds.
|
||||
closeBaton-> njsRS-> state_ = INVALID;
|
||||
}
|
||||
Local<Function> callback = NanNew(closeBaton->cb);
|
||||
delete closeBaton;
|
||||
NanMakeCallback( NanGetCurrentContext()->Global(), callback, 1, argv );
|
||||
if(tc.HasCaught())
|
||||
{
|
||||
node::FatalException(tc);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
DESCRIPTION
|
||||
Free FetchBuffers
|
||||
|
||||
PARAMETERS:
|
||||
Fetch Buffer, numCols
|
||||
*/
|
||||
void ResultSet::nullifyFetchBuffer( Define* fetchBuffers, unsigned int numCols)
|
||||
{
|
||||
for( unsigned int i=0; i<numCols; i++ )
|
||||
{
|
||||
if ( fetchBuffers[i].dttmarr )
|
||||
{
|
||||
fetchBuffers[i].dttmarr->release ();
|
||||
fetchBuffers[i].extbuf = NULL;
|
||||
}
|
||||
free(fetchBuffers[i].buf);
|
||||
free(fetchBuffers[i].len);
|
||||
free(fetchBuffers[i].ind);
|
||||
}
|
||||
delete [] fetchBuffers;
|
||||
fetchBuffers = NULL;
|
||||
}
|
||||
|
||||
/* end of file njsPool.cpp */
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* You may not use the identified files except in compliance with the Apache
|
||||
* License, Version 2.0 (the "License.")
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file uses NAN:
|
||||
*
|
||||
* Copyright (c) 2015 NAN contributors
|
||||
*
|
||||
* NAN contributors listed at https://github.com/rvagg/nan#contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* NAME
|
||||
* njsResultSet.h
|
||||
*
|
||||
* DESCRIPTION
|
||||
* ResultSet class
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __NJSRESULTSET_H__
|
||||
#define __NJSRESULTSET_H__
|
||||
|
||||
#include "dpi.h"
|
||||
#include <node.h>
|
||||
#include "nan.h"
|
||||
#include <v8.h>
|
||||
#include <string>
|
||||
#include "njsUtils.h"
|
||||
#include "njsConnection.h"
|
||||
|
||||
using namespace v8;
|
||||
using namespace node;
|
||||
|
||||
|
||||
class ResultSet: public ObjectWrap {
|
||||
public:
|
||||
|
||||
static void Init(Handle<Object> target);
|
||||
|
||||
void setResultSet ( dpi::Stmt *dpistmt, dpi::Env *env,
|
||||
Connection* conn, unsigned int outFormat );
|
||||
// Define ResultSet Constructor
|
||||
static Persistent<FunctionTemplate> resultSetTemplate_s ;
|
||||
|
||||
private:
|
||||
|
||||
static NAN_METHOD(New);
|
||||
|
||||
// Get Rows Methods
|
||||
static NAN_METHOD(GetRows);
|
||||
static void Async_GetRows(uv_work_t *req);
|
||||
static void Async_AfterGetRows(uv_work_t *req);
|
||||
|
||||
// Close Methods
|
||||
static NAN_METHOD(Close);
|
||||
static void Async_Close(uv_work_t *req);
|
||||
static void Async_AfterClose(uv_work_t *req);
|
||||
|
||||
// Define Getter Accessors to properties
|
||||
static NAN_PROPERTY_GETTER(GetMetaData);
|
||||
|
||||
// Define Setter Accessors to properties
|
||||
static NAN_SETTER(SetMetaData);
|
||||
|
||||
static void nullifyFetchBuffer( Define* fetchBuffers,
|
||||
unsigned int numCols );
|
||||
|
||||
ResultSet();
|
||||
~ResultSet();
|
||||
|
||||
dpi::Stmt *dpistmt_;
|
||||
dpi::Env *dpienv_;
|
||||
Connection *njsconn_;
|
||||
State state_;
|
||||
bool rsEmpty_;
|
||||
|
||||
Define* fetchBuffers_;
|
||||
const dpi::MetaData *meta_;
|
||||
unsigned int numCols_;
|
||||
unsigned int bufferSize_;
|
||||
unsigned int outFormat_;
|
||||
};
|
||||
|
||||
typedef struct rsBaton
|
||||
{
|
||||
uv_work_t req;
|
||||
std::string error;
|
||||
eBaton *ebaton;
|
||||
unsigned int numRows;
|
||||
Persistent<Function> cb;
|
||||
ResultSet* njsRS;
|
||||
|
||||
rsBaton() : error(""), ebaton(NULL), numRows(0)
|
||||
{}
|
||||
|
||||
~rsBaton()
|
||||
{
|
||||
delete ebaton;
|
||||
NanDisposePersistent(cb);
|
||||
}
|
||||
|
||||
}rsBaton;
|
||||
|
||||
|
||||
#endif /* __NJSRESULTSET_H__ */
|
|
@ -83,15 +83,13 @@ typedef enum
|
|||
ROWS_OBJECT = 2
|
||||
}RowsType;
|
||||
|
||||
// args
|
||||
// states
|
||||
typedef enum
|
||||
{
|
||||
ARGS_ZERO = 0,
|
||||
ARGS_ONE = 1,
|
||||
ARGS_TWO = 2,
|
||||
ARGS_THREE = 3,
|
||||
ARGS_FOUR = 4
|
||||
}ArgsType;
|
||||
INVALID = 0,
|
||||
ACTIVE = 1,
|
||||
INACTIVE = 2,
|
||||
}State;
|
||||
|
||||
/*
|
||||
* Get the callback from the last argument.
|
||||
|
@ -179,6 +177,25 @@ typedef enum
|
|||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Get v8 uint from provided argument.
|
||||
* If it is not a uint, set the error for the given index &
|
||||
* val is nullified.
|
||||
*/
|
||||
#define NJS_GET_ARG_V8UINT( val, err, args, index, exitCode) \
|
||||
{ \
|
||||
if( args[index]->IsUint32() ) \
|
||||
{ \
|
||||
val = args[index]->ToUint32()->Value(); \
|
||||
err.clear(); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
err = NJSMessages::getErrorMsg ( errInvalidParameterType, index+1 ) ; \
|
||||
goto exitCode ; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the std string value from JSON for the given key.
|
||||
* index is the argument index in the caller.
|
||||
|
|
Loading…
Reference in New Issue