コード例 #1
0
ファイル: connection.c プロジェクト: Hydrophile/RMySQL
/* RS_MySQL_createConnection - internal function
 *
 * Used by both RS_MySQL_newConnection and RS_MySQL_cloneConnection.
 * It is responsible for the memory associated with conParams.
 */
SEXP RS_MySQL_createConnection(SEXP mgrHandle, RS_MySQL_conParams *conParams) {
  RS_DBI_connection  *con;
  SEXP conHandle;
  MYSQL     *my_connection;

  /* Initialize MySQL connection */
  my_connection = mysql_init(NULL);
  // Always enable INFILE option, since needed for dbWriteTable
  mysql_options(my_connection, MYSQL_OPT_LOCAL_INFILE, 0);

  /* Load MySQL default connection values from a group.
  *
  * MySQL will combine the options found in the '[client]' group and one more group
  * specified by MYSQL_READ_DEFAULT_GROUP. Typically, this will
  * be '[rs-dbi]' but the user can override with another group. Note that
  * while our interface will allow a user to pass in a vector of groups,
  * only the first group in the vector will be combined with '[client]'.
  *
  * Should we make this an error in a later release?)
  */
  if (conParams->groups)
    mysql_options(my_connection, MYSQL_READ_DEFAULT_GROUP, conParams->groups);

  /* MySQL reads defaults from my.cnf or equivalent, but the user can supply
  * an alternative.
  */
  if(conParams->default_file)
    mysql_options(my_connection, MYSQL_READ_DEFAULT_FILE, conParams->default_file);

  if(!mysql_real_connect(my_connection,
    conParams->host, conParams->username, conParams->password, conParams->dbname,
    conParams->port, conParams->unix_socket, conParams->client_flag)){

    RS_MySQL_freeConParams(conParams);

    error(
      "Failed to connect to database: Error: %s\n",
      mysql_error(my_connection)
    );
  }

  /* MySQL connections can only have 1 result set open at a time */
  conHandle = RS_DBI_allocConnection(mgrHandle, (int) 1);
  con = RS_DBI_getConnection(conHandle);
  if(!con){
    mysql_close(my_connection);
    RS_MySQL_freeConParams(conParams);
    error("could not alloc space for connection object");
  }

  con->conParams = (void *) conParams;
  con->drvConnection = (void *) my_connection;

  return conHandle;
}
コード例 #2
0
ファイル: RS-PostgreSQL.c プロジェクト: neilt/RPostgreSQL
Con_Handle *
RS_PostgreSQL_newConnection(Mgr_Handle * mgrHandle, s_object * con_params)
{
    S_EVALUATOR RS_DBI_connection * con;
    RS_PostgreSQL_conParams *conParams;
    Con_Handle *conHandle;
    PGconn *my_connection;

    const char *user = NULL, *password = NULL, *host = NULL, *dbname = NULL, *port = NULL, *tty = NULL, *options = NULL;

    if (!is_validHandle(mgrHandle, MGR_HANDLE_TYPE)) {
        RS_DBI_errorMessage("invalid PostgreSQLManager", RS_DBI_ERROR);
    }

    user = CHR_EL(con_params, 0);
    password = CHR_EL(con_params, 1);
    host = CHR_EL(con_params, 2);
    dbname = CHR_EL(con_params, 3);
    port = CHR_EL(con_params, 4);
    tty = CHR_EL(con_params, 5);
    options = CHR_EL(con_params, 6);

    my_connection = PQsetdbLogin(host, port, options, tty, dbname, user, password);

    conParams = RS_postgresql_allocConParams();

    /* save actual connection parameters */
    conParams->user = RS_DBI_copyString(PQuser(my_connection));
    conParams->password = RS_DBI_copyString(PQpass(my_connection));
    {
        const char *tmphost = PQhost(my_connection);
        if (tmphost) {
            conParams->host = RS_DBI_copyString(tmphost);
        } else {
            conParams->host = RS_DBI_copyString("");
        }
    }
    conParams->dbname = RS_DBI_copyString(PQdb(my_connection));
    conParams->port = RS_DBI_copyString(PQport(my_connection));
    conParams->tty = RS_DBI_copyString(PQtty(my_connection));
    conParams->options = RS_DBI_copyString(PQoptions(my_connection));

    if (PQstatus(my_connection) != CONNECTION_OK) {
        char buf[1000];
        sprintf(buf, "could not connect %s@%s on dbname \"%s\"\n", PQuser(my_connection), host?host:"local", PQdb(my_connection));
        PQfinish(my_connection);
        my_connection = NULL;
        RS_PostgreSQL_freeConParams(conParams); /*free BEFORE emitting err message that do not come back */
        RS_DBI_errorMessage(buf, RS_DBI_ERROR);
        return R_NilValue; /* don't reach here as it goes back to R proc */
    }

    PROTECT(conHandle = RS_DBI_allocConnection(mgrHandle, (Sint) 1)); /* The second argument (1) specifies the number of result sets allocated */
    con = RS_DBI_getConnection(conHandle);
    if (my_connection && !con) {
        PQfinish(my_connection);
        my_connection = NULL;
        RS_PostgreSQL_freeConParams(conParams);
        conParams = (RS_PostgreSQL_conParams *) NULL;
        RS_DBI_errorMessage("could not alloc space for connection object", RS_DBI_ERROR);
    }
    if(con) {
        con->drvConnection = (void *) my_connection;
        con->conParams = (void *) conParams;
    }
    UNPROTECT(1);
    return conHandle;
}