dbTalk Databases Forums  

[BUGS] pg_dumpall bug in PG 8.0b3 Win32 port

mailing.database.pgsql-bugs mailing.database.pgsql-bugs


Discuss [BUGS] pg_dumpall bug in PG 8.0b3 Win32 port in the mailing.database.pgsql-bugs forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Luiz K. Matsumura
 
Posts: n/a

Default [BUGS] pg_dumpall bug in PG 8.0b3 Win32 port - 10-05-2004 , 06:16 PM






This is a multi-part message in MIME format.
--------------020506020407090407070609
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

I tried to use pg_dumpall in Win32 and receive a error message like this:

pg_dump.exe: [archiver (db)] connection to database "test" failed:
FATAL: user "'postgres'" does not exist

Well, the word "'postgres'" is the word is between simple quotations
marks and later between double quotations marks.
Then, I assume that the error must be in string that pg_dumpall mounts
to execute pg_dump

I modified pg_dumpall.c lines between 160 and 270 to add a #ifndef
WIN32... #endif clause to pgdumpopts to store
the parameters with double quotations intead simple quotation marks in
case of WIN32 ports
But, I don't have how to test it.
Please, somebody can test and fix the pg_dumpall.c of oficial source ?

Thanks in advance

Luiz



--------------020506020407090407070609
Content-Type: text/plain;
name="pg_dumpall.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="pg_dumpall.c"

/*-------------------------------------------------------------------------
*
* pg_dumpall
*
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $PostgreSQL: pgsql-server/src/bin/pg_dump/pg_dumpall.c,v 1.51 2004/08/29 05:06:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/

#include "postgres_fe.h"

#include <unistd.h>
#ifdef ENABLE_NLS
#include <locale.h>
#endif
#ifndef HAVE_STRDUP
#include "strdup.h"
#endif
#include <errno.h>
#include <time.h>

#include "getopt_long.h"

#ifndef HAVE_OPTRESET
int optreset;
#endif

#include "dumputils.h"
#include "libpq-fe.h"
#include "pg_backup.h"
#include "pqexpbuffer.h"

#define _(x) gettext((x))

/* version string we expect back from postgres */
#define PG_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"


static const char *progname;

static void help(void);

static void dumpUsers(PGconn *conn, bool initdbonly);
static void dumpGroups(PGconn *conn);
static void dumpTablespaces(PGconn *conn);
static void dumpCreateDB(PGconn *conn);
static void dumpDatabaseConfig(PGconn *conn, const char *dbname);
static void dumpUserConfig(PGconn *conn, const char *username);
static void makeAlterConfigCommand(const char *arrayitem, const char *type, const char *name);
static void dumpDatabases(PGconn *conn);
static void dumpTimestamp(char *msg);

static int runPgDump(const char *dbname);
static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
const char *pguser, bool require_password);
static PGresult *executeQuery(PGconn *conn, const char *query);

char pg_dump_bin[MAXPGPATH];
PQExpBuffer pgdumpopts;
bool output_clean = false;
bool skip_acls = false;
bool verbose = false;
int server_version;

/* flags for -X long options */
int disable_dollar_quoting = 0;
int disable_triggers = 0;
int use_setsessauth = 0;

int
main(int argc, char *argv[])
{
char *pghost = NULL;
char *pgport = NULL;
char *pguser = NULL;
bool force_password = false;
bool data_only = false;
bool globals_only = false;
bool schema_only = false;
PGconn *conn;
int c,
ret;

static struct option long_options[] = {
{"data-only", no_argument, NULL, 'a'},
{"clean", no_argument, NULL, 'c'},
{"inserts", no_argument, NULL, 'd'},
{"attribute-inserts", no_argument, NULL, 'D'},
{"column-inserts", no_argument, NULL, 'D'},
{"globals-only", no_argument, NULL, 'g'},
{"host", required_argument, NULL, 'h'},
{"ignore-version", no_argument, NULL, 'i'},
{"oids", no_argument, NULL, 'o'},
{"no-owner", no_argument, NULL, 'O'},
{"port", required_argument, NULL, 'p'},
{"password", no_argument, NULL, 'W'},
{"schema-only", no_argument, NULL, 's'},
{"superuser", required_argument, NULL, 'S'},
{"username", required_argument, NULL, 'U'},
{"verbose", no_argument, NULL, 'v'},
{"no-privileges", no_argument, NULL, 'x'},
{"no-acl", no_argument, NULL, 'x'},

/*
* the following options don't have an equivalent short option
* letter, but are available as '-X long-name'
*/
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
{"disable-triggers", no_argument, &disable_triggers, 1},
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},

{NULL, 0, NULL, 0}
};

int optindex;

set_pglocale_pgservice(argv[0], "pg_dump");

progname = get_progname(argv[0]);

if (argc > 1)
{
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
{
help();
exit(0);
}
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
{
puts("pg_dumpall (PostgreSQL) " PG_VERSION);
exit(0);
}
}

if ((ret = find_other_exec(argv[0], "pg_dump", PG_VERSIONSTR,
pg_dump_bin)) < 0)
{
if (ret == -1)
fprintf(stderr,
_("The program \"pg_dump\" is needed by %s "
"but was not found in the same directory as \"%s\".\n"
"Check your installation.\n"),
progname, progname);
else
fprintf(stderr,
_("The program \"pg_dump\" was found by %s "
"but was not the same version as \"%s\".\n"
"Check your installation.\n"),
progname, progname);
exit(1);
}

pgdumpopts = createPQExpBuffer();

while ((c = getopt_long(argc, argv, "acdDgh:ioOp:sS:U:vWxX:", long_options, &optindex)) != -1)
{
switch (c)
{
case 'a':
data_only = true;
appendPQExpBuffer(pgdumpopts, " -a");
break;

case 'c':
output_clean = true;
break;

case 'd':
case 'D':
appendPQExpBuffer(pgdumpopts, " -%c", c);
break;

case 'g':
globals_only = true;
break;

case 'h':
pghost = optarg;
#ifndef WIN32
appendPQExpBuffer(pgdumpopts, " -h '%s'", pghost);
#else
appendPQExpBuffer(pgdumpopts, " -h \"%s\"", pghost);
#endif

break;



case 'i':
case 'o':
appendPQExpBuffer(pgdumpopts, " -%c", c);
break;

case 'O':
appendPQExpBuffer(pgdumpopts, " -O");
break;

case 'p':
pgport = optarg;
#ifndef WIN32
appendPQExpBuffer(pgdumpopts, " -p '%s'", pgport);
#else
appendPQExpBuffer(pgdumpopts, " -p \"%s\"", pgport);
#endif
break;

case 's':
schema_only = true;
appendPQExpBuffer(pgdumpopts, " -s");
break;

case 'S':
#ifndef WIN32
appendPQExpBuffer(pgdumpopts, " -S '%s'", optarg);
#else
appendPQExpBuffer(pgdumpopts, " -S \"%s\"", optarg);
#endif
break;

case 'U':
pguser = optarg;
#ifndef WIN32
appendPQExpBuffer(pgdumpopts, " -U '%s'", pguser);
#else
appendPQExpBuffer(pgdumpopts, " -U \"%s\"", pguser);
#endif
break;

case 'v':
verbose = true;
appendPQExpBuffer(pgdumpopts, " -v");
break;

case 'W':
force_password = true;
appendPQExpBuffer(pgdumpopts, " -W");
break;

case 'x':
skip_acls = true;
appendPQExpBuffer(pgdumpopts, " -x");
break;

case 'X':
if (strcmp(optarg, "disable-dollar-quoting") == 0)
appendPQExpBuffer(pgdumpopts, " -X disable-dollar-quoting");
else if (strcmp(optarg, "disable-triggers") == 0)
appendPQExpBuffer(pgdumpopts, " -X disable-triggers");
else if (strcmp(optarg, "use-set-session-authorization") == 0)
/* no-op, still allowed for compatibility */ ;
else
{
fprintf(stderr,
_("%s: invalid -X option -- %s\n"),
progname, optarg);
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
}
break;

case 0:
break;

default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
}
}

/* Add long options to the pg_dump argument list */
if (disable_dollar_quoting)
appendPQExpBuffer(pgdumpopts, " -X disable-dollar-quoting");
if (disable_triggers)
appendPQExpBuffer(pgdumpopts, " -X disable-triggers");
if (use_setsessauth)
appendPQExpBuffer(pgdumpopts, " -X use-set-session-authorization");

if (optind < argc)
{
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);
}


conn = connectDatabase("template1", pghost, pgport, pguser, force_password);

printf("--\n-- PostgreSQL database cluster dump\n--\n\n");
if (verbose)
dumpTimestamp("Started on");

printf("\\connect \"template1\"\n\n");

if (!data_only)
{
/* Dump all users excluding the initdb user */
dumpUsers(conn, false);
dumpGroups(conn);
if (server_version >= 80000)
dumpTablespaces(conn);
if (!globals_only)
dumpCreateDB(conn);
/* Dump alter command for initdb user */
dumpUsers(conn, true);
}

if (!globals_only)
dumpDatabases(conn);

PQfinish(conn);

if (verbose)
dumpTimestamp("Completed on");
printf("--\n-- PostgreSQL database cluster dump complete\n--\n\n");

exit(0);
}



static void
help(void)
{
printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname);
printf(_("Usage:\n"));
printf(_(" %s [OPTION]...\n"), progname);

printf(_("\nGeneral options:\n"));
printf(_(" -i, --ignore-version proceed even when server version mismatches\n"
" pg_dumpall version\n"));
printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n"));
printf(_("\nOptions controlling the output content:\n"));
printf(_(" -a, --data-only dump only the data, not the schema\n"));
printf(_(" -c, --clean clean (drop) databases prior to create\n"));
printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n"));
printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n"));
printf(_(" -g, --globals-only dump only global objects, no databases\n"));
printf(_(" -o, --oids include OIDs in dump\n"));
printf(_(" -O, --no-owner do not output commands to set object ownership\n"));
printf(_(" -s, --schema-only dump only the schema, no data\n"));
printf(_(" -S, --superuser=NAME specify the superuser user name to use in the dump\n"));
printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
printf(_(" -X disable-dollar-quoting, --disable-dollar-quoting\n"
" disable dollar quoting, use SQL standard quoting\n"));
printf(_(" -X disable-triggers, --disable-triggers\n"
" disable triggers during data-only restore\n"));
printf(_(" -X use-set-session-authorization, --use-set-session-authorization\n"
" use SESSION AUTHORIZATION commands instead of\n"
" OWNER TO commands\n"));

