/* * the result is also available with the global variable 'connection'. */ void reconnect(int elevel) { StringInfoData buf; char *new_password; disconnect(); initStringInfo(&buf); if (dbname && dbname[0]) appendStringInfo(&buf, "dbname=%s ", dbname); if (host && host[0]) appendStringInfo(&buf, "host=%s ", host); if (port && port[0]) appendStringInfo(&buf, "port=%s ", port); if (username && username[0]) appendStringInfo(&buf, "user=%s ", username); if (password && password[0]) appendStringInfo(&buf, "password=%s ", password); connection = pgut_connect(buf.data, prompt_password, elevel); /* update password */ if (connection) { new_password = PQpass(connection); if (new_password && new_password[0] && (password == NULL || strcmp(new_password, password) != 0)) { free(password); password = pgut_strdup(new_password); } } termStringInfo(&buf); }
static int switch_database(struct dbpath *dbpath) { PGconn *newdbconn; if (dbpath_is_root(*dbpath)) return 1; if (strcmp(dbpath->database, PQdb(dbconn)) == 0) return 1; newdbconn = PQsetdbLogin(PQhost(dbconn), PQport(dbconn), PQoptions(dbconn), PQtty(dbconn), dbpath->database, PQuser(dbconn), PQpass(dbconn)); if (PQstatus(newdbconn) != CONNECTION_OK) { debug("new connection failed"); PQfinish(newdbconn); return 0; } PQfinish(dbconn); dbconn = newdbconn; return 1; }
/*************************************************************************** * \brief Create a PQconn object and store it in a list * * The PostGIS Raster driver keeps the connection with the PostgreSQL database * server for as long it leaves. Following PostGISRasterDataset instance * can re-use the existing connection as long it used the same database, * same user name, same password and same port. * * The PostGIS Raster driver will keep a list of all the successful * connections so, when connection is requested and it does not exist * on the list a new one will be instantiated, added to the list and * returned to the caller. * * All connection will be destroyed when the PostGISRasterDriver is destroyed. * ***************************************************************************/ PGconn* PostGISRasterDriver::GetConnection(const char* pszConnectionString, const char * pszHostIn, const char * pszPortIn, const char * pszUserIn, const char * pszPasswordIn) { int i = 0; PGconn * poConn = NULL; /** * Look for an existing connection in the list **/ for (i = 0; i < nRefCount; i++) { CPLDebug("PostGIS_Raster", "PostGISRasterDriver::GetConnection(): " "User: %s\nPassword: %s\nHost: %s\nPort: %s", pszUserIn, pszPasswordIn, pszHostIn, pszPortIn); if (EQUAL(pszUserIn, PQuser(papoConnection[i])) && EQUAL(pszPasswordIn, PQpass(papoConnection[i])) && EQUAL(pszHostIn, PQhost(papoConnection[i])) && EQUAL(pszPortIn, PQport(papoConnection[i]))) { return papoConnection[i]; } } /** * There's no existing connection. Create a new one. **/ poConn = PQconnectdb(pszConnectionString); if (poConn == NULL || PQstatus(poConn) == CONNECTION_BAD) { CPLError(CE_Failure, CPLE_AppDefined, "PGconnectcb failed: %s\n", PQerrorMessage(poConn)); PQfinish(poConn); return NULL; } /** * Save connection in connection list. **/ nRefCount++; papoConnection = (PGconn**) CPLRealloc(papoConnection, sizeof (PGconn*) * nRefCount); if (NULL != papoConnection) { papoConnection[nRefCount - 1] = poConn; return poConn; } else { CPLError(CE_Failure, CPLE_AppDefined, "Reallocation for new connection\ failed.\n"); PQfinish(poConn); return NULL; } }
LispObj * Lisp_PQpass(LispBuiltin *builtin) /* pq-pass connection */ { char *string; PGconn *conn; LispObj *connection; connection = ARGUMENT(0); if (!CHECKO(connection, PGconn_t)) LispDestroy("%s: cannot convert %s to PGconn*", STRFUN(builtin), STROBJ(connection)); conn = (PGconn*)(connection->data.opaque.data); string = PQpass(conn); return (string ? STRING(string) : NIL); }
int main() { // próba po³±czenia PGconn *myconnection = PQconnectdb(""); // sprawdzamy status po³±czenia if(PQstatus(myconnection) == CONNECTION_OK) { printf("connection made\n"); // informacje o po³±czeniu printf("PGDBNAME = %s\n",PQdb(myconnection)); printf("PGUSER = %s\n",PQuser(myconnection)); printf("PGPASSWORD = %s\n",PQpass(myconnection)); printf("PGHOST = %s\n",PQhost(myconnection)); printf("PGPORT = %s\n",PQport(myconnection)); printf("OPTIONS = %s\n",PQoptions(myconnection)); } else printf("connection failed: %s\n", PQerrorMessage(myconnection)); // w razie utraty po³±czenia wywo³anie // PQreset(myconnection); // zamyka op³±czenie i nawi±zuje je raz jeszcze // z dotychczasowymi parametrami PQfinish(myconnection); return EXIT_SUCCESS; }
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; }
/* GetSegmentDatabaseArray: This function reads all active instance segment pairs * from the function gp_segment_instance_map(). * It then uses the set specification fo filter out any instid, segid combinations * that don't match the set. bExcludeHead = true is used for restoring, because * the head is restored first seperately from the rest of the databases. */ bool GetDumpSegmentDatabaseArray(PGconn *pConn, int remote_version, SegmentDatabaseArray *pSegDBAr, ActorSet actors, char *dump_set_str, char *pszDBName, char *pszUserName, bool dataOnly, bool schemaOnly) { bool bRtn = true; PQExpBuffer pQry = NULL; PGresult *pRes = NULL; int ntups; int count; int i_dbid; int i_content; int i_host; int i_port; int i; int j; int x; int dbidset_count = 0; int *dbidset = NULL; SegmentDatabase *pSegDB; pQry = createPQExpBuffer(); if (remote_version >= 80214) /* 4.0 and beyond */ appendPQExpBuffer(pQry, "SELECT" " dbid," " content," " hostname," " port " "FROM " " gp_segment_configuration " "WHERE role='p' " "ORDER BY content DESC"); else /* pre 4.0 */ appendPQExpBuffer(pQry, "SELECT" " dbid," " content," " hostname," " port " "FROM" " gp_configuration " "WHERE valid = 't' " "AND isPrimary = 't' " "ORDER BY content DESC"); pRes = PQexec(pConn, pQry->data); if (!pRes || PQresultStatus(pRes) != PGRES_TUPLES_OK) { mpp_err_msg("ERROR", "gp_dump", "query to obtain list of Greenplum segment databases failed: %s", PQerrorMessage(pConn)); bRtn = false; goto cleanup; } ntups = PQntuples(pRes); if (ntups <= 0) { mpp_err_msg("ERROR", "gp_dump", "no Greenplum segment databases found on master segment schema"); bRtn = false; goto cleanup; } count = ntups + 1; /* * See how many set elements there are that were specified by HostIP or * name. */ /* * Allocate enough memory for all of them, even though some may be * filtered out. */ pSegDBAr->count = 0; pSegDBAr->pData = (SegmentDatabase *) calloc(count, sizeof(SegmentDatabase)); if (pSegDBAr->pData == NULL) { mpp_err_msg("ERROR", "gp_dump", "Unable to allocate memory for Greenplum segment/instances information\n"); bRtn = false; goto cleanup; } /* get the column numbers */ i_dbid = PQfnumber(pRes, "dbid"); i_content = PQfnumber(pRes, "content"); i_host = PQfnumber(pRes, "hostname"); i_port = PQfnumber(pRes, "port"); /* * if an individual set of dbid's was requested to be dumped, parse it and * check that it really exists and is a primary segment. */ if (actors == SET_INDIVIDUAL) { /* allocate dbidset. len is more than we need but it's a safe bet */ dbidset = (int *) calloc(strlen(dump_set_str), sizeof(int)); MemSet(dbidset, 0, strlen(dump_set_str) * sizeof(int)); if (dbidset == NULL) { mpp_err_msg("ERROR", "gp_dump", "Unable to allocate memory for Greenplum dbid set information\n"); bRtn = false; goto cleanup; } /* parse the user specified dbid list, return dbid count */ dbidset_count = parseDbidSet(dbidset, dump_set_str); if (dbidset_count < 1) { bRtn = false; goto cleanup; } for (i = 0; i < dbidset_count; i++) { bool match = false; for (j = 0; j < ntups; j++) { int dbid = atoi(PQgetvalue(pRes, j, i_dbid)); if (dbid == dbidset[i]) { match = true; break; } } if (!match) { mpp_err_msg("ERROR", "gp_dump", "dbid %d is not a correct Greenplum segment databases " "entry, or is not a primary segment\n ", dbidset[i]); bRtn = false; goto cleanup; } } } mpp_err_msg("INFO", "gp_dump", "Preparing to dump the following segments:\n"); /* Read through the results set (all primary segments) */ x = 0; for (i = 0; i < ntups; i++) { int dbid = atoi(PQgetvalue(pRes, i, i_dbid)); int content = atoi(PQgetvalue(pRes, i, i_content)); bool should_dump = false; /* in dataOnly we don't dump master information */ if (dataOnly && content == -1 && actors != SET_INDIVIDUAL) continue; /* in schemaOnly we skip all but the master */ if (schemaOnly && content != -1 && actors != SET_INDIVIDUAL) continue; if (actors == SET_INDIVIDUAL) { should_dump = false; for (j = 0; j < dbidset_count; j++) { if (dbid == dbidset[j]) should_dump = true; } if (!should_dump) continue; } pSegDB = &pSegDBAr->pData[x++]; pSegDB->dbid = dbid; pSegDB->content = content; pSegDB->role = (content == -1 ? ROLE_MASTER : ROLE_SEGDB); pSegDB->port = atoi(PQgetvalue(pRes, i, i_port)); pSegDB->pszHost = strdup(PQgetvalue(pRes, i, i_host)); pSegDB->pszDBName = pszDBName; pSegDB->pszDBUser = pszUserName; pSegDB->pszDBPswd = PQpass(pConn); if (pSegDB->role == ROLE_MASTER) mpp_err_msg("INFO", "gp_dump", "Master (dbid 1)\n"); else mpp_err_msg("INFO", "gp_dump", "Segment %d (dbid %d)\n", pSegDB->content, pSegDB->dbid); } /* set the count to be the number that passed the set inclusion test */ pSegDBAr->count = x; cleanup: if (pQry != NULL) destroyPQExpBuffer(pQry); if (pRes != NULL) PQclear(pRes); return bRtn; }
bool GetRestoreSegmentDatabaseArray(PGconn *pConn, RestorePairArray * restorePairAr, BackupLoc backupLocation, char *restore_set_str, bool dataOnly) { bool bRtn = true; PQExpBuffer pQry = NULL; PGresult *pRes = NULL; int ntups; int count; int i_dbid; int i_content; int i_host; int i_port; int i; int j; int x; int dbidset_count = 0; int *dbidset = NULL; SegmentDatabase *sourceSegDB; SegmentDatabase *targetSegDB; pQry = createPQExpBuffer(); appendPQExpBuffer(pQry, "SELECT" " dbid," " content," " hostname," " port " "FROM " " gp_segment_configuration " "WHERE role='p' " "ORDER BY content DESC"); pRes = PQexec(pConn, pQry->data); if (!pRes || PQresultStatus(pRes) != PGRES_TUPLES_OK) { mpp_err_msg("ERROR", "gp_restore", "query to obtain list of Greenplum segment databases failed: %s", PQerrorMessage(pConn)); bRtn = false; goto cleanup; } ntups = PQntuples(pRes); if (ntups <= 0) { mpp_err_msg("ERROR", "gp_restore", "no Greenplum segment databases found on master segment schema"); bRtn = false; goto cleanup; } count = ntups + 1; /* * Allocate enough memory for all of them, even though some may be * filtered out. */ restorePairAr->count = 0; restorePairAr->pData = (RestorePair *) calloc(count, sizeof(RestorePair)); if (restorePairAr->pData == NULL) { mpp_err_msg("ERROR", "gp_restore", "Unable to allocate memory for Greenplum segment database information\n"); bRtn = false; goto cleanup; } /* get the column numbers */ i_dbid = PQfnumber(pRes, "dbid"); i_content = PQfnumber(pRes, "content"); i_host = PQfnumber(pRes, "hostname"); i_port = PQfnumber(pRes, "port"); /* * if the dump file is on individual databases, parse the list of dbid's * where those files exist. */ if (backupLocation == FILE_ON_INDIVIDUAL) { /* allocate dbidset. len is more than we need but it's a safe bet */ dbidset = (int *) calloc(strlen(restore_set_str), sizeof(int)); MemSet(dbidset, 0, strlen(restore_set_str) * sizeof(int)); if (dbidset == NULL) { mpp_err_msg("ERROR", "gp_restore", "Unable to allocate memory for Greenplum dbidset information\n"); bRtn = false; goto cleanup; } /* parse the user specified dbid list, return dbid count */ dbidset_count = parseDbidSet(dbidset, restore_set_str); if (dbidset_count < 1) { bRtn = false; goto cleanup; } for (i = 0; i < dbidset_count; i++) { bool match = false; for (j = 0; j < ntups; j++) { int dbid = atoi(PQgetvalue(pRes, j, i_dbid)); if (dbid == dbidset[i]) { match = true; break; } } if (!match) { mpp_err_msg("ERROR", "gp_restore", "dbid %d is not a primary Greenplum segment databases entry\n", dbidset[i]); bRtn = false; goto cleanup; } } } mpp_err_msg("INFO", "gp_restore", "Preparing to restore the following segments:\n"); /* Read through the results set. */ x = 0; for (i = 0; i < ntups; i++) { int dbid = atoi(PQgetvalue(pRes, i, i_dbid)); int contentid = atoi(PQgetvalue(pRes, i, i_content)); bool should_restore = false; /* if dataOnly don't restore the master (table definitions) */ if (dataOnly && contentid == -1) continue; if (backupLocation == FILE_ON_INDIVIDUAL) { should_restore = false; for (j = 0; j < dbidset_count; j++) { if (dbid == dbidset[j]) should_restore = true; } if (!should_restore) continue; } targetSegDB = &restorePairAr->pData[x].segdb_target; targetSegDB->dbid = dbid; targetSegDB->role = (contentid == -1 ? ROLE_MASTER : ROLE_SEGDB); targetSegDB->port = atoi(PQgetvalue(pRes, i, i_port)); targetSegDB->pszHost = strdup(PQgetvalue(pRes, i, i_host)); targetSegDB->pszDBName = PQdb(pConn); targetSegDB->pszDBUser = PQuser(pConn); targetSegDB->pszDBPswd = PQpass(pConn); targetSegDB->content = contentid; sourceSegDB = &restorePairAr->pData[x].segdb_source; sourceSegDB->dbid = targetSegDB->dbid; sourceSegDB->role = targetSegDB->role; sourceSegDB->port = targetSegDB->port; sourceSegDB->pszHost = targetSegDB->pszHost; sourceSegDB->pszDBName = targetSegDB->pszDBName; sourceSegDB->pszDBUser = targetSegDB->pszDBUser; if (targetSegDB->pszDBPswd) sourceSegDB->pszDBPswd = targetSegDB->pszDBPswd; if (targetSegDB->role == ROLE_MASTER) mpp_err_msg("INFO", "gp_restore", "Master (dbid 1)\n"); else mpp_err_msg("INFO", "gp_restore", "Segment %d (dbid %d)\n", contentid, targetSegDB->dbid); x++; } /* set the count to be the number that passed the set inclusion test */ restorePairAr->count = x; cleanup: if (pQry != NULL) destroyPQExpBuffer(pQry); if (pRes != NULL) PQclear(pRes); return bRtn; }
/* * do_connect -- handler for \connect * * Connects to a database with given parameters. If there exists an * established connection, NULL values will be replaced with the ones * in the current connection. Otherwise NULL will be passed for that * parameter to PQconnectdbParams(), so the libpq defaults will be used. * * In interactive mode, if connection fails with the given parameters, * the old connection will be kept. */ static bool do_connect(char *dbname, char *user, char *host, char *port) { PGconn *o_conn = pset.db, *n_conn; char *password = NULL; if (!dbname) dbname = PQdb(o_conn); if (!user) user = PQuser(o_conn); if (!host) host = PQhost(o_conn); if (!port) port = PQport(o_conn); /* * If the user asked to be prompted for a password, ask for one now. If * not, use the password from the old connection, provided the username * has not changed. Otherwise, try to connect without a password first, * and then ask for a password if needed. * * XXX: this behavior leads to spurious connection attempts recorded in * the postmaster's log. But libpq offers no API that would let us obtain * a password and then continue with the first connection attempt. */ if (pset.getPassword == TRI_YES) { password = prompt_for_password(user); } else if (o_conn && user && strcmp(PQuser(o_conn), user) == 0) { password = strdup(PQpass(o_conn)); } while (true) { #define PARAMS_ARRAY_SIZE 7 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); keywords[0] = "host"; values[0] = host; keywords[1] = "port"; values[1] = port; keywords[2] = "user"; values[2] = user; keywords[3] = "password"; values[3] = password; keywords[4] = "dbname"; values[4] = dbname; keywords[5] = "fallback_application_name"; values[5] = pset.progname; keywords[6] = NULL; values[6] = NULL; n_conn = PQconnectdbParams(keywords, values, true); free(keywords); free(values); /* We can immediately discard the password -- no longer needed */ if (password) free(password); if (PQstatus(n_conn) == CONNECTION_OK) break; /* * Connection attempt failed; either retry the connection attempt with * a new password, or give up. */ if (!password && PQconnectionNeedsPassword(n_conn) && pset.getPassword != TRI_NO) { PQfinish(n_conn); password = prompt_for_password(user); continue; } /* * Failed to connect to the database. In interactive mode, keep the * previous connection to the DB; in scripting mode, close our * previous connection as well. */ if (pset.cur_cmd_interactive) { psql_error("%s", PQerrorMessage(n_conn)); /* pset.db is left unmodified */ if (o_conn) fputs(_("Previous connection kept\n"), stderr); } else { psql_error("\\connect: %s", PQerrorMessage(n_conn)); if (o_conn) { PQfinish(o_conn); pset.db = NULL; } } PQfinish(n_conn); return false; } /* * Replace the old connection with the new one, and update * connection-dependent variables. */ PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL); pset.db = n_conn; SyncVariables(); connection_warnings(false); /* Must be after SyncVariables */ /* Tell the user about the new connection */ if (!pset.quiet) { if (param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) || param_is_newly_set(PQport(o_conn), PQport(pset.db))) { char *host = PQhost(pset.db); if (host == NULL) host = DEFAULT_PGSOCKET_DIR; /* If the host is an absolute path, the connection is via socket */ if (is_absolute_path(host)) printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"), PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db)); else printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"), PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db)); } else printf(_("You are now connected to database \"%s\" as user \"%s\".\n"), PQdb(pset.db), PQuser(pset.db)); } if (o_conn) PQfinish(o_conn); return true; }
/* * Make a database connection with the given parameters. The * connection handle is returned, the parameters are stored in AHX. * An interactive password prompt is automatically issued if required. * * Note: it's not really all that sensible to use a single-entry password * cache if the username keeps changing. In current usage, however, the * username never does change, so one savedPassword is sufficient. */ void ConnectDatabase(Archive *AHX, const char *dbname, const char *pghost, const char *pgport, const char *username, trivalue prompt_password) { ArchiveHandle *AH = (ArchiveHandle *) AHX; char *password; bool new_pass; if (AH->connection) exit_horribly(modulename, "already connected to a database\n"); password = AH->savedPassword ? pg_strdup(AH->savedPassword) : NULL; if (prompt_password == TRI_YES && password == NULL) { password = simple_prompt("Password: "******"out of memory\n"); } AH->promptPassword = prompt_password; /* * Start the connection. Loop until we have a password if requested by * backend. */ do { const char *keywords[7]; const char *values[7]; keywords[0] = "host"; values[0] = pghost; keywords[1] = "port"; values[1] = pgport; keywords[2] = "user"; values[2] = username; keywords[3] = "password"; values[3] = password; keywords[4] = "dbname"; values[4] = dbname; keywords[5] = "fallback_application_name"; values[5] = progname; keywords[6] = NULL; values[6] = NULL; new_pass = false; AH->connection = PQconnectdbParams(keywords, values, true); if (!AH->connection) exit_horribly(modulename, "failed to connect to database\n"); if (PQstatus(AH->connection) == CONNECTION_BAD && PQconnectionNeedsPassword(AH->connection) && password == NULL && prompt_password != TRI_NO) { PQfinish(AH->connection); password = simple_prompt("Password: "******"out of memory\n"); new_pass = true; } } while (new_pass); /* check to see that the backend connection was successfully made */ if (PQstatus(AH->connection) == CONNECTION_BAD) exit_horribly(modulename, "connection to database \"%s\" failed: %s", PQdb(AH->connection) ? PQdb(AH->connection) : "", PQerrorMessage(AH->connection)); /* * We want to remember connection's actual password, whether or not we got * it by prompting. So we don't just store the password variable. */ if (PQconnectionUsedPassword(AH->connection)) { if (AH->savedPassword) free(AH->savedPassword); AH->savedPassword = pg_strdup(PQpass(AH->connection)); } if (password) free(password); /* check for version mismatch */ _check_database_version(AH); PQsetNoticeProcessor(AH->connection, notice_processor, NULL); }
/* * Connect to the db again. * * Note: it's not really all that sensible to use a single-entry password * cache if the username keeps changing. In current usage, however, the * username never does change, so one savedPassword is sufficient. We do * update the cache on the off chance that the password has changed since the * start of the run. */ static PGconn * _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) { PGconn *newConn; const char *newdb; const char *newuser; char *password; bool new_pass; if (!reqdb) newdb = PQdb(AH->connection); else newdb = reqdb; if (!requser || strlen(requser) == 0) newuser = PQuser(AH->connection); else newuser = requser; ahlog(AH, 1, "connecting to database \"%s\" as user \"%s\"\n", newdb, newuser); password = AH->savedPassword ? pg_strdup(AH->savedPassword) : NULL; if (AH->promptPassword == TRI_YES && password == NULL) { password = simple_prompt("Password: "******"out of memory\n"); } do { const char *keywords[7]; const char *values[7]; keywords[0] = "host"; values[0] = PQhost(AH->connection); keywords[1] = "port"; values[1] = PQport(AH->connection); keywords[2] = "user"; values[2] = newuser; keywords[3] = "password"; values[3] = password; keywords[4] = "dbname"; values[4] = newdb; keywords[5] = "fallback_application_name"; values[5] = progname; keywords[6] = NULL; values[6] = NULL; new_pass = false; newConn = PQconnectdbParams(keywords, values, true); if (!newConn) exit_horribly(modulename, "failed to reconnect to database\n"); if (PQstatus(newConn) == CONNECTION_BAD) { if (!PQconnectionNeedsPassword(newConn)) exit_horribly(modulename, "could not reconnect to database: %s", PQerrorMessage(newConn)); PQfinish(newConn); if (password) fprintf(stderr, "Password incorrect\n"); fprintf(stderr, "Connecting to %s as %s\n", newdb, newuser); if (password) free(password); if (AH->promptPassword != TRI_NO) password = simple_prompt("Password: "******"connection needs password\n"); if (password == NULL) exit_horribly(modulename, "out of memory\n"); new_pass = true; } } while (new_pass); /* * We want to remember connection's actual password, whether or not we got * it by prompting. So we don't just store the password variable. */ if (PQconnectionUsedPassword(newConn)) { if (AH->savedPassword) free(AH->savedPassword); AH->savedPassword = pg_strdup(PQpass(newConn)); } if (password) free(password); /* check for version mismatch */ _check_database_version(AH); PQsetNoticeProcessor(newConn, notice_processor, NULL); return newConn; }
void dbgPgThread::noticeHandler( void *arg, const char *message ) { // Remove the last char from the message as it'll be a \n wxString msg = wxString(message, wxConvUTF8); if (msg.EndsWith(wxT("\n"))) msg.RemoveLast(); wxLogInfo(wxT("%s"), msg.c_str()); dbgPgThread *thread = (dbgPgThread *)arg; wxEvtHandler *caller = thread->m_currentCommand->getCaller(); if( strstr( message, "PLDBGBREAK" )) { wxStringTokenizer tokens( wxString( message, wxConvUTF8 ), wxT( ":\n" )); wxString NOTICE = tokens.GetNextToken(); // NOTICE: wxString PLDBGBREAK = tokens.GetNextToken(); // PLDBGBREAK: wxString PORT = tokens.GetNextToken(); // port PGconn *conn = thread->m_owner.getConnection(); // Create a dbgConnProp object that contains the same information in a // more convenient format dbgConnProp *debugProps = new dbgConnProp; debugProps->m_host = wxString( PQhost( conn ), wxConvUTF8 ); debugProps->m_database = wxString( PQdb( conn ), wxConvUTF8 ); debugProps->m_userName = wxString( PQuser( conn ), wxConvUTF8 ); debugProps->m_debugPort = PORT; debugProps->m_port = wxString( PQport( conn ), wxConvUTF8 ); debugProps->m_password = wxString( PQpass( conn ), wxConvUTF8 ); wxCommandEvent buttonEvent( wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_SPAWN_DEBUGGER ); buttonEvent.SetClientData((wxClientData *)debugProps ); caller->AddPendingEvent( buttonEvent ); } else if( strstr( message, "INFO" )) { if( strstr( message, "CONTEXT:" ) == NULL ) { wxCommandEvent buttonEvent( wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_NOTICE_RECEIVED ); wxString strippedMessage( wxString( message, wxConvUTF8 )); strippedMessage.Replace( wxT( "INFO: " ), wxT( "" ), false ); buttonEvent.SetString( strippedMessage ); caller->AddPendingEvent( buttonEvent ); } } else { wxCommandEvent buttonEvent( wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_NOTICE_RECEIVED ); buttonEvent.SetString( wxString( message, wxConvUTF8 ) ); caller->AddPendingEvent( buttonEvent ); } }
int main(int argc, char *argv[]) { /* First, we need to take in input from the items file. */ if (argc != 6) { printf("Usage: workload total alpha beta gamma delta\n"); printf("The values for alpha, beta, gamma and delta need to be integers that sum to 100.\n"); exit(0); } int i, j, k, numrecs; // These are the parameters that come from the user. int total, nalpha, nbeta, ngamma, ndelta; // These represent thresholds. int talpha, tbeta, tgamma, tdelta; // These are derived parameters from the database. int alphacells, betacells, gammacells, deltacells; char **recs; PGconn *psql; AttributeInfo *head_alpha, *head_beta, *head_gamma, *head_delta; AttributeInfo *tail_alpha, *tail_beta, *tail_gamma, *tail_delta; AttributeInfo **alpha, **beta, **gamma, **delta; head_alpha = NULL; head_beta = NULL; head_gamma = NULL; head_delta = NULL; tail_alpha = NULL; tail_beta = NULL; tail_gamma = NULL; tail_delta = NULL; // Storing our parameters. total = atoi(argv[1]); nalpha = atoi(argv[2]); nbeta = atoi(argv[3]); ngamma = atoi(argv[4]); ndelta = atoi(argv[5]); // Establish thresholds for our RNG. tdelta = 100 - ndelta; tgamma = tdelta - ngamma; tbeta = tgamma - nbeta; talpha = 0; if (nalpha+nbeta+ngamma+ndelta != 100) { printf("The values for alpha, beta, gamma and delta need to be integers that sum to 100.\n"); exit(0); } // Seeding our RNG. srand(time(NULL)); // We start off by getting a recommender list. recs = recommenderList(&numrecs); printf("Numrecs: %d\n",numrecs); /* Connect to the database. */ psql = PQconnectdb("host = 'localhost' port = '5432' dbname = 'recathon'"); if (PQstatus(psql) != CONNECTION_OK) printf("bad conn\n"); printf("%s, %s, %s, %s, %s\n",PQdb(psql), PQuser(psql), PQpass(psql), PQhost(psql), PQport(psql)); if (psql == NULL) printf("connection failed\n"); // Next, we need to query the index of each recommender, to get the attribute information and // cell types. for (i = 0; i < numrecs; i++) { char *querystring, *celltype; PGresult *query; int rows, cols; AttributeInfo *newatt; querystring = (char*) malloc(1024*sizeof(char)); // Since we don't know all of the attributes, we need to request everything. sprintf(querystring,"select * from %sindex;",recs[i]); query = PQexec(psql,querystring); rows = PQntuples(query); cols = PQnfields(query); // A new AttributeInfo for each row. for (j = 0; j < rows; j++) { // Get query information. Cell type is attribute #8. Recommender-specific // attributes begin at #13. newatt = (AttributeInfo*) malloc(sizeof(AttributeInfo)); newatt->next = NULL; newatt->recname = (char*) malloc(128*sizeof(char)); sprintf(newatt->recname,"%s",recs[i]); newatt->numatts = cols - 12; newatt->attnames = (char**) malloc(newatt->numatts*sizeof(char*)); for (k = 0; k < newatt->numatts; k++) newatt->attnames[k] = (char*) malloc(64*sizeof(char)); newatt->attvalues = (char**) malloc(newatt->numatts*sizeof(char*)); for (k = 0; k < newatt->numatts; k++) newatt->attvalues[k] = (char*) malloc(64*sizeof(char)); celltype = PQgetvalue(query,j,7); if (strcmp(celltype,"Alpha") == 0) newatt->celltype = CELL_ALPHA; else if (strcmp(celltype,"Beta") == 0) newatt->celltype = CELL_BETA; else if (strcmp(celltype,"Gamma") == 0) newatt->celltype = CELL_GAMMA; else newatt->celltype = CELL_DELTA; // Get column information. for (k = 0; k < cols-12; k++) { sprintf(newatt->attnames[k],"%s",PQfname(query,k+12)); sprintf(newatt->attvalues[k],"%s",PQgetvalue(query,j,k+12)); } // With the item complete, we put it into the appropriate bucket. switch (newatt->celltype) { case CELL_ALPHA: if (!head_alpha) { head_alpha = newatt; tail_alpha = newatt; } else { tail_alpha->next = newatt; tail_alpha = newatt; } break; case CELL_BETA: if (!head_beta) { head_beta = newatt; tail_beta = newatt; } else { tail_beta->next = newatt; tail_beta = newatt; } break; case CELL_GAMMA: if (!head_gamma) { head_gamma = newatt; tail_gamma = newatt; } else { tail_gamma->next = newatt; tail_gamma = newatt; } break; default: if (!head_delta) { head_delta = newatt; tail_delta = newatt; } else { tail_delta->next = newatt; tail_delta = newatt; } break; } } PQclear(query); free(querystring); } // For easy randomization, we should flatten our AttributeInfo lists. alpha = flatten(head_alpha, &alphacells); beta = flatten(head_beta, &betacells); gamma = flatten(head_gamma, &gammacells); delta = flatten(head_delta, &deltacells); // DEBUG: loop through the lists of alpha/beta/gamma/delta cells and print info. if (DEBUG) { printf("--- ALPHA CELLS ---\n"); printCellList(alpha, alphacells); printf("--- BETA CELLS ---\n"); printCellList(beta, betacells); printf("--- GAMMA CELLS ---\n"); printCellList(gamma, gammacells); printf("--- DELTA CELLS ---\n"); printCellList(delta, deltacells); } // One more thing we need to do is obtain a list of users that will work for // each AttributeInfo. We can semi-randomize by sorting based on zip code. addUsers(alpha, alphacells, psql); addUsers(beta, betacells, psql); addUsers(gamma, gammacells, psql); addUsers(delta, deltacells, psql); // Now to issue the given number of queries, with the frequencies established // probabilistically. for (i = 0; i < total; i++) { int randnum, randatt, randuser, userid; recathon_cell celltype; bool valid = false; PGresult *workquery; char *qstring; AttributeInfo *queryatt; // It's possible one of our buckets will have nothing in it, so // we need to continue choosing until we get something valid. while (!valid) { // A RNG chooses which kind of cell we work with. randnum = rand() % 100; if (randnum < tbeta) { if (alphacells > 0) { valid = true; celltype = CELL_ALPHA; } } else if (randnum < tgamma) { if (betacells > 0) { valid = true; celltype = CELL_BETA; } } else if (randnum < tdelta) { if (gammacells > 0) { valid = true; celltype = CELL_GAMMA; } } else { if (deltacells > 0) { valid = true; celltype = CELL_DELTA; } } } // Depending on our cell type, we'll have a different set of possible // queries to issue; we can choose from the alpha, beta, gamma or delta // buckets. Which item we get is also random. switch (celltype) { case CELL_ALPHA: randatt = rand() % alphacells; queryatt = alpha[randatt]; break; case CELL_BETA: randatt = rand() % betacells; queryatt = beta[randatt]; break; case CELL_GAMMA: randatt = rand() % gammacells; queryatt = gamma[randatt]; break; default: randatt = rand() % deltacells; queryatt = delta[randatt]; break; } randuser = rand() % 10; userid = queryatt->valid_users[randuser]; qstring = (char*) malloc(1024*sizeof(char)); sprintf(qstring,"select itemid from %s recommend(10) userid=%d",queryatt->recname,userid); if (queryatt->numatts > 0) { strncat(qstring," and ",5); for (j = 0; j < queryatt->numatts; j++) { char addition[128]; sprintf(addition,"%s = '%s' ", queryatt->attnames[j],queryatt->attvalues[j]); strncat(qstring,addition,strlen(addition)); if (j+1 < queryatt->numatts) strncat(qstring,"and ",5); } } strncat(qstring,";",1); workquery = PQexec(psql,qstring); PQclear(workquery); free(qstring); } PQfinish(psql); }