📄 pg_dumpall.c
字号:
{ 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); if (server_version >= 70300) dumpDatabaseConfig(conn, dbname); free(fdbname); } PQclear(res); destroyPQExpBuffer(buf); printf("\n\n");}/* * Dump database-specific configuration */static voiddumpDatabaseConfig(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 voiddumpUserConfig(PGconn *conn, const char *username){ PQExpBuffer buf = createPQExpBuffer(); int count = 1; for (;;) { PGresult *res; if (server_version >= 80100) printfPQExpBuffer(buf, "SELECT rolconfig[%d] FROM pg_authid WHERE rolname = ", count); else printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count); appendStringLiteral(buf, username, true); res = executeQuery(conn, buf->data); if (PQntuples(res) == 1 && !PQgetisnull(res, 0, 0)) { makeAlterConfigCommand(PQgetvalue(res, 0, 0), "ROLE", username); PQclear(res); count++; } else { PQclear(res); break; } } destroyPQExpBuffer(buf);}/* * Helper function for dumpXXXConfig(). */static voidmakeAlterConfigCommand(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 (pg_strcasecmp(mine, "DateStyle") == 0 || pg_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 voiddumpDatabases(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 intrunPgDump(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 "postgres" which 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. * * If fail_on_error is false, we return NULL without printing any message * on failure, but preserve any prompted password for the next try. */static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport, const char *pguser, bool require_password, bool fail_on_error){ PGconn *conn; bool need_pass = false; const char *remoteversion_str; int my_version; static char *password = NULL; if (require_password && !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), PQnoPasswordSupplied) == 0 && !feof(stdin)) { PQfinish(conn); need_pass = true; if (password) free(password); password = NULL; password = simple_prompt("Password: ", 100, false); } } while (need_pass); /* check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { if (fail_on_error) { fprintf(stderr, _("%s: could not connect to database \"%s\": %s\n"), progname, dbname, PQerrorMessage(conn)); exit(1); } else { PQfinish(conn); return NULL; } } 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); } my_version = parse_version(PG_VERSION); if (my_version < 0) { fprintf(stderr, _("%s: could not parse version \"%s\"\n"), progname, PG_VERSION); exit(1); } if (my_version != server_version && (server_version < 70000 /* we can handle back to 7.0 */ || server_version > my_version)) { fprintf(stderr, _("server version: %s; %s version: %s\n"), remoteversion_str, progname, PG_VERSION); if (ignoreVersion) fprintf(stderr, _("proceeding despite version mismatch\n")); else { fprintf(stderr, _("aborting because of version mismatch (Use the -i option to proceed anyway.)\n")); exit(1); } } /* * On 7.3 and later, make sure we are not fooled by non-system schemas in * the search path. */ if (server_version >= 70300) executeCommand(conn, "SET search_path = pg_catalog"); 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;}/* * As above for a SQL command (which returns nothing). */static voidexecuteCommand(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_COMMAND_OK) { fprintf(stderr, _("%s: query failed: %s"), progname, PQerrorMessage(conn)); fprintf(stderr, _("%s: query was: %s\n"), progname, query); PQfinish(conn); exit(1); } PQclear(res);}/* * dumpTimestamp */static voiddumpTimestamp(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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -