mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Add ArchiveOpts to pass options to ArchiveEntry
The ArchiveEntry function has a number of arguments that can be considered optional. Split them out into a separate struct, to make the API more flexible for changes. Author: Dmitry Dolgov Discussion: https://postgr.es/m/CA+q6zcXRxPE+qp6oerQWJ3zS061WPOhdxeMrdc-Yf-2V5vsrEw@mail.gmail.com
This commit is contained in:
parent
456e3718e7
commit
f831d4accd
@ -77,7 +77,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
|
||||
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
|
||||
ArchiveHandle *AH);
|
||||
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData);
|
||||
static char *replace_line_endings(const char *str);
|
||||
static char *sanitize_line(const char *str, bool want_hyphen);
|
||||
static void _doSetFixedOutputState(ArchiveHandle *AH);
|
||||
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
|
||||
static void _reconnectToDB(ArchiveHandle *AH, const char *dbname);
|
||||
@ -1066,17 +1066,8 @@ WriteData(Archive *AHX, const void *data, size_t dLen)
|
||||
|
||||
/* Public */
|
||||
TocEntry *
|
||||
ArchiveEntry(Archive *AHX,
|
||||
CatalogId catalogId, DumpId dumpId,
|
||||
const char *tag,
|
||||
const char *namespace,
|
||||
const char *tablespace,
|
||||
const char *owner,
|
||||
const char *desc, teSection section,
|
||||
const char *defn,
|
||||
const char *dropStmt, const char *copyStmt,
|
||||
const DumpId *deps, int nDeps,
|
||||
DataDumperPtr dumpFn, void *dumpArg)
|
||||
ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId,
|
||||
ArchiveOpts *opts)
|
||||
{
|
||||
ArchiveHandle *AH = (ArchiveHandle *) AHX;
|
||||
TocEntry *newToc;
|
||||
@ -1094,22 +1085,22 @@ ArchiveEntry(Archive *AHX,
|
||||
|
||||
newToc->catalogId = catalogId;
|
||||
newToc->dumpId = dumpId;
|
||||
newToc->section = section;
|
||||
newToc->section = opts->section;
|
||||
|
||||
newToc->tag = pg_strdup(tag);
|
||||
newToc->namespace = namespace ? pg_strdup(namespace) : NULL;
|
||||
newToc->tablespace = tablespace ? pg_strdup(tablespace) : NULL;
|
||||
newToc->owner = pg_strdup(owner);
|
||||
newToc->desc = pg_strdup(desc);
|
||||
newToc->defn = pg_strdup(defn);
|
||||
newToc->dropStmt = pg_strdup(dropStmt);
|
||||
newToc->copyStmt = copyStmt ? pg_strdup(copyStmt) : NULL;
|
||||
newToc->tag = pg_strdup(opts->tag);
|
||||
newToc->namespace = opts->namespace ? pg_strdup(opts->namespace) : NULL;
|
||||
newToc->tablespace = opts->tablespace ? pg_strdup(opts->tablespace) : NULL;
|
||||
newToc->owner = opts->owner ? pg_strdup(opts->owner) : NULL;
|
||||
newToc->desc = pg_strdup(opts->description);
|
||||
newToc->defn = opts->createStmt ? pg_strdup(opts->createStmt) : NULL;
|
||||
newToc->dropStmt = opts->dropStmt ? pg_strdup(opts->dropStmt) : NULL;
|
||||
newToc->copyStmt = opts->copyStmt ? pg_strdup(opts->copyStmt) : NULL;
|
||||
|
||||
if (nDeps > 0)
|
||||
if (opts->nDeps > 0)
|
||||
{
|
||||
newToc->dependencies = (DumpId *) pg_malloc(nDeps * sizeof(DumpId));
|
||||
memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId));
|
||||
newToc->nDeps = nDeps;
|
||||
newToc->dependencies = (DumpId *) pg_malloc(opts->nDeps * sizeof(DumpId));
|
||||
memcpy(newToc->dependencies, opts->deps, opts->nDeps * sizeof(DumpId));
|
||||
newToc->nDeps = opts->nDeps;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1117,9 +1108,9 @@ ArchiveEntry(Archive *AHX,
|
||||
newToc->nDeps = 0;
|
||||
}
|
||||
|
||||
newToc->dataDumper = dumpFn;
|
||||
newToc->dataDumperArg = dumpArg;
|
||||
newToc->hadDumper = dumpFn ? true : false;
|
||||
newToc->dataDumper = opts->dumpFn;
|
||||
newToc->dataDumperArg = opts->dumpArg;
|
||||
newToc->hadDumper = opts->dumpFn ? true : false;
|
||||
|
||||
newToc->formatData = NULL;
|
||||
newToc->dataLength = 0;
|
||||
@ -1152,7 +1143,7 @@ PrintTOCSummary(Archive *AHX)
|
||||
|
||||
ahprintf(AH, ";\n; Archive created at %s\n", stamp_str);
|
||||
ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
|
||||
replace_line_endings(AH->archdbname),
|
||||
sanitize_line(AH->archdbname, false),
|
||||
AH->tocCount, AH->compression);
|
||||
|
||||
switch (AH->format)
|
||||
@ -1197,21 +1188,10 @@ PrintTOCSummary(Archive *AHX)
|
||||
char *sanitized_owner;
|
||||
|
||||
/*
|
||||
* As in _printTocEntry(), sanitize strings that might contain
|
||||
* newlines, to ensure that each logical output line is in fact
|
||||
* one physical output line. This prevents confusion when the
|
||||
* file is read by "pg_restore -L". Note that we currently don't
|
||||
* bother to quote names, meaning that the name fields aren't
|
||||
* automatically parseable. "pg_restore -L" doesn't care because
|
||||
* it only examines the dumpId field, but someday we might want to
|
||||
* try harder.
|
||||
*/
|
||||
sanitized_name = replace_line_endings(te->tag);
|
||||
if (te->namespace)
|
||||
sanitized_schema = replace_line_endings(te->namespace);
|
||||
else
|
||||
sanitized_schema = pg_strdup("-");
|
||||
sanitized_owner = replace_line_endings(te->owner);
|
||||
sanitized_name = sanitize_line(te->tag, false);
|
||||
sanitized_schema = sanitize_line(te->namespace, true);
|
||||
sanitized_owner = sanitize_line(te->owner, false);
|
||||
|
||||
ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
|
||||
te->catalogId.tableoid, te->catalogId.oid,
|
||||
@ -3577,21 +3557,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Zap any line endings embedded in user-supplied fields, to prevent
|
||||
* corruption of the dump (which could, in the worst case, present an
|
||||
* SQL injection vulnerability if someone were to incautiously load a
|
||||
* dump containing objects with maliciously crafted names).
|
||||
*/
|
||||
sanitized_name = replace_line_endings(te->tag);
|
||||
if (te->namespace)
|
||||
sanitized_schema = replace_line_endings(te->namespace);
|
||||
else
|
||||
sanitized_schema = pg_strdup("-");
|
||||
if (!ropt->noOwner)
|
||||
sanitized_owner = replace_line_endings(te->owner);
|
||||
else
|
||||
sanitized_owner = pg_strdup("-");
|
||||
sanitized_name = sanitize_line(te->tag, false);
|
||||
sanitized_schema = sanitize_line(te->namespace, true);
|
||||
sanitized_owner = sanitize_line(ropt->noOwner ? NULL : te->owner, true);
|
||||
|
||||
ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
|
||||
pfx, sanitized_name, te->desc, sanitized_schema,
|
||||
@ -3605,7 +3573,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
|
||||
{
|
||||
char *sanitized_tablespace;
|
||||
|
||||
sanitized_tablespace = replace_line_endings(te->tablespace);
|
||||
sanitized_tablespace = sanitize_line(te->tablespace, false);
|
||||
ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
|
||||
free(sanitized_tablespace);
|
||||
}
|
||||
@ -3629,7 +3597,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(te->defn) > 0)
|
||||
if (te->defn && strlen(te->defn) > 0)
|
||||
ahprintf(AH, "%s\n\n", te->defn);
|
||||
}
|
||||
|
||||
@ -3640,7 +3608,8 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
|
||||
* with DROP commands must appear in one list or the other.
|
||||
*/
|
||||
if (!ropt->noOwner && !ropt->use_setsessauth &&
|
||||
strlen(te->owner) > 0 && strlen(te->dropStmt) > 0)
|
||||
te->owner && strlen(te->owner) > 0 &&
|
||||
te->dropStmt && strlen(te->dropStmt) > 0)
|
||||
{
|
||||
if (strcmp(te->desc, "AGGREGATE") == 0 ||
|
||||
strcmp(te->desc, "BLOB") == 0 ||
|
||||
@ -3713,16 +3682,30 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanitize a string to be included in an SQL comment or TOC listing,
|
||||
* by replacing any newlines with spaces.
|
||||
* The result is a freshly malloc'd string.
|
||||
* Sanitize a string to be included in an SQL comment or TOC listing, by
|
||||
* replacing any newlines with spaces. This ensures each logical output line
|
||||
* is in fact one physical output line, to prevent corruption of the dump
|
||||
* (which could, in the worst case, present an SQL injection vulnerability
|
||||
* if someone were to incautiously load a dump containing objects with
|
||||
* maliciously crafted names).
|
||||
*
|
||||
* The result is a freshly malloc'd string. If the input string is NULL,
|
||||
* return a malloc'ed empty string, unless want_hyphen, in which case return a
|
||||
* malloc'ed hyphen.
|
||||
*
|
||||
* Note that we currently don't bother to quote names, meaning that the name
|
||||
* fields aren't automatically parseable. "pg_restore -L" doesn't care because
|
||||
* it only examines the dumpId field, but someday we might want to try harder.
|
||||
*/
|
||||
static char *
|
||||
replace_line_endings(const char *str)
|
||||
sanitize_line(const char *str, bool want_hyphen)
|
||||
{
|
||||
char *result;
|
||||
char *s;
|
||||
|
||||
if (!str)
|
||||
return pg_strdup(want_hyphen ? "-" : "");
|
||||
|
||||
result = pg_strdup(str);
|
||||
|
||||
for (s = result; *s != '\0'; s++)
|
||||
|
@ -405,17 +405,27 @@ extern void on_exit_close_archive(Archive *AHX);
|
||||
|
||||
extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) pg_attribute_printf(3, 4);
|
||||
|
||||
/* Options for ArchiveEntry */
|
||||
typedef struct _archiveOpts
|
||||
{
|
||||
const char *tag;
|
||||
const char *namespace;
|
||||
const char *tablespace;
|
||||
const char *owner;
|
||||
const char *description;
|
||||
teSection section;
|
||||
const char *createStmt;
|
||||
const char *dropStmt;
|
||||
const char *copyStmt;
|
||||
const DumpId *deps;
|
||||
int nDeps;
|
||||
DataDumperPtr dumpFn;
|
||||
void *dumpArg;
|
||||
} ArchiveOpts;
|
||||
#define ARCHIVE_OPTS(...) &(ArchiveOpts){__VA_ARGS__}
|
||||
/* Called to add a TOC entry */
|
||||
extern TocEntry *ArchiveEntry(Archive *AHX,
|
||||
CatalogId catalogId, DumpId dumpId,
|
||||
const char *tag,
|
||||
const char *namespace, const char *tablespace,
|
||||
const char *owner,
|
||||
const char *desc, teSection section,
|
||||
const char *defn,
|
||||
const char *dropStmt, const char *copyStmt,
|
||||
const DumpId *deps, int nDeps,
|
||||
DataDumperPtr dumpFn, void *dumpArg);
|
||||
extern TocEntry *ArchiveEntry(Archive *AHX, CatalogId catalogId,
|
||||
DumpId dumpId, ArchiveOpts *opts);
|
||||
|
||||
extern void WriteTOC(ArchiveHandle *AH);
|
||||
extern void ReadTOC(ArchiveHandle *AH);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user