/* 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; }
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; }