📄 pg_dumpall.c
字号:
"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 { /* * In 7.0, datpath is either the same as datname, or the user-given * location with "/" and the datname appended. We must strip this * junk off to produce a correct LOCATION value. * * 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, " "CASE WHEN length(datpath) > length(datname) THEN " "substr(datpath,1,length(datpath)-length(datname)-1) " "ELSE '' END as datpath, " "'' as datacl " "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 *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", fdbname); appendPQExpBuffer(buf, "CREATE DATABASE %s", fdbname); if (strlen(dbowner) != 0) appendPQExpBuffer(buf, " WITH OWNER = %s", fmtId(dbowner)); appendPQExpBuffer(buf, " TEMPLATE = template0"); if (strlen(dbpath) != 0) { appendPQExpBuffer(buf, " LOCATION = "); appendStringLiteral(buf, dbpath, true); } appendPQExpBuffer(buf, " ENCODING = "); appendStringLiteral(buf, dbencoding, true); 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 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; 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 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)); 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; appendPQExpBuffer(cmd, "%s %s -Fp '", pgdumploc, pgdumpopts->data); /* Shell quoting is not quite like SQL quoting, so can't use fmtId */ for (p = dbname; *p; p++) { if (*p == '\'') appendPQExpBuffer(cmd, "'\"'\"'"); else appendPQExpBufferChar(cmd, *p); } appendPQExpBufferChar(cmd, '\''); 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;}/* * Find location of pg_dump executable. */static char *findPgDump(const char *argv0){ char *last; PQExpBuffer cmd; static char *result = NULL; if (result) return result; cmd = createPQExpBuffer(); last = last_path_separator(argv0); if (!last) appendPQExpBuffer(cmd, "pg_dump"); else { char *dir = strdup(argv0); *(dir + (last - argv0)) = '\0'; appendPQExpBuffer(cmd, "%s/pg_dump", dir); } result = strdup(cmd->data); appendPQExpBuffer(cmd, " -V >/dev/null 2>&1"); if (system(cmd->data) == 0) goto end; result = BINDIR "/pg_dump"; if (system(BINDIR "/pg_dump -V >/dev/null 2>&1") == 0) goto end; fprintf(stderr, _("%s: could not find pg_dump\n" "Make sure it is in the path or in the same directory as %s.\n"), progname, progname); exit(1);end: destroyPQExpBuffer(cmd); return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -