*
* pg_dumpall
*
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.13 2003/01/16 15:27:59 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.26 2003/08/04 02:40:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef HAVE_GETOPT_LONG
#include "getopt_long.h"
-int optreset;
+int optreset;
#endif
#include "dumputils.h"
char *pgdumploc;
PQExpBuffer pgdumpopts;
bool output_clean = false;
+bool skip_acls = false;
bool verbose = false;
int server_version;
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;
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'},
{"port", required_argument, NULL, 'p'},
{"password", no_argument, NULL, 'W'},
+ {"schema-only", no_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'},
{NULL, 0, NULL, 0}
};
textdomain("pg_dump");
#endif
- if (!strrchr(argv[0], '/'))
- progname = argv[0];
- else
- progname = strrchr(argv[0], '/') + 1;
+ progname = get_progname(argv[0]);
if (argc > 1)
{
pgdumploc = findPgDump(argv[0]);
pgdumpopts = createPQExpBuffer();
- while ((c = getopt_long(argc, argv, "cdDgh:iop:U:vW", long_options, &optindex)) != -1)
+ while ((c = getopt_long(argc, argv, "acdDgh:iop:sU:vWx", long_options, &optindex)) != -1)
{
switch (c)
{
+ case 'a':
+ data_only = true;
+ appendPQExpBuffer(pgdumpopts, " -a");
+ break;
+
case 'c':
output_clean = true;
break;
appendPQExpBuffer(pgdumpopts, " -p '%s'", pgport);
break;
+ case 's':
+ schema_only = true;
+ appendPQExpBuffer(pgdumpopts, " -s");
+ break;
+
case 'U':
pguser = optarg;
appendPQExpBuffer(pgdumpopts, " -U '%s'", pguser);
appendPQExpBuffer(pgdumpopts, " -W");
break;
+ case 'x':
+ skip_acls = true;
+ appendPQExpBuffer(pgdumpopts, " -x");
+ break;
+
default:
- fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
}
}
if (optind < argc)
{
- fprintf(stderr,
- _("%s: too many command line options (first is '%s')\n"
- "Try '%s --help' for more information.\n"),
- progname, argv[optind], progname);
+ 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);
}
printf("--\n\n");
printf("\\connect \"template1\"\n\n");
- dumpUsers(conn);
- dumpGroups(conn);
-
- if (globals_only)
- goto end;
+ if (!data_only)
+ {
+ dumpUsers(conn);
+ dumpGroups(conn);
+ }
- dumpCreateDB(conn);
- dumpDatabases(conn);
+ if (!globals_only)
+ {
+ if (!data_only)
+ dumpCreateDB(conn);
+ dumpDatabases(conn);
+ }
-end:
PQfinish(conn);
exit(0);
}
printf(_(" %s [OPTION]...\n"), progname);
printf(_("\nOptions:\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(_(" -i, --ignore-version proceed even when server version mismatches\n"
" pg_dumpall version\n"));
+ printf(_(" -s, --schema-only dump only the schema, no data\n"));
printf(_(" -o, --oids include OIDs in dump\n"));
printf(_(" -v, --verbose verbose mode\n"));
+ printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n"));
printf(_("\nConnection options:\n"));
- printf(_(" -h, --host=HOSTNAME database server host name\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("--\n-- Users\n--\n\n");
printf("DELETE FROM pg_shadow WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');\n\n");
- res = executeQuery(conn,
- "SELECT usename, usesysid, passwd, usecreatedb, usesuper, CAST(valuntil AS timestamp) "
- "FROM pg_shadow "
- "WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');");
+ if (server_version >= 70100)
+ res = executeQuery(conn,
+ "SELECT usename, usesysid, passwd, usecreatedb, "
+ "usesuper, valuntil "
+ "FROM pg_shadow "
+ "WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0')");
+ else
+ res = executeQuery(conn,
+ "SELECT usename, usesysid, passwd, usecreatedb, "
+ "usesuper, valuntil "
+ "FROM pg_shadow "
+ "WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template1')");
for (i = 0; i < PQntuples(res); i++)
{
appendPQExpBuffer(buf, " NOCREATEUSER");
if (!PQgetisnull(res, i, 5))
- appendPQExpBuffer(buf, " VALID UNTIL '%s'", PQgetvalue(res, i, 5));
+ appendPQExpBuffer(buf, " VALID UNTIL '%s'",
+ PQgetvalue(res, i, 5));
appendPQExpBuffer(buf, ";\n");
printf("--\n-- Groups\n--\n\n");
printf("DELETE FROM pg_group;\n\n");
- res = executeQuery(conn, "SELECT groname, grosysid, grolist FROM pg_group;");
+ res = executeQuery(conn, "SELECT groname, grosysid, grolist FROM pg_group");
for (i = 0; i < PQntuples(res); i++)
{
val = strdup(PQgetvalue(res, i, 2));
tok = strtok(val, ",{}");
- do
+ while (tok)
{
PGresult *res2;
PQExpBuffer buf2 = createPQExpBuffer();
tok = strtok(NULL, "{},");
}
- while (tok);
+ free(val);
printf("%s", buf->data);
destroyPQExpBuffer(buf);
printf("--\n-- Database creation\n--\n\n");
- /*
- * Basically this query returns: dbname, dbowner, encoding,
- * istemplate, dbpath
- */
- 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, datpath FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) WHERE datallowconn ORDER BY 1;");
+ 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, datpath, datacl "
+ "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, datpath, '' as datacl "
+ "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, datpath, '' as datacl "
+ "FROM pg_database d "
+ "ORDER BY 1");
+ }
for (i = 0; i < PQntuples(res); i++)
{
char *dbencoding = PQgetvalue(res, i, 2);
char *dbistemplate = PQgetvalue(res, i, 3);
char *dbpath = PQgetvalue(res, i, 4);
+ char *dbacl = 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", fmtId(dbname));
+ appendPQExpBuffer(buf, "DROP DATABASE %s;\n", fdbname);
- appendPQExpBuffer(buf, "CREATE DATABASE %s", fmtId(dbname));
- appendPQExpBuffer(buf, " WITH OWNER = %s TEMPLATE = template0", fmtId(dbowner));
+ appendPQExpBuffer(buf, "CREATE DATABASE %s", fdbname);
+ if (strlen(dbowner) != 0)
+ appendPQExpBuffer(buf, " WITH OWNER = %s",
+ fmtId(dbowner));
+ appendPQExpBuffer(buf, " TEMPLATE = template0");
- if (strcmp(dbpath, "") != 0)
+ if (strlen(dbpath) != 0)
{
appendPQExpBuffer(buf, " LOCATION = ");
appendStringLiteral(buf, dbpath, true);
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);
PGresult *res;
int i;
- res = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;");
+ 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;
if (verbose)
fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);
- printf("\\connect %s\n", fmtId(dbname));
+ printf("\\connect %s\n\n", fmtId(dbname));
ret = runPgDump(dbname);
if (ret != 0)
{
- fprintf(stderr, _("%s: pg_dump failed on %s, exiting\n"), progname, dbname);
+ fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
exit(1);
}
}
appendPQExpBufferChar(cmd, '\'');
if (verbose)
- fprintf(stderr, _("%s: running %s\n"), progname, cmd->data);
+ fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data);
fflush(stdout);
fflush(stderr);
PGconn *conn;
char *password = NULL;
bool need_pass = false;
- PGresult *res;
+ const char *remoteversion_str;
if (require_password)
password = simple_prompt("Password: ", 100, false);
if (!conn)
{
- fprintf(stderr, _("%s: could not connect to database %s\n"),
+ fprintf(stderr, _("%s: could not connect to database \"%s\"\n"),
progname, dbname);
exit(1);
}
/* 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"),
+ fprintf(stderr, _("%s: could not connect to database \"%s\": %s\n"),
progname, dbname, PQerrorMessage(conn));
exit(1);
}
- res = executeQuery(conn, "SELECT version();");
- if (PQntuples(res) != 1)
+ remoteversion_str = PQparameterStatus(conn, "server_version");
+ if (!remoteversion_str)
{
fprintf(stderr, _("%s: could not get server version\n"), progname);
exit(1);
}
- else
+ server_version = parse_version(remoteversion_str);
+ if (server_version < 0)
{
- char *val = PQgetvalue(res, 0, 0);
- server_version = parse_version(val + strcspn(val, "0123456789"));
- if (server_version < 0)
- {
- fprintf(stderr, _("%s: could not parse server version \"%s\"\n"), progname, val);
- exit(1);
- }
+ fprintf(stderr, _("%s: could not parse server version \"%s\"\n"),
+ progname, remoteversion_str);
+ exit(1);
}
- PQclear(res);
return conn;
}
{
PGresult *res;
+ if (verbose)
+ fprintf(stderr, _("%s: executing %s\n"), progname, query);
+
res = PQexec(conn, query);
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
return result;
cmd = createPQExpBuffer();
- last = strrchr(argv0, '/');
+ last = last_path_separator(argv0);
if (!last)
appendPQExpBuffer(cmd, "pg_dump");