printf(_("\nConnection options:\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
printf(_(" -p, --port=PORT database server port number\n"));
printf(_(" -U, --username=NAME connect as specified database user\n"));
printf(_(" -W, --password force password prompt (should happen automatically)\n"));

printf(_("\nThe SQL script will be written to the standard output.\n\n"));
printf(_("Report bugs to <pgsql-bugs (AT) postgresql (DOT) org>.\n"));
}



/*
* Dump users
* Is able to dump all non initdb users or just the initdb user.
*/
static void
dumpUsers(PGconn *conn, bool initdbonly)
{
PGresult *res;
int i;

if (server_version >= 70100)
res = executeQuery(conn,
"SELECT usename, usesysid, passwd, usecreatedb, "
"usesuper, valuntil, "
"(usesysid = (SELECT datdba FROM pg_database WHERE datname = 'template0')) AS clusterowner "
"FROM pg_shadow");
else
res = executeQuery(conn,
"SELECT usename, usesysid, passwd, usecreatedb, "
"usesuper, valuntil, "
"(usesysid = (SELECT datdba FROM pg_database WHERE datname = 'template1')) AS clusterowner "
"FROM pg_shadow");

if (PQntuples(res) > 0 || (!initdbonly && output_clean))
printf("--\n-- Users\n--\n\n");
if (!initdbonly && output_clean)
printf("DELETE FROM pg_shadow WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');\n\n");

for (i = 0; i < PQntuples(res); i++)
{
const char *username;
bool clusterowner;
PQExpBuffer buf = createPQExpBuffer();

username = PQgetvalue(res, i, 0);
clusterowner = (strcmp(PQgetvalue(res, i, 6), "t") == 0);

/* Check which pass we're on */
if ((initdbonly && !clusterowner) || (!initdbonly && clusterowner))
continue;

/*
* Dump ALTER USER for the cluster owner and CREATE USER for all
* other users
*/
if (!clusterowner)
appendPQExpBuffer(buf, "CREATE USER %s WITH SYSID %s",
fmtId(username),
PQgetvalue(res, i, 1));
else
appendPQExpBuffer(buf, "ALTER USER %s WITH",
fmtId(username));

if (!PQgetisnull(res, i, 2))
{
appendPQExpBuffer(buf, " PASSWORD ");
appendStringLiteral(buf, PQgetvalue(res, i, 2), true);
}

if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
appendPQExpBuffer(buf, " CREATEDB");
else
appendPQExpBuffer(buf, " NOCREATEDB");

if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
appendPQExpBuffer(buf, " CREATEUSER");
else
appendPQExpBuffer(buf, " NOCREATEUSER");

if (!PQgetisnull(res, i, 5))
appendPQExpBuffer(buf, " VALID UNTIL '%s'",
PQgetvalue(res, i, 5));

appendPQExpBuffer(buf, ";\n");

printf("%s", buf->data);
destroyPQExpBuffer(buf);

if (server_version >= 70300)
dumpUserConfig(conn, username);
}

PQclear(res);
printf("\n\n");
}



/*
* Dump groups.
*/
static void
dumpGroups(PGconn *conn)
{
PGresult *res;
int i;

res = executeQuery(conn, "SELECT groname, grosysid, grolist FROM pg_group");

if (PQntuples(res) > 0 || output_clean)
printf("--\n-- Groups\n--\n\n");
if (output_clean)
printf("DELETE FROM pg_group;\n\n");

for (i = 0; i < PQntuples(res); i++)
{
PQExpBuffer buf = createPQExpBuffer();
char *val;
char *tok;

appendPQExpBuffer(buf, "CREATE GROUP %s WITH SYSID %s;\n",
fmtId(PQgetvalue(res, i, 0)),
PQgetvalue(res, i, 1));

val = strdup(PQgetvalue(res, i, 2));
tok = strtok(val, ",{}");
while (tok)
{
PGresult *res2;
PQExpBuffer buf2 = createPQExpBuffer();
int j;

appendPQExpBuffer(buf2, "SELECT usename FROM pg_shadow WHERE usesysid = %s;", tok);
res2 = executeQuery(conn, buf2->data);
destroyPQExpBuffer(buf2);

for (j = 0; j < PQntuples(res2); j++)
{
appendPQExpBuffer(buf, "ALTER GROUP %s ", fmtId(PQgetvalue(res, i, 0)));
appendPQExpBuffer(buf, "ADD USER %s;\n", fmtId(PQgetvalue(res2, j, 0)));
}

PQclear(res2);

tok = strtok(NULL, "{},");
}
free(val);

printf("%s", buf->data);
destroyPQExpBuffer(buf);
}

PQclear(res);
printf("\n\n");
}

/*
* Dump tablespaces.
*/
static void
dumpTablespaces(PGconn *conn)
{
PGresult *res;
int i;

/*
* Get all tablespaces except built-in ones (which we assume are named
* pg_xxx)
*/
res = executeQuery(conn, "SELECT spcname, "
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
"spclocation, spcacl "
"FROM pg_catalog.pg_tablespace "
"WHERE spcname NOT LIKE 'pg\\_%'");

if (PQntuples(res) > 0)
printf("--\n-- Tablespaces\n--\n\n");

for (i = 0; i < PQntuples(res); i++)
{
PQExpBuffer buf = createPQExpBuffer();
char *spcname = PQgetvalue(res, i, 0);
char *spcowner = PQgetvalue(res, i, 1);
char *spclocation = PQgetvalue(res, i, 2);
char *spcacl = PQgetvalue(res, i, 3);
char *fspcname;

/* needed for buildACLCommands() */
fspcname = strdup(fmtId(spcname));

if (output_clean)
appendPQExpBuffer(buf, "DROP TABLESPACE %s;\n", fspcname);

appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));

appendPQExpBuffer(buf, " LOCATION ");
appendStringLiteral(buf, spclocation, true);
appendPQExpBuffer(buf, ";\n");

if (!skip_acls &&
!buildACLCommands(fspcname, "TABLESPACE", spcacl, spcowner,
server_version, buf))
{
fprintf(stderr, _("%s: could not parse ACL list (%s) for tablespace \"%s\"\n"),
progname, spcacl, fspcname);
PQfinish(conn);
exit(1);
}

printf("%s", buf->data);

free(fspcname);
destroyPQExpBuffer(buf);
}

