diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7dab5e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +build \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7b6a8e3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,18 @@ +{ + "name": "sqlanywhere", + "version": "1.0.24", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "help": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/help/-/help-3.0.2.tgz", + "integrity": "sha1-luGQ1KCkU7icLLSwWrOOOo+f2t0=" + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + } + } +} diff --git a/package.json b/package.json index 088d5d2..faf4836 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "SQL ANYWHERE", "name": "sqlanywhere", "description": "SQL Anywhere JavaScript Driver.", - "version": "1.0.24", + "version": "2.0.0", "repository": { "url": "https://github.com/sqlanywhere/node-sqlanywhere" }, @@ -15,6 +15,6 @@ }, "dependencies": { "help": "^3.0.2", - "nan": "2.11.1" + "nan": "^2.14.0" } } diff --git a/src/h/sqlany_utils.h b/src/h/sqlany_utils.h index 928b1cc..908b5d2 100644 --- a/src/h/sqlany_utils.h +++ b/src/h/sqlany_utils.h @@ -157,7 +157,7 @@ void callBack( std::string * str, #endif bool getBindParameters( std::vector &execData - , Handle arg + , Local arg , std::vector ¶ms , unsigned &num_rows ); diff --git a/src/sqlanywhere.cpp b/src/sqlanywhere.cpp index df1018a..10416e7 100644 --- a/src/sqlanywhere.cpp +++ b/src/sqlanywhere.cpp @@ -3,6 +3,7 @@ // *************************************************************************** #include "nodever_cover.h" #include "sqlany_utils.h" +#include "nan.h" #if !v010 @@ -454,7 +455,7 @@ NODE_API_FUNC( Connection::exec ) return; } - String::Utf8Value param0( args[0]->ToString() ); + Nan::Utf8String param0( args[0]->ToString(isolate) ); executeBaton *baton = new executeBaton(); baton->obj = obj; @@ -641,7 +642,7 @@ NODE_API_FUNC( Connection::prepare ) return; } - String::Utf8Value param0( args[0]->ToString() ); + Nan::Utf8String param0( args[0]->ToString(isolate) ); prepareBaton *baton = new prepareBaton(); baton->obj = obj; @@ -797,6 +798,7 @@ NODE_API_FUNC( Connection::connect ) /**********************************/ { Isolate *isolate = args.GetIsolate(); + Local context = isolate->GetCurrentContext(); HandleScope scope( isolate ); int num_args = args.Length(); Connection *obj; @@ -856,26 +858,26 @@ NODE_API_FUNC( Connection::connect ) baton->sqlca_connection = sqlca_connection; if( sqlca_connection ) { - baton->sqlca = (void *)(long)args[0]->NumberValue(); + baton->sqlca = (void *)(long)args[0]->NumberValue(context).ToChecked(); } else { Local localArg = Local::New( isolate, obj->_arg ); if( localArg->Length() > 0 ) { - String::Utf8Value param0( localArg ); + Nan::Utf8String param0( localArg ); baton->conn_string = std::string(*param0); } else { baton->conn_string = std::string(); } if( arg_is_string ) { - String::Utf8Value param0( args[0]->ToString() ); + Nan::Utf8String param0( args[0]->ToString(isolate) ); baton->conn_string.append( ";" ); baton->conn_string.append(*param0); } else if( arg_is_object ) { Persistent arg_string; - HashToString( args[0]->ToObject(), arg_string ); + HashToString( args[0]->ToObject(context).ToLocalChecked(), arg_string ); Local local_arg_string = Local::New( isolate, arg_string ); - String::Utf8Value param0( local_arg_string ); + Nan::Utf8String param0( local_arg_string ); baton->conn_string.append( ";" ); baton->conn_string.append(*param0); arg_string.Reset(); diff --git a/src/utils.cpp b/src/utils.cpp index 319ddd6..b378f56 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -82,6 +82,7 @@ void throwError( int code ) { Isolate *isolate = Isolate::GetCurrent(); std::string message; + getErrorMsg( code, message ); isolate->ThrowException( Exception::Error( String::NewFromUtf8( isolate, message.c_str() ) ) ); @@ -194,49 +195,51 @@ void callBack( std::string * str, } static bool getWideBindParameters( std::vector &execData, - Handle arg, + Local arg, std::vector & params, unsigned &num_rows ) /*********************************************************************************/ { - Handle rows = Handle::Cast( arg ); - num_rows = rows->Length(); + Isolate* isolate = Isolate::GetCurrent(); + Local context = isolate->GetCurrentContext(); + Local rows = Local::Cast( arg ); + num_rows = rows->Length(); - Handle row0 = Handle::Cast( rows->Get(0) ); - unsigned num_cols = row0->Length(); - unsigned c; + Local row0 = Local::Cast( rows->Get(0) ); + unsigned num_cols = row0->Length(); + unsigned c; - if( num_cols == 0 ) { + if( num_cols == 0 ) { // if an empty array was passed in, we still need ExecuteData ExecuteData *ex = new ExecuteData; execData.push_back( ex ); return true; - } + } - // Make sure that each array in the list has the same number and types - // of values - for( unsigned int r = 1; r < num_rows; r++ ) { - Handle row = Handle::Cast( rows->Get(r) ); + // Make sure that each array in the list has the same number and types + // of values + for( unsigned int r = 1; r < num_rows; r++ ) { + Local row = Local::Cast( rows->Get(r) ); for( c = 0; c < num_cols; c++ ) { - Handle val0 = row0->Get(c); - Handle val = row->Get(c); + Local val0 = row0->Get(c); + Local val = row->Get(c); - if( ( val0->IsInt32() || val0->IsNumber() ) && + if( ( val0->IsInt32() || val0->IsNumber() ) && ( !val->IsInt32() && !val->IsNumber() && !val->IsNull() ) ) { return false; - } - if( val0->IsString() && + } + if( val0->IsString() && !val->IsString() && !val->IsNull() ) { return false; - } - if( Buffer::HasInstance( val0 ) && + } + if( Buffer::HasInstance( val0 ) && !Buffer::HasInstance( val ) && !val->IsNull() ) { return false; - } + } } - } + } - for( c = 0; c < num_cols; c++ ) { + for( c = 0; c < num_cols; c++ ) { a_sqlany_bind_param param; memset( ¶m, 0, sizeof( param ) ); @@ -254,66 +257,69 @@ static bool getWideBindParameters( std::vector &execData, param.value.is_address = false; if( row0->Get(c)->IsInt32() || row0->Get(c)->IsNumber() ) { - param.value.type = A_DOUBLE; - param.value.buffer = (char *)( param_double ); + param.value.type = A_DOUBLE; + param.value.buffer = (char *)( param_double ); } else if( row0->Get(c)->IsString() ) { - param.value.type = A_STRING; - param.value.buffer = (char *)char_arr; - param.value.length = len; - param.value.is_address = true; + param.value.type = A_STRING; + param.value.buffer = (char *)char_arr; + param.value.length = len; + param.value.is_address = true; } else if( Buffer::HasInstance( row0->Get(c) ) ) { - param.value.type = A_BINARY; - param.value.buffer = (char *)char_arr; - param.value.length = len; - param.value.is_address = true; - + param.value.type = A_BINARY; + param.value.buffer = (char *)char_arr; + param.value.length = len; + param.value.is_address = true; + } else if( row0->Get(c)->IsNull() ) { } else{ - return false; + return false; } for( unsigned int r = 0; r < num_rows; r++ ) { - Handle bind_params = Handle::Cast( rows->Get(r) ); + Local bind_params = Local::Cast( rows->Get(r) ); - is_null[r] = false; - if( bind_params->Get(c)->IsInt32() || bind_params->Get(c)->IsNumber() ) { - param_double[r] = bind_params->Get(c)->NumberValue(); + is_null[r] = false; + if( bind_params->Get(c)->IsInt32() || bind_params->Get(c)->IsNumber() ) { + param_double[r] = bind_params->Get(c)->NumberValue(context).ToChecked(); - } else if( bind_params->Get(c)->IsString() ) { - String::Utf8Value paramValue( bind_params->Get(c)->ToString() ); + } else if( bind_params->Get(c)->IsString() ) { + Nan::Utf8String paramValue( bind_params->Get(c)->ToString(isolate) ); const char* param_string = (*paramValue); len[r] = (size_t)paramValue.length(); char *param_char = new char[len[r] + 1]; char_arr[r] = param_char; memcpy( param_char, param_string, len[r] + 1 ); - } else if( Buffer::HasInstance( bind_params->Get(c) ) ) { + } else if( Buffer::HasInstance( bind_params->Get(c) ) ) { len[r] = Buffer::Length( bind_params->Get(c) ); char *param_char = new char[len[r]]; char_arr[r] = param_char; memcpy( param_char, Buffer::Data( bind_params->Get(c) ), len[r] ); - } else if( bind_params->Get(c)->IsNull() ) { + } else if( bind_params->Get(c)->IsNull() ) { is_null[r] = true; - } + } } - + params.push_back( param ); - } + } return true; } bool getBindParameters( std::vector &execData, - Handle arg, + Local arg, std::vector & params, unsigned &num_rows ) /*************************************************************************/ { - Handle bind_params = Handle::Cast( arg ); + + Isolate* isolate = Isolate::GetCurrent(); + Local context = isolate->GetCurrentContext(); + Local bind_params = Local::Cast( arg ); if( bind_params->Length() == 0 ) { // if an empty array was passed in, we still need ExecuteData @@ -336,20 +342,20 @@ bool getBindParameters( std::vector &execData, if( bind_params->Get(i)->IsInt32() ) { int *param_int = new int; - *param_int = bind_params->Get(i)->Int32Value(); + *param_int = bind_params->Get(i)->Int32Value(context).ToChecked(); ex->addInt( param_int ); param.value.buffer = (char *)( param_int ); param.value.type = A_VAL32; } else if( bind_params->Get(i)->IsNumber() ) { double *param_double = new double; - *param_double = bind_params->Get(i)->NumberValue(); // Remove Round off Error + *param_double = bind_params->Get(i)->NumberValue(context).ToChecked(); // Remove Round off Error ex->addNum( param_double ); param.value.buffer = (char *)( param_double ); param.value.type = A_DOUBLE; } else if( bind_params->Get(i)->IsString() ) { - String::Utf8Value paramValue( bind_params->Get(i)->ToString() ); + Nan::Utf8String paramValue( bind_params->Get(i)->ToString(context).ToLocalChecked() ); const char* param_string = (*paramValue); size_t *len = new size_t; *len = (size_t)paramValue.length(); @@ -755,6 +761,7 @@ void StmtObject::Init( Isolate *isolate ) /***************************************/ { HandleScope scope(isolate); + Local context = isolate->GetCurrentContext(); // Prepare constructor template Local tpl = FunctionTemplate::New( isolate, New ); tpl->SetClassName( String::NewFromUtf8( isolate, "StmtObject" ) ); @@ -764,7 +771,7 @@ void StmtObject::Init( Isolate *isolate ) NODE_SET_PROTOTYPE_METHOD( tpl, "exec", exec ); NODE_SET_PROTOTYPE_METHOD( tpl, "drop", drop ); NODE_SET_PROTOTYPE_METHOD( tpl, "getMoreResults", getMoreResults ); - constructor.Reset( isolate, tpl->GetFunction() ); + constructor.Reset( isolate, tpl->GetFunction(context).ToLocalChecked() ); } void StmtObject::New( const FunctionCallbackInfo &args ) @@ -791,7 +798,7 @@ void StmtObject::CreateNewInstance( const FunctionCallbackInfo & args, Isolate *isolate = args.GetIsolate(); HandleScope scope(isolate); const unsigned argc = 1; - Handle argv[argc] = { args[0] }; + Local argv[argc] = { args[0] }; Localcons = Local::New( isolate, constructor ); #if NODE_MAJOR_VERSION >= 10 Local env = isolate->GetCurrentContext(); @@ -829,15 +836,16 @@ void HashToString( Local obj, Persistent &ret ) { Isolate *isolate = Isolate::GetCurrent(); HandleScope scope(isolate); - Local props = obj->GetOwnPropertyNames(); - int length = props->Length(); + Local context = isolate->GetCurrentContext(); + MaybeLocal props = obj->GetOwnPropertyNames(context); + int length = props.ToLocalChecked()->Length(); std::string params = ""; bool first = true; for( int i = 0; i < length; i++ ) { - Local key = props->Get(i).As(); + Local key = props.ToLocalChecked()->Get(i).As(); Local val = obj->Get(key).As(); - String::Utf8Value key_utf8( key ); - String::Utf8Value val_utf8( val ); + String::Utf8Value key_utf8( isolate, key ); + String::Utf8Value val_utf8( isolate, val ); if( !first ) { params += ";"; } @@ -899,6 +907,7 @@ Connection::Connection( const FunctionCallbackInfo &args ) /***************************************************************/ { Isolate *isolate = args.GetIsolate(); + Local context = isolate->GetCurrentContext(); HandleScope scope( isolate ); uv_mutex_init(&conn_mutex); conn = NULL; @@ -911,14 +920,14 @@ Connection::Connection( const FunctionCallbackInfo &args ) if( args.Length() == 1 ) { //CheckArgType( args[0] ); if( args[0]->IsString() ) { - Local str = args[0]->ToString(); - int string_len = str->Utf8Length(); + MaybeLocal str = args[0]->ToString(context); + int string_len = str.ToLocalChecked()->Utf8Length(isolate); char *buf = new char[string_len+1]; - str->WriteUtf8( buf ); + str.ToLocalChecked()->WriteUtf8(isolate, buf ); _arg.Reset( isolate, String::NewFromUtf8( isolate, buf ) ); delete [] buf; } else if( args[0]->IsObject() ) { - HashToString( args[0]->ToObject(), _arg ); + HashToString(args[0]->ToObject(context).ToLocalChecked(), _arg); } else if( !args[0]->IsUndefined() && !args[0]->IsNull() ) { throwError( JS_ERR_INVALID_ARGUMENTS ); } else { @@ -977,6 +986,7 @@ void Connection::Init( Isolate *isolate ) /***************************************/ { HandleScope scope( isolate ); + Local context = isolate->GetCurrentContext(); // Prepare constructor template Local tpl = FunctionTemplate::New( isolate, New ); tpl->SetClassName( String::NewFromUtf8( isolate, "Connection" ) ); @@ -992,7 +1002,7 @@ void Connection::Init( Isolate *isolate ) NODE_SET_PROTOTYPE_METHOD( tpl, "rollback", rollback ); NODE_SET_PROTOTYPE_METHOD( tpl, "connected", connected ); - constructor.Reset( isolate, tpl->GetFunction() ); + constructor.Reset( isolate, tpl->GetFunction(context).ToLocalChecked() ); } void Connection::New( const FunctionCallbackInfo &args ) @@ -1026,7 +1036,7 @@ void Connection::NewInstance( const FunctionCallbackInfo &args ) Isolate *isolate = args.GetIsolate(); HandleScope scope( isolate ); const unsigned argc = 1; - Handle argv[argc] = { args[0] }; + Local argv[argc] = { args[0] }; Local cons = Local::New( isolate, constructor ); #if NODE_MAJOR_VERSION >= 10 Local env = isolate->GetCurrentContext();