static void BaseBackup(void) { PGresult *res; char *sysidentifier; uint32 timeline; char current_path[MAXPGPATH]; char escaped_label[MAXPGPATH]; int i; char xlogstart[64]; char xlogend[64]; /* * Connect in replication mode to the server */ conn = GetConnection(); /* * Run IDENTIFY_SYSTEM so we can get the timeline */ res = PQexec(conn, "IDENTIFY_SYSTEM"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, _("%s: could not identify system: %s\n"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (PQntuples(res) != 1) { fprintf(stderr, _("%s: could not identify system, got %i rows\n"), progname, PQntuples(res)); disconnect_and_exit(1); } sysidentifier = strdup(PQgetvalue(res, 0, 0)); timeline = atoi(PQgetvalue(res, 0, 1)); PQclear(res); /* * Start the actual backup */ PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i); snprintf(current_path, sizeof(current_path), "BASE_BACKUP LABEL '%s' %s %s %s %s", escaped_label, showprogress ? "PROGRESS" : "", includewal && !streamwal ? "WAL" : "", fastcheckpoint ? "FAST" : "", includewal ? "NOWAIT" : ""); if (PQsendQuery(conn, current_path) == 0) { fprintf(stderr, _("%s: could not send base backup command: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } /* * Get the starting xlog position */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, _("%s: could not initiate base backup: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (PQntuples(res) != 1) { fprintf(stderr, _("%s: no start point returned from server\n"), progname); disconnect_and_exit(1); } strcpy(xlogstart, PQgetvalue(res, 0, 0)); if (verbose && includewal) fprintf(stderr, "xlog start point: %s\n", xlogstart); PQclear(res); MemSet(xlogend, 0, sizeof(xlogend)); /* * Get the header */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, _("%s: could not get backup header: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (PQntuples(res) < 1) { fprintf(stderr, _("%s: no data returned from server\n"), progname); disconnect_and_exit(1); } /* * Sum up the total size, for progress reporting */ totalsize = totaldone = 0; tablespacecount = PQntuples(res); for (i = 0; i < PQntuples(res); i++) { if (showprogress) totalsize += atol(PQgetvalue(res, i, 2)); /* * Verify tablespace directories are empty. Don't bother with the * first once since it can be relocated, and it will be checked before * we do anything anyway. */ if (format == 'p' && !PQgetisnull(res, i, 1)) verify_dir_is_empty_or_create(PQgetvalue(res, i, 1)); } /* * When writing to stdout, require a single tablespace */ if (format == 't' && strcmp(basedir, "-") == 0 && PQntuples(res) > 1) { fprintf(stderr, _("%s: can only write single tablespace to stdout, database has %d\n"), progname, PQntuples(res)); disconnect_and_exit(1); } /* * If we're streaming WAL, start the streaming session before we start * receiving the actual data chunks. */ if (streamwal) { if (verbose) fprintf(stderr, _("%s: starting background WAL receiver\n"), progname); StartLogStreamer(xlogstart, timeline, sysidentifier); } /* * Start receiving chunks */ for (i = 0; i < PQntuples(res); i++) { if (format == 't') ReceiveTarFile(conn, res, i); else ReceiveAndUnpackTarFile(conn, res, i); } /* Loop over all tablespaces */ if (showprogress) { progress_report(PQntuples(res), NULL); fprintf(stderr, "\n"); /* Need to move to next line */ } PQclear(res); /* * Get the stop position */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, _("%s: could not get WAL end position from server\n"), progname); disconnect_and_exit(1); } if (PQntuples(res) != 1) { fprintf(stderr, _("%s: no WAL end position returned from server\n"), progname); disconnect_and_exit(1); } strcpy(xlogend, PQgetvalue(res, 0, 0)); if (verbose && includewal) fprintf(stderr, "xlog end point: %s\n", xlogend); PQclear(res); res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, _("%s: final receive failed: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (bgchild > 0) { #ifndef WIN32 int status; int r; #else DWORD status; #endif if (verbose) fprintf(stderr, _("%s: waiting for background process to finish streaming...\n"), progname); #ifndef WIN32 if (pipewrite(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend)) { fprintf(stderr, _("%s: could not send command to background pipe: %s\n"), progname, strerror(errno)); disconnect_and_exit(1); } /* Just wait for the background process to exit */ r = waitpid(bgchild, &status, 0); if (r == -1) { fprintf(stderr, _("%s: could not wait for child process: %s\n"), progname, strerror(errno)); disconnect_and_exit(1); } if (r != bgchild) { fprintf(stderr, _("%s: child %i died, expected %i\n"), progname, r, bgchild); disconnect_and_exit(1); } if (!WIFEXITED(status)) { fprintf(stderr, _("%s: child process did not exit normally\n"), progname); disconnect_and_exit(1); } if (WEXITSTATUS(status) != 0) { fprintf(stderr, _("%s: child process exited with error %i\n"), progname, WEXITSTATUS(status)); disconnect_and_exit(1); } /* Exited normally, we're happy! */ #else /* WIN32 */ /* * On Windows, since we are in the same process, we can just store the * value directly in the variable, and then set the flag that says * it's there. */ if (sscanf(xlogend, "%X/%X", &xlogendptr.xlogid, &xlogendptr.xrecoff) != 2) { fprintf(stderr, _("%s: could not parse xlog end position \"%s\"\n"), progname, xlogend); exit(1); } InterlockedIncrement(&has_xlogendptr); /* First wait for the thread to exit */ if (WaitForSingleObjectEx((HANDLE) bgchild, INFINITE, FALSE) != WAIT_OBJECT_0) { _dosmaperr(GetLastError()); fprintf(stderr, _("%s: could not wait for child thread: %s\n"), progname, strerror(errno)); disconnect_and_exit(1); } if (GetExitCodeThread((HANDLE) bgchild, &status) == 0) { _dosmaperr(GetLastError()); fprintf(stderr, _("%s: could not get child thread exit status: %s\n"), progname, strerror(errno)); disconnect_and_exit(1); } if (status != 0) { fprintf(stderr, _("%s: child thread exited with error %u\n"), progname, (unsigned int) status); disconnect_and_exit(1); } /* Exited normally, we're happy */ #endif } /* * End of copy data. Final result is already checked inside the loop. */ PQfinish(conn); if (verbose) fprintf(stderr, "%s: base backup completed\n", progname); }
int main(int argc, char **argv) { PGconn *conn; PQExpBufferData sql; PGresult *res; PGresult *pkrel_res; PGresult *fkrel_res; char *fk_relname; char *fk_nspname; char *fk_attname; char *pk_relname; char *pk_nspname; int fk, pk; /* loop counters */ if (argc != 2) { fprintf(stderr, "Usage: %s database\n", argv[0]); exit(EXIT_FAILURE); } initPQExpBuffer(&sql); appendPQExpBuffer(&sql, "dbname=%s", argv[1]); conn = PQconnectdb(sql.data); if (PQstatus(conn) == CONNECTION_BAD) { fprintf(stderr, "connection error: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } /* Get a list of relations that have OIDs */ printfPQExpBuffer(&sql, "%s", "SET search_path = public;" "SELECT c.relname, (SELECT nspname FROM " "pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname " "FROM pg_catalog.pg_class c " "WHERE c.relkind = 'r' " "AND c.relhasoids " "ORDER BY nspname, c.relname" ); res = PQexec(conn, sql.data); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "sql error: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } pkrel_res = res; /* Get a list of columns of OID type (or any OID-alias type) */ printfPQExpBuffer(&sql, "%s", "SELECT c.relname, " "(SELECT nspname FROM pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname, " "a.attname " "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " "WHERE a.attnum > 0 AND c.relkind = 'r' " "AND a.attrelid = c.oid " "AND a.atttypid IN ('pg_catalog.oid'::regtype, " " 'pg_catalog.regclass'::regtype, " " 'pg_catalog.regoper'::regtype, " " 'pg_catalog.regoperator'::regtype, " " 'pg_catalog.regproc'::regtype, " " 'pg_catalog.regprocedure'::regtype, " " 'pg_catalog.regtype'::regtype, " " 'pg_catalog.regconfig'::regtype, " " 'pg_catalog.regdictionary'::regtype) " "ORDER BY nspname, c.relname, a.attnum" ); res = PQexec(conn, sql.data); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "sql error: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } fkrel_res = res; /* * For each column and each relation-having-OIDs, look to see if the * column contains any values matching entries in the relation. */ for (fk = 0; fk < PQntuples(fkrel_res); fk++) { fk_relname = PQgetvalue(fkrel_res, fk, 0); fk_nspname = PQgetvalue(fkrel_res, fk, 1); fk_attname = PQgetvalue(fkrel_res, fk, 2); for (pk = 0; pk < PQntuples(pkrel_res); pk++) { pk_relname = PQgetvalue(pkrel_res, pk, 0); pk_nspname = PQgetvalue(pkrel_res, pk, 1); printfPQExpBuffer(&sql, "SELECT 1 " "FROM \"%s\".\"%s\" t1, " "\"%s\".\"%s\" t2 " "WHERE t1.\"%s\"::pg_catalog.oid = t2.oid " "LIMIT 1", fk_nspname, fk_relname, pk_nspname, pk_relname, fk_attname); res = PQexec(conn, sql.data); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "sql error: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } if (PQntuples(res) != 0) printf("Join %s.%s.%s => %s.%s.oid\n", fk_nspname, fk_relname, fk_attname, pk_nspname, pk_relname); PQclear(res); } } PQclear(fkrel_res); /* Now, do the same for referencing columns that are arrays */ /* Get a list of columns of OID-array type (or any OID-alias type) */ printfPQExpBuffer(&sql, "%s", "SELECT c.relname, " "(SELECT nspname FROM pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname, " "a.attname " "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " "WHERE a.attnum > 0 AND c.relkind = 'r' " "AND a.attrelid = c.oid " "AND a.atttypid IN ('pg_catalog.oid[]'::regtype, " " 'pg_catalog.regclass[]'::regtype, " " 'pg_catalog.regoper[]'::regtype, " " 'pg_catalog.regoperator[]'::regtype, " " 'pg_catalog.regproc[]'::regtype, " " 'pg_catalog.regprocedure[]'::regtype, " " 'pg_catalog.regtype[]'::regtype, " " 'pg_catalog.regconfig[]'::regtype, " " 'pg_catalog.regdictionary[]'::regtype) " "ORDER BY nspname, c.relname, a.attnum" ); res = PQexec(conn, sql.data); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "sql error: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } fkrel_res = res; /* * For each column and each relation-having-OIDs, look to see if the * column contains any values matching entries in the relation. */ for (fk = 0; fk < PQntuples(fkrel_res); fk++) { fk_relname = PQgetvalue(fkrel_res, fk, 0); fk_nspname = PQgetvalue(fkrel_res, fk, 1); fk_attname = PQgetvalue(fkrel_res, fk, 2); for (pk = 0; pk < PQntuples(pkrel_res); pk++) { pk_relname = PQgetvalue(pkrel_res, pk, 0); pk_nspname = PQgetvalue(pkrel_res, pk, 1); printfPQExpBuffer(&sql, "SELECT 1 " "FROM \"%s\".\"%s\" t1, " "\"%s\".\"%s\" t2 " "WHERE t2.oid = ANY(t1.\"%s\")" "LIMIT 1", fk_nspname, fk_relname, pk_nspname, pk_relname, fk_attname); res = PQexec(conn, sql.data); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "sql error: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } if (PQntuples(res) != 0) printf("Join %s.%s.%s []=> %s.%s.oid\n", fk_nspname, fk_relname, fk_attname, pk_nspname, pk_relname); PQclear(res); } } PQclear(fkrel_res); PQclear(pkrel_res); PQfinish(conn); termPQExpBuffer(&sql); exit(EXIT_SUCCESS); }
/* * SendQuery: send the query string to the backend * (and print out results) * * Note: This is the "front door" way to send a query. That is, use it to * send queries actually entered by the user. These queries will be subject to * single step mode. * To send "back door" queries (generated by slash commands, etc.) in a * controlled way, use PSQLexec(). * * Returns true if the query executed successfully, false otherwise. */ bool SendQuery(const char *query) { PGresult *results; PGTransactionStatusType transaction_status; double elapsed_msec = 0; bool OK = false; bool on_error_rollback_savepoint = false; static bool on_error_rollback_warning = false; if (!pset.db) { psql_error("You are currently not connected to a database.\n"); goto sendquery_cleanup; } if (pset.singlestep) { char buf[3]; printf(_("***(Single step mode: verify command)*******************************************\n" "%s\n" "***(press return to proceed or enter x and return to cancel)********************\n"), query); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) != NULL) if (buf[0] == 'x') goto sendquery_cleanup; } else if (pset.echo == PSQL_ECHO_QUERIES) { puts(query); fflush(stdout); } if (pset.logfile) { fprintf(pset.logfile, _("********* QUERY **********\n" "%s\n" "**************************\n\n"), query); fflush(pset.logfile); } SetCancelConn(); transaction_status = PQtransactionStatus(pset.db); if (transaction_status == PQTRANS_IDLE && !pset.autocommit && !command_no_begin(query)) { results = PQexec(pset.db, "BEGIN"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); PQclear(results); ResetCancelConn(); goto sendquery_cleanup; } PQclear(results); transaction_status = PQtransactionStatus(pset.db); } if (transaction_status == PQTRANS_INTRANS && pset.on_error_rollback != PSQL_ERROR_ROLLBACK_OFF && (pset.cur_cmd_interactive || pset.on_error_rollback == PSQL_ERROR_ROLLBACK_ON)) { if (on_error_rollback_warning == false && pset.sversion < 80000) { psql_error("The server (version %d.%d) does not support savepoints for ON_ERROR_ROLLBACK.\n", pset.sversion / 10000, (pset.sversion / 100) % 100); on_error_rollback_warning = true; } else { results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); PQclear(results); ResetCancelConn(); goto sendquery_cleanup; } PQclear(results); on_error_rollback_savepoint = true; } } if (pset.fetch_count <= 0 || !is_select_command(query)) { /* Default fetch-it-all-and-print mode */ instr_time before, after; if (pset.timing) INSTR_TIME_SET_CURRENT(before); results = PQexec(pset.db, query); /* these operations are included in the timing result: */ ResetCancelConn(); OK = ProcessResult(&results); if (pset.timing) { INSTR_TIME_SET_CURRENT(after); INSTR_TIME_SUBTRACT(after, before); elapsed_msec = INSTR_TIME_GET_MILLISEC(after); } /* but printing results isn't: */ if (OK && results) OK = PrintQueryResults(results); } else { /* Fetch-in-segments mode */ OK = ExecQueryUsingCursor(query, &elapsed_msec); ResetCancelConn(); results = NULL; /* PQclear(NULL) does nothing */ } /* If we made a temporary savepoint, possibly release/rollback */ if (on_error_rollback_savepoint) { const char *svptcmd = NULL; transaction_status = PQtransactionStatus(pset.db); switch (transaction_status) { case PQTRANS_INERROR: /* We always rollback on an error */ svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint"; break; case PQTRANS_IDLE: /* If they are no longer in a transaction, then do nothing */ break; case PQTRANS_INTRANS: /* * Do nothing if they are messing with savepoints themselves: * If the user did RELEASE or ROLLBACK, our savepoint is gone. * If they issued a SAVEPOINT, releasing ours would remove * theirs. */ if (results && (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 || strcmp(PQcmdStatus(results), "RELEASE") == 0 || strcmp(PQcmdStatus(results), "ROLLBACK") == 0)) svptcmd = NULL; else svptcmd = "RELEASE pg_psql_temporary_savepoint"; break; case PQTRANS_ACTIVE: case PQTRANS_UNKNOWN: default: OK = false; /* PQTRANS_UNKNOWN is expected given a broken connection. */ if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp()) psql_error("unexpected transaction status (%d)\n", transaction_status); break; } if (svptcmd) { PGresult *svptres; svptres = PQexec(pset.db, svptcmd); if (PQresultStatus(svptres) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); PQclear(svptres); OK = false; PQclear(results); ResetCancelConn(); goto sendquery_cleanup; } PQclear(svptres); } } PQclear(results); /* Possible microtiming output */ if (pset.timing) printf(_("Time: %.3f ms\n"), elapsed_msec); /* check for events that may occur during query execution */ if (pset.encoding != PQclientEncoding(pset.db) && PQclientEncoding(pset.db) >= 0) { /* track effects of SET CLIENT_ENCODING */ pset.encoding = PQclientEncoding(pset.db); pset.popt.topt.encoding = pset.encoding; SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); } PrintNotifications(); /* perform cleanup that should occur after any attempted query */ sendquery_cleanup: /* reset \g's output-to-filename trigger */ if (pset.gfname) { free(pset.gfname); pset.gfname = NULL; } /* reset \gset trigger */ if (pset.gset_prefix) { free(pset.gset_prefix); pset.gset_prefix = NULL; } return OK; }
int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) { char *maskeddata, *temp, *sql, *column; char *conn_decrypted; int i, test; PGresult *query_result; msPOSTGRESQLJoinInfo *joininfo; if(join->joininfo) return MS_SUCCESS; joininfo = (msPOSTGRESQLJoinInfo *)malloc(sizeof(msPOSTGRESQLJoinInfo)); if(!joininfo) { msSetError(MS_MEMERR, "Error allocating join info struct.", "msPOSTGRESQLJoinConnect()"); return MS_FAILURE; } joininfo->conn = NULL; joininfo->row_num = 0; joininfo->query_result = NULL; joininfo->from_index = 0; joininfo->to_column = join->to; joininfo->from_value = NULL; joininfo->layer_debug = layer->debug; join->joininfo = joininfo; /* * We need three things at a minimum, the connection string, a table * name, and a column to join on. */ if(!join->connection) { msSetError(MS_QUERYERR, "No connection information provided.", "MSPOSTGRESQLJoinConnect()"); return MS_FAILURE; } if(!join->table) { msSetError(MS_QUERYERR, "No join table name found.", "msPOSTGRESQLJoinConnect()"); return MS_FAILURE; } if(!joininfo->to_column) { msSetError(MS_QUERYERR, "No join to column name found.", "msPOSTGRESQLJoinConnect()"); return MS_FAILURE; } /* Establish database connection */ conn_decrypted = msDecryptStringTokens(layer->map, join->connection); if (conn_decrypted != NULL) { joininfo->conn = PQconnectdb(conn_decrypted); free(conn_decrypted); } if(!joininfo->conn || PQstatus(joininfo->conn) == CONNECTION_BAD) { maskeddata = (char *)malloc(strlen(layer->connection) + 1); strcpy(maskeddata, join->connection); temp = strstr(maskeddata, "password="******"Unable to connect to PostgreSQL using the string %s.\n Error reported: %s\n", "msPOSTGRESQLJoinConnect()", maskeddata, PQerrorMessage(joininfo->conn)); free(maskeddata); if(!joininfo->conn) { free(joininfo->conn); } free(joininfo); join->joininfo = NULL; return MS_FAILURE; } /* Determine the number and names of columns in the join table. */ sql = (char *)malloc(36 + strlen(join->table) + 1); sprintf(sql, "SELECT * FROM %s WHERE false LIMIT 0", join->table); if(joininfo->layer_debug) { msDebug("msPOSTGRESQLJoinConnect(): executing %s.\n", sql); } query_result = PQexec(joininfo->conn, sql); if(!query_result || PQresultStatus(query_result) != PGRES_TUPLES_OK) { msSetError(MS_QUERYERR, "Error determining join items: %s.", "msPOSTGRESQLJoinConnect()", PQerrorMessage(joininfo->conn)); if(query_result) { PQclear(query_result); query_result = NULL; } free(sql); return MS_FAILURE; } free(sql); join->numitems = PQnfields(query_result); join->items = malloc(sizeof(char *) * (join->numitems)); /* We want the join-to column to be first in the list. */ test = 1; for(i = 0; i < join->numitems; i++) { column = PQfname(query_result, i); if(strcmp(column, joininfo->to_column) != 0) { join->items[i + test] = (char *)malloc(strlen(column) + 1); strcpy(join->items[i + test], column); } else { test = 0; join->items[0] = (char *)malloc(strlen(column) + 1); strcpy(join->items[0], column); } } PQclear(query_result); query_result = NULL; if(test == 1) { msSetError(MS_QUERYERR, "Unable to find join to column: %s", "msPOSTGRESQLJoinConnect()", joininfo->to_column); return MS_FAILURE; } if(joininfo->layer_debug) { for(i = 0; i < join->numitems; i++) { msDebug("msPOSTGRESQLJoinConnect(): Column %d named %s\n", i, join->items[i]); } } /* Determine the index of the join from column. */ for(i = 0; i < layer->numitems; i++) { if(strcasecmp(layer->items[i], join->from) == 0) { joininfo->from_index = i; break; } } if(i == layer->numitems) { msSetError(MS_JOINERR, "Item %s not found in layer %s.", "msPOSTGRESQLJoinConnect()", join->from, layer->name); return MS_FAILURE; } return MS_SUCCESS; }
/* * * main * */ int main(int argc, char *argv[]) { struct adhoc_opts options; int successResult; char *password = NULL; char *password_prompt = NULL; bool new_pass; set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql")); if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { usage(); exit(EXIT_SUCCESS); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { showVersion(); exit(EXIT_SUCCESS); } } #ifdef WIN32 setvbuf(stderr, NULL, _IONBF, 0); #endif setup_cancel_handler(); pset.progname = get_progname(argv[0]); pset.db = NULL; setDecimalLocale(); pset.encoding = PQenv2encoding(); pset.queryFout = stdout; pset.queryFoutPipe = false; pset.cur_cmd_source = stdin; pset.cur_cmd_interactive = false; /* We rely on unmentioned fields of pset.popt to start out 0/false/NULL */ pset.popt.topt.format = PRINT_ALIGNED; pset.popt.topt.border = 1; pset.popt.topt.pager = 1; pset.popt.topt.start_table = true; pset.popt.topt.stop_table = true; pset.popt.default_footer = true; /* We must get COLUMNS here before readline() sets it */ pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0; pset.notty = (!isatty(fileno(stdin)) || !isatty(fileno(stdout))); pset.getPassword = TRI_DEFAULT; EstablishVariableSpace(); SetVariable(pset.vars, "VERSION", PG_VERSION_STR); /* Default values for variables */ SetVariableBool(pset.vars, "AUTOCOMMIT"); SetVariable(pset.vars, "VERBOSITY", "default"); SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1); SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2); SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3); parse_psql_options(argc, argv, &options); if (!pset.popt.topt.fieldSep) pset.popt.topt.fieldSep = pg_strdup(DEFAULT_FIELD_SEP); if (!pset.popt.topt.recordSep) pset.popt.topt.recordSep = pg_strdup(DEFAULT_RECORD_SEP); if (options.username == NULL) password_prompt = pg_strdup(_("Password: "******"Password for user %s: ")) - 2 + strlen(options.username) + 1); sprintf(password_prompt, _("Password for user %s: "), options.username); } if (pset.getPassword == TRI_YES) password = simple_prompt(password_prompt, 100, false); /* loop until we have a password if requested by backend */ do { #define PARAMS_ARRAY_SIZE 8 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] = options.host; keywords[1] = "port"; values[1] = options.port; keywords[2] = "user"; values[2] = options.username; keywords[3] = "password"; values[3] = password; keywords[4] = "dbname"; values[4] = (options.action == ACT_LIST_DB && options.dbname == NULL) ? "postgres" : options.dbname; keywords[5] = "fallback_application_name"; values[5] = pset.progname; keywords[6] = "client_encoding"; values[6] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto"; keywords[7] = NULL; values[7] = NULL; new_pass = false; pset.db = PQconnectdbParams(keywords, values, true); free(keywords); free(values); if (PQstatus(pset.db) == CONNECTION_BAD && PQconnectionNeedsPassword(pset.db) && password == NULL && pset.getPassword != TRI_NO) { PQfinish(pset.db); password = simple_prompt(password_prompt, 100, false); new_pass = true; } } while (new_pass); free(password); free(password_prompt); if (PQstatus(pset.db) == CONNECTION_BAD) { fprintf(stderr, "%s: %s", pset.progname, PQerrorMessage(pset.db)); PQfinish(pset.db); exit(EXIT_BADCONN); } PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL); SyncVariables(); if (options.action == ACT_LIST_DB) { int success; if (!options.no_psqlrc) process_psqlrc(argv[0]); success = listAllDbs(false); PQfinish(pset.db); exit(success ? EXIT_SUCCESS : EXIT_FAILURE); } if (options.logfilename) { pset.logfile = fopen(options.logfilename, "a"); if (!pset.logfile) fprintf(stderr, _("%s: could not open log file \"%s\": %s\n"), pset.progname, options.logfilename, strerror(errno)); } /* * Now find something to do */ /* * process file given by -f */ if (options.action == ACT_FILE) { if (!options.no_psqlrc) process_psqlrc(argv[0]); successResult = process_file(options.action_string, options.single_txn, false); } /* * process slash command if one was given to -c */ else if (options.action == ACT_SINGLE_SLASH) { PsqlScanState scan_state; if (pset.echo == PSQL_ECHO_ALL) puts(options.action_string); scan_state = psql_scan_create(); psql_scan_setup(scan_state, options.action_string, strlen(options.action_string)); successResult = HandleSlashCmds(scan_state, NULL) != PSQL_CMD_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; psql_scan_destroy(scan_state); } /* * If the query given to -c was a normal one, send it */ else if (options.action == ACT_SINGLE_QUERY) { if (pset.echo == PSQL_ECHO_ALL) puts(options.action_string); successResult = SendQuery(options.action_string) ? EXIT_SUCCESS : EXIT_FAILURE; } /* * or otherwise enter interactive main loop */ else { if (!options.no_psqlrc) process_psqlrc(argv[0]); connection_warnings(true); if (!pset.quiet && !pset.notty) printf(_("Type \"help\" for help.\n\n")); if (!pset.notty) initializeInput(options.no_readline ? 0 : 1); if (options.action_string) /* -f - was used */ pset.inputfile = "<stdin>"; successResult = MainLoop(stdin); } /* clean up */ if (pset.logfile) fclose(pset.logfile); PQfinish(pset.db); setQFout(NULL); return successResult; }
void save_TUBii_command(client *c, int argc, sds *argv) { /* Update the TUBii state. */ uint32_t key; PGconn *conn; char conninfo[1024]; PGresult *res = NULL; char command[10000]; //char* dbname="test", dbhost="", dbuser="", dbpass=""; sprintf(conninfo, "dbname=%s host=%s user=%s password=%s", dbconfig.name, dbconfig.host, dbconfig.user, dbconfig.password); /* Now we update the database */ conn = PQconnectdb(conninfo); if (PQstatus(conn) != CONNECTION_OK) { addReplyErrorFormat(c, "connection to database failed: %s", PQerrorMessage(conn)); goto pq_error; } sprintf(command, "insert into TUBii (" "control_reg, trigger_mask, speaker_mask, counter_mask," "caen_gain_reg, caen_channel_reg, lockout_reg, dgt_reg, dac_reg," "combo_enable_mask, combo_mask, counter_mode, clock_status," "prescale_value, prescale_channel, burst_rate, burst_channel" ") " "VALUES (" "%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u" ") " "RETURNING key", mReadReg((u32) MappedRegsBaseAddress, RegOffset10), getTriggerMask(), getSpeakerMask(), getCounterMask(), mReadReg((u32) MappedRegsBaseAddress, RegOffset11), mReadReg((u32) MappedRegsBaseAddress, RegOffset12), mReadReg((u32) MappedRegsBaseAddress, RegOffset14), mReadReg((u32) MappedRegsBaseAddress, RegOffset15), mReadReg((u32) MappedRegsBaseAddress, RegOffset13), mReadReg((u32) MappedComboBaseAddress, RegOffset2), mReadReg((u32) MappedComboBaseAddress, RegOffset3), counter_mode, clockStatus(), mReadReg((u32) MappedPrescaleBaseAddress, RegOffset2), mReadReg((u32) MappedPrescaleBaseAddress, RegOffset3), mReadReg((u32) MappedBurstBaseAddress, RegOffset2), mReadReg((u32) MappedBurstBaseAddress, RegOffset3) ); res = PQexec(conn, command); if (PQresultStatus(res) != PGRES_TUPLES_OK) { addReplyErrorFormat(c, "insert command failed: %s", PQerrorMessage(conn)); goto pq_error; } if (PQnfields(res) != 1) { addReplyError(c, "failed to get key from insert"); goto pq_error; } if (safe_strtoul(PQgetvalue(res, 0, 0), &key)) { addReplyErrorFormat(c, "couldn't convert key from '%s' -> int", PQgetvalue(res, 0, 0)); goto pq_error; } PQclear(res); PQfinish(conn); addReply(c, ":%u", key); return; err: addReplyError(c, tubii_err); return; pq_error: if (res) PQclear(res); PQfinish(conn); }
/* * Connect to the server. Returns a valid PGconn pointer if connected, * or NULL on non-permanent error. On permanent error, the function will * call exit(1) directly. */ PGconn * GetConnection(void) { PGconn *tmpconn; int argcount = 7; /* dbname, replication, fallback_app_name, * host, user, port, password */ int i; const char **keywords; const char **values; const char *tmpparam; bool need_password; PQconninfoOption *conn_opts = NULL; PQconninfoOption *conn_opt; char *err_msg = NULL; /* * Merge the connection info inputs given in form of connection string, * options and default values (dbname=replication, replication=true, etc.) */ i = 0; if (connection_string) { conn_opts = PQconninfoParse(connection_string, &err_msg); if (conn_opts == NULL) { fprintf(stderr, "%s: %s", progname, err_msg); exit(1); } for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++) { if (conn_opt->val != NULL && conn_opt->val[0] != '\0') argcount++; } keywords = pg_malloc0((argcount + 1) * sizeof(*keywords)); values = pg_malloc0((argcount + 1) * sizeof(*values)); for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++) { if (conn_opt->val != NULL && conn_opt->val[0] != '\0') { keywords[i] = conn_opt->keyword; values[i] = conn_opt->val; i++; } } } else { keywords = pg_malloc0((argcount + 1) * sizeof(*keywords)); values = pg_malloc0((argcount + 1) * sizeof(*values)); } keywords[i] = "dbname"; values[i] = "replication"; i++; keywords[i] = "replication"; values[i] = "true"; i++; keywords[i] = "fallback_application_name"; values[i] = progname; i++; if (dbhost) { keywords[i] = "host"; values[i] = dbhost; i++; } if (dbuser) { keywords[i] = "user"; values[i] = dbuser; i++; } if (dbport) { keywords[i] = "port"; values[i] = dbport; i++; } /* If -W was given, force prompt for password, but only the first time */ need_password = (dbgetpassword == 1 && dbpassword == NULL); while (true) { /* Get a new password if appropriate */ if (need_password) { if (dbpassword) free(dbpassword); dbpassword = simple_prompt(_("Password: "******"password"; values[i] = dbpassword; } else { keywords[i] = NULL; values[i] = NULL; } tmpconn = PQconnectdbParams(keywords, values, true); /* * If there is too little memory even to allocate the PGconn object * and PQconnectdbParams returns NULL, we call exit(1) directly. */ if (!tmpconn) { fprintf(stderr, _("%s: could not connect to server\n"), progname); exit(1); } /* If we need a password and -w wasn't given, loop back and get one */ if (PQstatus(tmpconn) == CONNECTION_BAD && PQconnectionNeedsPassword(tmpconn) && dbgetpassword != -1) { PQfinish(tmpconn); need_password = true; } else break; } if (PQstatus(tmpconn) != CONNECTION_OK) { fprintf(stderr, _("%s: could not connect to server: %s\n"), progname, PQerrorMessage(tmpconn)); PQfinish(tmpconn); free(values); free(keywords); if (conn_opts) PQconninfoFree(conn_opts); return NULL; } /* Connection ok! */ free(values); free(keywords); if (conn_opts) PQconninfoFree(conn_opts); /* * Ensure we have the same value of integer timestamps as the server we * are connecting to. */ tmpparam = PQparameterStatus(tmpconn, "integer_datetimes"); if (!tmpparam) { fprintf(stderr, _("%s: could not determine server setting for integer_datetimes\n"), progname); PQfinish(tmpconn); exit(1); } #ifdef HAVE_INT64_TIMESTAMP if (strcmp(tmpparam, "on") != 0) #else if (strcmp(tmpparam, "off") != 0) #endif { fprintf(stderr, _("%s: integer_datetimes compile flag does not match server\n"), progname); PQfinish(tmpconn); exit(1); } return tmpconn; }
/* * Receive a tar format stream from the connection to the server, and unpack * the contents of it into a directory. Only files, directories and * symlinks are supported, no other kinds of special files. * * If the data is for the main data directory, it will be restored in the * specified directory. If it's for another tablespace, it will be restored * in the original directory, since relocation of tablespaces is not * supported. */ static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) { char current_path[MAXPGPATH]; char filename[MAXPGPATH]; int current_len_left; int current_padding = 0; bool basetablespace = PQgetisnull(res, rownum, 0); char *copybuf = NULL; FILE *file = NULL; if (basetablespace) strcpy(current_path, basedir); else strcpy(current_path, PQgetvalue(res, rownum, 1)); /* * Get the COPY data */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COPY_OUT) { fprintf(stderr, _("%s: could not get COPY data stream: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } while (1) { int r; if (copybuf != NULL) { PQfreemem(copybuf); copybuf = NULL; } r = PQgetCopyData(conn, ©buf, 0); if (r == -1) { /* * End of chunk */ if (file) fclose(file); break; } else if (r == -2) { fprintf(stderr, _("%s: could not read COPY data: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (file == NULL) { int filemode; /* * No current file, so this must be the header for a new file */ if (r != 512) { fprintf(stderr, _("%s: invalid tar block header size: %d\n"), progname, r); disconnect_and_exit(1); } totaldone += 512; if (sscanf(copybuf + 124, "%11o", ¤t_len_left) != 1) { fprintf(stderr, _("%s: could not parse file size\n"), progname); disconnect_and_exit(1); } /* Set permissions on the file */ if (sscanf(©buf[100], "%07o ", &filemode) != 1) { fprintf(stderr, _("%s: could not parse file mode\n"), progname); disconnect_and_exit(1); } /* * All files are padded up to 512 bytes */ current_padding = ((current_len_left + 511) & ~511) - current_len_left; /* * First part of header is zero terminated filename */ snprintf(filename, sizeof(filename), "%s/%s", current_path, copybuf); if (filename[strlen(filename) - 1] == '/') { /* * Ends in a slash means directory or symlink to directory */ if (copybuf[156] == '5') { /* * Directory */ filename[strlen(filename) - 1] = '\0'; /* Remove trailing slash */ if (mkdir(filename, S_IRWXU) != 0) { /* * When streaming WAL, pg_xlog will have been created * by the wal receiver process. Also, when transaction * log directory location was specified, pg_xlog has * already been created as a symbolic link before * starting the actual backup. So just ignore failure * on them. */ if ((!streamwal && (strcmp(xlog_dir, "") == 0)) || strcmp(filename + strlen(filename) - 8, "/pg_xlog") != 0) { fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"), progname, filename, strerror(errno)); disconnect_and_exit(1); } } #ifndef WIN32 if (chmod(filename, (mode_t) filemode)) fprintf(stderr, _("%s: could not set permissions on directory \"%s\": %s\n"), progname, filename, strerror(errno)); #endif } else if (copybuf[156] == '2') { /* * Symbolic link */ filename[strlen(filename) - 1] = '\0'; /* Remove trailing slash */ if (symlink(©buf[157], filename) != 0) { fprintf(stderr, _("%s: could not create symbolic link from \"%s\" to \"%s\": %s\n"), progname, filename, ©buf[157], strerror(errno)); disconnect_and_exit(1); } } else { fprintf(stderr, _("%s: unrecognized link indicator \"%c\"\n"), progname, copybuf[156]); disconnect_and_exit(1); } continue; /* directory or link handled */ } /* * regular file */ file = fopen(filename, "wb"); if (!file) { fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno)); disconnect_and_exit(1); } #ifndef WIN32 if (chmod(filename, (mode_t) filemode)) fprintf(stderr, _("%s: could not set permissions on file \"%s\": %s\n"), progname, filename, strerror(errno)); #endif if (current_len_left == 0) { /* * Done with this file, next one will be a new tar header */ fclose(file); file = NULL; continue; } } /* new file */ else { /* * Continuing blocks in existing file */ if (current_len_left == 0 && r == current_padding) { /* * Received the padding block for this file, ignore it and * close the file, then move on to the next tar header. */ fclose(file); file = NULL; totaldone += r; continue; } if (fwrite(copybuf, r, 1, file) != 1) { fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), progname, filename, strerror(errno)); disconnect_and_exit(1); } totaldone += r; if (showprogress) progress_report(rownum, filename); current_len_left -= r; if (current_len_left == 0 && current_padding == 0) { /* * Received the last block, and there is no padding to be * expected. Close the file and move on to the next tar * header. */ fclose(file); file = NULL; continue; } } /* continuing data in existing file */ } /* loop over all data blocks */ if (file != NULL) { fprintf(stderr, _("%s: COPY stream ended before last file was finished\n"), progname); disconnect_and_exit(1); } if (copybuf != NULL) PQfreemem(copybuf); if (basetablespace && writerecoveryconf) WriteRecoveryConf(); }
int main (int argc, char **argv) { /* Local Vars */ PGconn *conn; PGresult *res; char *val, *val2; float delay = 0; /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) critical("Setup SIGALRM trap failed!"); /* Process check arguments */ if (process_arguments(argc, argv) != OK) unknown("Parsing arguments failed!"); /* Start plugin timeout */ alarm(mp_timeout); /* Connectiong to PostgreSQL server */ conn = mp_pgsql_init(); /* Check Recovery state */ res = mp_pgsql_exec(conn, "SELECT pg_is_in_recovery() AS recovery, NOW() - pg_last_xact_replay_timestamp() AS replication_delay;"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { critical("Query 'SELECT pg_is_in_recovery() AS recovery, NOW() - pg_last_xact_replay_timestamp() AS replication_delay;' failed: %s", PQerrorMessage(conn)); } val = PQgetvalue(res, 0, 0); if (val[0] == 'f') { mp_pgsql_deinit(conn); critical("PostgreSQL is not in recover mode."); } /* Calculate delay */ val = PQgetvalue(res, 0, 1); delay = strtol(val, &val2, 10) * 3600; delay += strtol(++val2, NULL,10) * 60; delay += strtof((val2+=3), NULL); val = strdup(val); mp_pgsql_deinit(conn); mp_perfdata_float("delay", (float)delay, "s", delay_thresholds); switch(get_status(delay, delay_thresholds)) { case STATE_OK: free_threshold(delay_thresholds); ok("PostgreSQL Slave Delay: %s", val); break; case STATE_WARNING: free_threshold(delay_thresholds); warning("PostgreSQL Slave Delay: %s", val); break; case STATE_CRITICAL: free_threshold(delay_thresholds); critical("PostgreSQL Slave Delay: %s", val); break; } free_threshold(delay_thresholds); critical("You should never reach this point."); }
static void BaseBackup(void) { PGresult *res; char *sysidentifier; uint32 latesttli; uint32 starttli; char current_path[MAXPGPATH]; char escaped_label[MAXPGPATH]; int i; char xlogstart[64]; char xlogend[64]; int minServerMajor, maxServerMajor; int serverMajor; /* * Connect in replication mode to the server */ conn = GetConnection(); if (!conn) /* Error message already written in GetConnection() */ exit(1); /* * Check server version. BASE_BACKUP command was introduced in 9.1, so we * can't work with servers older than 9.1. */ minServerMajor = 901; maxServerMajor = PG_VERSION_NUM / 100; serverMajor = PQserverVersion(conn) / 100; if (serverMajor < minServerMajor || serverMajor > maxServerMajor) { const char *serverver = PQparameterStatus(conn, "server_version"); fprintf(stderr, _("%s: incompatible server version %s\n"), progname, serverver ? serverver : "'unknown'"); disconnect_and_exit(1); } /* * If WAL streaming was requested, also check that the server is new * enough for that. */ if (streamwal && !CheckServerVersionForStreaming(conn)) { /* Error message already written in CheckServerVersionForStreaming() */ disconnect_and_exit(1); } /* * Build contents of recovery.conf if requested */ if (writerecoveryconf) GenerateRecoveryConf(conn); /* * Run IDENTIFY_SYSTEM so we can get the timeline */ res = PQexec(conn, "IDENTIFY_SYSTEM"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), progname, "IDENTIFY_SYSTEM", PQerrorMessage(conn)); disconnect_and_exit(1); } if (PQntuples(res) != 1 || PQnfields(res) != 3) { fprintf(stderr, _("%s: could not identify system: got %d rows and %d fields, expected %d rows and %d fields\n"), progname, PQntuples(res), PQnfields(res), 1, 3); disconnect_and_exit(1); } sysidentifier = pg_strdup(PQgetvalue(res, 0, 0)); latesttli = atoi(PQgetvalue(res, 0, 1)); PQclear(res); /* * Start the actual backup */ PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i); snprintf(current_path, sizeof(current_path), "BASE_BACKUP LABEL '%s' %s %s %s %s", escaped_label, showprogress ? "PROGRESS" : "", includewal && !streamwal ? "WAL" : "", fastcheckpoint ? "FAST" : "", includewal ? "NOWAIT" : ""); if (PQsendQuery(conn, current_path) == 0) { fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), progname, "BASE_BACKUP", PQerrorMessage(conn)); disconnect_and_exit(1); } /* * Get the starting xlog position */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, _("%s: could not initiate base backup: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (PQntuples(res) != 1) { fprintf(stderr, _("%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n"), progname, PQntuples(res), PQnfields(res), 1, 2); disconnect_and_exit(1); } strcpy(xlogstart, PQgetvalue(res, 0, 0)); /* * 9.3 and later sends the TLI of the starting point. With older servers, * assume it's the same as the latest timeline reported by * IDENTIFY_SYSTEM. */ if (PQnfields(res) >= 2) starttli = atoi(PQgetvalue(res, 0, 1)); else starttli = latesttli; PQclear(res); MemSet(xlogend, 0, sizeof(xlogend)); if (verbose && includewal) fprintf(stderr, _("transaction log start point: %s on timeline %u\n"), xlogstart, starttli); /* * Get the header */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, _("%s: could not get backup header: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (PQntuples(res) < 1) { fprintf(stderr, _("%s: no data returned from server\n"), progname); disconnect_and_exit(1); } /* * Sum up the total size, for progress reporting */ totalsize = totaldone = 0; tablespacecount = PQntuples(res); for (i = 0; i < PQntuples(res); i++) { if (showprogress) totalsize += atol(PQgetvalue(res, i, 2)); /* * Verify tablespace directories are empty. Don't bother with the * first once since it can be relocated, and it will be checked before * we do anything anyway. */ if (format == 'p' && !PQgetisnull(res, i, 1)) verify_dir_is_empty_or_create(PQgetvalue(res, i, 1)); } /* * When writing to stdout, require a single tablespace */ if (format == 't' && strcmp(basedir, "-") == 0 && PQntuples(res) > 1) { fprintf(stderr, _("%s: can only write single tablespace to stdout, database has %d\n"), progname, PQntuples(res)); disconnect_and_exit(1); } /* * If we're streaming WAL, start the streaming session before we start * receiving the actual data chunks. */ if (streamwal) { if (verbose) fprintf(stderr, _("%s: starting background WAL receiver\n"), progname); StartLogStreamer(xlogstart, starttli, sysidentifier); } /* * Start receiving chunks */ for (i = 0; i < PQntuples(res); i++) { if (format == 't') ReceiveTarFile(conn, res, i); else ReceiveAndUnpackTarFile(conn, res, i); } /* Loop over all tablespaces */ if (showprogress) { progress_report(PQntuples(res), NULL); fprintf(stderr, "\n"); /* Need to move to next line */ } PQclear(res); /* * Get the stop position */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, _("%s: could not get transaction log end position from server: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (PQntuples(res) != 1) { fprintf(stderr, _("%s: no transaction log end position returned from server\n"), progname); disconnect_and_exit(1); } strcpy(xlogend, PQgetvalue(res, 0, 0)); if (verbose && includewal) fprintf(stderr, "transaction log end point: %s\n", xlogend); PQclear(res); res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, _("%s: final receive failed: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (bgchild > 0) { #ifndef WIN32 int status; int r; #else DWORD status; uint32 hi, lo; #endif if (verbose) fprintf(stderr, _("%s: waiting for background process to finish streaming ...\n"), progname); #ifndef WIN32 if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend)) { fprintf(stderr, _("%s: could not send command to background pipe: %s\n"), progname, strerror(errno)); disconnect_and_exit(1); } /* Just wait for the background process to exit */ r = waitpid(bgchild, &status, 0); if (r == -1) { fprintf(stderr, _("%s: could not wait for child process: %s\n"), progname, strerror(errno)); disconnect_and_exit(1); } if (r != bgchild) { fprintf(stderr, _("%s: child %d died, expected %d\n"), progname, r, (int) bgchild); disconnect_and_exit(1); } if (!WIFEXITED(status)) { fprintf(stderr, _("%s: child process did not exit normally\n"), progname); disconnect_and_exit(1); } if (WEXITSTATUS(status) != 0) { fprintf(stderr, _("%s: child process exited with error %d\n"), progname, WEXITSTATUS(status)); disconnect_and_exit(1); } /* Exited normally, we're happy! */ #else /* WIN32 */ /* * On Windows, since we are in the same process, we can just store the * value directly in the variable, and then set the flag that says * it's there. */ if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2) { fprintf(stderr, _("%s: could not parse transaction log location \"%s\"\n"), progname, xlogend); disconnect_and_exit(1); } xlogendptr = ((uint64) hi) << 32 | lo; InterlockedIncrement(&has_xlogendptr); /* First wait for the thread to exit */ if (WaitForSingleObjectEx((HANDLE) bgchild, INFINITE, FALSE) != WAIT_OBJECT_0) { _dosmaperr(GetLastError()); fprintf(stderr, _("%s: could not wait for child thread: %s\n"), progname, strerror(errno)); disconnect_and_exit(1); } if (GetExitCodeThread((HANDLE) bgchild, &status) == 0) { _dosmaperr(GetLastError()); fprintf(stderr, _("%s: could not get child thread exit status: %s\n"), progname, strerror(errno)); disconnect_and_exit(1); } if (status != 0) { fprintf(stderr, _("%s: child thread exited with error %u\n"), progname, (unsigned int) status); disconnect_and_exit(1); } /* Exited normally, we're happy */ #endif } /* Free the recovery.conf contents */ destroyPQExpBuffer(recoveryconfcontents); /* * End of copy data. Final result is already checked inside the loop. */ PQclear(res); PQfinish(conn); if (verbose) fprintf(stderr, "%s: base backup completed\n", progname); }
/* * Receive a tar format file from the connection to the server, and write * the data from this file directly into a tar file. If compression is * enabled, the data will be compressed while written to the file. * * The file will be named base.tar[.gz] if it's for the main data directory * or <tablespaceoid>.tar[.gz] if it's for another tablespace. * * No attempt to inspect or validate the contents of the file is done. */ static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) { char filename[MAXPGPATH]; char *copybuf = NULL; FILE *tarfile = NULL; char tarhdr[512]; bool basetablespace = PQgetisnull(res, rownum, 0); bool in_tarhdr = true; bool skip_file = false; size_t tarhdrsz = 0; size_t filesz = 0; #ifdef HAVE_LIBZ gzFile ztarfile = NULL; #endif if (basetablespace) { /* * Base tablespaces */ if (strcmp(basedir, "-") == 0) { #ifdef HAVE_LIBZ if (compresslevel != 0) { ztarfile = gzdopen(dup(fileno(stdout)), "wb"); if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif tarfile = stdout; } else { #ifdef HAVE_LIBZ if (compresslevel != 0) { snprintf(filename, sizeof(filename), "%s/base.tar.gz", basedir); ztarfile = gzopen(filename, "wb"); if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif { snprintf(filename, sizeof(filename), "%s/base.tar", basedir); tarfile = fopen(filename, "wb"); } } } else { /* * Specific tablespace */ #ifdef HAVE_LIBZ if (compresslevel != 0) { snprintf(filename, sizeof(filename), "%s/%s.tar.gz", basedir, PQgetvalue(res, rownum, 0)); ztarfile = gzopen(filename, "wb"); if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif { snprintf(filename, sizeof(filename), "%s/%s.tar", basedir, PQgetvalue(res, rownum, 0)); tarfile = fopen(filename, "wb"); } } #ifdef HAVE_LIBZ if (compresslevel != 0) { if (!ztarfile) { /* Compression is in use */ fprintf(stderr, _("%s: could not create compressed file \"%s\": %s\n"), progname, filename, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif { /* Either no zlib support, or zlib support but compresslevel = 0 */ if (!tarfile) { fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno)); disconnect_and_exit(1); } } /* * Get the COPY data stream */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COPY_OUT) { fprintf(stderr, _("%s: could not get COPY data stream: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } while (1) { int r; if (copybuf != NULL) { PQfreemem(copybuf); copybuf = NULL; } r = PQgetCopyData(conn, ©buf, 0); if (r == -1) { /* * End of chunk. If requested, and this is the base tablespace, * write recovery.conf into the tarfile. When done, close the file * (but not stdout). * * Also, write two completely empty blocks at the end of the tar * file, as required by some tar programs. */ char zerobuf[1024]; MemSet(zerobuf, 0, sizeof(zerobuf)); if (basetablespace && writerecoveryconf) { char header[512]; int padding; tarCreateHeader(header, "recovery.conf", NULL, recoveryconfcontents->len, 0600, 04000, 02000, time(NULL)); padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len; WRITE_TAR_DATA(header, sizeof(header)); WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len); if (padding) WRITE_TAR_DATA(zerobuf, padding); } /* 2 * 512 bytes empty data at end of file */ WRITE_TAR_DATA(zerobuf, sizeof(zerobuf)); #ifdef HAVE_LIBZ if (ztarfile != NULL) { if (gzclose(ztarfile) != 0) { fprintf(stderr, _("%s: could not close compressed file \"%s\": %s\n"), progname, filename, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif { if (strcmp(basedir, "-") != 0) { if (fclose(tarfile) != 0) { fprintf(stderr, _("%s: could not close file \"%s\": %s\n"), progname, filename, strerror(errno)); disconnect_and_exit(1); } } } break; } else if (r == -2) { fprintf(stderr, _("%s: could not read COPY data: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } if (!writerecoveryconf || !basetablespace) { /* * When not writing recovery.conf, or when not working on the base * tablespace, we never have to look for an existing recovery.conf * file in the stream. */ WRITE_TAR_DATA(copybuf, r); } else { /* * Look for a recovery.conf in the existing tar stream. If it's * there, we must skip it so we can later overwrite it with our * own version of the file. * * To do this, we have to process the individual files inside the * TAR stream. The stream consists of a header and zero or more * chunks, all 512 bytes long. The stream from the server is * broken up into smaller pieces, so we have to track the size of * the files to find the next header structure. */ int rr = r; int pos = 0; while (rr > 0) { if (in_tarhdr) { /* * We're currently reading a header structure inside the * TAR stream, i.e. the file metadata. */ if (tarhdrsz < 512) { /* * Copy the header structure into tarhdr in case the * header is not aligned to 512 bytes or it's not * returned in whole by the last PQgetCopyData call. */ int hdrleft; int bytes2copy; hdrleft = 512 - tarhdrsz; bytes2copy = (rr > hdrleft ? hdrleft : rr); memcpy(&tarhdr[tarhdrsz], copybuf + pos, bytes2copy); rr -= bytes2copy; pos += bytes2copy; tarhdrsz += bytes2copy; } else { /* * We have the complete header structure in tarhdr, * look at the file metadata: - the subsequent file * contents have to be skipped if the filename is * recovery.conf - find out the size of the file * padded to the next multiple of 512 */ int padding; skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0); sscanf(&tarhdr[124], "%11o", (unsigned int *) &filesz); padding = ((filesz + 511) & ~511) - filesz; filesz += padding; /* Next part is the file, not the header */ in_tarhdr = false; /* * If we're not skipping the file, write the tar * header unmodified. */ if (!skip_file) WRITE_TAR_DATA(tarhdr, 512); } } else { /* * We're processing a file's contents. */ if (filesz > 0) { /* * We still have data to read (and possibly write). */ int bytes2write; bytes2write = (filesz > rr ? rr : filesz); if (!skip_file) WRITE_TAR_DATA(copybuf + pos, bytes2write); rr -= bytes2write; pos += bytes2write; filesz -= bytes2write; } else { /* * No more data in the current file, the next piece of * data (if any) will be a new file header structure. */ in_tarhdr = true; skip_file = false; tarhdrsz = 0; filesz = 0; } } } } totaldone += r; if (showprogress) progress_report(rownum, filename); } /* while (1) */ if (copybuf != NULL) PQfreemem(copybuf); }
int nominatim_import(const char *conninfo, const char *partionTagsFilename, const char *filename) { xmlTextReaderPtr reader; int ret = 0; PGresult * res; FILE * partionTagsFile; char * partionQueryName; char partionQuerySQL[1024]; conn = PQconnectdb(conninfo); if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } partionTableTagsHash = xmlHashCreate(200); partionTableTagsHashDelete = xmlHashCreate(200); partionTagsFile = fopen(partionTagsFilename, "rt"); if (!partionTagsFile) { fprintf(stderr, "Unable to read partition tags file: %s\n", partionTagsFilename); exit(EXIT_FAILURE); } char buffer[1024], osmkey[256], osmvalue[256]; int fields; while (fgets(buffer, sizeof(buffer), partionTagsFile) != NULL) { fields = sscanf( buffer, "%23s %63s", osmkey, osmvalue ); if ( fields <= 0 ) continue; if ( fields != 2 ) { fprintf( stderr, "Error partition file\n"); exit_nicely(); } partionQueryName = malloc(strlen("partition_insert_")+strlen(osmkey)+strlen(osmvalue)+2); strcpy(partionQueryName, "partition_insert_"); strcat(partionQueryName, osmkey); strcat(partionQueryName, "_"); strcat(partionQueryName, osmvalue); strcpy(partionQuerySQL, "insert into place_classtype_"); strcat(partionQuerySQL, osmkey); strcat(partionQuerySQL, "_"); strcat(partionQuerySQL, osmvalue); strcat(partionQuerySQL, " (place_id, centroid) values ($1, ST_Centroid(st_setsrid($2, 4326)))"); res = PQprepare(conn, partionQueryName, partionQuerySQL, 2, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare %s: %s\n", partionQueryName, PQerrorMessage(conn)); exit(EXIT_FAILURE); } xmlHashAddEntry2(partionTableTagsHash, BAD_CAST osmkey, BAD_CAST osmvalue, BAD_CAST partionQueryName); partionQueryName = malloc(strlen("partition_delete_")+strlen(osmkey)+strlen(osmvalue)+2); strcpy(partionQueryName, "partition_delete_"); strcat(partionQueryName, osmkey); strcat(partionQueryName, "_"); strcat(partionQueryName, osmvalue); strcpy(partionQuerySQL, "delete from place_classtype_"); strcat(partionQuerySQL, osmkey); strcat(partionQuerySQL, "_"); strcat(partionQuerySQL, osmvalue); strcat(partionQuerySQL, " where place_id = $1::integer"); res = PQprepare(conn, partionQueryName, partionQuerySQL, 1, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare %s: %s\n", partionQueryName, PQerrorMessage(conn)); exit(EXIT_FAILURE); } xmlHashAddEntry2(partionTableTagsHashDelete, BAD_CAST osmkey, BAD_CAST osmvalue, BAD_CAST partionQueryName); } res = PQprepare(conn, "get_new_place_id", "select nextval('seq_place')", 0, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare get_new_place_id: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } res = PQprepare(conn, "get_place_id", "select place_id from placex where osm_type = $1 and osm_id = $2 and class = $3 and type = $4", 4, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare get_place_id: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } res = PQprepare(conn, "placex_insert", "insert into placex (place_id,osm_type,osm_id,class,type,name,country_code,extratags,parent_place_id,admin_level,housenumber,rank_address,rank_search,geometry) " "values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, st_setsrid($14, 4326))", 12, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare placex_insert: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } res = PQprepare(conn, "search_name_insert", "insert into search_name (place_id, search_rank, address_rank, country_code, name_vector, nameaddress_vector, centroid) " "select place_id, rank_search, rank_address, country_code, make_keywords(name), " "(select uniq(sort(array_agg(parent_search_name.name_vector))) from search_name as parent_search_name where place_id in " "(select distinct address_place_id from place_addressline where place_addressline.place_id = $1 limit 1000)" "), st_centroid(geometry) from placex " "where place_id = $1", 1, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare search_name_insert: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } res = PQprepare(conn, "search_name_from_parent_insert", "insert into search_name (place_id, search_rank, address_rank, country_code, name_vector, nameaddress_vector, centroid) " "select place_id, rank_search, rank_address, country_code, make_keywords(name), " "(select uniq(sort(name_vector+nameaddress_vector)) from search_name as parent_search_name " "where parent_search_name.place_id = $2 ), st_centroid(geometry) from placex " "where place_id = $1", 2, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare search_name_insert: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } res = PQprepare(conn, "place_addressline_insert", "insert into place_addressline (place_id, address_place_id, fromarea, isaddress, distance, cached_rank_address) " "select $1, place_id, false, $7, $2, rank_address from placex where osm_type = $3 and osm_id = $4 and class = $5 and type = $6", 7, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare place_addressline_insert: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } res = PQprepare(conn, "placex_delete", "delete from placex where place_id = $1", 1, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare placex_delete: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } res = PQprepare(conn, "search_name_delete", "delete from search_name where place_id = $1", 1, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare search_name_delete: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } res = PQprepare(conn, "place_addressline_delete", "delete from place_addressline where place_id = $1", 1, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Failed to prepare place_addressline_delete: %s\n", PQerrorMessage(conn)); exit(EXIT_FAILURE); } featureCount = 0; reader = inputUTF8(filename); if (reader == NULL) { fprintf(stderr, "Unable to open %s\n", filename); return 1; } ret = xmlTextReaderRead(reader); while (ret == 1) { processNode(reader); ret = xmlTextReaderRead(reader); } if (ret != 0) { fprintf(stderr, "%s : failed to parse\n", filename); return ret; } xmlFreeTextReader(reader); xmlHashFree(partionTableTagsHash, NULL); xmlHashFree(partionTableTagsHashDelete, NULL); return 0; }
void EndElement(xmlTextReaderPtr reader, const xmlChar *name) { PGresult * res; const char * paramValues[14]; char * place_id; char * partionQueryName; int i, namePos, lineTypeLen, lineValueLen; if (xmlStrEqual(name, BAD_CAST "feature")) { featureCount++; if (featureCount % 1000 == 0) printf("feature %i(k)\n", featureCount/1000); /* if (fileMode == FILEMODE_ADD) { resPlaceID = PQexecPrepared(conn, "get_new_place_id", 0, NULL, NULL, NULL, 0); if (PQresultStatus(resPlaceID) != PGRES_TUPLES_OK) { fprintf(stderr, "get_place_id: INSERT failed: %s", PQerrorMessage(conn)); PQclear(resPlaceID); exit(EXIT_FAILURE); } } else { paramValues[0] = (const char *)feature.type; paramValues[1] = (const char *)feature.id; paramValues[2] = (const char *)feature.key; paramValues[3] = (const char *)feature.value; resPlaceID = PQexecPrepared(conn, "get_new_place_id", 4, paramValues, NULL, NULL, 0); if (PQresultStatus(resPlaceID) != PGRES_TUPLES_OK) { fprintf(stderr, "index_placex: INSERT failed: %s", PQerrorMessage(conn)); PQclear(resPlaceID); exit(EXIT_FAILURE); } } */ place_id = (char *)feature.placeID; if (fileMode == FILEMODE_UPDATE || fileMode == FILEMODE_DELETE || fileMode == FILEMODE_ADD) { paramValues[0] = (const char *)place_id; if (verbose) fprintf(stderr, "placex_delete: %s\n", paramValues[0]); res = PQexecPrepared(conn, "placex_delete", 1, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "placex_delete: DELETE failed: %s", PQerrorMessage(conn)); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); if (verbose) fprintf(stderr, "search_name_delete: %s\n", paramValues[0]); res = PQexecPrepared(conn, "search_name_delete", 1, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "search_name_delete: DELETE failed: %s", PQerrorMessage(conn)); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); if (verbose) fprintf(stderr, "place_addressline_delete: %s\n", paramValues[0]); res = PQexecPrepared(conn, "place_addressline_delete", 1, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "place_addressline_delete: DELETE failed: %s", PQerrorMessage(conn)); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); partionQueryName = xmlHashLookup2(partionTableTagsHashDelete, feature.key, feature.value); if (partionQueryName) { res = PQexecPrepared(conn, partionQueryName, 1, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "%s: DELETE failed: %s", partionQueryName, PQerrorMessage(conn)); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); } } if (fileMode == FILEMODE_UPDATE || fileMode == FILEMODE_ADD) { // Insert into placex paramValues[0] = (const char *)place_id; paramValues[1] = (const char *)feature.type; paramValues[2] = (const char *)feature.id; paramValues[3] = (const char *)feature.key; paramValues[4] = (const char *)feature.value; featureNameString[0] = 0; if (featureNameLines) { namePos = 0; lineTypeLen = 0; lineValueLen = 0; for (i = 0; i < featureNameLines; i++) { lineTypeLen = (int)strlen((char *) featureName[i].type); lineValueLen = (int)strlen((char *) featureName[i].value); if (namePos+lineTypeLen+lineValueLen+7 > MAX_FEATURENAMESTRING) { fprintf(stderr, "feature name too long: %s", (const char *)featureName[i].value); break; } if (namePos) strcpy(featureNameString+(namePos++), ","); strcpy(featureNameString+(namePos++), "\""); strcpy(featureNameString+namePos, (char*) featureName[i].type); namePos += lineTypeLen; strcpy(featureNameString+namePos, "\"=>\""); namePos += 4; strcpy(featureNameString+namePos, (char *) featureName[i].value); namePos += lineValueLen; strcpy(featureNameString+(namePos++), "\""); xmlFree(featureName[i].type); xmlFree(featureName[i].value); } } paramValues[5] = (const char *)featureNameString; paramValues[6] = (const char *)feature.countryCode; featureExtraTagString[0] = 0; if (featureExtraTagLines) { namePos = 0; lineTypeLen = 0; lineValueLen = 0; for (i = 0; i < featureExtraTagLines; i++) { lineTypeLen = strlen((char *) featureExtraTag[i].type); lineValueLen = strlen((char *) featureExtraTag[i].value); if (namePos+lineTypeLen+lineValueLen+7 > MAX_FEATUREEXTRATAGSTRING) { fprintf(stderr, "feature extra tag too long: %s", (const char *)featureExtraTag[i].value); break; } if (namePos) strcpy(featureExtraTagString+(namePos++),","); strcpy(featureExtraTagString+(namePos++), "\""); strcpy(featureExtraTagString+namePos, (char *) featureExtraTag[i].type); namePos += lineTypeLen; strcpy(featureExtraTagString+namePos, "\"=>\""); namePos += 4; strcpy(featureExtraTagString+namePos, (char *) featureExtraTag[i].value); namePos += lineValueLen; strcpy(featureExtraTagString+(namePos++), "\""); xmlFree(featureExtraTag[i].type); xmlFree(featureExtraTag[i].value); } } paramValues[7] = (const char *)featureExtraTagString; if (strlen(feature.parentPlaceID) == 0) paramValues[8] = "0"; else paramValues[8] = (const char *)feature.parentPlaceID; paramValues[9] = (const char *)feature.adminLevel; paramValues[10] = (const char *)feature.houseNumber; paramValues[11] = (const char *)feature.rankAddress; paramValues[12] = (const char *)feature.rankSearch; paramValues[13] = (const char *)feature.geometry; if (strlen(paramValues[3]) && strlen(paramValues[13])) { if (verbose) fprintf(stderr, "placex_insert: %s\n", paramValues[0]); res = PQexecPrepared(conn, "placex_insert", 14, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "index_placex: INSERT failed: %s", PQerrorMessage(conn)); fprintf(stderr, "index_placex: INSERT failed: %s %s %s", paramValues[0], paramValues[1], paramValues[2]); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); } for (i = 0; i < featureAddressLines; i++) { // insert into place_address paramValues[0] = (const char *)place_id; paramValues[1] = (const char *)featureAddress[i].distance; if (paramValues[1] == NULL || strlen(paramValues[1]) == 0) paramValues[1] = "0"; paramValues[2] = (const char *)featureAddress[i].type; paramValues[3] = (const char *)featureAddress[i].id; paramValues[4] = (const char *)featureAddress[i].key; paramValues[5] = (const char *)featureAddress[i].value; paramValues[6] = (const char *)featureAddress[i].isAddress; if (verbose) fprintf(stderr, "placex_insert: %s %s\n", paramValues[2], paramValues[3]); res = PQexecPrepared(conn, "place_addressline_insert", 7, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "place_addressline_insert: INSERT failed: %s", PQerrorMessage(conn)); fprintf(stderr, "(%s,%s,%s,%s,%s,%s,%s)",paramValues[0],paramValues[1],paramValues[2],paramValues[3],paramValues[4],paramValues[5],paramValues[6]); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); xmlFree(featureAddress[i].type); xmlFree(featureAddress[i].id); xmlFree(featureAddress[i].key); xmlFree(featureAddress[i].value); xmlFree(featureAddress[i].distance); } if (featureNameLines) { if (strlen(feature.parentPlaceID) > 0 && featureAddressLines == 0) { paramValues[0] = (const char *)place_id; paramValues[1] = feature.parentPlaceID; if (verbose) fprintf(stderr, "search_name_from_parent_insert: INSERT %s %s\n", paramValues[0], paramValues[1]); res = PQexecPrepared(conn, "search_name_from_parent_insert", 2, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "search_name_from_parent_insert: INSERT failed: %s", PQerrorMessage(conn)); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); } else { paramValues[0] = (const char *)place_id; if (verbose) fprintf(stderr, "search_name_insert: INSERT %s\n", paramValues[0]); res = PQexecPrepared(conn, "search_name_insert", 1, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "search_name_insert: INSERT failed: %s", PQerrorMessage(conn)); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); } } partionQueryName = xmlHashLookup2(partionTableTagsHash, feature.key, feature.value); if (partionQueryName) { // insert into partition table paramValues[0] = (const char *)place_id; paramValues[1] = (const char *)feature.geometry; res = PQexecPrepared(conn, partionQueryName, 2, paramValues, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "%s: INSERT failed: %s", partionQueryName, PQerrorMessage(conn)); PQclear(res); exit(EXIT_FAILURE); } PQclear(res); } } else { for (i = 0; i < featureAddressLines; i++) { xmlFree(featureAddress[i].type); xmlFree(featureAddress[i].id); xmlFree(featureAddress[i].key); xmlFree(featureAddress[i].value); xmlFree(featureAddress[i].distance); } } xmlFree(feature.placeID); xmlFree(feature.type); xmlFree(feature.id); xmlFree(feature.key); xmlFree(feature.value); xmlFree(feature.rankAddress); xmlFree(feature.rankSearch); if (feature.countryCode) xmlFree(feature.countryCode); if (feature.parentPlaceID) xmlFree(feature.parentPlaceID); if (feature.parentType) xmlFree(feature.parentType); if (feature.parentID) xmlFree(feature.parentID); // if (feature.name) xmlFree(feature.name); if (feature.adminLevel) xmlFree(feature.adminLevel); if (feature.houseNumber) xmlFree(feature.houseNumber); if (feature.geometry) xmlFree(feature.geometry); // PQclear(resPlaceID); } }
int main(int argc, char *argv[]) { static struct option long_options[] = { {"list", no_argument, NULL, 'l'}, {"host", required_argument, NULL, 'h'}, {"port", required_argument, NULL, 'p'}, {"username", required_argument, NULL, 'U'}, {"no-password", no_argument, NULL, 'w'}, {"password", no_argument, NULL, 'W'}, {"dbname", required_argument, NULL, 'd'}, {"echo", no_argument, NULL, 'e'}, {NULL, 0, NULL, 0} }; const char *progname; int optindex; int c; bool listlangs = false; const char *dbname = NULL; char *host = NULL; char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; bool echo = false; char *langname = NULL; char *p; PQExpBufferData sql; PGconn *conn; PGresult *result; progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); handle_help_version_opts(argc, argv, "createlang", help); while ((c = getopt_long(argc, argv, "lh:p:U:wWd:e", long_options, &optindex)) != -1) { switch (c) { case 'l': listlangs = true; break; case 'h': host = optarg; break; case 'p': port = optarg; break; case 'U': username = optarg; break; case 'w': prompt_password = TRI_NO; break; case 'W': prompt_password = TRI_YES; break; case 'd': dbname = optarg; break; case 'e': echo = true; break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } } if (argc - optind > 0) { if (listlangs) dbname = argv[optind++]; else { langname = argv[optind++]; if (argc - optind > 0) dbname = argv[optind++]; } } if (argc - optind > 0) { fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } if (dbname == NULL) { if (getenv("PGDATABASE")) dbname = getenv("PGDATABASE"); else if (getenv("PGUSER")) dbname = getenv("PGUSER"); else dbname = get_user_name(progname); } initPQExpBuffer(&sql); /* * List option */ if (listlangs) { printQueryOpt popt; static const bool translate_columns[] = {false, true}; conn = connectDatabase(dbname, host, port, username, prompt_password, progname); printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", " "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" " "FROM pg_catalog.pg_language WHERE lanispl;", gettext_noop("Name"), gettext_noop("yes"), gettext_noop("no"), gettext_noop("Trusted?")); result = executeQuery(conn, sql.data, progname, echo); memset(&popt, 0, sizeof(popt)); popt.topt.format = PRINT_ALIGNED; popt.topt.border = 1; popt.topt.start_table = true; popt.topt.stop_table = true; popt.topt.encoding = PQclientEncoding(conn); popt.title = _("Procedural Languages"); popt.translate_header = true; popt.translate_columns = translate_columns; printQuery(result, &popt, stdout, NULL); PQfinish(conn); exit(0); } if (langname == NULL) { fprintf(stderr, _("%s: missing required argument language name\n"), progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } for (p = langname; *p; p++) if (*p >= 'A' && *p <= 'Z') *p += ('a' - 'A'); conn = connectDatabase(dbname, host, port, username, prompt_password, progname); /* * Make sure the language isn't already installed */ printfPQExpBuffer(&sql, "SELECT oid FROM pg_catalog.pg_language WHERE lanname = '%s';", langname); result = executeQuery(conn, sql.data, progname, echo); if (PQntuples(result) > 0) { PQfinish(conn); fprintf(stderr, _("%s: language \"%s\" is already installed in database \"%s\"\n"), progname, langname, dbname); /* separate exit status for "already installed" */ exit(2); } PQclear(result); printfPQExpBuffer(&sql, "CREATE LANGUAGE \"%s\";\n", langname); if (echo) printf("%s", sql.data); result = PQexec(conn, sql.data); if (PQresultStatus(result) != PGRES_COMMAND_OK) { fprintf(stderr, _("%s: language installation failed: %s"), progname, PQerrorMessage(conn)); PQfinish(conn); exit(1); } PQclear(result); PQfinish(conn); exit(0); }
void *dbgPgThread::Entry( void ) { wxLogInfo( wxT( "worker thread waiting for some work to do..." )); // This thread should hang at the call to m_condition.Wait() // When m_condition is signaled, we wake up, send a command // to the PostgreSQL server, and wait for a result. while( m_queueCounter.Wait() == wxSEMA_NO_ERROR && !die && !TestDestroy() ) { m_owner.setNoticeHandler( noticeHandler, this ); m_currentCommand = getNextCommand(); wxString command = m_currentCommand->getCommand(); wxLogInfo( wxT( "Executing: %s" ), command.c_str()); // This call to PQexec() will hang until we've received // a complete result set from the server. PGresult *result = 0; #if defined (__WXMSW__) || (EDB_LIBPQ) // If we have a set of params, and we have the required functions... dbgPgParams *params = m_currentCommand->getParams(); bool use_callable = true; // we do not need all of PQi stuff AS90 onwards if (m_owner.EdbMinimumVersion(9, 0)) use_callable = false; #ifdef EDB_LIBPQ if (params && use_callable) #else if (PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut && params && use_callable) #endif { wxLogInfo(wxT("Using an EnterpriseDB callable statement")); wxString stmt = wxString::Format(wxT("DebugStmt-%d-%d"), this->GetId(), ++run); PGresult *res = PQiPrepareOut(m_owner.getConnection(), stmt.mb_str(wxConvUTF8), command.mb_str(wxConvUTF8), params->nParams, params->paramTypes, params->paramModes); if( PQresultStatus(res) != PGRES_COMMAND_OK) { wxLogError(_( "Could not prepare the callable statement: %s, error: %s" ), stmt.c_str(), wxString(PQresultErrorMessage(res), *conv).c_str()); PQclear(res); return this; } int ret = PQiSendQueryPreparedOut(m_owner.getConnection(), stmt.mb_str(wxConvUTF8), params->nParams, params->paramValues, NULL, // Can be null - all params are text NULL, // Can be null - all params are text 1); if (ret != 1) { wxLogError(_( "Couldn't execute the callable statement: %s" ), stmt.c_str()); PQclear(res); return this; } // We need to call PQgetResult before we can call PQgetOutResult // Note that this is all async code as far as libpq is concerned to // ensure we can always bail out when required, without leaving threads // hanging around. PGresult *dummy; while(true) { if (die || TestDestroy()) { PQrequestCancel(m_owner.getConnection()); return this; } PQconsumeInput(m_owner.getConnection()); if (PQisBusy(m_owner.getConnection())) { Yield(); wxMilliSleep(10); continue; } dummy = PQgetResult(m_owner.getConnection()); // There should be 2 results - the first is the dummy, the second // contains our out params. if (dummy) break; } if((PQresultStatus(dummy) == PGRES_NONFATAL_ERROR) || (PQresultStatus(dummy) == PGRES_FATAL_ERROR)) result = dummy; else { PQclear(dummy); result = PQiGetOutResult(m_owner.getConnection()); } } else { #endif // This is the normal case for a pl/pgsql function, or if we don't // have access to PQgetOutResult. // Note that this is all async code as far as libpq is concerned to // ensure we can always bail out when required, without leaving threads // hanging around. int ret = PQsendQuery(m_owner.getConnection(), command.mb_str(wxConvUTF8)); if (ret != 1) { wxLogError(_( "Couldn't execute the query (%s): %s" ), command.c_str(), wxString(PQerrorMessage(m_owner.getConnection()), *conv).c_str()); return this; } PGresult *part; while(true) { if (die || TestDestroy()) { PQrequestCancel(m_owner.getConnection()); return this; } PQconsumeInput(m_owner.getConnection()); if (PQisBusy(m_owner.getConnection())) { Yield(); wxMilliSleep(10); continue; } // In theory we should only get one result here, but we'll loop // anyway until we get the last one. part = PQgetResult(m_owner.getConnection()); if (!part) break; result = part; } #if defined (__WXMSW__) || (EDB_LIBPQ) } #endif if(!result) { wxLogInfo(wxT( "NULL PGresult - user abort?" )); return this; } wxLogInfo(wxT( "Complete: %s" ), wxString(PQresStatus(PQresultStatus(result)), *conv).c_str()); // Notify the GUI thread that a result set is ready for display if( m_currentCommand->getEventType() == wxEVT_NULL ) { wxCommandEvent resultEvent( wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_DIRECT_TARGET_COMPLETE ); resultEvent.SetClientData( result ); m_currentCommand->getCaller()->AddPendingEvent( resultEvent ); } else { wxCommandEvent resultEvent( wxEVT_COMMAND_MENU_SELECTED, m_currentCommand->getEventType()); resultEvent.SetClientData( result ); m_currentCommand->getCaller()->AddPendingEvent( resultEvent ); } } return this; }
/* this contains some quick hacks, needs to be cleaned up, but it works */ bool ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit) { struct sqlca_t *sqlca = ECPGget_sqlca(); enum COMPAT_MODE compat = c; struct connection *this; int i; char *dbname = name ? ecpg_strdup(name, lineno) : NULL, *host = NULL, *tmp, *port = NULL, *realname = NULL, *options = NULL, *connect_string = NULL; ecpg_init_sqlca(sqlca); /* * clear auto_mem structure because some error handling functions might * access it */ ecpg_clear_auto_mem(); if (INFORMIX_MODE(compat)) { char *envname; /* * Informix uses an environment variable DBPATH that overrides the * connection parameters given here. We do the same with PG_DBPATH as * the syntax is different. */ envname = getenv("PG_DBPATH"); if (envname) { ecpg_free(dbname); dbname = ecpg_strdup(envname, lineno); } } if (dbname == NULL && connection_name == NULL) connection_name = "DEFAULT"; #if ENABLE_THREAD_SAFETY ecpg_pthreads_init(); #endif /* check if the identifier is unique */ if (ecpg_get_connection(connection_name)) { ecpg_free(dbname); ecpg_log("ECPGconnect: connection identifier %s is already in use\n", connection_name); return false; } if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL) return false; if (dbname != NULL) { /* get the detail information out of dbname */ if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0) { int offset = 0; /* * only allow protocols tcp and unix */ if (strncmp(dbname, "tcp:", 4) == 0) offset = 4; else if (strncmp(dbname, "unix:", 5) == 0) offset = 5; if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0) { /*------ * new style: * <tcp|unix>:postgresql://server[:port|:/unixsocket/path:] * [/db name][?options] *------ */ offset += strlen("postgresql://"); tmp = strrchr(dbname + offset, '?'); if (tmp != NULL) /* options given */ { options = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } tmp = last_dir_separator(dbname + offset); if (tmp != NULL) /* database name given */ { if (tmp[1] != '\0') /* non-empty database name */ realname = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } tmp = strrchr(dbname + offset, ':'); if (tmp != NULL) /* port number or Unix socket path given */ { char *tmp2; *tmp = '\0'; if ((tmp2 = strchr(tmp + 1, ':')) != NULL) { *tmp2 = '\0'; host = ecpg_strdup(tmp + 1, lineno); if (strncmp(dbname, "unix:", 5) != 0) { ecpg_log("ECPGconnect: socketname %s given for TCP connection on line %d\n", host, lineno); ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>")); if (host) ecpg_free(host); /* * port not set yet if (port) ecpg_free(port); */ if (options) ecpg_free(options); if (realname) ecpg_free(realname); if (dbname) ecpg_free(dbname); free(this); return false; } } else port = ecpg_strdup(tmp + 1, lineno); } if (strncmp(dbname, "unix:", 5) == 0) { if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0) { ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno); ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>")); if (host) ecpg_free(host); if (port) ecpg_free(port); if (options) ecpg_free(options); if (realname) ecpg_free(realname); if (dbname) ecpg_free(dbname); free(this); return false; } } else host = ecpg_strdup(dbname + offset, lineno); } } else { /* old style: dbname[@server][:port] */ tmp = strrchr(dbname, ':'); if (tmp != NULL) /* port number given */ { port = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } tmp = strrchr(dbname, '@'); if (tmp != NULL) /* host name given */ { host = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } realname = (strlen(dbname) > 0) ? ecpg_strdup(dbname, lineno) : NULL; } } else realname = NULL; /* add connection to our list */ #ifdef ENABLE_THREAD_SAFETY pthread_mutex_lock(&connections_mutex); #endif if (connection_name != NULL) this->name = ecpg_strdup(connection_name, lineno); else this->name = ecpg_strdup(realname, lineno); this->cache_head = NULL; this->prep_stmts = NULL; if (all_connections == NULL) this->next = NULL; else this->next = all_connections; all_connections = this; #ifdef ENABLE_THREAD_SAFETY pthread_setspecific(actual_connection_key, all_connections); #endif actual_connection = all_connections; ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n", realname ? realname : "<DEFAULT>", host ? host : "<DEFAULT>", port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>", options ? "with options " : "", options ? options : "", user ? "for user " : "", user ? user : ""); connect_string = ecpg_alloc(strlen_or_null(host) + strlen_or_null(port) + strlen_or_null(options) + strlen_or_null(realname) + strlen_or_null(user) + strlen_or_null(passwd) + sizeof(" host = port = dbname = user = password ="******"%s%s %s%s %s%s %s%s %s%s %s", realname ? "dbname=" : "", realname ? realname : "", host ? "host=" : "", host ? host : "", port ? "port=" : "", port ? port : "", user ? "user="******"", user ? user : "", passwd ? "password="******"", passwd ? passwd : "", options ? options : ""); /* * this is deprecated this->connection = PQsetdbLogin(host, port, options, * NULL, realname, user, passwd); */ this->connection = PQconnectdb(connect_string); ecpg_free(connect_string); if (host) ecpg_free(host); if (port) ecpg_free(port); if (options) ecpg_free(options); if (dbname) ecpg_free(dbname); if (PQstatus(this->connection) == CONNECTION_BAD) { const char *errmsg = PQerrorMessage(this->connection); const char *db = realname ? realname : ecpg_gettext("<DEFAULT>"); ecpg_log("ECPGconnect: could not open database: %s\n", errmsg); ecpg_finish(this); #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db); if (realname) ecpg_free(realname); return false; } if (realname) ecpg_free(realname); #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif this->committed = true; this->autocommit = autocommit; PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this); return true; }
int main(int argc, char *argv[]) { int append=0; int create=0; int slim=0; int sanitize=0; int long_usage_bool=0; int pass_prompt=0; int projection = PROJ_SPHERE_MERC; int expire_tiles_zoom = -1; int expire_tiles_zoom_min = -1; int enable_hstore = HSTORE_NONE; int hstore_match_only = 0; int enable_multi = 0; int parallel_indexing = 1; int flat_node_cache_enabled = 0; #ifdef __amd64__ int alloc_chunkwise = ALLOC_SPARSE | ALLOC_DENSE; #else int alloc_chunkwise = ALLOC_SPARSE; #endif int num_procs = 1; int droptemp = 0; int unlogged = 0; int excludepoly = 0; time_t start, end; time_t overall_start, overall_end; time_t now; time_t end_nodes; time_t end_way; time_t end_rel; const char *expire_tiles_filename = "dirty_tiles"; const char *db = "gis"; const char *username=NULL; const char *host=NULL; const char *password=NULL; const char *port = "5432"; const char *tblsmain_index = NULL; /* no default TABLESPACE for index on main tables */ const char *tblsmain_data = NULL; /* no default TABLESPACE for main tables */ const char *tblsslim_index = NULL; /* no default TABLESPACE for index on slim mode tables */ const char *tblsslim_data = NULL; /* no default TABLESPACE for slim mode tables */ const char *conninfo = NULL; const char *prefix = "planet_osm"; const char *style = OSM2PGSQL_DATADIR "/default.style"; const char *temparg; const char *output_backend = "pgsql"; const char *input_reader = "auto"; const char **hstore_columns = NULL; const char *flat_nodes_file = NULL; int n_hstore_columns = 0; int keep_coastlines=0; int cache = 800; struct output_options options; PGconn *sql_conn; int (*streamFile)(char *, int, struct osmdata_t *); printf("osm2pgsql SVN version %s (%lubit id space)\n\n", VERSION, 8 * sizeof(osmid_t)); while (1) { int c, option_index = 0; static struct option long_options[] = { {"append", 0, 0, 'a'}, {"bbox", 1, 0, 'b'}, {"create", 0, 0, 'c'}, {"database", 1, 0, 'd'}, {"latlong", 0, 0, 'l'}, {"verbose", 0, 0, 'v'}, {"slim", 0, 0, 's'}, {"prefix", 1, 0, 'p'}, {"proj", 1, 0, 'E'}, {"merc", 0, 0, 'm'}, {"oldmerc", 0, 0, 'M'}, {"utf8-sanitize", 0, 0, 'u'}, {"cache", 1, 0, 'C'}, {"username", 1, 0, 'U'}, {"password", 0, 0, 'W'}, {"host", 1, 0, 'H'}, {"port", 1, 0, 'P'}, {"tablespace-index", 1, 0, 'i'}, {"tablespace-slim-data", 1, 0, 200}, {"tablespace-slim-index", 1, 0, 201}, {"tablespace-main-data", 1, 0, 202}, {"tablespace-main-index", 1, 0, 203}, {"help", 0, 0, 'h'}, {"style", 1, 0, 'S'}, {"expire-tiles", 1, 0, 'e'}, {"expire-output", 1, 0, 'o'}, {"output", 1, 0, 'O'}, {"extra-attributes", 0, 0, 'x'}, {"hstore", 0, 0, 'k'}, {"hstore-all", 0, 0, 'j'}, {"hstore-column", 1, 0, 'z'}, {"hstore-match-only", 0, 0, 208}, {"multi-geometry", 0, 0, 'G'}, {"keep-coastlines", 0, 0, 'K'}, {"input-reader", 1, 0, 'r'}, {"version", 0, 0, 'V'}, {"disable-parallel-indexing", 0, 0, 'I'}, {"cache-strategy", 1, 0, 204}, {"number-processes", 1, 0, 205}, {"drop", 0, 0, 206}, {"unlogged", 0, 0, 207}, {"flat-nodes",1,0,209}, {"exclude-invalid-polygon",0,0,210}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "ab:cd:KhlmMp:suvU:WH:P:i:IE:C:S:e:o:O:xkjGz:r:V", long_options, &option_index); if (c == -1) break; switch (c) { case 'a': append=1; break; case 'b': osmdata.bbox=optarg; break; case 'c': create=1; break; case 'v': verbose=1; break; case 's': slim=1; break; case 'K': keep_coastlines=1; break; case 'u': sanitize=1; break; case 'l': projection=PROJ_LATLONG; break; case 'm': projection=PROJ_SPHERE_MERC; break; case 'M': projection=PROJ_MERC; break; case 'E': projection=-atoi(optarg); break; case 'p': prefix=optarg; break; case 'd': db=optarg; break; case 'C': cache = atoi(optarg); break; case 'U': username=optarg; break; case 'W': pass_prompt=1; break; case 'H': host=optarg; break; case 'P': port=optarg; break; case 'S': style=optarg; break; case 'i': tblsmain_index=tblsslim_index=optarg; break; case 200: tblsslim_data=optarg; break; case 201: tblsslim_index=optarg; break; case 202: tblsmain_data=optarg; break; case 203: tblsmain_index=optarg; break; case 'e': expire_tiles_zoom_min = atoi(optarg); temparg = strchr(optarg, '-'); if (temparg) expire_tiles_zoom = atoi(temparg + 1); if (expire_tiles_zoom < expire_tiles_zoom_min) expire_tiles_zoom = expire_tiles_zoom_min; break; case 'o': expire_tiles_filename=optarg; break; case 'O': output_backend = optarg; break; case 'x': osmdata.extra_attributes=1; break; case 'k': enable_hstore=HSTORE_NORM; break; case 208: hstore_match_only = 1; break; case 'j': enable_hstore=HSTORE_ALL; break; case 'z': n_hstore_columns++; hstore_columns = (const char**)realloc(hstore_columns, sizeof(&n_hstore_columns) * n_hstore_columns); hstore_columns[n_hstore_columns-1] = optarg; break; case 'G': enable_multi=1; break; case 'r': input_reader = optarg; break; case 'h': long_usage_bool=1; break; case 'I': #ifdef HAVE_PTHREAD parallel_indexing=0; #endif break; case 204: if (strcmp(optarg,"dense") == 0) alloc_chunkwise = ALLOC_DENSE; if (strcmp(optarg,"chunk") == 0) alloc_chunkwise = ALLOC_DENSE | ALLOC_DENSE_CHUNK; if (strcmp(optarg,"sparse") == 0) alloc_chunkwise = ALLOC_SPARSE; if (strcmp(optarg,"optimized") == 0) alloc_chunkwise = ALLOC_DENSE | ALLOC_SPARSE; break; case 205: num_procs = atoi(optarg); break; case 206: droptemp = 1; break; case 207: unlogged = 1; break; case 209: flat_node_cache_enabled = 1; flat_nodes_file = optarg; break; case 210: excludepoly = 1; exclude_broken_polygon(); break; case 'V': exit(EXIT_SUCCESS); case '?': default: short_usage(argv[0]); exit(EXIT_FAILURE); } } if (long_usage_bool) { long_usage(argv[0]); exit(EXIT_SUCCESS); } if (argc == optind) { /* No non-switch arguments */ short_usage(argv[0]); exit(EXIT_FAILURE); } if (append && create) { fprintf(stderr, "Error: --append and --create options can not be used at the same time!\n"); exit(EXIT_FAILURE); } if (droptemp && !slim) { fprintf(stderr, "Error: --drop only makes sense with --slim.\n"); exit(EXIT_FAILURE); } if (unlogged && !create) { fprintf(stderr, "Warning: --unlogged only makes sense with --create; ignored.\n"); unlogged = 0; } if (enable_hstore == HSTORE_NONE && !n_hstore_columns && hstore_match_only) { fprintf(stderr, "Warning: --hstore-match-only only makes sense with --hstore, --hstore-all, or --hstore-column; ignored.\n"); hstore_match_only = 0; } if (cache < 0) cache = 0; if (num_procs < 1) num_procs = 1; if (pass_prompt) password = simple_prompt("Password:"******"PGPASS"); } conninfo = build_conninfo(db, username, password, host, port); sql_conn = PQconnectdb(conninfo); if (PQstatus(sql_conn) != CONNECTION_OK) { fprintf(stderr, "Error: Connection to database failed: %s\n", PQerrorMessage(sql_conn)); exit(EXIT_FAILURE); } if (unlogged && PQserverVersion(sql_conn) < 90100) { fprintf(stderr, "Error: --unlogged works only with PostgreSQL 9.1 and above, but\n"); fprintf(stderr, "you are using PostgreSQL %d.%d.%d.\n", PQserverVersion(sql_conn) / 10000, (PQserverVersion(sql_conn) / 100) % 100, PQserverVersion(sql_conn) % 100); exit(EXIT_FAILURE); } PQfinish(sql_conn); text_init(); initList(&osmdata.tags); osmdata.count_node = osmdata.max_node = 0; osmdata.count_way = osmdata.max_way = 0; osmdata.count_rel = osmdata.max_rel = 0; LIBXML_TEST_VERSION project_init(projection); fprintf(stderr, "Using projection SRS %d (%s)\n", project_getprojinfo()->srs, project_getprojinfo()->descr ); if (parse_bbox(&osmdata)) return 1; options.conninfo = conninfo; options.prefix = prefix; options.append = append; options.slim = slim; options.projection = project_getprojinfo()->srs; options.scale = (projection==PROJ_LATLONG)?10000000:100; options.mid = slim ? &mid_pgsql : &mid_ram; options.cache = cache; options.style = style; options.tblsmain_index = tblsmain_index; options.tblsmain_data = tblsmain_data; options.tblsslim_index = tblsslim_index; options.tblsslim_data = tblsslim_data; options.expire_tiles_zoom = expire_tiles_zoom; options.expire_tiles_zoom_min = expire_tiles_zoom_min; options.expire_tiles_filename = expire_tiles_filename; options.enable_multi = enable_multi; options.enable_hstore = enable_hstore; options.hstore_match_only = hstore_match_only; options.hstore_columns = hstore_columns; options.n_hstore_columns = n_hstore_columns; options.keep_coastlines = keep_coastlines; options.parallel_indexing = parallel_indexing; options.alloc_chunkwise = alloc_chunkwise; options.num_procs = num_procs; options.droptemp = droptemp; options.unlogged = unlogged; options.flat_node_cache_enabled = flat_node_cache_enabled; options.flat_node_file = flat_nodes_file; options.excludepoly = excludepoly; if (strcmp("pgsql", output_backend) == 0) { osmdata.out = &out_pgsql; } else if (strcmp("gazetteer", output_backend) == 0) { osmdata.out = &out_gazetteer; } else if (strcmp("null", output_backend) == 0) { osmdata.out = &out_null; } else { fprintf(stderr, "Output backend `%s' not recognised. Should be one of [pgsql, gazetteer, null].\n", output_backend); exit(EXIT_FAILURE); } options.out = osmdata.out; if (strcmp("auto", input_reader) != 0) { if (strcmp("libxml2", input_reader) == 0) { streamFile = &streamFileXML2; } else if (strcmp("primitive", input_reader) == 0) { streamFile = &streamFilePrimitive; #ifdef BUILD_READER_PBF } else if (strcmp("pbf", input_reader) == 0) { streamFile = &streamFilePbf; #endif } else if (strcmp("o5m", input_reader) == 0) { streamFile = &streamFileO5m; } else { fprintf(stderr, "Input parser `%s' not recognised. Should be one of [libxml2, primitive, o5m" #ifdef BUILD_READER_PBF ", pbf" #endif "].\n", input_reader); exit(EXIT_FAILURE); } } time(&overall_start); osmdata.out->start(&options); realloc_nodes(&osmdata); realloc_members(&osmdata); if (sizeof(int*) == 4 && options.slim != 1) { fprintf(stderr, "\n!! You are running this on 32bit system, so at most\n"); fprintf(stderr, "!! 3GB of RAM can be used. If you encounter unexpected\n"); fprintf(stderr, "!! exceptions during import, you should try running in slim\n"); fprintf(stderr, "!! mode using parameter -s.\n"); } while (optind < argc) { /* if input_reader is not forced by -r switch try to auto-detect it by file extension */ if (strcmp("auto", input_reader) == 0) { #ifdef BUILD_READER_PBF if (strcasecmp(".pbf",argv[optind]+strlen(argv[optind])-4) == 0) { streamFile = &streamFilePbf; } else if (strcasecmp(".o5m",argv[optind]+strlen(argv[optind])-4) == 0) { streamFile = &streamFileO5m; } else { streamFile = &streamFileXML2; } #else streamFile = &streamFileXML2; #endif } fprintf(stderr, "\nReading in file: %s\n", argv[optind]); time(&start); if (streamFile(argv[optind], sanitize, &osmdata) != 0) exit_nicely(); time(&end); fprintf(stderr, " parse time: %ds\n", (int)(end - start)); optind++; } xmlCleanupParser(); xmlMemoryDump(); if (osmdata.count_node || osmdata.count_way || osmdata.count_rel) { time(&now); end_nodes = osmdata.start_way > 0 ? osmdata.start_way : now; end_way = osmdata.start_rel > 0 ? osmdata.start_rel : now; end_rel = now; fprintf(stderr, "\n"); fprintf(stderr, "Node stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_node, osmdata.max_node, osmdata.count_node > 0 ? (int)(end_nodes - osmdata.start_node) : 0); fprintf(stderr, "Way stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_way, osmdata.max_way, osmdata.count_way > 0 ? (int)(end_way - osmdata.start_way) : 0); fprintf(stderr, "Relation stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_rel, osmdata.max_rel, osmdata.count_rel > 0 ? (int)(end_rel - osmdata.start_rel) : 0); } osmdata.out->stop(); free(osmdata.nds); free(osmdata.members); /* free the column pointer buffer */ free(hstore_columns); project_exit(); text_exit(); fprintf(stderr, "\n"); time(&overall_end); fprintf(stderr, "Osm2pgsql took %ds overall\n", (int)(overall_end - overall_start)); return 0; }
static void full_connect(VALUE self, PGconn *db) { PGresult *result = NULL; VALUE r_host, r_user, r_password, r_path, r_port, r_query, r_options; char *host = NULL, *user = NULL, *password = NULL, *path = NULL, *database = NULL; const char *port = "5432"; VALUE encoding = Qnil; const char *search_path = NULL; char *search_path_query = NULL; const char *backslash_off = "SET backslash_quote = off"; const char *standard_strings_on = "SET standard_conforming_strings = on"; const char *warning_messages = "SET client_min_messages = warning"; if((r_host = rb_iv_get(self, "@host")) != Qnil) { host = StringValuePtr(r_host); } if((r_user = rb_iv_get(self, "@user")) != Qnil) { user = StringValuePtr(r_user); } if((r_password = rb_iv_get(self, "@password")) != Qnil) { password = StringValuePtr(r_password); } if((r_port = rb_iv_get(self, "@port")) != Qnil) { port = StringValuePtr(r_port); } if((r_path = rb_iv_get(self, "@path")) != Qnil) { path = StringValuePtr(r_path); database = strtok(path, "/"); } if (NULL == database || 0 == strlen(database)) { rb_raise(eConnectionError, "Database must be specified"); } r_query = rb_iv_get(self, "@query"); search_path = get_uri_option(r_query, "search_path"); db = PQsetdbLogin( host, port, NULL, NULL, database, user, password ); if ( PQstatus(db) == CONNECTION_BAD ) { rb_raise(eConnectionError, "%s", PQerrorMessage(db)); } if (search_path != NULL) { search_path_query = (char *)calloc(256, sizeof(char)); snprintf(search_path_query, 256, "set search_path to %s;", search_path); r_query = rb_str_new2(search_path_query); result = cCommand_execute(self, db, r_query); if (PQresultStatus(result) != PGRES_COMMAND_OK) { free((void *)search_path_query); raise_error(self, result, r_query); } free((void *)search_path_query); } r_options = rb_str_new2(backslash_off); result = cCommand_execute(self, db, r_options); if (PQresultStatus(result) != PGRES_COMMAND_OK) { rb_warn("%s", PQresultErrorMessage(result)); } r_options = rb_str_new2(standard_strings_on); result = cCommand_execute(self, db, r_options); if (PQresultStatus(result) != PGRES_COMMAND_OK) { rb_warn("%s", PQresultErrorMessage(result)); } r_options = rb_str_new2(warning_messages); result = cCommand_execute(self, db, r_options); if (PQresultStatus(result) != PGRES_COMMAND_OK) { rb_warn("%s", PQresultErrorMessage(result)); } encoding = rb_iv_get(self, "@encoding"); #ifdef HAVE_PQSETCLIENTENCODING VALUE pg_encoding = rb_hash_aref(CONST_GET(mEncoding, "MAP"), encoding); if(pg_encoding != Qnil) { if(PQsetClientEncoding(db, rb_str_ptr_readonly(pg_encoding))) { rb_raise(eConnectionError, "Couldn't set encoding: %s", rb_str_ptr_readonly(encoding)); } else { #ifdef HAVE_RUBY_ENCODING_H rb_iv_set(self, "@encoding_id", INT2FIX(rb_enc_find_index(rb_str_ptr_readonly(encoding)))); #endif rb_iv_set(self, "@pg_encoding", pg_encoding); } } else { rb_warn("Encoding %s is not a known Ruby encoding for PostgreSQL\n", rb_str_ptr_readonly(encoding)); rb_iv_set(self, "@encoding", rb_str_new2("UTF-8")); #ifdef HAVE_RUBY_ENCODING_H rb_iv_set(self, "@encoding_id", INT2FIX(rb_enc_find_index("UTF-8"))); #endif rb_iv_set(self, "@pg_encoding", rb_str_new2("UTF8")); } #endif rb_iv_set(self, "@connection", Data_Wrap_Struct(rb_cObject, 0, 0, db)); }
void load_TUBii_command(client *c, int argc, sds *argv) { /* Load CAEN hardware settings from the database. */ uint32_t key; PGconn *conn; PGresult *res = NULL; char conninfo[1024]; char command[10000]; char *name, *value_str; uint32_t value; int i; int rows; if (safe_strtoul(argv[1], &key)) { addReplyErrorFormat(c, "'%s' is not a valid uint32_t", argv[1]); return; } sprintf(command, "select * from TUBii where key = %i", key); sprintf(conninfo, "dbname=%s host=%s user=%s password=%s", dbconfig.name, dbconfig.host, dbconfig.user, dbconfig.password); /* Request row from the database. */ conn = PQconnectdb(conninfo); if (PQstatus(conn) != CONNECTION_OK) { addReplyErrorFormat(c, "connection to database failed: %s", PQerrorMessage(conn)); goto pq_error; } res = PQexec(conn, command); if (PQresultStatus(res) != PGRES_TUPLES_OK) { addReplyErrorFormat(c, "select command failed: %s", PQerrorMessage(conn)); goto pq_error; } rows = PQntuples(res); if (rows != 1) { if (rows == 0) { addReplyErrorFormat(c, "no database row with key = %i", key); } else { addReplyError(c, "this should never happen. Call Tony"); } goto pq_error; } for (i = 0; i < PQnfields(res); i++) { name = PQfname(res, i); if (!strcmp(name, "key") || !strcmp(name, "timestamp")) continue; value_str = PQgetvalue(res, 0, i); if (safe_strtoul(value_str, &value)) { addReplyErrorFormat(c, "unable to convert value '%s' for field %s", value_str, name); goto pq_error; } if (!strcmp(name, "control_reg")) { ControlReg(value); } else if (!strcmp(name, "trigger_mask")) { triggerMask(value,0); } else if (!strcmp(name, "speaker_mask")) { speakerMask(value); } else if (!strcmp(name, "counter_mask")) { counterMask(value); } else if (!strcmp(name, "caen_gain_reg")) { CAENWords(value, mReadReg((u32) MappedRegsBaseAddress, RegOffset12)); } else if (!strcmp(name, "caen_channel_reg")) { CAENWords(mReadReg((u32) MappedRegsBaseAddress, RegOffset11), value); } else if (!strcmp(name, "lockout_reg")) { GTDelays(value, mReadReg((u32) MappedRegsBaseAddress, RegOffset15)); } else if (!strcmp(name, "dgt_reg")) { GTDelays(mReadReg((u32) MappedRegsBaseAddress, RegOffset14), value); } else if (!strcmp(name, "dac_reg")) { DACThresholds(value); } else if (!strcmp(name, "counter_mode")) { counterMode(value); } else if (!strcmp(name, "clock_status")) { // Do Nowt } else if (!strcmp(name, "combo_enable_mask")) { mWriteReg((u32) MappedComboBaseAddress, RegOffset2, value); } else if (!strcmp(name, "combo_mask")) { mWriteReg((u32) MappedComboBaseAddress, RegOffset3, value); } else if (!strcmp(name, "prescale_value")) { mWriteReg((u32) MappedPrescaleBaseAddress, RegOffset2, value); } else if (!strcmp(name, "prescale_channel")) { mWriteReg((u32) MappedPrescaleBaseAddress, RegOffset3, value); } else if (!strcmp(name, "burst_rate")) { mWriteReg((u32) MappedBurstBaseAddress, RegOffset2, value); } else if (!strcmp(name, "burst_channel")) { mWriteReg((u32) MappedBurstBaseAddress, RegOffset3, value); } else { addReplyErrorFormat(c, "got unknown field '%s'", name); goto pq_error; } } addReplyStatus(c, "OK"); PQclear(res); PQfinish(conn); return; err: addReplyError(c, tubii_err); return; pq_error: if (res) PQclear(res); PQfinish(conn); }
/************************************************************************* * * Function: sql_query * * Purpose: Issue a query to the database * *************************************************************************/ static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) { rlm_sql_postgres_sock *pg_sock = sqlsocket->conn; int numfields = 0; char *errorcode; char *errormsg; if (config->sqltrace) radlog(L_DBG,"rlm_sql_postgresql: query:\n%s", querystr); if (pg_sock->conn == NULL) { radlog(L_ERR, "rlm_sql_postgresql: Socket not connected"); return SQL_DOWN; } pg_sock->result = PQexec(pg_sock->conn, querystr); /* * Returns a PGresult pointer or possibly a null pointer. * A non-null pointer will generally be returned except in * out-of-memory conditions or serious errors such as inability * to send the command to the server. If a null pointer is * returned, it should be treated like a PGRES_FATAL_ERROR * result. */ if (!pg_sock->result) { radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s", PQerrorMessage(pg_sock->conn)); /* As this error COULD be a connection error OR an out-of-memory * condition return value WILL be wrong SOME of the time regardless! * Pick your poison.... */ return SQL_DOWN; } else { ExecStatusType status = PQresultStatus(pg_sock->result); radlog(L_DBG, "rlm_sql_postgresql: Status: %s", PQresStatus(status)); switch (status) { case PGRES_COMMAND_OK: /*Successful completion of a command returning no data.*/ /*affected_rows function only returns the number of affected rows of a command returning no data... */ pg_sock->affected_rows = affected_rows(pg_sock->result); radlog(L_DBG, "rlm_sql_postgresql: query affected rows = %i", pg_sock->affected_rows); return 0; break; case PGRES_TUPLES_OK: /*Successful completion of a command returning data (such as a SELECT or SHOW).*/ pg_sock->cur_row = 0; pg_sock->affected_rows = PQntuples(pg_sock->result); numfields = PQnfields(pg_sock->result); /*Check row storing functions..*/ radlog(L_DBG, "rlm_sql_postgresql: query affected rows = %i , fields = %i", pg_sock->affected_rows, numfields); return 0; break; case PGRES_BAD_RESPONSE: /*The server's response was not understood.*/ radlog(L_DBG, "rlm_sql_postgresql: Bad Response From Server!!"); return -1; break; case PGRES_NONFATAL_ERROR: /*A nonfatal error (a notice or warning) occurred. Possibly never returns*/ return -1; break; case PGRES_FATAL_ERROR: #if defined(PG_DIAG_SQLSTATE) && defined(PG_DIAG_MESSAGE_PRIMARY) /*A fatal error occurred.*/ errorcode = PQresultErrorField(pg_sock->result, PG_DIAG_SQLSTATE); errormsg = PQresultErrorField(pg_sock->result, PG_DIAG_MESSAGE_PRIMARY); radlog(L_DBG, "rlm_sql_postgresql: Error %s", errormsg); return check_fatal_error(errorcode); #endif break; default: /* FIXME: An unhandled error occurred.*/ /* PGRES_EMPTY_QUERY PGRES_COPY_OUT PGRES_COPY_IN */ return -1; break; } /* Note to self ... sql_store_result returns 0 anyway after setting the sqlsocket->affected_rows.. sql_num_fields returns 0 at worst case which means the check below has a really small chance to return false.. lets remove it then .. yuck!! */ /* } else { if ((sql_store_result(sqlsocket, config) == 0) && (sql_num_fields(sqlsocket, config) >= 0)) return 0; else return -1; } */ } return -1; }
int msPOSTGRESQLJoinNext(joinObj *join) { msPOSTGRESQLJoinInfo *joininfo = join->joininfo; int i, length, row_count; char *sql, *columns; /* We need a connection, and a join value. */ if(!joininfo || !joininfo->conn) { msSetError(MS_JOINERR, "Join has not been connected.\n", "msPOSTGRESQLJoinNext()"); return MS_FAILURE; } if(!joininfo->from_value) { msSetError(MS_JOINERR, "Join has not been prepared.\n", "msPOSTGRESQLJoinNext()"); return MS_FAILURE; } /* Free the previous results. */ if(join->values) { msFreeCharArray(join->values, join->numitems); join->values = NULL; } /* We only need to execute the query if no results exist. */ if(!joininfo->query_result) { /* Write the list of column names. */ length = 0; for(i = 0; i < join->numitems; i++) { length += 8 + strlen(join->items[i]) + 2; } columns = (char *)malloc(length); if(!columns) { msSetError(MS_MEMERR, "Failure to malloc.\n", "msPOSTGRESQLJoinNext()"); return MS_FAILURE; } strcpy(columns, ""); for(i = 0; i < join->numitems; i++) { strcat(columns, "\""); strcat(columns, join->items[i]); strcat(columns, "\"::text"); if(i != join->numitems - 1) { strcat(columns, ", "); } } /* Create the query string. */ sql = (char *)malloc(26 + strlen(columns) + strlen(join->table) + strlen(join->to) + strlen(joininfo->from_value)); if(!sql) { msSetError(MS_MEMERR, "Failure to malloc.\n", "msPOSTGRESQLJoinNext()"); return MS_FAILURE; } sprintf(sql, "SELECT %s FROM %s WHERE %s = '%s'", columns, join->table, join->to, joininfo->from_value); if(joininfo->layer_debug) { msDebug("msPOSTGRESQLJoinNext(): executing %s.\n", sql); } free(columns); joininfo->query_result = PQexec(joininfo->conn, sql); if(!joininfo->query_result || PQresultStatus(joininfo->query_result) != PGRES_TUPLES_OK) { msSetError(MS_QUERYERR, "Error executing queri %s: %s\n", "msPOSTGRESQLJoinNext()", sql, PQerrorMessage(joininfo->conn)); if(joininfo->query_result) { PQclear(joininfo->query_result); joininfo->query_result = NULL; } free(sql); return MS_FAILURE; } free(sql); } row_count = PQntuples(joininfo->query_result); /* see if we're done processing this set */ if(joininfo->row_num >= row_count) { return(MS_DONE); } if(joininfo->layer_debug) { msDebug("msPOSTGRESQLJoinNext(): fetching row %ld.\n", joininfo->row_num); } /* Copy the resulting values into the joinObj. */ join->values = (char **)malloc(sizeof(char *) * join->numitems); for(i = 0; i < join->numitems; i++) { join->values[i] = msStrdup(PQgetvalue( joininfo->query_result, joininfo->row_num, i)); } joininfo->row_num++; return MS_SUCCESS; }
/************************************************************************* * * Function: sql_error * * Purpose: database specific error. Returns error associated with * connection * *************************************************************************/ static const char *sql_error(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) { rlm_sql_postgres_sock *pg_sock = sqlsocket->conn; return PQerrorMessage(pg_sock->conn); }
int main(int argc, char * argv[]) { PGconn *conn; PGresult *res; char * conninfo = calloc (MAX_LEN, sizeof (char)); char * query = calloc (MAX_LEN, sizeof (char)); char * nama = calloc (MAX_LEN, sizeof (char)); char * alamat = calloc (MAX_LEN, sizeof (char)); char * temp = calloc (MAX_LEN, sizeof (char)); int field_count; int rec_count; int c,menu; int i,j; strcpy (conninfo, "dbname=test user=nop"); conn = PQconnectdb (conninfo); if (PQstatus (conn) != CONNECTION_OK) { fprintf (stderr, "Kesalahan koneksi: %s\n", PQerrorMessage (conn)); exit (1); } while ( 1 ) { fprintf(stdout, "\n\n\nDATA PASIEN\n"); fprintf(stdout, "***********\n\n"); fprintf(stdout, "a Tambah data\n"); fprintf(stdout, "b Tampil data\n"); fprintf(stdout, "x Keluar aplikasi\n"); fprintf(stdout, "Pilihan Anda: "); c = tolower(fgetc (stdin)); menu = c; while (c != '\n' && c != EOF) c = fgetc (stdin); if (menu == 'a') { fprintf(stdout, "Tambah data\n"); fprintf(stdout, "===========\n"); fprintf(stdout, "Nama : "); fgets (nama, MAX_LEN-1, stdin); fprintf(stdout, "Alamat : "); fgets (alamat, MAX_LEN-1, stdin); sprintf (query, "insert into pasien (nama, alamat) values ('%s','%s')", nama, alamat); res = PQexec (conn, query); PQclear (res); } else if (menu == 'b') { fprintf(stdout, "Tampil data\n"); fprintf(stdout, "===========\n"); sprintf (query, "select nama,alamat from pasien"); res = PQexec (conn, query); field_count = PQnfields (res); for (i=0; i< field_count; i++) { fprintf (stdout, "%-40s", PQfname (res, i)); } fprintf (stdout, "\n"); rec_count = PQntuples (res); for (i=0; i< rec_count; i++) { for (j=0; j< field_count; j++) { strcpy (temp, PQgetvalue (res, i, j)); temp[strlen(temp)-1] = 0; fprintf (stdout, "%-40s", temp); } fprintf (stdout, "\n"); } PQclear (res); } else if (menu == 'x') { fprintf(stdout, "Bye\n"); break; } }; PQfinish (conn); free (nama); free (alamat); free (query); free (conninfo); free (temp); return 0; }
static int submit_query(db_con_t* _h, const char* _s) { int rv; /* ** this bit of nonsense in case our connection get screwed up */ switch(rv = PQstatus(CON_CONNECTION(_h))) { case CONNECTION_OK: break; case CONNECTION_BAD: PLOG("submit_query", "connection reset"); PQreset(CON_CONNECTION(_h)); break; } /* ** free any previous query that is laying about */ if(CON_RESULT(_h)) { free_query(_h); } /* ** exec the query */ CON_RESULT(_h) = PQexec(CON_CONNECTION(_h), _s); rv = 0; if(PQresultStatus(CON_RESULT(_h)) == 0) { PLOG("submit_query", "initial failure, FATAL"); /* ** terrible error?? */ rv = -3; } else { /* ** the query ran, get the status */ switch(PQresultStatus(CON_RESULT(_h))) { case PGRES_EMPTY_QUERY: rv = -9; break; case PGRES_COMMAND_OK: rv = 0; break; case PGRES_TUPLES_OK: rv = 0; break; case PGRES_COPY_OUT: rv = -4; break; case PGRES_COPY_IN: rv = -5; break; case PGRES_BAD_RESPONSE: rv = -6; break; case PGRES_NONFATAL_ERROR: rv = -7; break; case PGRES_FATAL_ERROR: rv = -8; break; default: rv = -2; break; } } if(rv < 0) { /* ** log the error */ char buf[256]; sprintf(buf, "query '%s', result '%s'\n", _s, PQerrorMessage(CON_CONNECTION(_h))); PLOG("submit_query", buf); } return(rv); }
int db__driver_create_table(dbTable * table) { int col, ncols; dbColumn *column; const char *colname; int sqltype; char buf[500]; PGresult *res; dbString sql; dbConnection connection; G_debug(3, "db__driver_create_table()"); init_error(); db_init_string(&sql); /* db_table_to_sql ( table, &sql ); */ db_set_string(&sql, "create table "); db_append_string(&sql, db_get_table_name(table)); db_append_string(&sql, " ( "); ncols = db_get_table_number_of_columns(table); for (col = 0; col < ncols; col++) { column = db_get_table_column(table, col); colname = db_get_column_name(column); sqltype = db_get_column_sqltype(column); G_debug(3, "%s (%s)", colname, db_sqltype_name(sqltype)); if (col > 0) db_append_string(&sql, ", "); db_append_string(&sql, colname); db_append_string(&sql, " "); switch (sqltype) { case DB_SQL_TYPE_CHARACTER: sprintf(buf, "varchar(%d)", db_get_column_length(column)); db_append_string(&sql, buf); break; case DB_SQL_TYPE_TEXT: db_append_string(&sql, "text"); break; case DB_SQL_TYPE_SMALLINT: db_append_string(&sql, "smallint"); break; case DB_SQL_TYPE_INTEGER: db_append_string(&sql, "integer"); break; case DB_SQL_TYPE_REAL: db_append_string(&sql, "real"); break; /* TODO: better numeric types */ case DB_SQL_TYPE_DOUBLE_PRECISION: case DB_SQL_TYPE_DECIMAL: case DB_SQL_TYPE_NUMERIC: case DB_SQL_TYPE_INTERVAL: db_append_string(&sql, "double precision"); break; case DB_SQL_TYPE_DATE: db_append_string(&sql, "date"); break; case DB_SQL_TYPE_TIME: db_append_string(&sql, "time"); break; case DB_SQL_TYPE_TIMESTAMP: db_append_string(&sql, "timestamp"); break; default: G_warning("Unknown column type (%s)", colname); return DB_FAILED; } } db_append_string(&sql, " )"); G_debug(3, " SQL: %s", db_get_string(&sql)); res = PQexec(pg_conn, db_get_string(&sql)); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { append_error("Cannot create table:\n"); append_error(db_get_string(&sql)); append_error("\n"); append_error(PQerrorMessage(pg_conn)); report_error(); PQclear(res); db_free_string(&sql); return DB_FAILED; } PQclear(res); /* Grant privileges */ db_get_connection(&connection); db_set_string(&sql, "grant select on "); db_append_string(&sql, db_get_table_name(table)); db_append_string(&sql, " to public"); if (connection.group) { db_append_string(&sql, ", group "); db_append_string(&sql, connection.group); } G_debug(3, " SQL: %s", db_get_string(&sql)); res = PQexec(pg_conn, db_get_string(&sql)); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { append_error("Cannot grant select on table:\n"); append_error(db_get_string(&sql)); append_error("\n"); append_error(PQerrorMessage(pg_conn)); report_error(); PQclear(res); db_free_string(&sql); return DB_FAILED; } PQclear(res); db_free_string(&sql); return DB_OK; }
static int begin_transaction(db_con_t * _h, char *_s) { PGresult *mr; int rv; /* ** Note: ** The upper layers of code may attempt a transaction ** before opening or having a valid connection to the ** database. We try to sense this, and open the database ** if we have the sqlurl in the _h structure. Otherwise, ** all we can do is return an error. */ if(_h) { if(CON_CONNECTED(_h)) { mr = PQexec(CON_CONNECTION(_h), "BEGIN"); if(!mr || PQresultStatus(mr) != PGRES_COMMAND_OK) { /* ** We get here if the connection to the ** db is corrupt, which can happen a few ** different ways, but all of them are ** related to the parent process forking, ** or being forked. */ PLOG("begin_transaction","corrupt connection"); CON_CONNECTED(_h) = 0; } else { /* ** this is the normal way out. ** the transaction ran fine. */ PQclear(mr); return(0); } } else { DLOG("begin_transaction", "called before db_init"); } /* ** if we get here we have a corrupt db connection, ** but we probably have a valid db_con_t structure. ** attempt to open the db. */ if((rv = connect_db(_h, CON_SQLURL(_h))) != 0) { /* ** our attempt to fix the connection failed */ char buf[256]; sprintf(buf, "no connection, FATAL %d!", rv); PLOG("begin_transaction",buf); return(rv); } } else { PLOG("begin_transaction","must call db_init first!"); return(-1); } /* ** we get here if the database connection was corrupt, ** i didn't want to use recursion ... */ mr = PQexec(CON_CONNECTION(_h), "BEGIN"); if(!mr || PQresultStatus(mr) != PGRES_COMMAND_OK) { char buf[256]; sprintf("FATAL %s, '%s'!\n", PQerrorMessage(CON_CONNECTION(_h)), _s); PLOG("begin_transaction", buf); return(-1); } DLOG("begin_transaction", "db channel reset successful"); PQclear(mr); return(0); }
static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q, udb_query_preparation_area_t *prep_area) { PGresult *res; c_psql_user_data_t *data; const char *host; char **column_names; char **column_values; int column_num; int rows_num; int status; int row, col; /* The user data may hold parameter information, but may be NULL. */ data = udb_query_get_user_data (q); /* Versions up to `3' don't know how to handle parameters. */ if (3 <= db->proto_version) res = c_psql_exec_query_params (db, q, data); else if ((NULL == data) || (0 == data->params_num)) res = c_psql_exec_query_noparams (db, q); else { log_err ("Connection to database \"%s\" does not support parameters " "(protocol version %d) - cannot execute query \"%s\".", db->database, db->proto_version, udb_query_get_name (q)); return -1; } column_names = NULL; column_values = NULL; #define BAIL_OUT(status) \ sfree (column_names); \ sfree (column_values); \ PQclear (res); \ return status if (PGRES_TUPLES_OK != PQresultStatus (res)) { log_err ("Failed to execute SQL query: %s", PQerrorMessage (db->conn)); log_info ("SQL query was: %s", udb_query_get_statement (q)); BAIL_OUT (-1); } rows_num = PQntuples (res); if (1 > rows_num) { BAIL_OUT (0); } column_num = PQnfields (res); column_names = (char **) calloc (column_num, sizeof (char *)); if (NULL == column_names) { log_err ("calloc failed."); BAIL_OUT (-1); } column_values = (char **) calloc (column_num, sizeof (char *)); if (NULL == column_values) { log_err ("calloc failed."); BAIL_OUT (-1); } for (col = 0; col < column_num; ++col) { /* Pointers returned by `PQfname' are freed by `PQclear' via * `BAIL_OUT'. */ column_names[col] = PQfname (res, col); if (NULL == column_names[col]) { log_err ("Failed to resolve name of column %i.", col); BAIL_OUT (-1); } } if (C_PSQL_IS_UNIX_DOMAIN_SOCKET (db->host) || (0 == strcmp (db->host, "localhost"))) host = hostname_g; else host = db->host; status = udb_query_prepare_result (q, prep_area, host, "postgresql", db->database, column_names, (size_t) column_num, db->interval); if (0 != status) { log_err ("udb_query_prepare_result failed with status %i.", status); BAIL_OUT (-1); } for (row = 0; row < rows_num; ++row) { for (col = 0; col < column_num; ++col) { /* Pointers returned by `PQgetvalue' are freed by `PQclear' via * `BAIL_OUT'. */ column_values[col] = PQgetvalue (res, row, col); if (NULL == column_values[col]) { log_err ("Failed to get value at (row = %i, col = %i).", row, col); break; } } /* check for an error */ if (col < column_num) continue; status = udb_query_handle_result (q, prep_area, column_values); if (status != 0) { log_err ("udb_query_handle_result failed with status %i.", status); } } /* for (row = 0; row < rows_num; ++row) */ udb_query_finish_result (q, prep_area); BAIL_OUT (0); #undef BAIL_OUT } /* c_psql_exec_query */
static int connect_db(db_con_t* _h, const char* _db_url) { char* user, *password, *host, *port, *database; if(! _h) { PLOG("connect_db", "must pass db_con_t!"); return(-1); } if(CON_CONNECTED(_h)) { DLOG("connect_db", "disconnect first!"); disconnect_db(_h); } /* ** CON_CONNECTED(_h) is now 0, set by disconnect_db() */ /* ** Note : ** Make a scratch pad copy of given SQL URL. ** all memory allocated to this connection is rooted ** from this. ** This is an important concept. ** as long as you always allocate memory using the function: ** mem = aug_alloc(size, CON_SQLURL(_h)) or ** str = aug_strdup(string, CON_SQLURL(_h)) ** where size is the amount of memory, then in the future ** when CON_SQLURL(_h) is freed (in the function disconnect_db()) ** all other memory allocated in this manner is freed. ** this will keep memory leaks from happening. */ CON_SQLURL(_h) = aug_strdup((char *) _db_url, (char *) _h); /* ** get the connection parameters parsed from the db_url string ** it looks like: postgres://username:[email protected]:dbport/dbname ** username/userpass : name and password for the database ** dbhost : the host name or ip address hosting the database ** dbport : the port to connect to database on ** dbname : the name of the database */ if(parse_sql_url(CON_SQLURL(_h), &user,&password,&host,&port,&database) < 0) { char buf[256]; sprintf(buf, "Error while parsing %s", _db_url); PLOG("connect_db", buf); aug_free(CON_SQLURL(_h)); return -3; } /* ** finally, actually connect to the database */ CON_CONNECTION(_h) = PQsetdbLogin(host,port,NULL,NULL,database,user, password); if(CON_CONNECTION(_h) == 0 || PQstatus(CON_CONNECTION(_h)) != CONNECTION_OK) { PLOG("connect_db", PQerrorMessage(CON_CONNECTION(_h))); PQfinish(CON_CONNECTION(_h)); aug_free(CON_SQLURL(_h)); return -4; } CON_PID(_h) = getpid(); /* ** all is well, database was connected, we can now submit_query's */ CON_CONNECTED(_h) = 1; return 0; }
static int aPGSQL_query(struct cw_channel *chan, void *data) { char *s1,*s2,*s3,*s4; char s[100] = ""; char *querystring; char *var; int l; int res,nres; PGconn *karoto; PGresult *PGSQLres; int id,id1; char *stringp=NULL; res=0; l=strlen(data)+2; s1=malloc(l); s2=malloc(l); strncpy(s1, data, l - 1); stringp=s1; strsep(&stringp," "); /* eat the first token, we already know it :P */ s3=strsep(&stringp," "); while (1) { /* ugly trick to make branches with break; */ var=s3; s4=strsep(&stringp," "); id=atoi(s4); querystring=strsep(&stringp,"\n"); if ((karoto=find_identifier(id,CW_PGSQL_ID_CONNID))==NULL) { cw_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_query\n",id); res=-1; break; } PGSQLres=PQexec(karoto,querystring); if (PGSQLres==NULL) { cw_log(LOG_WARNING,"aPGSQL_query: Connection Error (connection identifier = %d, error message : %s)\n",id,PQerrorMessage(karoto)); res=-1; break; } if (PQresultStatus(PGSQLres) == PGRES_BAD_RESPONSE || PQresultStatus(PGSQLres) == PGRES_NONFATAL_ERROR || PQresultStatus(PGSQLres) == PGRES_FATAL_ERROR) { cw_log(LOG_WARNING,"aPGSQL_query: Query Error (connection identifier : %d, error message : %s)\n",id,PQcmdStatus(PGSQLres)); res=-1; break; } nres=PQnfields(PGSQLres); id1=add_identifier(CW_PGSQL_ID_RESID,PGSQLres); snprintf(s, sizeof(s), "%d", id1); pbx_builtin_setvar_helper(chan,var,s); break; } free(s1); free(s2); return(res); }
/* * Receive a tar format file from the connection to the server, and write * the data from this file directly into a tar file. If compression is * enabled, the data will be compressed while written to the file. * * The file will be named base.tar[.gz] if it's for the main data directory * or <tablespaceoid>.tar[.gz] if it's for another tablespace. * * No attempt to inspect or validate the contents of the file is done. */ static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) { char filename[MAXPGPATH]; char *copybuf = NULL; FILE *tarfile = NULL; #ifdef HAVE_LIBZ gzFile *ztarfile = NULL; #endif if (PQgetisnull(res, rownum, 0)) /* * Base tablespaces */ if (strcmp(basedir, "-") == 0) { #ifdef HAVE_LIBZ if (compresslevel != 0) { ztarfile = gzdopen(dup(fileno(stdout)), "wb"); if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif tarfile = stdout; } else { #ifdef HAVE_LIBZ if (compresslevel != 0) { snprintf(filename, sizeof(filename), "%s/base.tar.gz", basedir); ztarfile = gzopen(filename, "wb"); if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif { snprintf(filename, sizeof(filename), "%s/base.tar", basedir); tarfile = fopen(filename, "wb"); } } else { /* * Specific tablespace */ #ifdef HAVE_LIBZ if (compresslevel != 0) { snprintf(filename, sizeof(filename), "%s/%s.tar.gz", basedir, PQgetvalue(res, rownum, 0)); ztarfile = gzopen(filename, "wb"); if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif { snprintf(filename, sizeof(filename), "%s/%s.tar", basedir, PQgetvalue(res, rownum, 0)); tarfile = fopen(filename, "wb"); } } #ifdef HAVE_LIBZ if (compresslevel != 0) { if (!ztarfile) { /* Compression is in use */ fprintf(stderr, _("%s: could not create compressed file \"%s\": %s\n"), progname, filename, get_gz_error(ztarfile)); disconnect_and_exit(1); } } else #endif { /* Either no zlib support, or zlib support but compresslevel = 0 */ if (!tarfile) { fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno)); disconnect_and_exit(1); } } /* * Get the COPY data stream */ res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COPY_OUT) { fprintf(stderr, _("%s: could not get COPY data stream: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } while (1) { int r; if (copybuf != NULL) { PQfreemem(copybuf); copybuf = NULL; } r = PQgetCopyData(conn, ©buf, 0); if (r == -1) { /* * End of chunk. Close file (but not stdout). * * Also, write two completely empty blocks at the end of the tar * file, as required by some tar programs. */ char zerobuf[1024]; MemSet(zerobuf, 0, sizeof(zerobuf)); #ifdef HAVE_LIBZ if (ztarfile != NULL) { if (gzwrite(ztarfile, zerobuf, sizeof(zerobuf)) != sizeof(zerobuf)) { fprintf(stderr, _("%s: could not write to compressed file \"%s\": %s\n"), progname, filename, get_gz_error(ztarfile)); } } else #endif { if (fwrite(zerobuf, sizeof(zerobuf), 1, tarfile) != 1) { fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), progname, filename, strerror(errno)); disconnect_and_exit(1); } } if (strcmp(basedir, "-") == 0) { #ifdef HAVE_LIBZ if (ztarfile) gzclose(ztarfile); #endif } else { #ifdef HAVE_LIBZ if (ztarfile != NULL) gzclose(ztarfile); #endif if (tarfile != NULL) fclose(tarfile); } break; } else if (r == -2) { fprintf(stderr, _("%s: could not read COPY data: %s"), progname, PQerrorMessage(conn)); disconnect_and_exit(1); } #ifdef HAVE_LIBZ if (ztarfile != NULL) { if (gzwrite(ztarfile, copybuf, r) != r) { fprintf(stderr, _("%s: could not write to compressed file \"%s\": %s\n"), progname, filename, get_gz_error(ztarfile)); } } else #endif { if (fwrite(copybuf, r, 1, tarfile) != 1) { fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), progname, filename, strerror(errno)); disconnect_and_exit(1); } } totaldone += r; if (showprogress) progress_report(rownum, filename); } /* while (1) */ if (copybuf != NULL) PQfreemem(copybuf); }