dump for this table only\n"
+ " -u use password authentication\n"
+ " -v verbose\n"
+ " -x do not dump ACL's (grant/revoke)\n"
+ " -Z {0-9} compression level for compressed formats\n"
);
#endif
puts("If no database name is not supplied, then the PGDATABASE environment\nvariable value is used.\n");
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "isViewRule(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "isViewRule(): SELECT failed. Explanation from backend: '%s'.\n",
+ PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
#define COPYBUFSIZ 8192
-
-static void
-dumpClasses_nodumpData(FILE *fout, const char *classname, const bool oids)
+/*
+ * Dump a table's contents for loading using the COPY command
+ * - this routine is called by the Archiver when it wants the table
+ * to be dumped.
+ */
+static int
+dumpClasses_nodumpData(Archive *fout, char* oid, void *dctxv)
{
+ const DumpContext *dctx = (DumpContext*)dctxv;
+ const char *classname = dctx->tblinfo[dctx->tblidx].relname;
+ const bool oids = dctx->oids;
PGresult *res;
char query[255];
if (oids == true)
{
- fprintf(fout, "COPY %s WITH OIDS FROM stdin;\n",
+ archprintf(fout, "COPY %s WITH OIDS FROM stdin;\n",
fmtId(classname, force_quotes));
sprintf(query, "COPY %s WITH OIDS TO stdout;\n",
fmtId(classname, force_quotes));
}
else
{
- fprintf(fout, "COPY %s FROM stdin;\n", fmtId(classname, force_quotes));
+ archprintf(fout, "COPY %s FROM stdin;\n", fmtId(classname, force_quotes));
sprintf(query, "COPY %s TO stdout;\n", fmtId(classname, force_quotes));
}
res = PQexec(g_conn, query);
}
else
{
- fputs(copybuf, fout);
+ archputs(copybuf, fout);
switch (ret)
{
case EOF:
copydone = true;
/* FALLTHROUGH */
case 0:
- fputc('\n', fout);
+ archputc('\n', fout);
break;
case 1:
break;
}
}
}
- fprintf(fout, "\\.\n");
+ archprintf(fout, "\\.\n");
}
ret = PQendcopy(g_conn);
if (ret != 0)
exit_nicely(g_conn);
}
}
+ return 1;
}
-static void
-dumpClasses_dumpData(FILE *fout, const char *classname)
+static int
+dumpClasses_dumpData(Archive *fout, char* oid, void *dctxv)
{
+ const DumpContext *dctx = (DumpContext*)dctxv;
+ const char *classname = dctx->tblinfo[dctx->tblidx].relname;
+
PGresult *res;
PQExpBuffer q = createPQExpBuffer();
int tuple;
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "dumpClasses(): command failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "dumpClasses(): command failed. Explanation from backend: '%s'.\n",
+ PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
for (tuple = 0; tuple < PQntuples(res); tuple++)
{
- fprintf(fout, "INSERT INTO %s ", fmtId(classname, force_quotes));
+ archprintf(fout, "INSERT INTO %s ", fmtId(classname, force_quotes));
if (attrNames == true)
{
resetPQExpBuffer(q);
appendPQExpBuffer(q, fmtId(PQfname(res, field), force_quotes));
}
appendPQExpBuffer(q, ") ");
- fprintf(fout, "%s", q->data);
+ archprintf(fout, "%s", q->data);
}
- fprintf(fout, "VALUES (");
+ archprintf(fout, "VALUES (");
for (field = 0; field < PQnfields(res); field++)
{
if (field > 0)
- fprintf(fout, ",");
+ archprintf(fout, ",");
if (PQgetisnull(res, tuple, field))
{
- fprintf(fout, "NULL");
+ archprintf(fout, "NULL");
continue;
}
switch (PQftype(res, field))
case FLOAT4OID:
case FLOAT8OID:/* float types */
/* These types are printed without quotes */
- fprintf(fout, "%s",
+ archprintf(fout, "%s",
PQgetvalue(res, tuple, field));
break;
default:
* Quote mark ' goes to '' per SQL standard, other
* stuff goes to \ sequences.
*/
- putc('\'', fout);
+ archputc('\'', fout);
expsrc = PQgetvalue(res, tuple, field);
while (*expsrc)
{
if (ch == '\\' || ch == '\'')
{
- putc(ch, fout); /* double these */
- putc(ch, fout);
+ archputc(ch, fout); /* double these */
+ archputc(ch, fout);
}
else if (ch < '\040')
{
/* generate octal escape for control chars */
- putc('\\', fout);
- putc(((ch >> 6) & 3) + '0', fout);
- putc(((ch >> 3) & 7) + '0', fout);
- putc((ch & 7) + '0', fout);
+ archputc('\\', fout);
+ archputc(((ch >> 6) & 3) + '0', fout);
+ archputc(((ch >> 3) & 7) + '0', fout);
+ archputc((ch & 7) + '0', fout);
}
else
- putc(ch, fout);
+ archputc(ch, fout);
}
- putc('\'', fout);
+ archputc('\'', fout);
break;
}
}
- fprintf(fout, ");\n");
+ archprintf(fout, ");\n");
}
PQclear(res);
+ return 1;
}
-
-
/*
* DumpClasses -
* dump the contents of all the classes.
*/
static void
-dumpClasses(const TableInfo *tblinfo, const int numTables, FILE *fout,
+dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout,
const char *onlytable, const bool oids)
{
- int i;
- char *all_only;
+ int i;
+ char *all_only;
+ DataDumperPtr dumpFn;
+ DumpContext *dumpCtx;
if (onlytable == NULL)
all_only = "all";
if (g_verbose)
fprintf(stderr, "%s dumping out schema of sequence '%s' %s\n",
g_comment_start, tblinfo[i].relname, g_comment_end);
- becomeUser(fout, tblinfo[i].usename);
+ /* becomeUser(fout, tblinfo[i].usename); */
dumpSequence(fout, tblinfo[i]);
}
}
fprintf(stderr, "%s dumping out the contents of Table '%s' %s\n",
g_comment_start, classname, g_comment_end);
- becomeUser(fout, tblinfo[i].usename);
+ /* becomeUser(fout, tblinfo[i].usename); */
+
+ dumpCtx = (DumpContext*)malloc(sizeof(DumpContext));
+ dumpCtx->tblinfo = (TableInfo*)tblinfo;
+ dumpCtx->tblidx = i;
+ dumpCtx->oids = oids;
if (!dumpData)
- dumpClasses_nodumpData(fout, classname, oids);
+ dumpFn = dumpClasses_nodumpData;
+ /* dumpClasses_nodumpData(fout, classname, oids); */
else
- dumpClasses_dumpData(fout, classname);
+ dumpFn = dumpClasses_dumpData;
+ /* dumpClasses_dumpData(fout, classname); */
+
+ ArchiveEntry(fout, tblinfo[i].oid, fmtId(tblinfo[i].relname, false),
+ "TABLE DATA", NULL, "", "", tblinfo[i].usename,
+ dumpFn, dumpCtx);
}
}
}
-
static void
prompt_for_password(char *username, char *password)
{
int c;
const char *progname;
const char *filename = NULL;
+ const char *format = "p";
const char *dbname = NULL;
const char *pghost = NULL;
const char *pgport = NULL;
char username[100];
char password[100];
bool use_password = false;
+ int compressLevel = -1;
bool ignore_version = false;
+ int plainText = 0;
+ int outputClean = 0;
+ RestoreOptions *ropt;
#ifdef HAVE_GETOPT_LONG
static struct option long_options[] = {
{"data-only", no_argument, NULL, 'a'},
{"clean", no_argument, NULL, 'c'},
+ {"file", required_argument, NULL, 'f'},
+ {"format", required_argument, NULL, 'F'},
{"inserts", no_argument, NULL, 'd'},
{"attribute-inserts", no_argument, NULL, 'D'},
{"host", required_argument, NULL, 'h'},
{"password", no_argument, NULL, 'u'},
{"verbose", no_argument, NULL, 'v'},
{"no-acl", no_argument, NULL, 'x'},
+ {"compress", required_argument, NULL, 'Z'},
{"help", no_argument, NULL, '?'},
{"version", no_argument, NULL, 'V'}
};
g_verbose = false;
force_quotes = true;
- dropSchema = false;
strcpy(g_comment_start, "-- ");
g_comment_end[0] = '\0';
#ifdef HAVE_GETOPT_LONG
- while ((c = getopt_long(argc, argv, "acdDf:h:inNop:st:uvxzV?", long_options, &optindex)) != -1)
+ while ((c = getopt_long(argc, argv, "acdDf:F:h:inNop:st:uvxzZ:V?", long_options, &optindex)) != -1)
#else
- while ((c = getopt(argc, argv, "acdDf:h:inNop:st:uvxzV?-")) != -1)
+ while ((c = getopt(argc, argv, "acdDf:F:h:inNop:st:uvxzZ:V?-")) != -1)
#endif
{
switch (c)
dataOnly = true;
break;
case 'c': /* clean (i.e., drop) schema prior to
- * create */
- dropSchema = true;
- break;
+ * create */
+ outputClean = 1;
+ break;
+
case 'd': /* dump data as proper insert strings */
dumpData = true;
break;
case 'f':
filename = optarg;
break;
+ case 'F':
+ format = optarg;
+ break;
case 'h': /* server host */
pghost = optarg;
break;
case 'x': /* skip ACL dump */
aclsSkip = true;
break;
+ case 'Z': /* Compression Level */
+ compressLevel = atoi(optarg);
+ break;
case 'V':
version();
exit(0);
}
}
+ if (dataOnly && schemaOnly)
+ {
+ fprintf(stderr,
+ "%s: 'Schema Only' and 'Data Only' are incompatible options.\n",
+ progname);
+ exit(1);
+ }
+
if (dumpData == true && oids == true)
{
fprintf(stderr,
}
/* open the output file */
- if (filename == NULL)
- g_fout = stdout;
- else
- {
- g_fout = fopen(filename, PG_BINARY_W);
- if (g_fout == NULL)
- {
+ switch (format[0]) {
+
+ case 'c':
+ case 'C':
+ g_fout = CreateArchive(filename, archCustom, compressLevel);
+ break;
+
+ case 'f':
+ case 'F':
+ g_fout = CreateArchive(filename, archFiles, compressLevel);
+ break;
+
+ case 'p':
+ case 'P':
+ plainText = 1;
+ g_fout = CreateArchive(filename, archPlainText, 0);
+ break;
+
+ default:
fprintf(stderr,
- "%s: could not open output file named %s for writing\n",
- progname, filename);
- exit(1);
- }
+ "%s: invalid output format '%s' specified\n", progname, format);
+ exit(1);
+ }
+
+ if (g_fout == NULL)
+ {
+ fprintf(stderr,
+ "%s: could not open output file named %s for writing\n",
+ progname, filename);
+ exit(1);
}
/* find database */
if (oids == true)
setMaxOid(g_fout);
- if (!dataOnly)
- {
- if (g_verbose)
+
+ if (g_verbose)
fprintf(stderr, "%s last builtin oid is %u %s\n",
g_comment_start, g_last_builtin_oid, g_comment_end);
- tblinfo = dumpSchema(g_fout, &numTables, tablename, aclsSkip);
- }
- else
- tblinfo = dumpSchema(NULL, &numTables, tablename, aclsSkip);
+ tblinfo = dumpSchema(g_fout, &numTables, tablename, aclsSkip, oids, schemaOnly, dataOnly);
if (!schemaOnly)
- {
- if (dataOnly)
- fprintf(g_fout, "UPDATE \"pg_class\" SET \"reltriggers\" = 0 WHERE \"relname\" !~ '^pg_';\n");
-
- dumpClasses(tblinfo, numTables, g_fout, tablename, oids);
-
- if (dataOnly)
- {
- fprintf(g_fout, "BEGIN TRANSACTION;\n");
- fprintf(g_fout, "CREATE TEMP TABLE \"tr\" (\"tmp_relname\" name, \"tmp_reltriggers\" smallint);\n");
- fprintf(g_fout, "INSERT INTO \"tr\" SELECT C.\"relname\", count(T.\"oid\") FROM \"pg_class\" C, \"pg_trigger\" T WHERE C.\"oid\" = T.\"tgrelid\" AND C.\"relname\" !~ '^pg_' GROUP BY 1;\n");
- fprintf(g_fout, "UPDATE \"pg_class\" SET \"reltriggers\" = TMP.\"tmp_reltriggers\" FROM \"tr\" TMP WHERE \"pg_class\".\"relname\" = TMP.\"tmp_relname\";\n");
- fprintf(g_fout, "COMMIT TRANSACTION;\n");
- }
- }
+ dumpClasses(tblinfo, numTables, g_fout, tablename, oids);
if (!dataOnly) /* dump indexes and triggers at the end
* for performance */
dumpRules(g_fout, tablename, tblinfo, numTables);
}
- fflush(g_fout);
- if (g_fout != stdout)
- fclose(g_fout);
+ if (plainText)
+ {
+ ropt = NewRestoreOptions();
+ ropt->filename = (char*)filename;
+ ropt->dropSchema = outputClean;
+ ropt->aclsSkip = aclsSkip;
+
+ if (compressLevel == -1)
+ ropt->compression = 0;
+ else
+ ropt->compression = compressLevel;
+
+ RestoreArchive(g_fout, ropt);
+ }
+
+ CloseArchive(g_fout);
clearTableInfo(tblinfo, numTables);
PQfinish(g_conn);
if (tblinfo[i].typnames[j])
free(tblinfo[i].typnames[j]);
}
+
+ if (tblinfo[i].triggers) {
+ for (j = 0; j < tblinfo[i].ntrig ; j++)
+ {
+ if (tblinfo[i].triggers[j].tgsrc)
+ free(tblinfo[i].triggers[j].tgsrc);
+ if (tblinfo[i].triggers[j].oid)
+ free(tblinfo[i].triggers[j].oid);
+ if (tblinfo[i].triggers[j].tgname)
+ free(tblinfo[i].triggers[j].tgname);
+ if (tblinfo[i].triggers[j].tgdel)
+ free(tblinfo[i].triggers[j].tgdel);
+ }
+ free(tblinfo[i].triggers);
+ }
+
if (tblinfo[i].atttypmod)
free((int *) tblinfo[i].atttypmod);
if (tblinfo[i].inhAttrs)
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getAggregates(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getAggregates(): SELECT failed. Explanation from backend: '%s'.\n",
+ PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getFuncs(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getFuncs(): SELECT failed. Explanation from backend: '%s'.\n",
+ PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
int ntups;
int i;
PQExpBuffer query = createPQExpBuffer();
+ PQExpBuffer delqry = createPQExpBuffer();
TableInfo *tblinfo;
- int i_oid;
+ int i_reloid;
int i_relname;
int i_relkind;
int i_relacl;
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getTables(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getTables(): SELECT failed. Explanation from backend: '%s'.\n",
+ PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
tblinfo = (TableInfo *) malloc(ntups * sizeof(TableInfo));
- i_oid = PQfnumber(res, "oid");
+ i_reloid = PQfnumber(res, "oid");
i_relname = PQfnumber(res, "relname");
i_relkind = PQfnumber(res, "relkind");
i_relacl = PQfnumber(res, "relacl");
for (i = 0; i < ntups; i++)
{
- tblinfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
+ tblinfo[i].oid = strdup(PQgetvalue(res, i, i_reloid));
tblinfo[i].relname = strdup(PQgetvalue(res, i, i_relname));
tblinfo[i].relacl = strdup(PQgetvalue(res, i, i_relacl));
tblinfo[i].sequence = (strcmp(PQgetvalue(res, i, i_relkind), "S") == 0);
if (!res2 ||
PQresultStatus(res2) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getTables(): SELECT (for inherited CHECK) failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getTables(): SELECT (for inherited CHECK) failed. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
ntups2 = PQntuples(res2);
if (!res2 ||
PQresultStatus(res2) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getTables(): SELECT (for CHECK) failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getTables(): SELECT (for CHECK) failed. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
ntups2 = PQntuples(res2);
if (!res2 ||
PQresultStatus(res2) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getTables(): SELECT (for TRIGGER) failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getTables(): SELECT (for TRIGGER) failed. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
ntups2 = PQntuples(res2);
i_tgdeferrable = PQfnumber(res2, "tgdeferrable");
i_tginitdeferred = PQfnumber(res2, "tginitdeferred");
- tblinfo[i].triggers = (char **) malloc(ntups2 * sizeof(char *));
- tblinfo[i].trcomments = (char **) malloc(ntups2 * sizeof(char *));
- tblinfo[i].troids = (char **) malloc(ntups2 * sizeof(char *));
+ tblinfo[i].triggers = (TrigInfo*) malloc(ntups2 * sizeof(TrigInfo));
resetPQExpBuffer(query);
for (i2 = 0; i2 < ntups2; i2++)
{
}
else
tgfunc = strdup(finfo[findx].proname);
-#if 0
- /* XXX - how to emit this DROP TRIGGER? */
- if (dropSchema)
- {
- resetPQExpBuffer(query);
- appendPQExpBuffer(query, "DROP TRIGGER %s ",
+
+ appendPQExpBuffer(delqry, "DROP TRIGGER %s ",
fmtId(PQgetvalue(res2, i2, i_tgname),
- force_quotes));
- appendPQExpBuffer(query, "ON %s;\n",
- fmtId(tblinfo[i].relname, force_quotes));
- fputs(query->data, fout);
- }
-#endif
+ force_quotes));
+ appendPQExpBuffer(delqry, "ON %s;\n",
+ fmtId(tblinfo[i].relname, force_quotes));
resetPQExpBuffer(query);
if (tgisconstraint)
p = strchr(p, '\\');
if (p == NULL)
{
- fprintf(stderr, "getTables(): relation '%s': bad argument string (%s) for trigger '%s'\n",
+ fprintf(stderr, "getTables(): relation '%s': bad argument "
+ "string (%s) for trigger '%s'\n",
tblinfo[i].relname,
PQgetvalue(res2, i2, i_tgargs),
PQgetvalue(res2, i2, i_tgname));
}
appendPQExpBuffer(query, ");\n");
- tblinfo[i].triggers[i2] = strdup(query->data);
+ tblinfo[i].triggers[i2].tgsrc = strdup(query->data);
/*** Initialize trcomments and troids ***/
fmtId(PQgetvalue(res2, i2, i_tgname), force_quotes));
appendPQExpBuffer(query, "ON %s",
fmtId(tblinfo[i].relname, force_quotes));
- tblinfo[i].trcomments[i2] = strdup(query->data);
- tblinfo[i].troids[i2] = strdup(PQgetvalue(res2, i2, i_tgoid));
+ tblinfo[i].triggers[i2].tgcomment = strdup(query->data);
+ tblinfo[i].triggers[i2].oid = strdup(PQgetvalue(res2, i2, i_tgoid));
+ tblinfo[i].triggers[i2].tgname = strdup(fmtId(PQgetvalue(res2, i2, i_tgname),false));
+ tblinfo[i].triggers[i2].tgdel = strdup(delqry->data);
if (tgfunc)
free(tgfunc);
else
{
tblinfo[i].triggers = NULL;
- tblinfo[i].trcomments = NULL;
- tblinfo[i].troids = NULL;
}
}
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getInherits(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getInherits(): SELECT failed. Explanation from backend: '%s'.\n",
+ PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getTableAttrs(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getTableAttrs(): SELECT failed. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
if (!res2 ||
PQresultStatus(res2) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getTableAttrs(): SELECT (for DEFAULT) failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getTableAttrs(): SELECT (for DEFAULT) failed. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
tblinfo[i].adef_expr[j] = strdup(PQgetvalue(res2, 0, PQfnumber(res2, "adsrc")));
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "getIndices(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "getIndices(): SELECT failed. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
*/
static void
-dumpComment(FILE *fout, const char *target, const char *oid)
+dumpComment(Archive *fout, const char *target, const char *oid)
{
PGresult *res;
if (PQntuples(res) != 0)
{
i_description = PQfnumber(res, "description");
- fprintf(fout, "COMMENT ON %s IS '%s';\n",
- target, checkForQuote(PQgetvalue(res, 0, i_description)));
+ resetPQExpBuffer(query);
+ appendPQExpBuffer(query, "COMMENT ON %s IS '%s';\n",
+ target, checkForQuote(PQgetvalue(res, 0, i_description)));
+
+ ArchiveEntry(fout, oid, target, "COMMENT", NULL, query->data, "" /*Del*/,
+ "" /*Owner*/, NULL, NULL);
+
}
/*** Clear the statement buffer and return ***/
*/
void
-dumpDBComment(FILE *fout)
+dumpDBComment(Archive *fout)
{
PGresult *res;
*
*/
void
-dumpTypes(FILE *fout, FuncInfo *finfo, int numFuncs,
+dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
TypeInfo *tinfo, int numTypes)
{
int i;
PQExpBuffer q = createPQExpBuffer();
+ PQExpBuffer delq = createPQExpBuffer();
int funcInd;
for (i = 0; i < numTypes; i++)
if (funcInd != -1)
dumpOneFunc(fout, finfo, funcInd, tinfo, numTypes);
- becomeUser(fout, tinfo[i].usename);
-
- if (dropSchema)
- {
- resetPQExpBuffer(q);
- appendPQExpBuffer(q, "DROP TYPE %s;\n", fmtId(tinfo[i].typname, force_quotes));
- fputs(q->data, fout);
- }
+ appendPQExpBuffer(delq, "DROP TYPE %s;\n", fmtId(tinfo[i].typname, force_quotes));
resetPQExpBuffer(q);
appendPQExpBuffer(q,
else
appendPQExpBuffer(q, ");\n");
- fputs(q->data, fout);
+ ArchiveEntry(fout, tinfo[i].oid, fmtId(tinfo[i].typname, force_quotes), "TYPE", NULL,
+ q->data, delq->data, tinfo[i].usename, NULL, NULL);
/*** Dump Type Comments ***/
resetPQExpBuffer(q);
+ resetPQExpBuffer(delq);
+
appendPQExpBuffer(q, "TYPE %s", fmtId(tinfo[i].typname, force_quotes));
dumpComment(fout, q->data, tinfo[i].oid);
+ resetPQExpBuffer(q);
}
}
*
*/
void
-dumpProcLangs(FILE *fout, FuncInfo *finfo, int numFuncs,
+dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs,
TypeInfo *tinfo, int numTypes)
{
PGresult *res;
PQExpBuffer query = createPQExpBuffer();
+ PQExpBuffer defqry = createPQExpBuffer();
+ PQExpBuffer delqry = createPQExpBuffer();
int ntups;
+ int i_oid;
int i_lanname;
int i_lanpltrusted;
int i_lanplcallfoid;
int i,
fidx;
- appendPQExpBuffer(query, "SELECT * FROM pg_language "
+ appendPQExpBuffer(query, "SELECT oid, * FROM pg_language "
"WHERE lanispl "
"ORDER BY oid");
res = PQexec(g_conn, query->data);
i_lanpltrusted = PQfnumber(res, "lanpltrusted");
i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
i_lancompiler = PQfnumber(res, "lancompiler");
+ i_oid = PQfnumber(res, "oid");
for (i = 0; i < ntups; i++)
{
}
if (fidx >= numFuncs)
{
- fprintf(stderr, "dumpProcLangs(): handler procedure for language %s not found\n", PQgetvalue(res, i, i_lanname));
+ fprintf(stderr, "dumpProcLangs(): handler procedure for "
+ "language %s not found\n", PQgetvalue(res, i, i_lanname));
exit_nicely(g_conn);
}
lanname = checkForQuote(PQgetvalue(res, i, i_lanname));
lancompiler = checkForQuote(PQgetvalue(res, i, i_lancompiler));
- if (dropSchema)
- fprintf(fout, "DROP PROCEDURAL LANGUAGE '%s';\n", lanname);
+ appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE '%s';\n", lanname);
- fprintf(fout, "CREATE %sPROCEDURAL LANGUAGE '%s' "
+ appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE '%s' "
"HANDLER %s LANCOMPILER '%s';\n",
- (PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ? "TRUSTED " : "",
+ (PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ? "TRUSTED " : "",
lanname,
fmtId(finfo[fidx].proname, force_quotes),
lancompiler);
+ ArchiveEntry(fout, PQgetvalue(res, i, i_oid), lanname, "PROCEDURAL LANGUAGE",
+ NULL, defqry->data, delqry->data, "", NULL, NULL);
+
free(lanname);
free(lancompiler);
}
*
*/
void
-dumpFuncs(FILE *fout, FuncInfo *finfo, int numFuncs,
+dumpFuncs(Archive *fout, FuncInfo *finfo, int numFuncs,
TypeInfo *tinfo, int numTypes)
{
int i;
*/
static void
-dumpOneFunc(FILE *fout, FuncInfo *finfo, int i,
+dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
TypeInfo *tinfo, int numTypes)
{
PQExpBuffer q = createPQExpBuffer();
+ PQExpBuffer fn = createPQExpBuffer();
+ PQExpBuffer delqry = createPQExpBuffer();
PQExpBuffer fnlist = createPQExpBuffer();
int j;
char *func_def;
else
finfo[i].dumped = 1;
- becomeUser(fout, finfo[i].usename);
+ /* becomeUser(fout, finfo[i].usename); */
sprintf(query, "SELECT lanname FROM pg_language WHERE oid = %u",
finfo[i].lang);
res = PQexec(g_conn, query);
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK)
- {
+ {
fprintf(stderr, "dumpOneFunc(): SELECT for procedural language failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
- }
+ }
nlangs = PQntuples(res);
if (nlangs != 1)
- {
+ {
fprintf(stderr, "dumpOneFunc(): procedural language for function %s not found\n", finfo[i].proname);
exit_nicely(g_conn);
- }
-
+ }
+
i_lanname = PQfnumber(res, "lanname");
-
+
func_def = finfo[i].prosrc;
strcpy(func_lang, PQgetvalue(res, 0, i_lanname));
-
+
PQclear(res);
-
- if (dropSchema)
- {
- resetPQExpBuffer(q);
- appendPQExpBuffer(q, "DROP FUNCTION %s (", fmtId(finfo[i].proname, force_quotes));
- for (j = 0; j < finfo[i].nargs; j++)
- {
- char *typname;
-
- typname = findTypeByOid(tinfo, numTypes, finfo[i].argtypes[j]);
- appendPQExpBuffer(q, "%s%s",
- (j > 0) ? "," : "",
- fmtId(typname, false));
- }
- appendPQExpBuffer(q, ");\n");
- fputs(q->data, fout);
- }
-
- resetPQExpBuffer(q);
- appendPQExpBuffer(q, "CREATE FUNCTION %s (", fmtId(finfo[i].proname, force_quotes));
+
+ resetPQExpBuffer(fn);
+ appendPQExpBuffer(fn, "%s (", fmtId(finfo[i].proname, force_quotes));
for (j = 0; j < finfo[i].nargs; j++)
{
- char *typname;
+ char *typname;
typname = findTypeByOid(tinfo, numTypes, finfo[i].argtypes[j]);
- appendPQExpBuffer(q, "%s%s",
- (j > 0) ? "," : "",
- fmtId(typname, false));
+ appendPQExpBuffer(fn, "%s%s",
+ (j > 0) ? "," : "",
+ fmtId(typname, false));
appendPQExpBuffer(fnlist, "%s%s",
- (j > 0) ? "," : "",
- fmtId(typname, false));
+ (j > 0) ? "," : "",
+ fmtId(typname, false));
}
- appendPQExpBuffer(q, " ) RETURNS %s%s AS '%s' LANGUAGE '%s';\n",
+ appendPQExpBuffer(fn, ")");
+
+ resetPQExpBuffer(delqry);
+ appendPQExpBuffer(delqry, "DROP FUNCTION %s;\n", fn->data );
+
+ resetPQExpBuffer(q);
+ appendPQExpBuffer(q, "CREATE FUNCTION %s ", fn->data );
+ appendPQExpBuffer(q, "RETURNS %s%s AS '%s' LANGUAGE '%s';\n",
(finfo[i].retset) ? " SETOF " : "",
- fmtId(findTypeByOid(tinfo, numTypes, finfo[i].prorettype), false),
+ fmtId(findTypeByOid(tinfo, numTypes, finfo[i].prorettype), false),
func_def, func_lang);
- fputs(q->data, fout);
+ ArchiveEntry(fout, finfo[i].oid, fn->data, "FUNCTION", NULL, q->data, delqry->data,
+ finfo[i].usename, NULL, NULL);
/*** Dump Function Comments ***/
*
*/
void
-dumpOprs(FILE *fout, OprInfo *oprinfo, int numOperators,
+dumpOprs(Archive *fout, OprInfo *oprinfo, int numOperators,
TypeInfo *tinfo, int numTypes)
{
int i;
PQExpBuffer q = createPQExpBuffer();
+ PQExpBuffer delq = createPQExpBuffer();
PQExpBuffer leftarg = createPQExpBuffer();
PQExpBuffer rightarg = createPQExpBuffer();
PQExpBuffer commutator = createPQExpBuffer();
appendPQExpBuffer(sort2, ",\n\tSORT2 = %s ",
findOprByOid(oprinfo, numOperators, oprinfo[i].oprrsortop));
- becomeUser(fout, oprinfo[i].usename);
-
- if (dropSchema)
- {
- resetPQExpBuffer(q);
- appendPQExpBuffer(q, "DROP OPERATOR %s (%s", oprinfo[i].oprname,
+ resetPQExpBuffer(delq);
+ appendPQExpBuffer(delq, "DROP OPERATOR %s (%s", oprinfo[i].oprname,
fmtId(findTypeByOid(tinfo, numTypes, oprinfo[i].oprleft),
false));
- appendPQExpBuffer(q, ", %s);\n",
- fmtId(findTypeByOid(tinfo, numTypes, oprinfo[i].oprright),
+ appendPQExpBuffer(delq, ", %s);\n",
+ fmtId(findTypeByOid(tinfo, numTypes, oprinfo[i].oprright),
false));
- fputs(q->data, fout);
- }
resetPQExpBuffer(q);
appendPQExpBuffer(q,
commutator->data,
negator->data,
restrictor->data,
- (strcmp(oprinfo[i].oprcanhash, "t") == 0) ? ",\n\tHASHES" : "",
+ (strcmp(oprinfo[i].oprcanhash, "t") == 0) ? ",\n\tHASHES" : "",
join->data,
sort1->data,
sort2->data);
- fputs(q->data, fout);
+ ArchiveEntry(fout, oprinfo[i].oid, oprinfo[i].oprname, "OPERATOR", NULL,
+ q->data, delq->data, oprinfo[i].usename, NULL, NULL);
}
}
*
*/
void
-dumpAggs(FILE *fout, AggInfo *agginfo, int numAggs,
+dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs,
TypeInfo *tinfo, int numTypes)
{
int i;
PQExpBuffer q = createPQExpBuffer();
+ PQExpBuffer delq = createPQExpBuffer();
+ PQExpBuffer aggSig = createPQExpBuffer();
PQExpBuffer sfunc1 = createPQExpBuffer();
PQExpBuffer sfunc2 = createPQExpBuffer();
PQExpBuffer basetype = createPQExpBuffer();
else
comma2[0] = '\0';
- becomeUser(fout, agginfo[i].usename);
+ resetPQExpBuffer(aggSig);
+ appendPQExpBuffer(aggSig, "%s %s", agginfo[i].aggname,
+ fmtId(findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype), false));
- if (dropSchema)
- {
- resetPQExpBuffer(q);
- appendPQExpBuffer(q, "DROP AGGREGATE %s %s;\n", agginfo[i].aggname,
- fmtId(findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype), false));
- fputs(q->data, fout);
- }
+ resetPQExpBuffer(delq);
+ appendPQExpBuffer(delq, "DROP AGGREGATE %s;\n", aggSig->data);
resetPQExpBuffer(q);
appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s %s%s %s%s %s );\n",
comma2,
finalfunc->data);
- fputs(q->data, fout);
+ ArchiveEntry(fout, agginfo[i].oid, aggSig->data, "AGGREGATE", NULL,
+ q->data, delq->data, agginfo[i].usename, NULL, NULL);
/*** Dump Aggregate Comments ***/
return strdup(aclbuf);
}
+/*
+ * The name says it all; a function to append a string is the dest
+ * is big enough. If not, it does a realloc.
+ */
+static void strcatalloc(char **dest, int *dSize, char *src)
+{
+ int dLen = strlen(*dest);
+ int sLen = strlen(src);
+ if ( (dLen + sLen) >= *dSize) {
+ *dSize = (dLen + sLen) * 2;
+ *dest = realloc(*dest, *dSize);
+ }
+ strcpy(*dest + dLen, src);
+}
+
+
/*
* dumpACL:
* Write out grant/revoke information
*/
static void
-dumpACL(FILE *fout, TableInfo tbinfo)
+dumpACL(Archive *fout, TableInfo tbinfo)
{
- const char *acls = tbinfo.relacl;
- char *aclbuf,
+ const char *acls = tbinfo.relacl;
+ char *aclbuf,
*tok,
*eqpos,
*priv;
+ char *sql;
+ char tmp[1024];
+ int sSize = 4096;
if (strlen(acls) == 0)
return; /* table has default permissions */
+ /*
+ * Allocate a larginsh buffer for the output SQL.
+ */
+ sql = (char*)malloc(sSize);
+
/*
* Revoke Default permissions for PUBLIC. Is this actually necessary,
* or is it just a waste of time?
*/
- fprintf(fout,
- "REVOKE ALL on %s from PUBLIC;\n",
+ sprintf(sql, "REVOKE ALL on %s from PUBLIC;\n",
fmtId(tbinfo.relname, force_quotes));
/* Make a working copy of acls so we can use strtok */
priv = GetPrivileges(eqpos + 1);
if (*priv)
{
- fprintf(fout,
- "GRANT %s on %s to ",
+ sprintf(tmp, "GRANT %s on %s to ",
priv, fmtId(tbinfo.relname, force_quotes));
+ strcatalloc(&sql, &sSize, tmp);
/*
* Note: fmtId() can only be called once per printf, so don't
if (eqpos == tok)
{
/* Empty left-hand side means "PUBLIC" */
- fprintf(fout, "PUBLIC;\n");
+ strcatalloc(&sql, &sSize, "PUBLIC;\n");
}
else
{
*eqpos = '\0'; /* it's ok to clobber aclbuf */
if (strncmp(tok, "group ", strlen("group ")) == 0)
- fprintf(fout, "GROUP %s;\n",
+ sprintf(tmp, "GROUP %s;\n",
fmtId(tok + strlen("group "), force_quotes));
else
- fprintf(fout, "%s;\n", fmtId(tok, force_quotes));
+ sprintf(tmp, "%s;\n", fmtId(tok, force_quotes));
+ strcatalloc(&sql, &sSize, tmp);
}
}
free(priv);
}
free(aclbuf);
+
+ ArchiveEntry(fout, tbinfo.oid, tbinfo.relname, "ACL", NULL, sql, "", "", NULL, NULL);
+
}
*/
void
-dumpTables(FILE *fout, TableInfo *tblinfo, int numTables,
+dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
InhInfo *inhinfo, int numInherits,
TypeInfo *tinfo, int numTypes, const char *tablename,
- const bool aclsSkip)
+ const bool aclsSkip, const bool oids,
+ const bool schemaOnly, const bool dataOnly)
{
int i,
j,
k;
PQExpBuffer q = createPQExpBuffer();
+ PQExpBuffer delq = createPQExpBuffer();
char *serialSeq = NULL; /* implicit sequence name created
* by SERIAL datatype */
const char *serialSeqSuffix = "_id_seq"; /* suffix for implicit
int precision;
int scale;
-
/* First - dump SEQUENCEs */
if (tablename)
{
if (!tablename || (!strcmp(tblinfo[i].relname, tablename))
|| (serialSeq && !strcmp(tblinfo[i].relname, serialSeq)))
{
- becomeUser(fout, tblinfo[i].usename);
+ /* becomeUser(fout, tblinfo[i].usename); */
dumpSequence(fout, tblinfo[i]);
if (!aclsSkip)
dumpACL(fout, tblinfo[i]);
parentRels = tblinfo[i].parentRels;
numParents = tblinfo[i].numParents;
- becomeUser(fout, tblinfo[i].usename);
-
- if (dropSchema)
- {
- resetPQExpBuffer(q);
- appendPQExpBuffer(q, "DROP TABLE %s;\n", fmtId(tblinfo[i].relname, force_quotes));
- fputs(q->data, fout);
- }
+ resetPQExpBuffer(delq);
+ appendPQExpBuffer(delq, "DROP TABLE %s;\n", fmtId(tblinfo[i].relname, force_quotes));
resetPQExpBuffer(q);
appendPQExpBuffer(q, "CREATE TABLE %s (\n\t", fmtId(tblinfo[i].relname, force_quotes));
}
appendPQExpBuffer(q, ";\n");
- fputs(q->data, fout);
- if (!aclsSkip)
+
+ if (!dataOnly) {
+ ArchiveEntry(fout, tblinfo[i].oid, fmtId(tblinfo[i].relname, false),
+ "TABLE", NULL, q->data, delq->data, tblinfo[i].usename,
+ NULL, NULL);
+ }
+
+ if (!dataOnly && !aclsSkip)
dumpACL(fout, tblinfo[i]);
/* Dump Field Comments */
* write out to fout all the user-define indices
*/
void
-dumpIndices(FILE *fout, IndInfo *indinfo, int numIndices,
+dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
TableInfo *tblinfo, int numTables, const char *tablename)
{
int i,
int nclass;
PQExpBuffer q = createPQExpBuffer(),
+ delq = createPQExpBuffer(),
id1 = createPQExpBuffer(),
id2 = createPQExpBuffer();
PGresult *res;
res = PQexec(g_conn, q->data);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "dumpIndices(): SELECT (funcname) failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "dumpIndices(): SELECT (funcname) failed. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
- funcname = strdup(PQgetvalue(res, 0,
- PQfnumber(res, "proname")));
+ funcname = strdup(PQgetvalue(res, 0, PQfnumber(res, "proname")));
PQclear(res);
}
res = PQexec(g_conn, q->data);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "dumpIndices(): SELECT (classname) failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "dumpIndices(): SELECT (classname) failed. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
- classname[nclass] = strdup(PQgetvalue(res, 0,
- PQfnumber(res, "opcname")));
+ classname[nclass] = strdup(PQgetvalue(res, 0, PQfnumber(res, "opcname")));
PQclear(res);
}
* is not necessarily right but should answer 99% of the time.
* Would have to add owner name to IndInfo to do it right.
*/
- becomeUser(fout, tblinfo[tableInd].usename);
resetPQExpBuffer(id1);
resetPQExpBuffer(id2);
appendPQExpBuffer(id1, fmtId(indinfo[i].indexrelname, force_quotes));
appendPQExpBuffer(id2, fmtId(indinfo[i].indrelname, force_quotes));
- if (dropSchema)
- {
- resetPQExpBuffer(q);
- appendPQExpBuffer(q, "DROP INDEX %s;\n", id1->data);
- fputs(q->data, fout);
- }
+ resetPQExpBuffer(delq);
+ appendPQExpBuffer(delq, "DROP INDEX %s;\n", id1->data);
- fprintf(fout, "CREATE %s INDEX %s on %s using %s (",
- (strcmp(indinfo[i].indisunique, "t") == 0) ? "UNIQUE" : "",
+ resetPQExpBuffer(q);
+ appendPQExpBuffer(q, "CREATE %s INDEX %s on %s using %s (",
+ (strcmp(indinfo[i].indisunique, "t") == 0) ? "UNIQUE" : "",
id1->data,
id2->data,
indinfo[i].indamname);
if (funcname)
{
/* need 2 printf's here cuz fmtId has static return area */
- fprintf(fout, " %s", fmtId(funcname, false));
- fprintf(fout, " (%s) %s );\n", attlist->data, fmtId(classname[0], force_quotes));
+ appendPQExpBuffer(q, " %s", fmtId(funcname, false));
+ appendPQExpBuffer(q, " (%s) %s );\n", attlist->data,
+ fmtId(classname[0], force_quotes));
free(funcname);
free(classname[0]);
}
else
- fprintf(fout, " %s );\n", attlist->data);
+ appendPQExpBuffer(q, " %s );\n", attlist->data);
/* Dump Index Comments */
+ ArchiveEntry(fout, tblinfo[tableInd].oid, id1->data, "INDEX", NULL, q->data, delq->data,
+ tblinfo[tableInd].usename, NULL, NULL);
+
resetPQExpBuffer(q);
appendPQExpBuffer(q, "INDEX %s", id1->data);
dumpComment(fout, q->data, indinfo[i].indoid);
*/
static void
-setMaxOid(FILE *fout)
+setMaxOid(Archive *fout)
{
- PGresult *res;
- Oid max_oid;
+ PGresult *res;
+ Oid max_oid;
+ char sql[1024];
+ int pos;
res = PQexec(g_conn, "CREATE TABLE pgdump_oid (dummy int4)");
if (!res ||
PQresultStatus(res) != PGRES_COMMAND_OK)
{
- fprintf(stderr, "Can not create pgdump_oid table. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "Can not create pgdump_oid table. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
PQclear(res);
if (!res ||
PQresultStatus(res) != PGRES_COMMAND_OK)
{
- fprintf(stderr, "Can not insert into pgdump_oid table. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "Can not insert into pgdump_oid table. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
max_oid = atol(PQoidStatus(res));
if (!res ||
PQresultStatus(res) != PGRES_COMMAND_OK)
{
- fprintf(stderr, "Can not drop pgdump_oid table. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+ fprintf(stderr, "Can not drop pgdump_oid table. "
+ "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
PQclear(res);
if (g_verbose)
fprintf(stderr, "%s maximum system oid is %u %s\n",
g_comment_start, max_oid, g_comment_end);
- fprintf(fout, "CREATE TABLE pgdump_oid (dummy int4);\n");
- fprintf(fout, "COPY pgdump_oid WITH OIDS FROM stdin;\n");
- fprintf(fout, "%-d\t0\n", max_oid);
- fprintf(fout, "\\.\n");
- fprintf(fout, "DROP TABLE pgdump_oid;\n");
+ pos = snprintf(sql, 1024, "CREATE TABLE pgdump_oid (dummy int4);\n");
+ pos = pos + snprintf(sql+pos, 1024-pos, "COPY pgdump_oid WITH OIDS FROM stdin;\n");
+ pos = pos + snprintf(sql+pos, 1024-pos, "%-d\t0\n", max_oid);
+ pos = pos + snprintf(sql+pos, 1024-pos, "\\.\n");
+ pos = pos + snprintf(sql+pos, 1024-pos, "DROP TABLE pgdump_oid;\n");
+
+ ArchiveEntry(fout, "0", "Max OID", "", NULL, sql, "","", NULL, NULL);
}
/*
static void
-dumpSequence(FILE *fout, TableInfo tbinfo)
+dumpSequence(Archive *fout, TableInfo tbinfo)
{
PGresult *res;
int4 last,
called;
const char *t;
PQExpBuffer query = createPQExpBuffer();
+ PQExpBuffer delqry = createPQExpBuffer();
appendPQExpBuffer(query,
"SELECT sequence_name, last_value, increment_by, max_value, "
res = PQexec(g_conn, query->data);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
{
- fprintf(stderr, "dumpSequence(%s): SELECT failed. Explanation from backend: '%s'.\n", tbinfo.relname, PQerrorMessage(g_conn));
+ fprintf(stderr, "dumpSequence(%s): SELECT failed. "
+ "Explanation from backend: '%s'.\n", tbinfo.relname, PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
PQclear(res);
- if (dropSchema)
- {
- resetPQExpBuffer(query);
- appendPQExpBuffer(query, "DROP SEQUENCE %s;\n", fmtId(tbinfo.relname, force_quotes));
- fputs(query->data, fout);
- }
+ resetPQExpBuffer(delqry);
+ appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n", fmtId(tbinfo.relname, force_quotes));
resetPQExpBuffer(query);
appendPQExpBuffer(query,
"CREATE SEQUENCE %s start %d increment %d maxvalue %d "
"minvalue %d cache %d %s;\n",
- fmtId(tbinfo.relname, force_quotes), last, incby, maxv, minv, cache,
+ fmtId(tbinfo.relname, force_quotes), last, incby, maxv, minv, cache,
(cycled == 't') ? "cycle" : "");
- fputs(query->data, fout);
+ if (called != 'f') {
+ appendPQExpBuffer(query, "SELECT nextval ('%s');\n", fmtId(tbinfo.relname, force_quotes));
+ }
+
+ ArchiveEntry(fout, tbinfo.oid, fmtId(tbinfo.relname, force_quotes), "SEQUENCE", NULL,
+ query->data, delqry->data, tbinfo.usename, NULL, NULL);
/* Dump Sequence Comments */
appendPQExpBuffer(query, "SEQUENCE %s", fmtId(tbinfo.relname, force_quotes));
dumpComment(fout, query->data, tbinfo.oid);
- if (called == 'f')
- return; /* nothing to do more */
-
- resetPQExpBuffer(query);
- appendPQExpBuffer(query, "SELECT nextval ('%s');\n", fmtId(tbinfo.relname, force_quotes));
- fputs(query->data, fout);
-
}
static void
-dumpTriggers(FILE *fout, const char *tablename,
+dumpTriggers(Archive *fout, const char *tablename,
TableInfo *tblinfo, int numTables)
{
int i,
continue;
for (j = 0; j < tblinfo[i].ntrig; j++)
{
- becomeUser(fout, tblinfo[i].usename);
- fputs(tblinfo[i].triggers[j], fout);
- dumpComment(fout, tblinfo[i].trcomments[j], tblinfo[i].troids[j]);
+ ArchiveEntry(fout, tblinfo[i].triggers[j].oid, tblinfo[i].triggers[j].tgname,
+ "TRIGGER", NULL, tblinfo[i].triggers[j].tgsrc, "",
+ tblinfo[i].usename, NULL, NULL);
+ dumpComment(fout, tblinfo[i].triggers[j].tgcomment, tblinfo[i].triggers[j].oid);
}
}
}
static void
-dumpRules(FILE *fout, const char *tablename,
+dumpRules(Archive *fout, const char *tablename,
TableInfo *tblinfo, int numTables)
{
PGresult *res;
for (i = 0; i < nrules; i++)
{
- fprintf(fout, "%s\n", PQgetvalue(res, i, i_definition));
+ ArchiveEntry(fout, PQgetvalue(res, i, i_oid), PQgetvalue(res, i, i_rulename),
+ "RULE", NULL, PQgetvalue(res, i, i_definition),
+ "", "", NULL, NULL);
/* Dump rule comments */
}
}
-
-/* Issue a psql \connect command to become the specified user.
- * We want to do this only if we are dumping ACLs,
- * and only if the new username is different from the last one
- * (to avoid the overhead of useless backend launches).
- */
-
-static void
-becomeUser(FILE *fout, const char *username)
-{
- static const char *lastusername = "";
-
- if (aclsSkip)
- return;
-
- if (strcmp(lastusername, username) == 0)
- return;
-
- fprintf(fout, "\\connect - %s\n", username);
-
- lastusername = username;
-}
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_dump.h,v 1.48 2000/04/12 17:16:15 momjian Exp $
+ * $Id: pg_dump.h,v 1.49 2000/07/04 14:25:28 momjian Exp $
*
*
#include "pqexpbuffer.h"
#include "catalog/pg_index.h"
+#include "pg_backup.h"
/* The data structures used to store system catalog information */
int dumped; /* 1 if already dumped */
} FuncInfo;
+typedef struct _trigInfo
+{
+ char *oid;
+ char *tgname;
+ char *tgsrc;
+ char *tgdel;
+ char *tgcomment;
+} TrigInfo;
+
typedef struct _tableInfo
{
char *oid;
int ncheck; /* # of CHECK expressions */
char **check_expr; /* [CONSTRAINT name] CHECK expressions */
int ntrig; /* # of triggers */
- char **triggers; /* CREATE TRIGGER ... */
- char **trcomments; /* COMMENT ON TRIGGER ... */
- char **troids; /* TRIGGER oids */
+ TrigInfo *triggers; /* Triggers on the table */
char *primary_key; /* PRIMARY KEY of the table, if any */
} TableInfo;
extern bool g_force_quotes; /* double-quotes for identifiers flag */
extern bool g_verbose; /* verbose flag */
extern int g_last_builtin_oid; /* value of the last builtin oid */
-extern FILE *g_fout; /* the script file */
+extern Archive *g_fout; /* the script file */
/* placeholders for comment starting and ending delimiters */
extern char g_comment_start[10];
* common utility functions
*/
-extern TableInfo *dumpSchema(FILE *fout,
+extern TableInfo *dumpSchema(Archive *fout,
int *numTablesPtr,
const char *tablename,
- const bool acls);
-extern void dumpSchemaIdx(FILE *fout,
+ const bool acls,
+ const bool oids,
+ const bool schemaOnly,
+ const bool dataOnly);
+extern void dumpSchemaIdx(Archive *fout,
const char *tablename,
TableInfo *tblinfo,
int numTables);
extern InhInfo *getInherits(int *numInherits);
extern void getTableAttrs(TableInfo *tbinfo, int numTables);
extern IndInfo *getIndices(int *numIndices);
-extern void dumpDBComment(FILE *outfile);
-extern void dumpTypes(FILE *fout, FuncInfo *finfo, int numFuncs,
+extern void dumpDBComment(Archive *outfile);
+extern void dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
TypeInfo *tinfo, int numTypes);
-extern void dumpProcLangs(FILE *fout, FuncInfo *finfo, int numFuncs,
+extern void dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs,
TypeInfo *tinfo, int numTypes);
-extern void dumpFuncs(FILE *fout, FuncInfo *finfo, int numFuncs,
+extern void dumpFuncs(Archive *fout, FuncInfo *finfo, int numFuncs,
TypeInfo *tinfo, int numTypes);
-extern void dumpAggs(FILE *fout, AggInfo *agginfo, int numAggregates,
+extern void dumpAggs(Archive *fout, AggInfo *agginfo, int numAggregates,
TypeInfo *tinfo, int numTypes);
-extern void dumpOprs(FILE *fout, OprInfo *agginfo, int numOperators,
+extern void dumpOprs(Archive *fout, OprInfo *agginfo, int numOperators,
TypeInfo *tinfo, int numTypes);
-extern void dumpTables(FILE *fout, TableInfo *tbinfo, int numTables,
+extern void dumpTables(Archive *fout, TableInfo *tbinfo, int numTables,
InhInfo *inhinfo, int numInherits,
TypeInfo *tinfo, int numTypes, const char *tablename,
- const bool acls);
-extern void dumpIndices(FILE *fout, IndInfo *indinfo, int numIndices,
+ const bool acls, const bool oids,
+ const bool schemaOnly, const bool dataOnly);
+extern void dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
TableInfo *tbinfo, int numTables, const char *tablename);
extern const char *fmtId(const char *identifier, bool force_quotes);
# and "pg_group" tables, which belong to the whole installation rather
# than any one individual database.
#
-# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_dumpall.sh,v 1.1 2000/07/03 16:35:39 petere Exp $
+# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_dumpall.sh,v 1.2 2000/07/04 14:25:28 momjian Exp $
CMDNAME=`basename $0`
PSQL="${PGPATH}/psql $connectopts"
-PGDUMP="${PGPATH}/pg_dump $connectopts $pgdumpextraopts"
+PGDUMP="${PGPATH}/pg_dump $connectopts $pgdumpextraopts -Fp"
echo "--"
--- /dev/null
+/*-------------------------------------------------------------------------\r
+ *\r
+ * pg_restore.c\r
+ * pg_restore is an utility extracting postgres database definitions\r
+ * from a backup archive created by pg_dump using the archiver \r
+ * interface.\r
+ *\r
+ * pg_restore will read the backup archive and\r
+ * dump out a script that reproduces\r
+ * the schema of the database in terms of\r
+ * user-defined types\r
+ * user-defined functions\r
+ * tables\r
+ * indices\r
+ * aggregates\r
+ * operators\r
+ * ACL - grant/revoke\r
+ *\r
+ * the output script is SQL that is understood by PostgreSQL\r
+ *\r
+ * Basic process in a restore operation is:\r
+ * \r
+ * Open the Archive and read the TOC.\r
+ * Set flags in TOC entries, and *maybe* reorder them.\r
+ * Generate script to stdout\r
+ * Exit\r
+ *\r
+ * Copyright (c) 2000, Philip Warner\r
+ * Rights are granted to use this software in any way so long\r
+ * as this notice is not removed.\r
+ *\r
+ * The author is not responsible for loss or damages that may\r
+ * result from it's use.\r
+ *\r
+ *\r
+ * IDENTIFICATION\r
+ *\r
+ *\r
+ * Initial version. Command processing taken from original pg_dump.\r
+ *\r
+ *-------------------------------------------------------------------------\r
+ */\r
+\r
+#include \r
+#include \r
+#include \r
+#include \r
+\r
+\r
+/*\r
+#include "postgres.h"\r
+#include "access/htup.h"\r
+#include "catalog/pg_type.h"\r
+#include "catalog/pg_language.h"\r
+#include "catalog/pg_index.h"\r
+#include "catalog/pg_trigger.h"\r
+#include "libpq-fe.h"\r
+*/\r
+\r
+#include "pg_backup.h"\r
+\r
+#ifndef HAVE_STRDUP\r
+#include "strdup.h"\r
+#endif\r
+\r
+#ifdef HAVE_TERMIOS_H\r
+#include \r
+#endif\r
+\r
+#ifdef HAVE_GETOPT_H \r
+#include \r
+#else\r
+#include \r
+#endif\r
+\r
+/* Forward decls */\r
+static void usage(const char *progname);\r
+static char* _cleanupName(char* name);\r
+\r
+typedef struct option optType;\r
+\r
+#ifdef HAVE_GETOPT_H\r
+struct option cmdopts[] = { \r
+ { "clean", 0, NULL, 'c' },\r
+ { "data-only", 0, NULL, 'a' },\r
+ { "file", 1, NULL, 'f' },\r
+ { "format", 1, NULL, 'F' },\r
+ { "function", 2, NULL, 'p' },\r
+ { "index", 2, NULL, 'i'},\r
+ { "list", 0, NULL, 'l'},\r
+ { "no-acl", 0, NULL, 'x' },\r
+ { "oid-order", 0, NULL, 'o'},\r
+ { "orig-order", 0, NULL, 'O' },\r
+ { "rearrange", 0, NULL, 'r'},\r
+ { "schema-only", 0, NULL, 's' },\r
+ { "table", 2, NULL, 't'},\r
+ { "trigger", 2, NULL, 'T' },\r
+ { "use-list", 1, NULL, 'u'},\r
+ { "verbose", 0, NULL, 'v' },\r
+ { NULL, 0, NULL, 0}\r
+ };\r
+#endif\r
+\r
+int main(int argc, char **argv)\r
+{\r
+ RestoreOptions *opts;\r
+ char *progname;\r
+ int c;\r
+ Archive* AH;\r
+ char *fileSpec;\r
+\r
+ opts = NewRestoreOptions();\r
+\r
+ progname = *argv;\r
+\r
+#ifdef HAVE_GETOPT_LONG\r
+ while ((c = getopt_long(argc, argv, "acf:F:i:loOp:st:T:u:vx", cmdopts, NULL)) != EOF)\r
+#else\r
+ while ((c = getopt(argc, argv, "acf:F:i:loOp:st:T:u:vx")) != -1)\r
+#endif\r
+ {\r
+ switch (c)\r
+ {\r
+ case 'a': /* Dump data only */\r
+ opts->dataOnly = 1;\r
+ break;\r
+ case 'c': /* clean (i.e., drop) schema prior to\r
+ * create */\r
+ opts->dropSchema = 1;\r
+ break;\r
+ case 'f': /* output file name */\r
+ opts->filename = strdup(optarg);\r
+ break;\r
+ case 'F':\r
+ if (strlen(optarg) != 0) \r
+ opts->formatName = strdup(optarg);\r
+ break;\r
+ case 'o':\r
+ opts->oidOrder = 1;\r
+ break;\r
+ case 'O':\r
+ opts->origOrder = 1;\r
+ break;\r
+ case 'r':\r
+ opts->rearrange = 1;\r
+ break;\r
+\r
+ case 'p': /* Function */\r
+ opts->selTypes = 1;\r
+ opts->selFunction = 1;\r
+ opts->functionNames = _cleanupName(optarg);\r
+ break;\r
+ case 'i': /* Index */\r
+ opts->selTypes = 1;\r
+ opts->selIndex = 1;\r
+ opts->indexNames = _cleanupName(optarg);\r
+ break;\r
+ case 'T': /* Trigger */\r
+ opts->selTypes = 1;\r
+ opts->selTrigger = 1;\r
+ opts->triggerNames = _cleanupName(optarg);\r
+ break;\r
+ case 's': /* dump schema only */\r
+ opts->schemaOnly = 1;\r
+ break;\r
+ case 't': /* Dump data for this table only */\r
+ opts->selTypes = 1;\r
+ opts->selTable = 1;\r
+ opts->tableNames = _cleanupName(optarg);\r
+ break;\r
+ case 'l': /* Dump the TOC summary */\r
+ opts->tocSummary = 1;\r
+ break;\r
+\r
+ case 'u': /* input TOC summary file name */\r
+ opts->tocFile = strdup(optarg);\r
+ break;\r
+\r
+ case 'v': /* verbose */\r
+ opts->verbose = 1;\r
+ break;\r
+ case 'x': /* skip ACL dump */\r
+ opts->aclsSkip = 1;\r
+ break;\r
+ default:\r
+ usage(progname);\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (optind < argc) {\r
+ fileSpec = argv[optind];\r
+ } else {\r
+ fileSpec = NULL;\r
+ }\r
+\r
+ if (opts->formatName) { \r
+\r
+ switch (opts->formatName[0]) {\r
+\r
+ case 'c':\r
+ case 'C':\r
+ opts->format = archCustom;\r
+ break;\r
+\r
+ case 'f':\r
+ case 'F':\r
+ opts->format = archFiles;\r
+ break;\r
+\r
+ default:\r
+ fprintf(stderr, "%s: Unknown archive format '%s', please specify 'f' or 'c'\n", progname, opts->formatName);\r
+ exit (1);\r
+ }\r
+ }\r
+\r
+ AH = OpenArchive(fileSpec, opts->format);\r
+\r
+ if (opts->tocFile)\r
+ SortTocFromFile(AH, opts);\r
+\r
+ if (opts->oidOrder)\r
+ SortTocByOID(AH);\r
+ else if (opts->origOrder)\r
+ SortTocByID(AH);\r
+\r
+ if (opts->rearrange) {\r
+ MoveToEnd(AH, "TABLE DATA");\r
+ MoveToEnd(AH, "INDEX");\r
+ MoveToEnd(AH, "TRIGGER");\r
+ MoveToEnd(AH, "RULE");\r
+ MoveToEnd(AH, "ACL");\r
+ }\r
+\r
+ if (opts->tocSummary) {\r
+ PrintTOCSummary(AH, opts);\r
+ } else {\r
+ RestoreArchive(AH, opts);\r
+ }\r
+\r
+ CloseArchive(AH);\r
+\r
+ return 1;\r
+}\r
+\r
+static void usage(const char *progname)\r
+{\r
+#ifdef HAVE_GETOPT_LONG\r
+ fprintf(stderr,\r
+ "usage: %s [options] [backup file]\n"\r
+ " -a, --data-only \t dump out only the data, no schema\n"\r
+ " -c, --clean \t clean(drop) schema prior to create\n"\r
+ " -f filename \t script output filename\n"\r
+ " -F, --format {c|f} \t specify backup file format\n"\r
+ " -p, --function[=name] \t dump functions or named function\n"\r
+ " -i, --index[=name] \t dump indexes or named index\n"\r
+ " -l, --list \t dump summarized TOC for this file\n"\r
+ " -o, --oid-order \t dump in oid order\n"\r
+ " -O, --orig-order \t dump in original dump order\n"\r
+ " -r, --rearrange \t rearrange output to put indexes etc at end\n"\r
+ " -s, --schema-only \t dump out only the schema, no data\n"\r
+ " -t [table], --table[=table] \t dump for this table only\n"\r
+ " -T, --trigger[=name] \t dump triggers or named trigger\n"\r
+ " -u, --use-list filename \t use specified TOC for ordering output from this file\n"\r
+ " -v \t verbose\n"\r
+ " -x, --no-acl \t skip dumping of ACLs (grant/revoke)\n"\r
+ , progname);\r
+#else\r
+ fprintf(stderr,\r
+ "usage: %s [options] [backup file]\n"\r
+ " -a \t dump out only the data, no schema\n"\r
+ " -c \t clean(drop) schema prior to create\n"\r
+ " -f filename NOT IMPLEMENTED \t script output filename\n"\r
+ " -F {c|f} \t specify backup file format\n"\r
+ " -p name \t dump functions or named function\n"\r
+ " -i name \t dump indexes or named index\n"\r
+ " -l \t dump summarized TOC for this file\n"\r
+ " -o \t dump in oid order\n"\r
+ " -O \t dump in original dump order\n"\r
+ " -r \t rearrange output to put indexes etc at end\n"\r
+ " -s \t dump out only the schema, no data\n"\r
+ " -t name \t dump for this table only\n"\r
+ " -T name \t dump triggers or named trigger\n"\r
+ " -u filename \t use specified TOC for ordering output from this file\n"\r
+ " -v \t verbose\n"\r
+ " -x \t skip dumping of ACLs (grant/revoke)\n"\r
+ , progname);\r
+#endif\r
+ fprintf(stderr,\r
+ "\nIf [backup file] is not supplied, then standard input "\r
+ "is used.\n");\r
+ fprintf(stderr, "\n");\r
+\r
+ exit(1);\r
+}\r
+\r
+static char* _cleanupName(char* name)\r
+{\r
+ int i;\r
+\r
+ if (!name)\r
+ return NULL;\r
+\r
+ if (strlen(name) == 0)\r
+ return NULL;\r
+\r
+ name = strdup(name);\r
+\r
+ if (name[0] == '"')\r
+ {\r
+ strcpy(name, &name[1]);\r
+ if (*(name + strlen(name) - 1) == '"')\r
+ *(name + strlen(name) - 1) = '\0';\r
+ }\r
+ /* otherwise, convert table name to lowercase... */\r
+ else\r
+ {\r
+ for (i = 0; name[i]; i++)\r
+ if (isascii((unsigned char) name[i]) && isupper(name[i]))\r
+ name[i] = tolower(name[i]);\r
+ }\r
+ return name;\r
+}\r
+\r