PQclear(res);
printf("\n\n");
}

/*
* Dump commands to create each database.
*
* To minimize the number of reconnections (and possibly ensuing
* password prompts) required by the output script, we emit all CREATE
* DATABASE commands during the initial phase of the script, and then
* run pg_dump for each database to dump the contents of that
* database. We skip databases marked not datallowconn, since we'd be
* unable to connect to them anyway (and besides, we don't want to
* dump template0).
*/
static void
dumpCreateDB(PGconn *conn)
{
PGresult *res;
int i;

printf("--\n-- Database creation\n--\n\n");

if (server_version >= 80000)
res = executeQuery(conn,
"SELECT datname, "
"coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
"datistemplate, datacl, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
"FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
"WHERE datallowconn ORDER BY 1");
else if (server_version >= 70300)
res = executeQuery(conn,
"SELECT datname, "
"coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
"datistemplate, datacl, "
"'pg_default' AS dattablespace "
"FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
"WHERE datallowconn ORDER BY 1");
else if (server_version >= 70100)
res = executeQuery(conn,
"SELECT datname, "
"coalesce("
"(select usename from pg_shadow where usesysid=datdba), "
"(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
"datistemplate, '' as datacl, "
"'pg_default' AS dattablespace "
"FROM pg_database d "
"WHERE datallowconn ORDER BY 1");
else
{
/*
* Note: 7.0 fails to cope with sub-select in COALESCE, so just
* deal with getting a NULL by not printing any OWNER clause.
*/
res = executeQuery(conn,
"SELECT datname, "
"(select usename from pg_shadow where usesysid=datdba), "
"pg_encoding_to_char(d.encoding), "
"'f' as datistemplate, "
"'' as datacl, "
"'pg_default' AS dattablespace "
"FROM pg_database d "
"ORDER BY 1");
}

for (i = 0; i < PQntuples(res); i++)
{
PQExpBuffer buf;
char *dbname = PQgetvalue(res, i, 0);
char *dbowner = PQgetvalue(res, i, 1);
char *dbencoding = PQgetvalue(res, i, 2);
char *dbistemplate = PQgetvalue(res, i, 3);
char *dbacl = PQgetvalue(res, i, 4);
char *dbtablespace = PQgetvalue(res, i, 5);
char *fdbname;

if (strcmp(dbname, "template1") == 0)
continue;

buf = createPQExpBuffer();

/* needed for buildACLCommands() */
fdbname = strdup(fmtId(dbname));

if (output_clean)
appendPQExpBuffer(buf, "DROP DATABASE %s;\n", fdbname);

appendPQExpBuffer(buf, "CREATE DATABASE %s", fdbname);

appendPQExpBuffer(buf, " WITH TEMPLATE = template0");

if (strlen(dbowner) != 0)
appendPQExpBuffer(buf, " OWNER = %s",
fmtId(dbowner));

appendPQExpBuffer(buf, " ENCODING = ");
appendStringLiteral(buf, dbencoding, true);

/* Output tablespace if it isn't default */
if (strcmp(dbtablespace, "pg_default") != 0)
appendPQExpBuffer(buf, " TABLESPACE = %s",
fmtId(dbtablespace));

appendPQExpBuffer(buf, ";\n");

if (strcmp(dbistemplate, "t") == 0)
{
appendPQExpBuffer(buf, "UPDATE pg_database SET datistemplate = 't' WHERE datname = ");
appendStringLiteral(buf, dbname, true);
appendPQExpBuffer(buf, ";\n");
}

if (!skip_acls &&
!buildACLCommands(fdbname, "DATABASE", dbacl, dbowner,
server_version, buf))
{
fprintf(stderr, _("%s: could not parse ACL list (%s) for database \"%s\"\n"),
progname, dbacl, fdbname);
PQfinish(conn);
exit(1);
}

printf("%s", buf->data);
destroyPQExpBuffer(buf);
free(fdbname);

if (server_version >= 70300)
dumpDatabaseConfig(conn, dbname);
}

PQclear(res);
printf("\n\n");
}



