diff -c -r postgresql-8.4.6/src/bin/pg_dump/pg_backup_archiver.c postgresql-8.4.6-pg-dump-split/src/bin/pg_dump/pg_backup_archiver.c *** postgresql-8.4.6/src/bin/pg_dump/pg_backup_archiver.c 2010-12-14 03:59:19.000000000 +0100 --- postgresql-8.4.6-pg-dump-split/src/bin/pg_dump/pg_backup_archiver.c 2010-12-29 01:13:06.195510786 +0100 *************** *** 27,32 **** --- 27,34 ---- #include #include #include + #include + #include #ifdef WIN32 #include *************** *** 2752,2757 **** --- 2754,2832 ---- return; } + /* + * Split object into separate file, + * if the --split option is enabled and, + * if the object has an oid and, + * if the object has a namespace. + */ + if (ropt->split_files && te->catalogId.oid && te->namespace) + { + char splitFilename[1024]; + char *tag; + char *tagArgPos; + char *desc; + char *descSpacePos; + mode_t omode; + + /* + * Strip eventual argument part from "tag" (e.g. the name of functions) + * Example: "foobar(_arg1 int, _arg2 int)" --> "foobar" + */ + tagArgPos = strstr(te->tag,"("); + if (tagArgPos == NULL) + tag = strdup(te->tag); + else + tag = strndup(te->tag, tagArgPos - te->tag); + + desc = strdup(te->desc); + descSpacePos = strstr(desc," "); + /* + * Replace " " with "_" in "desc" + * Example: "FK CONSTRAINT" --> "FK_CONSTRAINT" + */ + while ((descSpacePos = strstr(desc, " ")) != NULL) + { + char *dup = strdup(desc); + strlcpy(desc, dup, descSpacePos - desc + 1); + strcat(desc, "_"); + strcat(desc, dup + (descSpacePos - desc) + strlen("_")); + free(dup); + } + + /* + * Build path consisting of [filename]-split/[schema]/[desc]/[tag].sql + * Create the directories + * + * Example: dumpfile-split/public/FUNCTION/foobar.sql + */ + omode = S_IRWXU | S_IRWXG | S_IRWXO; + snprintf(splitFilename, 1024, "%s-split", ropt->filename); + mkdir(splitFilename, omode); + snprintf(splitFilename, 1024, "%s-split/%s", ropt->filename, te->namespace); + mkdir(splitFilename, omode); + snprintf(splitFilename, 1024, "%s-split/%s/%s", ropt->filename, te->namespace, desc); + mkdir(splitFilename, omode); + + snprintf(splitFilename, 1024, "%s-split/%s/%s/%s.sql", ropt->filename, te->namespace, desc, tag); + + /* Add \i to main dump file */ + ahprintf(AH, "\\i %s\n", splitFilename); + + /* + * Close the normal file handle to which non-splittable + * objects are written. + * + * Open split file handle for splitFilename. + * + * In the end of the function, + * the split file handle will be closed, and + * the normal file handle will be reopened again. + */ + fclose(AH->OF); + AH->OF = fopen(splitFilename, PG_BINARY_A); + } + /* Select owner, schema, and tablespace as necessary */ _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); *************** *** 2881,2886 **** --- 2956,2971 ---- free(AH->currUser); AH->currUser = NULL; } + + /* + * If we are using the --split option, + * close the split file handle, and reopen the normal file handle. + */ + if (ropt->split_files && te->catalogId.oid && te->namespace) + { + fclose(AH->OF); + AH->OF = fopen(ropt->filename, PG_BINARY_A); + } } void diff -c -r postgresql-8.4.6/src/bin/pg_dump/pg_backup.h postgresql-8.4.6-pg-dump-split/src/bin/pg_dump/pg_backup.h *** postgresql-8.4.6/src/bin/pg_dump/pg_backup.h 2010-12-14 03:59:19.000000000 +0100 --- postgresql-8.4.6-pg-dump-split/src/bin/pg_dump/pg_backup.h 2010-12-29 01:08:42.255541320 +0100 *************** *** 142,147 **** --- 142,148 ---- int number_of_jobs; bool *idWanted; /* array showing which dump IDs to emit */ + int split_files; /* --split option, split objects into separate files */ } RestoreOptions; /* diff -c -r postgresql-8.4.6/src/bin/pg_dump/pg_dump.c postgresql-8.4.6-pg-dump-split/src/bin/pg_dump/pg_dump.c *** postgresql-8.4.6/src/bin/pg_dump/pg_dump.c 2010-12-14 03:59:19.000000000 +0100 --- postgresql-8.4.6-pg-dump-split/src/bin/pg_dump/pg_dump.c 2010-12-29 01:08:42.255541320 +0100 *************** *** 111,116 **** --- 111,117 ---- static int disable_dollar_quoting = 0; static int dump_inserts = 0; static int column_inserts = 0; + static int split_files = 0; static void help(const char *progname); *************** *** 277,282 **** --- 278,284 ---- {"no-tablespaces", no_argument, &outputNoTablespaces, 1}, {"role", required_argument, NULL, 3}, {"use-set-session-authorization", no_argument, &use_setsessauth, 1}, + {"split", no_argument, &split_files, 1}, {NULL, 0, NULL, 0} }; *************** *** 765,770 **** --- 767,773 ---- ropt->disable_triggers = disable_triggers; ropt->use_setsessauth = use_setsessauth; ropt->dataOnly = dataOnly; + ropt->split_files = split_files; if (compressLevel == -1) ropt->compression = 0; *************** *** 797,802 **** --- 800,806 ---- printf(_(" -v, --verbose verbose mode\n")); printf(_(" -Z, --compress=0-9 compression level for compressed formats\n")); printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n")); + printf(_(" --split split objects into separate plain text files\n")); printf(_(" --help show this help, then exit\n")); printf(_(" --version output version information, then exit\n"));