aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/Makefile2
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c44
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.h2
-rw-r--r--src/bin/pg_dump/pg_backup_db.c93
-rw-r--r--src/bin/pg_dump/pg_backup_plain_text.c115
-rw-r--r--src/bin/pg_dump/pg_dump.c13
6 files changed, 122 insertions, 147 deletions
diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile
index 6b104028615..6bbef564c5f 100644
--- a/src/bin/pg_dump/Makefile
+++ b/src/bin/pg_dump/Makefile
@@ -4,7 +4,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
-# $Header: /cvsroot/pgsql/src/bin/pg_dump/Makefile,v 1.20 2000/07/21 11:40:08 pjw Exp $
+# $Header: /cvsroot/pgsql/src/bin/pg_dump/Makefile,v 1.21 2000/07/24 06:24:26 pjw Exp $
#
#-------------------------------------------------------------------------
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index e210780196b..55fb0f742f1 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -43,6 +43,8 @@ static int _tocSortCompareByIDNum(const void *p1, const void *p2);
static ArchiveHandle* _allocAH(const char* FileSpec, const ArchiveFormat fmt,
int compression, ArchiveMode mode);
static int _printTocEntry(ArchiveHandle* AH, TocEntry* te, RestoreOptions *ropt);
+static void _reconnectAsOwner(ArchiveHandle* AH, TocEntry* te);
+
static int _tocEntryRequired(TocEntry* te, RestoreOptions *ropt);
static void _disableTriggers(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
static void _enableTriggers(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
@@ -153,6 +155,12 @@ void RestoreArchive(Archive* AHX, RestoreOptions *ropt)
/* Work out what, if anything, we want from this entry */
reqs = _tocEntryRequired(te, ropt);
+ /* Reconnect if necessary */
+ if (reqs != 0)
+ {
+ _reconnectAsOwner(AH, te);
+ }
+
if ( (reqs & 1) != 0) /* We want the schema */
{
ahlog(AH, 1, "Creating %s %s\n", te->desc, te->name);
@@ -773,6 +781,14 @@ void ahlog(ArchiveHandle* AH, int level, const char *fmt, ...)
}
/*
+ * Single place for logic which says 'We are restoring to a direct DB connection'.
+ */
+int RestoringToDB(ArchiveHandle* AH)
+{
+ return (AH->ropt && AH->ropt->useDB && AH->connection);
+}
+
+/*
* Write buffer to the output file (usually stdout). This is user for
* outputting 'restore' scripts etc. It is even possible for an archive
* format to create a custom output routine to 'fake' a restore if it
@@ -798,7 +814,7 @@ int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle* AH)
* If we're doing a restore, and it's direct to DB, and we're connected
* then send it to the DB.
*/
- if (AH->ropt && AH->ropt->useDB && AH->connection)
+ if (RestoringToDB(AH))
return ExecuteSqlCommandBuf(AH, (void*)ptr, size*nmemb);
else
return fwrite((void*)ptr, size, nmemb, AH->OF);
@@ -1335,22 +1351,32 @@ static int _tocEntryRequired(TocEntry* te, RestoreOptions *ropt)
return res;
}
+static void _reconnectAsOwner(ArchiveHandle* AH, TocEntry* te)
+{
+ if (te->owner && strlen(te->owner) != 0 && strcmp(AH->currUser, te->owner) != 0) {
+ if (RestoringToDB(AH))
+ {
+ ReconnectDatabase(AH, te->owner);
+ //todo pjw - ???? fix for db connection...
+ }
+ else
+ {
+ ahprintf(AH, "\\connect - %s\n", te->owner);
+ }
+ AH->currUser = te->owner;
+ }
+}
+
static int _printTocEntry(ArchiveHandle* AH, TocEntry* te, RestoreOptions *ropt)
{
ahprintf(AH, "--\n-- TOC Entry ID %d (OID %s)\n--\n-- Name: %s Type: %s Owner: %s\n",
te->id, te->oid, te->name, te->desc, te->owner);
if (AH->PrintExtraTocPtr != NULL) {
- (*AH->PrintExtraTocPtr)(AH, te);
+ (*AH->PrintExtraTocPtr)(AH, te);
}
ahprintf(AH, "--\n\n");
- if (te->owner && strlen(te->owner) != 0 && strcmp(AH->currUser, te->owner) != 0) {
- //todo pjw - fix for db connection...
- //ahprintf(AH, "\\connect - %s\n", te->owner);
- AH->currUser = te->owner;
- }
-
- ahprintf(AH, "%s\n", te->defn);
+ ahprintf(AH, "%s\n", te->defn);
return 1;
}
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index f3b0ba53858..326cb4df7f1 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -264,6 +264,8 @@ extern int isValidTarHeader(char *header);
extern OutputContext SetOutput(ArchiveHandle* AH, char *filename, int compression);
extern void ResetOutput(ArchiveHandle* AH, OutputContext savedContext);
+extern int RestoringToDB(ArchiveHandle* AH);
+extern int ReconnectDatabase(ArchiveHandle *AH, char *newUser);
int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle* AH);
int ahprintf(ArchiveHandle* AH, const char *fmt, ...);
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 62e4c2b0dd8..17f025ab9fb 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -48,20 +48,26 @@ _prompt_for_password(char *username, char *password)
t;
#endif
- fprintf(stderr, "Username: ");
- fflush(stderr);
- fgets(username, 100, stdin);
- length = strlen(username);
- /* skip rest of the line */
- if (length > 0 && username[length - 1] != '\n')
+ /*
+ * Allow for forcing a specific username
+ */
+ if (strlen(username) == 0)
{
- do
+ fprintf(stderr, "Username: ");
+ fflush(stderr);
+ fgets(username, 100, stdin);
+ length = strlen(username);
+ /* skip rest of the line */
+ if (length > 0 && username[length - 1] != '\n')
{
- fgets(buf, 512, stdin);
- } while (buf[strlen(buf) - 1] != '\n');
+ do
+ {
+ fgets(buf, 512, stdin);
+ } while (buf[strlen(buf) - 1] != '\n');
+ }
+ if (length > 0 && username[length - 1] == '\n')
+ username[length - 1] = '\0';
}
- if (length > 0 && username[length - 1] == '\n')
- username[length - 1] = '\0';
#ifdef HAVE_TERMIOS_H
tcgetattr(0, &t);
@@ -125,17 +131,69 @@ _check_database_version(ArchiveHandle *AH, bool ignoreVersion)
PQclear(res);
}
+int ReconnectDatabase(ArchiveHandle *AH, char *newUser)
+{
+ int need_pass;
+ PGconn *newConn;
+ char password[100];
+ char *pwparam = NULL;
+ int badPwd = 0;
+ int noPwd = 0;
+
+ ahlog(AH, 1, "Connecting as %s\n", newUser);
+
+ do
+ {
+ need_pass = false;
+ newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
+ NULL, NULL, PQdb(AH->connection),
+ newUser, pwparam);
+ if (!newConn)
+ die_horribly(AH, "%s: Failed to reconnect (PQsetdbLogin failed).\n", progname);
+
+ if (PQstatus(newConn) == CONNECTION_BAD)
+ {
+ noPwd = (strcmp(PQerrorMessage(newConn), "fe_sendauth: no password supplied\n") == 0);
+ badPwd = (strncmp(PQerrorMessage(newConn), "Password authentication failed for user", 39)
+ == 0);
+
+ if (noPwd || badPwd)
+ {
+
+ if (badPwd)
+ fprintf(stderr, "Password incorrect\n");
+
+ fprintf(stderr, "Connecting to %s as %s\n", PQdb(AH->connection), newUser);
+
+ need_pass = true;
+ _prompt_for_password(newUser, password);
+ pwparam = password;
+ }
+ else
+ die_horribly(AH, "%s: Could not reconnect. %s\n", progname, PQerrorMessage(newConn));
+ }
+
+ } while (need_pass);
+
+ PQfinish(AH->connection);
+ AH->connection = newConn;
+ strcpy(AH->username, newUser);
+
+ return 1;
+}
+
+
PGconn* ConnectDatabase(Archive *AHX,
const char* dbname,
const char* pghost,
const char* pgport,
- const int reqPwd,
- const int ignoreVersion)
+ const int reqPwd,
+ const int ignoreVersion)
{
ArchiveHandle *AH = (ArchiveHandle*)AHX;
- char connect_string[512] = "";
- char tmp_string[128];
- char password[100];
+ char connect_string[512] = "";
+ char tmp_string[128];
+ char password[100];
if (AH->connection)
die_horribly(AH, "%s: already connected to database\n", progname);
@@ -168,6 +226,7 @@ PGconn* ConnectDatabase(Archive *AHX,
if (reqPwd)
{
+ AH->username[0] = '\0';
_prompt_for_password(AH->username, password);
strcat(connect_string, "authtype=password ");
sprintf(tmp_string, "user=%s ", AH->username);
@@ -188,6 +247,8 @@ PGconn* ConnectDatabase(Archive *AHX,
/* check for version mismatch */
_check_database_version(AH, ignoreVersion);
+ AH->currUser = PQuser(AH->connection);
+
return AH->connection;
}
diff --git a/src/bin/pg_dump/pg_backup_plain_text.c b/src/bin/pg_dump/pg_backup_plain_text.c
index 56866f10368..e69de29bb2d 100644
--- a/src/bin/pg_dump/pg_backup_plain_text.c
+++ b/src/bin/pg_dump/pg_backup_plain_text.c
@@ -1,115 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * pg_backup_plain_text.c
- *
- * This file is copied from the 'custom' format file, but dumps data into
- * directly to a text file, and the TOC into the 'main' file.
- *
- * See the headers to pg_restore for more details.
- *
- * Copyright (c) 2000, Philip Warner
- * Rights are granted to use this software in any way so long
- * as this notice is not removed.
- *
- * The author is not responsible for loss or damages that may
- * result from it's use.
- *
- *
- * IDENTIFICATION
- *
- * Modifications - 01-Jul-2000 - pjw@rhyme.com.au
- *
- * Initial version.
- *
- *-------------------------------------------------------------------------
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h> /* for dup */
-#include "pg_backup.h"
-#include "pg_backup_archiver.h"
-
-static void _ArchiveEntry(ArchiveHandle* AH, TocEntry* te);
-static void _StartData(ArchiveHandle* AH, TocEntry* te);
-static int _WriteData(ArchiveHandle* AH, const void* data, int dLen);
-static void _EndData(ArchiveHandle* AH, TocEntry* te);
-static int _WriteByte(ArchiveHandle* AH, const int i);
-static int _WriteBuf(ArchiveHandle* AH, const void* buf, int len);
-static void _CloseArchive(ArchiveHandle* AH);
-static void _PrintTocData(ArchiveHandle* AH, TocEntry* te, RestoreOptions *ropt);
-
-/*
- * Initializer
- */
-void InitArchiveFmt_PlainText(ArchiveHandle* AH)
-{
- /* Assuming static functions, this can be copied for each format. */
- AH->ArchiveEntryPtr = _ArchiveEntry;
- AH->StartDataPtr = _StartData;
- AH->WriteDataPtr = _WriteData;
- AH->EndDataPtr = _EndData;
- AH->WriteBytePtr = _WriteByte;
- AH->WriteBufPtr = _WriteBuf;
- AH->ClosePtr = _CloseArchive;
- AH->PrintTocDataPtr = _PrintTocData;
-
- /*
- * Now prevent reading...
- */
- if (AH->mode == archModeRead)
- die_horribly("%s: This format can not be read\n");
-
-}
-
-/*
- * - Start a new TOC entry
- */
-static void _ArchiveEntry(ArchiveHandle* AH, TocEntry* te)
-{
- /* Don't need to do anything */
-}
-
-static void _StartData(ArchiveHandle* AH, TocEntry* te)
-{
- ahprintf(AH, "--\n-- Data for TOC Entry ID %d (OID %s) %s %s\n--\n\n",
- te->id, te->oid, te->desc, te->name);
-}
-
-static int _WriteData(ArchiveHandle* AH, const void* data, int dLen)
-{
- ahwrite(data, 1, dLen, AH);
- return dLen;
-}
-
-static void _EndData(ArchiveHandle* AH, TocEntry* te)
-{
- ahprintf(AH, "\n\n");
-}
-
-/*
- * Print data for a given TOC entry
-*/
-static void _PrintTocData(ArchiveHandle* AH, TocEntry* te, RestoreOptions *ropt)
-{
- if (*te->dataDumper)
- (*te->dataDumper)((Archive*)AH, te->oid, te->dataDumperArg);
-}
-
-static int _WriteByte(ArchiveHandle* AH, const int i)
-{
- /* Don't do anything */
- return 0;
-}
-
-static int _WriteBuf(ArchiveHandle* AH, const void* buf, int len)
-{
- /* Don't do anything */
- return len;
-}
-
-static void _CloseArchive(ArchiveHandle* AH)
-{
- /* Nothing to do */
-}
-
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index e4a47b9ef10..7c89573e291 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.160 2000/07/21 11:40:08 pjw Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.161 2000/07/24 06:24:26 pjw Exp $
*
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
*
@@ -883,7 +883,6 @@ main(int argc, char **argv)
MoveToEnd(g_fout, "INDEX");
MoveToEnd(g_fout, "TRIGGER");
MoveToEnd(g_fout, "RULE");
- MoveToEnd(g_fout, "ACL");
if (plainText)
{
@@ -3819,6 +3818,7 @@ dumpRules(Archive *fout, const char *tablename,
int i_definition;
int i_oid;
+ int i_owner;
int i_rulename;
if (g_verbose)
@@ -3837,8 +3837,9 @@ dumpRules(Archive *fout, const char *tablename,
* Get all rules defined for this table
*/
resetPQExpBuffer(query);
- appendPQExpBuffer(query, "SELECT pg_get_ruledef(pg_rewrite.rulename) "
- "AS definition, pg_rewrite.oid, pg_rewrite.rulename FROM pg_rewrite, pg_class "
+ appendPQExpBuffer(query, "SELECT pg_get_ruledef(pg_rewrite.rulename) AS definition,"
+ "pg_get_userbyid(pg_class.relowner) AS viewowner, "
+ "pg_rewrite.oid, pg_rewrite.rulename FROM pg_rewrite, pg_class "
"WHERE pg_class.relname = '%s' "
"AND pg_rewrite.ev_class = pg_class.oid "
"ORDER BY pg_rewrite.oid",
@@ -3854,6 +3855,7 @@ dumpRules(Archive *fout, const char *tablename,
nrules = PQntuples(res);
i_definition = PQfnumber(res, "definition");
+ i_owner = PQfnumber(res, "viewowner");
i_oid = PQfnumber(res, "oid");
i_rulename = PQfnumber(res, "rulename");
@@ -3863,10 +3865,9 @@ dumpRules(Archive *fout, const char *tablename,
for (i = 0; i < nrules; i++)
{
-
ArchiveEntry(fout, PQgetvalue(res, i, i_oid), PQgetvalue(res, i, i_rulename),
"RULE", NULL, PQgetvalue(res, i, i_definition),
- "", "", "", NULL, NULL);
+ "", "", PQgetvalue(res, i, i_owner), NULL, NULL);
/* Dump rule comments */