Пример #1
0
/* open a connection with the same parameters used for in
 *  conHandle
 */
Con_Handle *
RS_PostgreSQL_cloneConnection(Con_Handle * conHandle)
{
    S_EVALUATOR Mgr_Handle * mgrHandle;
    RS_DBI_connection *con;
    RS_PostgreSQL_conParams *conParams;
    s_object *con_params;

    /* get connection params used to open existing connection */
    con = RS_DBI_getConnection(conHandle);
    conParams = con->conParams;

    mgrHandle = RS_DBI_asMgrHandle(MGR_ID(conHandle));


    /* Connection parameters need to be put into a 8-element character
     * vector to be passed to the RS_PostgreSQL_newConnection() function.
     */

    MEM_PROTECT(con_params = NEW_CHARACTER((Sint) 7));
    SET_CHR_EL(con_params, 0, C_S_CPY(conParams->user));
    SET_CHR_EL(con_params, 1, C_S_CPY(conParams->password));
    SET_CHR_EL(con_params, 2, C_S_CPY(conParams->host));
    SET_CHR_EL(con_params, 3, C_S_CPY(conParams->dbname));
    SET_CHR_EL(con_params, 4, C_S_CPY(conParams->port));
    SET_CHR_EL(con_params, 5, C_S_CPY(conParams->tty));
    SET_CHR_EL(con_params, 6, C_S_CPY(conParams->options));

    MEM_UNPROTECT(1);

    return RS_PostgreSQL_newConnection(mgrHandle, con_params);
}
Пример #2
0
SEXP RS_DBI_allocResultSet(SEXP conHandle) {
  RS_DBI_connection *con = RS_DBI_getConnection(conHandle);

  int indx = RS_DBI_newEntry(con->resultSetIds, con->length);
  if (indx < 0) {
    error(
      "cannot allocate a new resultSet -- maximum of %d resultSets already reached",
      con->length
    );
  }
  RS_DBI_resultSet* result = malloc(sizeof(RS_DBI_resultSet));
  if (!result) {
    RS_DBI_freeEntry(con->resultSetIds, indx);
    error("could not malloc dbResultSet");
  }
  result->drvResultSet = (void *) NULL; /* driver's own resultSet (cursor)*/
  result->statement = (char *) NULL;
  result->connectionId = CON_ID(conHandle);
  result->resultSetId = con->counter;
  result->isSelect = (int) -1;
  result->rowsAffected = (int) -1;
  result->rowCount = (int) 0;
  result->completed = (int) -1;
  result->fields = NULL;

  /* update connection's resultSet table */
  int res_id = con->counter;
  con->num_res += (int) 1;
  con->counter += (int) 1;
  con->resultSets[indx] = result;
  con->resultSetIds[indx] = res_id;

  return RS_DBI_asResHandle(MGR_ID(conHandle), CON_ID(conHandle), res_id);
}
s_object *
RS_PostgreSQL_getResult(Con_Handle * conHandle)
{
    S_EVALUATOR RS_DBI_connection * con;
    S_EVALUATOR RS_DBI_resultSet * result;
    PGconn *my_connection;
    Res_Handle *rsHandle;
    Sint res_id;
 
    PGresult *my_result;
   
    con = RS_DBI_getConnection(conHandle);
    my_connection = (PGconn *) con->drvConnection;

    if (con->num_res > 0) {
        res_id = (Sint) con->resultSetIds[0];
        rsHandle = RS_DBI_asResHandle(MGR_ID(conHandle), CON_ID(conHandle), res_id);
        result = RS_DBI_getResultSet(rsHandle);
        if (result->completed == 0) {
            RS_DBI_errorMessage("connection with pending rows, close resultSet before continuing", RS_DBI_ERROR);
        }
        else {
            RS_PostgreSQL_closeResultSet(rsHandle);
        }
    }

    my_result = PQgetResult(my_connection);
    if(my_result == NULL)
       return S_NULL_ENTRY;
    if (strcmp(PQresultErrorMessage(my_result), "") != 0) {
        char *errResultMsg;
        const char *omsg;
        size_t len;
        omsg = PQerrorMessage(my_connection);
        len = strlen(omsg);
        errResultMsg = malloc(len + 80); /* 80 should be larger than the length of "could not ..."*/
        snprintf(errResultMsg, len + 80, "could not Retrieve the result : %s", omsg);
        RS_DBI_errorMessage(errResultMsg, RS_DBI_ERROR);
        free(errResultMsg);

        /*  Frees the storage associated with a PGresult.
         *  void PQclear(PGresult *res);   */

        PQclear(my_result);

    }

    /* we now create the wrapper and copy values */
    PROTECT(rsHandle = RS_DBI_allocResultSet(conHandle));
    result = RS_DBI_getResultSet(rsHandle);
    result->drvResultSet = (void *) my_result;
    result->rowCount = (Sint) 0;
    result->isSelect = 0;
    result->rowsAffected = 0;
    result->completed = 1;
    UNPROTECT(1);
    return rsHandle;
}
Пример #4
0
SEXP RS_DBI_asConHandle(int mgrId, int conId) {
  SEXP conHandle;

  PROTECT(conHandle = NEW_INTEGER((int) 2));
  MGR_ID(conHandle) = mgrId;
  CON_ID(conHandle) = conId;
  UNPROTECT(1);
  return conHandle;
}
Пример #5
0
RMT_DEV::RMT_DEV() :
  CDevice(&scm_stFBInterfaceSpec, CStringDictionary::scm_nInvalidStringId, m_anFBConnData, m_anFBVarsData),
      MGR(g_nStringIdMGR, this){

  MGR_ID().fromString("localhost:61499");

  //we nee to manually crate this interface2internal connection as the MGR is not managed by device
  m_oDConnMGR_ID.setSource(this, 0);
  m_oDConnMGR_ID.connect(&MGR, g_nStringIdMGR_ID);
}
Пример #6
0
SEXP RS_DBI_allocConnection(SEXP mgrHandle, int max_res) {
  MySQLDriver* mgr = rmysql_driver();

  int indx = RS_DBI_newEntry(mgr->connectionIds, mgr->length);
  if (indx < 0) {
    error(
      "Cannot allocate a new connection: %d connections already opened",
      mgr->length
    );
  }

  RS_DBI_connection* con = malloc(sizeof(RS_DBI_connection));
  if (!con){
    error("Could not allocate memory for connection");
  }

  int con_id = mgr->counter;
  con->connectionId = con_id;
  con->drvConnection = (void *) NULL;
  con->conParams = (void *) NULL;
  con->counter = (int) 0;
  con->length = max_res; /* length of resultSet vector */

  /* result sets for this connection */
  con->resultSets = calloc(max_res, sizeof(RS_DBI_resultSet));
  if (!con->resultSets) {
    error("Could not allocate memory for result sets");
  }

  con->num_res = (int) 0;
  con->resultSetIds = (int *) calloc((size_t) max_res, sizeof(int));
  if (!con->resultSetIds) {
    error("Could not allocate memory for result set ids");
  }
  for(int i = 0; i < max_res; i++){
    con->resultSets[i] = (RS_DBI_resultSet *) NULL;
    con->resultSetIds[i] = -1;
  }

  /* Finally, update connection table in mgr */
  mgr->num_con += 1;
  mgr->counter += 1;
  mgr->connections[indx] = con;
  mgr->connectionIds[indx] = con_id;
  SEXP conHandle = RS_DBI_asConHandle(MGR_ID(mgrHandle), con_id);
  return conHandle;
}
Пример #7
0
Res_Handle *
RS_PostgreSQL_exec(Con_Handle * conHandle, s_object * statement)
{
    S_EVALUATOR RS_DBI_connection * con;
    Res_Handle *rsHandle;
    RS_DBI_resultSet *result;
    PGconn *my_connection;
    PGresult *my_result;

    Sint res_id, is_select=0;
    char *dyn_statement;

    con = RS_DBI_getConnection(conHandle);
    my_connection = (PGconn *) con->drvConnection;
    dyn_statement = RS_DBI_copyString(CHR_EL(statement, 0));

    /* Do we have a pending resultSet in the current connection?
     * PostgreSQL only allows  one resultSet per connection.
     */
    if (con->num_res > 0) {
        res_id = (Sint) con->resultSetIds[0];   /* recall, PostgreSQL has only 1 res */
        rsHandle = RS_DBI_asResHandle(MGR_ID(conHandle), CON_ID(conHandle), res_id);
        result = RS_DBI_getResultSet(rsHandle);
        if (result->completed == 0) {
            free(dyn_statement);
            RS_DBI_errorMessage("connection with pending rows, close resultSet before continuing", RS_DBI_ERROR);
        }
        else {
            RS_PostgreSQL_closeResultSet(rsHandle);
        }
    }

    /* Here is where we actually run the query */

    /* Example: PGresult *PQexec(PGconn *conn, const char *command); */

    my_result = PQexec(my_connection, dyn_statement);
    if (my_result == NULL) {
        char *errMsg;
        const char *omsg;
        size_t len;
        omsg = PQerrorMessage(my_connection);
        len = strlen(omsg);
        free(dyn_statement);
        errMsg = R_alloc(len + 80, 1); /* 80 should be larger than the length of "could not ..."*/
        snprintf(errMsg, len + 80,  "could not run statement: %s", omsg);
        RS_DBI_errorMessage(errMsg, RS_DBI_ERROR);
    }


    /* ExecStatusType PQresultStatus(const PGresult *res); */

    if (PQresultStatus(my_result) == PGRES_TUPLES_OK) {
        is_select = (Sint) TRUE;
    }
    if (PQresultStatus(my_result) == PGRES_COMMAND_OK) {
        is_select = (Sint) FALSE;
    }

    /* char *PQresultErrorMessage(const PGresult *res); */

    if (strcmp(PQresultErrorMessage(my_result), "") != 0) {
        char *errResultMsg;
        const char *omsg;
        size_t len;
        omsg = PQerrorMessage(my_connection);
        len = strlen(omsg);
        errResultMsg = R_alloc(len + 80, 1); /* 80 should be larger than the length of "could not ..."*/
        snprintf(errResultMsg, len + 80, "could not Retrieve the result : %s", omsg);
        /*  Frees the storage associated with a PGresult.
         *  void PQclear(PGresult *res);   */
        PQclear(my_result);
        free(dyn_statement);
        RS_DBI_errorMessage(errResultMsg, RS_DBI_ERROR);
    }

    /* we now create the wrapper and copy values */
    PROTECT(rsHandle = RS_DBI_allocResultSet(conHandle));
    result = RS_DBI_getResultSet(rsHandle);
    result->statement = RS_DBI_copyString(dyn_statement);
    result->drvResultSet = (void *) my_result;
    result->rowCount = (Sint) 0;
    result->isSelect = is_select;

    /*  Returns the number of rows affected by the SQL command.
     *  char *PQcmdTuples(PGresult *res);
     */

    if (!is_select) {
        result->rowsAffected = (Sint) atoi(PQcmdTuples(my_result));
        result->completed = 1;
    }
    else {
        result->rowsAffected = (Sint) - 1;
        result->completed = 0;
    }

    if (is_select) {
        result->fields = RS_PostgreSQL_createDataMappings(rsHandle);
    }
    free(dyn_statement);
    UNPROTECT(1);
    return rsHandle;
}
Пример #8
0
void RMT_DEV::setMGR_ID(const char * const pa_acConn){
  MGR_ID().fromString(pa_acConn);
}
Пример #9
0
/* Execute (currently) one sql statement (INSERT, DELETE, SELECT, etc.),
* set coercion type mappings between the server internal data types and
* S classes.   Returns  an S handle to a resultSet object.
*/
SEXP RS_MySQL_exec(SEXP conHandle, SEXP statement) {
  RS_DBI_connection *con;
  SEXP rsHandle;
  RS_DBI_resultSet  *result;
  MYSQL             *my_connection;
  MYSQL_RES         *my_result;
  int      num_fields, state;
  int     res_id, is_select;
  char     *dyn_statement;

  con = RS_DBI_getConnection(conHandle);
  my_connection = (MYSQL *) con->drvConnection;
  dyn_statement = RS_DBI_copyString(CHR_EL(statement,0));

  /* Do we have a pending resultSet in the current connection?
   * MySQL only allows  one resultSet per connection.
   */
  if(con->num_res>0){
    res_id = (int) con->resultSetIds[0]; /* recall, MySQL has only 1 res */
  rsHandle = RS_DBI_asResHandle(MGR_ID(conHandle),
    CON_ID(conHandle), res_id);
  result = RS_DBI_getResultSet(rsHandle);
  if(result->completed == 0){
    free(dyn_statement);
    error("connection with pending rows, close resultSet before continuing");
  }
  else
    RS_MySQL_closeResultSet(rsHandle);
  }

  /* Here is where we actually run the query */
  state = mysql_query(my_connection, dyn_statement);
  if(state) {
    error("could not run statement: %s", mysql_error(my_connection));
  }

  /* Do we need output column/field descriptors?  Only for SELECT-like
   * statements. The MySQL reference manual suggests invoking
   * mysql_use_result() and if it succeed the statement is SELECT-like
   * that can use a resultSet.  Otherwise call mysql_field_count()
   * and if it returns zero, the sql was not a SELECT-like statement.
   * Finally a non-zero means a failed SELECT-like statement.
   */
  my_result = mysql_use_result(my_connection);
  if(!my_result)
    my_result = (MYSQL_RES *) NULL;

  num_fields = (int) mysql_field_count(my_connection);
  is_select = (int) TRUE;
  if(!my_result){
    if(num_fields>0){
      free(dyn_statement);
      error("error in select/select-like");
    }
    else
      is_select = FALSE;
  }

  /* we now create the wrapper and copy values */
  rsHandle = RS_DBI_allocResultSet(conHandle);
  result = RS_DBI_getResultSet(rsHandle);
  result->statement = RS_DBI_copyString(dyn_statement);
  result->drvResultSet = (void *) my_result;
  result->rowCount = (int) 0;
  result->isSelect = is_select;
  if(!is_select){
    result->rowsAffected = (int) mysql_affected_rows(my_connection);
    result->completed = 1;
  }
  else {
    result->rowsAffected = (int) -1;
    result->completed = 0;
  }

  if(is_select)
    result->fields = RS_MySQL_createDataMappings(rsHandle);

  free(dyn_statement);
  return rsHandle;
}