/*
* Dump database-specific configuration
*/
static void
dumpDatabaseConfig(PGconn *conn, const char *dbname)
{
PQExpBuffer buf = createPQExpBuffer();
int count = 1;

for (;
{
PGresult *res;

printfPQExpBuffer(buf, "SELECT datconfig[%d] FROM pg_database WHERE datname = ", count);
appendStringLiteral(buf, dbname, true);
appendPQExpBuffer(buf, ";");

res = executeQuery(conn, buf->data);
if (!PQgetisnull(res, 0, 0))
{
makeAlterConfigCommand(PQgetvalue(res, 0, 0), "DATABASE", dbname);
PQclear(res);
count++;
}
else
{
PQclear(res);
break;
}
}

destroyPQExpBuffer(buf);
}



/*
* Dump user-specific configuration
*/
static void
dumpUserConfig(PGconn *conn, const char *username)
{
PQExpBuffer buf = createPQExpBuffer();
int count = 1;

for (;
{
PGresult *res;

printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count);
appendStringLiteral(buf, username, true);
appendPQExpBuffer(buf, ";");

res = executeQuery(conn, buf->data);
if (!PQgetisnull(res, 0, 0))
{
makeAlterConfigCommand(PQgetvalue(res, 0, 0), "USER", username);
PQclear(res);
count++;
}
else
{
PQclear(res);
break;
}
}

destroyPQExpBuffer(buf);
}



/*
* Helper function for dumpXXXConfig().
*/
static void
makeAlterConfigCommand(const char *arrayitem, const char *type, const char *name)
{
char *pos;
char *mine;
PQExpBuffer buf = createPQExpBuffer();

mine = strdup(arrayitem);
pos = strchr(mine, '=');
if (pos == NULL)
return;

*pos = 0;
appendPQExpBuffer(buf, "ALTER %s %s ", type, fmtId(name));
appendPQExpBuffer(buf, "SET %s TO ", fmtId(mine));

/*
* Some GUC variable names are 'LIST' type and hence must not be
* quoted.
*/
if (strcasecmp(mine, "DateStyle") == 0
Quote:
| strcasecmp(mine, "search_path") == 0)
appendPQExpBuffer(buf, "%s", pos + 1);
else
appendStringLiteral(buf, pos + 1, false);
appendPQExpBuffer(buf, ";\n");

printf("%s", buf->data);
destroyPQExpBuffer(buf);
free(mine);
}



/*
* Dump contents of databases.
*/
static void
dumpDatabases(PGconn *conn)
{
PGresult *res;
int i;

if (server_version >= 70100)
res = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1");
else
res = executeQuery(conn, "SELECT datname FROM pg_database ORDER BY 1");

for (i = 0; i < PQntuples(res); i++)
{
int ret;

char *dbname = PQgetvalue(res, i, 0);

if (verbose)
fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);

printf("\\connect %s\n\n", fmtId(dbname));
ret = runPgDump(dbname);
if (ret != 0)
{
fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
exit(1);
}
}

PQclear(res);
}



