Exemplo n.º 1
0
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());
}
Exemplo n.º 2
0
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());
}
Exemplo n.º 3
0
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());
}
Exemplo n.º 4
0
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());
}
Exemplo n.º 5
0
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());
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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());
}
Exemplo n.º 9
0
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());
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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());
}
Exemplo n.º 12
0
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);
}