*/
#include "postgres_fe.h"
-#include "dumputils.h"
-#include "fe_utils/string_utils.h"
-#include "parallel.h"
-#include "pg_backup_archiver.h"
-#include "pg_backup_db.h"
-#include "pg_backup_utils.h"
-
#include <unistd.h>
#include <ctype.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
-
-/* translator: this is a module name */
-static const char *modulename = gettext_noop("archiver (db)");
+#include "dumputils.h"
+#include "fe_utils/connect.h"
+#include "fe_utils/string_utils.h"
+#include "parallel.h"
+#include "pg_backup_archiver.h"
+#include "pg_backup_db.h"
+#include "pg_backup_utils.h"
static void _check_database_version(ArchiveHandle *AH);
static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser);
remoteversion_str = PQparameterStatus(AH->connection, "server_version");
remoteversion = PQserverVersion(AH->connection);
if (remoteversion == 0 || !remoteversion_str)
- exit_horribly(modulename, "could not get server_version from libpq\n");
+ fatal("could not get server_version from libpq");
AH->public.remoteVersionStr = pg_strdup(remoteversion_str);
AH->public.remoteVersion = remoteversion;
&& (remoteversion < AH->public.minRemoteVersion ||
remoteversion > AH->public.maxRemoteVersion))
{
- write_msg(NULL, "server version: %s; %s version: %s\n",
- remoteversion_str, progname, PG_VERSION);
- exit_horribly(NULL, "aborting because of server version mismatch\n");
+ pg_log_error("server version: %s; %s version: %s",
+ remoteversion_str, progname, PG_VERSION);
+ fatal("aborting because of server version mismatch");
}
/*
/*
* Reconnect to the server. If dbname is not NULL, use that database,
* else the one associated with the archive handle. If username is
- * not NULL, use that user name, else the one from the handle. If
- * both the database and the user match the existing connection already,
- * nothing will be done.
- *
- * Returns 1 in any case.
+ * not NULL, use that user name, else the one from the handle.
*/
-int
+void
ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username)
{
PGconn *newConn;
else
newusername = username;
- /* Let's see if the request is already satisfied */
- if (strcmp(newdbname, PQdb(AH->connection)) == 0 &&
- strcmp(newusername, PQuser(AH->connection)) == 0)
- return 1;
-
newConn = _connectDB(AH, newdbname, newusername);
/* Update ArchiveHandle's connCancel before closing old connection */
PQfinish(AH->connection);
AH->connection = newConn;
- return 1;
+ /* Start strict; later phases may override this. */
+ PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH,
+ ALWAYS_SECURE_SEARCH_PATH_SQL));
}
/*
else
newuser = requser;
- ahlog(AH, 1, "connecting to database \"%s\" as user \"%s\"\n",
- newdb, newuser);
+ pg_log_info("connecting to database \"%s\" as user \"%s\"",
+ newdb, newuser);
password = AH->savedPassword;
}
initPQExpBuffer(&connstr);
- appendPQExpBuffer(&connstr, "dbname=");
+ appendPQExpBufferStr(&connstr, "dbname=");
appendConnStrVal(&connstr, newdb);
do
newConn = PQconnectdbParams(keywords, values, true);
if (!newConn)
- exit_horribly(modulename, "failed to reconnect to database\n");
+ fatal("could not reconnect to database");
if (PQstatus(newConn) == CONNECTION_BAD)
{
if (!PQconnectionNeedsPassword(newConn))
- exit_horribly(modulename, "could not reconnect to database: %s",
- PQerrorMessage(newConn));
+ fatal("could not reconnect to database: %s",
+ PQerrorMessage(newConn));
PQfinish(newConn);
if (password)
password = passbuf;
}
else
- exit_horribly(modulename, "connection needs password\n");
+ fatal("connection needs password");
new_pass = true;
}
bool new_pass;
if (AH->connection)
- exit_horribly(modulename, "already connected to a database\n");
+ fatal("already connected to a database");
password = AH->savedPassword;
AH->connection = PQconnectdbParams(keywords, values, true);
if (!AH->connection)
- exit_horribly(modulename, "failed to connect to database\n");
+ fatal("could not connect to database");
if (PQstatus(AH->connection) == CONNECTION_BAD &&
PQconnectionNeedsPassword(AH->connection) &&
/* check to see that the backend connection was successfully made */
if (PQstatus(AH->connection) == CONNECTION_BAD)
- exit_horribly(modulename, "connection to database \"%s\" failed: %s",
- PQdb(AH->connection) ? PQdb(AH->connection) : "",
- PQerrorMessage(AH->connection));
+ fatal("connection to database \"%s\" failed: %s",
+ PQdb(AH->connection) ? PQdb(AH->connection) : "",
+ PQerrorMessage(AH->connection));
+
+ /* Start strict; later phases may override this. */
+ PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH,
+ ALWAYS_SECURE_SEARCH_PATH_SQL));
/*
* We want to remember connection's actual password, whether or not we got
/*
* If we have an active query, send a cancel before closing, ignoring
* any errors. This is of no use for a normal exit, but might be
- * helpful during exit_horribly().
+ * helpful during fatal().
*/
if (PQtransactionStatus(AH->connection) == PQTRANS_ACTIVE)
(void) PQcancel(AH->connCancel, errbuf, sizeof(errbuf));
static void
notice_processor(void *arg, const char *message)
{
- write_msg(NULL, "%s", message);
+ pg_log_generic(PG_LOG_INFO, "%s", message);
}
-/* Like exit_horribly(), but with a complaint about a particular query. */
+/* Like fatal(), but with a complaint about a particular query. */
static void
-die_on_query_failure(ArchiveHandle *AH, const char *modulename, const char *query)
+die_on_query_failure(ArchiveHandle *AH, const char *query)
{
- write_msg(modulename, "query failed: %s",
- PQerrorMessage(AH->connection));
- exit_horribly(modulename, "query was: %s\n", query);
+ pg_log_error("query failed: %s",
+ PQerrorMessage(AH->connection));
+ fatal("query was: %s", query);
}
void
res = PQexec(AH->connection, query);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
- die_on_query_failure(AH, modulename, query);
+ die_on_query_failure(AH, query);
PQclear(res);
}
res = PQexec(AH->connection, query);
if (PQresultStatus(res) != status)
- die_on_query_failure(AH, modulename, query);
+ die_on_query_failure(AH, query);
return res;
}
* Execute an SQL query and verify that we got exactly one row back.
*/
PGresult *
-ExecuteSqlQueryForSingleRow(Archive *fout, char *query)
+ExecuteSqlQueryForSingleRow(Archive *fout, const char *query)
{
PGresult *res;
int ntups;
/* Expecting a single result only */
ntups = PQntuples(res);
if (ntups != 1)
- exit_horribly(NULL,
- ngettext("query returned %d row instead of one: %s\n",
- "query returned %d rows instead of one: %s\n",
- ntups),
- ntups, query);
+ fatal(ngettext("query returned %d row instead of one: %s",
+ "query returned %d rows instead of one: %s",
+ ntups),
+ ntups, query);
return res;
}
break;
default:
/* trouble */
- warn_or_exit_horribly(AH, modulename, "%s: %s Command was: %s\n",
+ warn_or_exit_horribly(AH, "%s: %sCommand was: %s",
desc, PQerrorMessage(conn), qry);
break;
}
*/
if (AH->pgCopyIn &&
PQputCopyData(AH->connection, buf, bufLen) <= 0)
- exit_horribly(modulename, "error returned by PQputCopyData: %s",
- PQerrorMessage(AH->connection));
+ fatal("error returned by PQputCopyData: %s",
+ PQerrorMessage(AH->connection));
}
else if (AH->outputKind == OUTPUT_OTHERDATA)
{
PGresult *res;
if (PQputCopyEnd(AH->connection, NULL) <= 0)
- exit_horribly(modulename, "error returned by PQputCopyEnd: %s",
- PQerrorMessage(AH->connection));
+ fatal("error returned by PQputCopyEnd: %s",
+ PQerrorMessage(AH->connection));
/* Check command status and return to normal libpq state */
res = PQgetResult(AH->connection);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
- warn_or_exit_horribly(AH, modulename, "COPY failed for table \"%s\": %s",
- tocEntryTag, PQerrorMessage(AH->connection));
+ warn_or_exit_horribly(AH, "COPY failed for table \"%s\": %s",
+ tocEntryTag, PQerrorMessage(AH->connection));
PQclear(res);
/* Do this to ensure we've pumped libpq back to idle state */
if (PQgetResult(AH->connection) != NULL)
- write_msg(NULL, "WARNING: unexpected extra results during COPY of table \"%s\"\n",
- tocEntryTag);
+ pg_log_warning("unexpected extra results during COPY of table \"%s\"",
+ tocEntryTag);
AH->pgCopyIn = false;
}