/*
* Run pg_dump on dbname.
*/
static int
runPgDump(const char *dbname)
{
PQExpBuffer cmd = createPQExpBuffer();
const char *p;
int ret;

/*
* Win32 has to use double-quotes for args, rather than single quotes.
* Strangely enough, this is the only place we pass a database name on
* the command line, except template1 that doesn't need quoting.
*/
#ifndef WIN32
appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp '", SYSTEMQUOTE, pg_dump_bin,
#else
appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp \"", SYSTEMQUOTE, pg_dump_bin,
#endif
pgdumpopts->data);

/* Shell quoting is not quite like SQL quoting, so can't use fmtId */
for (p = dbname; *p; p++)
{
#ifndef WIN32
if (*p == '\'')
appendPQExpBuffer(cmd, "'\"'\"'");
#else
if (*p == '"')
appendPQExpBuffer(cmd, "\\\"");
#endif
else
appendPQExpBufferChar(cmd, *p);
}

#ifndef WIN32
appendPQExpBufferChar(cmd, '\'');
#else
appendPQExpBufferChar(cmd, '"');
#endif

appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);

if (verbose)
fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data);

fflush(stdout);
fflush(stderr);

ret = system(cmd->data);

destroyPQExpBuffer(cmd);

return ret;
}



/*
* Make a database connection with the given parameters. An
* interactive password prompt is automatically issued if required.
*/
static PGconn *
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
const char *pguser, bool require_password)
{
PGconn *conn;
char *password = NULL;
bool need_pass = false;
const char *remoteversion_str;

if (require_password)
password = simple_prompt("Password: ", 100, false);

/*
* Start the connection. Loop until we have a password if requested
* by backend.
*/
do
{
need_pass = false;
conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);

if (!conn)
{
fprintf(stderr, _("%s: could not connect to database \"%s\"\n"),
progname, dbname);
exit(1);
}

if (PQstatus(conn) == CONNECTION_BAD &&
strcmp(PQerrorMessage(conn), "fe_sendauth: no password supplied\n") == 0 &&
!feof(stdin))
{
PQfinish(conn);
need_pass = true;
free(password);
password = NULL;
password = simple_prompt("Password: ", 100, false);
}
} while (need_pass);

if (password)
free(password);

/* check to see that the backend connection was successfully made */
if (PQstatus(conn) == CONNECTION_BAD)
{
fprintf(stderr, _("%s: could not connect to database \"%s\": %s\n"),
progname, dbname, PQerrorMessage(conn));
exit(1);
}

remoteversion_str = PQparameterStatus(conn, "server_version");
if (!remoteversion_str)
{
fprintf(stderr, _("%s: could not get server version\n"), progname);
exit(1);
}
server_version = parse_version(remoteversion_str);
if (server_version < 0)
{
fprintf(stderr, _("%s: could not parse server version \"%s\"\n"),
progname, remoteversion_str);
exit(1);
}

return conn;
}



/*
* Run a query, return the results, exit program on failure.
*/
static PGresult *
executeQuery(PGconn *conn, const char *query)
{
PGresult *res;

if (verbose)
fprintf(stderr, _("%s: executing %s\n"), progname, query);

res = PQexec(conn, query);
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, _("%s: query failed: %s"), progname, PQerrorMessage(conn));
fprintf(stderr, _("%s: query was: %s\n"), progname, query);
PQfinish(conn);
exit(1);
}

return res;
}


/*
* dumpTimestamp
*/
static void
dumpTimestamp(char *msg)
{
char buf[256];
time_t now = time(NULL);

if (strftime(buf, 256, "%Y-%m-%d %H:%M:%S %Z", localtime(&now)) != 0)
printf("-- %s %s\n\n", msg, buf);
}



--------------020506020407090407070609
Content-Type: text/plain
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
MIME-Version: 1.0


---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo (AT) postgresql (DOT) org

--------------020506020407090407070609--



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.