mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-29 23:17:21 +02:00
101 lines
3.0 KiB
C
101 lines
3.0 KiB
C
/*
|
|
* dump.c
|
|
*
|
|
* dump functions
|
|
*
|
|
* Copyright (c) 2010, PostgreSQL Global Development Group
|
|
* contrib/pg_upgrade/dump.c
|
|
*/
|
|
|
|
#include "pg_upgrade.h"
|
|
|
|
|
|
|
|
void
|
|
generate_old_dump(migratorContext *ctx)
|
|
{
|
|
/* run new pg_dumpall binary */
|
|
prep_status(ctx, "Creating catalog dump");
|
|
|
|
/*
|
|
* --binary-upgrade records the width of dropped columns in pg_class, and
|
|
* restores the frozenid's for databases and relations.
|
|
*/
|
|
exec_prog(ctx, true,
|
|
SYSTEMQUOTE "\"%s/pg_dumpall\" --port %d --username \"%s\" "
|
|
"--schema-only --binary-upgrade > \"%s/" ALL_DUMP_FILE "\""
|
|
SYSTEMQUOTE, ctx->new.bindir, ctx->old.port, ctx->user, ctx->cwd);
|
|
check_ok(ctx);
|
|
}
|
|
|
|
|
|
/*
|
|
* split_old_dump
|
|
*
|
|
* This function splits pg_dumpall output into global values and
|
|
* database creation, and per-db schemas. This allows us to create
|
|
* the toast place holders between restoring these two parts of the
|
|
* dump. We split on the first "\connect " after a CREATE ROLE
|
|
* username match; this is where the per-db restore starts.
|
|
*
|
|
* We suppress recreation of our own username so we don't generate
|
|
* an error during restore
|
|
*/
|
|
void
|
|
split_old_dump(migratorContext *ctx)
|
|
{
|
|
FILE *all_dump,
|
|
*globals_dump,
|
|
*db_dump;
|
|
FILE *current_output;
|
|
char line[LINE_ALLOC];
|
|
bool start_of_line = true;
|
|
char create_role_str[MAX_STRING];
|
|
char create_role_str_quote[MAX_STRING];
|
|
char filename[MAXPGPATH];
|
|
bool suppressed_username = false;
|
|
|
|
snprintf(filename, sizeof(filename), "%s/%s", ctx->cwd, ALL_DUMP_FILE);
|
|
if ((all_dump = fopen(filename, "r")) == NULL)
|
|
pg_log(ctx, PG_FATAL, "Cannot open dump file %s\n", filename);
|
|
snprintf(filename, sizeof(filename), "%s/%s", ctx->cwd, GLOBALS_DUMP_FILE);
|
|
if ((globals_dump = fopen(filename, "w")) == NULL)
|
|
pg_log(ctx, PG_FATAL, "Cannot write to dump file %s\n", filename);
|
|
snprintf(filename, sizeof(filename), "%s/%s", ctx->cwd, DB_DUMP_FILE);
|
|
if ((db_dump = fopen(filename, "w")) == NULL)
|
|
pg_log(ctx, PG_FATAL, "Cannot write to dump file %s\n", filename);
|
|
current_output = globals_dump;
|
|
|
|
/* patterns used to prevent our own username from being recreated */
|
|
snprintf(create_role_str, sizeof(create_role_str),
|
|
"CREATE ROLE %s;", ctx->user);
|
|
snprintf(create_role_str_quote, sizeof(create_role_str_quote),
|
|
"CREATE ROLE %s;", quote_identifier(ctx, ctx->user));
|
|
|
|
while (fgets(line, sizeof(line), all_dump) != NULL)
|
|
{
|
|
/* switch to db_dump file output? */
|
|
if (current_output == globals_dump && start_of_line &&
|
|
suppressed_username &&
|
|
strncmp(line, "\\connect ", strlen("\\connect ")) == 0)
|
|
current_output = db_dump;
|
|
|
|
/* output unless we are recreating our own username */
|
|
if (current_output != globals_dump || !start_of_line ||
|
|
(strncmp(line, create_role_str, strlen(create_role_str)) != 0 &&
|
|
strncmp(line, create_role_str_quote, strlen(create_role_str_quote)) != 0))
|
|
fputs(line, current_output);
|
|
else
|
|
suppressed_username = true;
|
|
|
|
if (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
|
|
start_of_line = true;
|
|
else
|
|
start_of_line = false;
|
|
}
|
|
|
|
fclose(all_dump);
|
|
fclose(globals_dump);
|
|
fclose(db_dump);
|
|
}
|