Handle<Value> ODBCStatement::ExecuteNonQuery(const Arguments& args) { DEBUG_PRINTF("ODBCStatement::ExecuteNonQuery\n"); HandleScope scope; REQ_FUN_ARG(0, cb); ODBCStatement* stmt = ObjectWrap::Unwrap<ODBCStatement>(args.Holder()); uv_work_t* work_req = (uv_work_t *) (calloc(1, sizeof(uv_work_t))); execute_work_data* data = (execute_work_data *) calloc(1, sizeof(execute_work_data)); data->cb = Persistent<Function>::New(cb); data->stmt = stmt; work_req->data = data; uv_queue_work( uv_default_loop(), work_req, UV_ExecuteNonQuery, (uv_after_work_cb)UV_AfterExecuteNonQuery); stmt->Ref(); return scope.Close(Undefined()); }
Handle<Value> ODBCStatement::New(const Arguments& args) { DEBUG_PRINTF("ODBCStatement::New\n"); HandleScope scope; REQ_EXT_ARG(0, js_henv); REQ_EXT_ARG(1, js_hdbc); REQ_EXT_ARG(2, js_hstmt); HENV hENV = static_cast<HENV>(js_henv->Value()); HDBC hDBC = static_cast<HDBC>(js_hdbc->Value()); HSTMT hSTMT = static_cast<HSTMT>(js_hstmt->Value()); //create a new OBCResult object ODBCStatement* stmt = new ODBCStatement(hENV, hDBC, hSTMT); //specify the buffer length stmt->bufferLength = MAX_VALUE_SIZE - 1; //initialze a buffer for this object stmt->buffer = (uint16_t *) malloc(stmt->bufferLength + 1); //TODO: make sure the malloc succeeded //set the initial colCount to 0 stmt->colCount = 0; //initialize the paramCount stmt->paramCount = 0; stmt->Wrap(args.Holder()); return scope.Close(args.Holder()); }
Handle<Value> ODBCStatement::CloseSync(const Arguments& args) { DEBUG_PRINTF("ODBCStatement::CloseSync\n"); HandleScope scope; OPT_INT_ARG(0, closeOption, SQL_DESTROY); ODBCStatement* stmt = ObjectWrap::Unwrap<ODBCStatement>(args.Holder()); DEBUG_PRINTF("ODBCStatement::CloseSync closeOption=%i\n", closeOption); if (closeOption == SQL_DESTROY) { stmt->Free(); } else { uv_mutex_lock(&ODBC::g_odbcMutex); SQLFreeStmt(stmt->m_hSTMT, closeOption); uv_mutex_unlock(&ODBC::g_odbcMutex); } return scope.Close(True()); }
void ODBCStatement::UV_AfterExecuteNonQuery(uv_work_t* req, int status) { DEBUG_PRINTF("ODBCStatement::ExecuteNonQuery\n"); execute_work_data* data = (execute_work_data *)(req->data); HandleScope scope; //an easy reference to the statment object ODBCStatement* self = data->stmt->self(); //First thing, let's check if the execution of the query returned any errors if(data->result == SQL_ERROR) { ODBC::CallbackSQLError( SQL_HANDLE_STMT, self->m_hSTMT, data->cb); } else { SQLLEN rowCount = 0; SQLRETURN ret = SQLRowCount(self->m_hSTMT, &rowCount); if (!SQL_SUCCEEDED(ret)) { rowCount = 0; } uv_mutex_lock(&ODBC::g_odbcMutex); SQLFreeStmt(self->m_hSTMT, SQL_CLOSE); uv_mutex_unlock(&ODBC::g_odbcMutex); Local<Value> args[2]; args[0] = Local<Value>::New(Null()); args[1] = Local<Value>::New(Number::New(rowCount)); TryCatch try_catch; data->cb->Call(Context::GetCurrent()->Global(), 2, args); if (try_catch.HasCaught()) { FatalException(try_catch); } } self->Unref(); data->cb.Dispose(); free(data); free(req); scope.Close(Undefined()); }
void ODBCStatement::UV_AfterExecuteDirect(uv_work_t* req, int status) { DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteDirect\n"); execute_direct_work_data* data = (execute_direct_work_data *)(req->data); HandleScope scope; //an easy reference to the statment object ODBCStatement* self = data->stmt->self(); //First thing, let's check if the execution of the query returned any errors if(data->result == SQL_ERROR) { ODBC::CallbackSQLError( SQL_HANDLE_STMT, self->m_hSTMT, data->cb); } else { Local<Value> args[3]; bool* canFreeHandle = new bool(false); args[0] = External::New(self->m_hENV); args[1] = External::New(self->m_hDBC); args[2] = External::New(self->m_hSTMT); args[3] = External::New(canFreeHandle); Persistent<Object> js_result(ODBCResult::constructor_template-> GetFunction()->NewInstance(4, args)); args[0] = Local<Value>::New(Null()); args[1] = Local<Object>::New(js_result); TryCatch try_catch; data->cb->Call(Context::GetCurrent()->Global(), 2, args); if (try_catch.HasCaught()) { FatalException(try_catch); } } self->Unref(); data->cb.Dispose(); free(data->sql); free(data); free(req); scope.Close(Undefined()); }
void ODBCStatement::UV_AfterExecuteDirect(uv_work_t* req, int status) { DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteDirect\n"); execute_direct_work_data* data = (execute_direct_work_data *)(req->data); Nan::HandleScope scope; //an easy reference to the statment object ODBCStatement* self = data->stmt->self(); //First thing, let's check if the execution of the query returned any errors if(data->result == SQL_ERROR) { ODBC::CallbackSQLError( SQL_HANDLE_STMT, self->m_hSTMT, data->cb); } else { Local<Value> info[4]; bool* canFreeHandle = new bool(false); info[0] = Nan::New<External>((void*) (intptr_t) self->m_hENV); info[1] = Nan::New<External>((void*) (intptr_t) self->m_hDBC); info[2] = Nan::New<External>((void*) (intptr_t) self->m_hSTMT); info[3] = Nan::New<External>((void*)canFreeHandle); //TODO persistent leak? Nan::Persistent<Object> js_result; js_result.Reset(Nan::New<Function>(ODBCResult::constructor)->NewInstance(4, info)); info[0] = Nan::Null(); info[1] = Nan::New(js_result); Nan::TryCatch try_catch; data->cb->Call(2, info); if (try_catch.HasCaught()) { FatalException(try_catch); } } self->Unref(); delete data->cb; free(data->sql); free(data); free(req); }
void ODBCStatement::UV_AfterExecuteNonQuery(uv_work_t* req, int status) { DEBUG_PRINTF("ODBCStatement::ExecuteNonQuery\n"); execute_work_data* data = (execute_work_data *)(req->data); Nan::HandleScope scope; //an easy reference to the statment object ODBCStatement* self = data->stmt->self(); //First thing, let's check if the execution of the query returned any errors if(data->result == SQL_ERROR) { ODBC::CallbackSQLError( SQL_HANDLE_STMT, self->m_hSTMT, data->cb); } else { SQLLEN rowCount = 0; SQLRETURN ret = SQLRowCount(self->m_hSTMT, &rowCount); if (!SQL_SUCCEEDED(ret)) { rowCount = 0; } SQLFreeStmt(self->m_hSTMT, SQL_CLOSE); Local<Value> info[2]; info[0] = Nan::Null(); info[1] = Nan::New<Number>(rowCount); Nan::TryCatch try_catch; data->cb->Call(Nan::GetCurrentContext()->Global(), 2, info); if (try_catch.HasCaught()) { FatalException(try_catch); } } self->Unref(); delete data->cb; free(data); free(req); }
Handle<Value> ODBCStatement::Prepare(const Arguments& args) { DEBUG_PRINTF("ODBCStatement::Prepare\n"); HandleScope scope; REQ_STRO_ARG(0, sql); REQ_FUN_ARG(1, cb); ODBCStatement* stmt = ObjectWrap::Unwrap<ODBCStatement>(args.Holder()); uv_work_t* work_req = (uv_work_t *) (calloc(1, sizeof(uv_work_t))); prepare_work_data* data = (prepare_work_data *) calloc(1, sizeof(prepare_work_data)); data->cb = Persistent<Function>::New(cb); data->sqlLen = sql->Length(); #ifdef UNICODE data->sql = (uint16_t *) malloc((data->sqlLen * sizeof(uint16_t)) + sizeof(uint16_t)); sql->Write((uint16_t *) data->sql); #else data->sql = (char *) malloc(data->sqlLen +1); sql->WriteUtf8((char *) data->sql); #endif data->stmt = stmt; work_req->data = data; uv_queue_work( uv_default_loop(), work_req, UV_Prepare, (uv_after_work_cb)UV_AfterPrepare); stmt->Ref(); return scope.Close(Undefined()); }
void ODBCStatement::UV_AfterBind(uv_work_t* req, int status) { DEBUG_PRINTF("ODBCStatement::UV_AfterBind\n"); bind_work_data* data = (bind_work_data *)(req->data); HandleScope scope; //an easy reference to the statment object ODBCStatement* self = data->stmt->self(); //Check if there were errors if(data->result == SQL_ERROR) { ODBC::CallbackSQLError( SQL_HANDLE_STMT, self->m_hSTMT, data->cb); } else { Local<Value> args[2]; args[0] = Local<Value>::New(Null()); args[1] = Local<Value>::New(True()); TryCatch try_catch; data->cb->Call(Context::GetCurrent()->Global(), 2, args); if (try_catch.HasCaught()) { FatalException(try_catch); } } self->Unref(); data->cb.Dispose(); free(data); free(req); scope.Close(Undefined()); }
void ODBCStatement::UV_AfterBind(uv_work_t* req, int status) { DEBUG_PRINTF("ODBCStatement::UV_AfterBind\n"); bind_work_data* data = (bind_work_data *)(req->data); Nan::HandleScope scope; //an easy reference to the statment object ODBCStatement* self = data->stmt->self(); //Check if there were errors if(data->result == SQL_ERROR) { ODBC::CallbackSQLError( SQL_HANDLE_STMT, self->m_hSTMT, data->cb); } else { Local<Value> info[2]; info[0] = Nan::Null(); info[1] = Nan::True(); Nan::TryCatch try_catch; data->cb->Call( 2, info); if (try_catch.HasCaught()) { FatalException(try_catch); } } self->Unref(); delete data->cb; free(data); free(req); }
Handle<Value> ODBCStatement::Bind(const Arguments& args) { DEBUG_PRINTF("ODBCStatement::Bind\n"); HandleScope scope; if ( !args[0]->IsArray() ) { return ThrowException(Exception::TypeError( String::New("Argument 1 must be an Array")) ); } REQ_FUN_ARG(1, cb); ODBCStatement* stmt = ObjectWrap::Unwrap<ODBCStatement>(args.Holder()); uv_work_t* work_req = (uv_work_t *) (calloc(1, sizeof(uv_work_t))); bind_work_data* data = (bind_work_data *) calloc(1, sizeof(bind_work_data)); //if we previously had parameters, then be sure to free them //before allocating more if (stmt->paramCount) { int count = stmt->paramCount; stmt->paramCount = 0; Parameter prm; //free parameter memory for (int i = 0; i < count; i++) { if (prm = stmt->params[i], prm.buffer != NULL) { switch (prm.c_type) { case SQL_C_WCHAR: free(prm.buffer); break; case SQL_C_CHAR: free(prm.buffer); break; case SQL_C_SBIGINT: delete (int64_t *)prm.buffer; break; case SQL_C_DOUBLE: delete (double *)prm.buffer; break; case SQL_C_BIT: delete (bool *)prm.buffer; break; } } } free(stmt->params); } data->stmt = stmt; DEBUG_PRINTF("ODBCStatement::Bind m_hDBC=%X m_hDBC=%X m_hSTMT=%X\n", data->stmt->m_hENV, data->stmt->m_hDBC, data->stmt->m_hSTMT ); data->cb = Persistent<Function>::New(cb); data->stmt->params = ODBC::GetParametersFromArray( Local<Array>::Cast(args[0]), &data->stmt->paramCount); work_req->data = data; uv_queue_work( uv_default_loop(), work_req, UV_Bind, (uv_after_work_cb)UV_AfterBind); stmt->Ref(); return scope.Close(Undefined()); }
void ODBCStatement::UV_AfterExecute(uv_work_t* req, int status) { DEBUG_PRINTF("ODBCStatement::UV_AfterExecute\n"); execute_work_data* data = (execute_work_data *)(req->data); Nan::HandleScope scope; int outParamCount = 0; // Non-zero tells its a SP with OUT param Local<Array> sp_result = Nan::New<Array>(); //an easy reference to the statment object ODBCStatement* stmt = data->stmt->self(); if (SQL_SUCCEEDED( data->result )) { for(int i = 0; i < stmt->paramCount; i++) { // For stored Procedure CALL if(stmt->params[i].paramtype % 2 == 0) { sp_result->Set(Nan::New(outParamCount), ODBC::GetOutputParameter(stmt->params[i])); outParamCount++; } } } if( stmt->paramCount ) { FREE_PARAMS( stmt->params, stmt->paramCount ) ; } //First thing, let's check if the execution of the query returned any errors if(data->result == SQL_ERROR) { ODBC::CallbackSQLError( SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb); } else { Local<Value> info[4]; bool* canFreeHandle = new bool(false); info[0] = Nan::New<External>((void*) (intptr_t) stmt->m_hENV); info[1] = Nan::New<External>((void*) (intptr_t) stmt->m_hDBC); info[2] = Nan::New<External>((void*) (intptr_t) stmt->m_hSTMT); info[3] = Nan::New<External>((void*)canFreeHandle); Local<Object> js_result = Nan::New<Function>(ODBCResult::constructor)->NewInstance(4, info); info[0] = Nan::Null(); info[1] = js_result; if(outParamCount) { info[2] = sp_result; // Must a CALL stmt } else info[2] = Nan::Null(); Nan::TryCatch try_catch; data->cb->Call(3, info); if (try_catch.HasCaught()) { FatalException(try_catch); } } stmt->Unref(); delete data->cb; free(data); free(req); }