diff options
Diffstat (limited to 'src/bin/pg_dump/pg_backup_archiver.c')
-rw-r--r-- | src/bin/pg_dump/pg_backup_archiver.c | 181 |
1 files changed, 163 insertions, 18 deletions
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index adaf7c46d24..09626453441 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.22 2001/03/22 04:00:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.23 2001/04/01 05:42:50 pjw Exp $ * * Modifications - 28-Jun-2000 - pjw@rhyme.com.au * @@ -41,6 +41,16 @@ * Modifications - 6-Mar-2001 - pjw@rhyme.com.au * - Only disable triggers in DataOnly (or implied data-only) restores. * + * Modifications - 31-Mar-2001 - pjw@rhyme.com.au + * + * - Rudimentary support for dependencies in archives. Current implementation + * uses dependencies to modify the OID used in sorting TOC entries. + * This will NOT handle multi-level dependencies, but will manage simple + * relationships like UDTs & their functions. + * + * - Treat OIDs with more respect (avoid using ints, use macros for + * conversion & comparison). + * *------------------------------------------------------------------------- */ @@ -75,6 +85,8 @@ static TocEntry *_getTocEntry(ArchiveHandle *AH, int id); static void _moveAfter(ArchiveHandle *AH, TocEntry *pos, TocEntry *te); static void _moveBefore(ArchiveHandle *AH, TocEntry *pos, TocEntry *te); static int _discoverArchiveFormat(ArchiveHandle *AH); +static void _fixupOidInfo(TocEntry *te); +static Oid _findMaxOID(const char *((*deps)[])); static char *progname = "Archiver"; @@ -557,7 +569,7 @@ WriteData(Archive *AHX, const void *data, int dLen) /* Public */ void ArchiveEntry(Archive *AHX, const char *oid, const char *name, - const char *desc, const char *(deps[]), const char *defn, + const char *desc, const char *((*deps)[]), const char *defn, const char *dropStmt, const char *copyStmt, const char *owner, DataDumperPtr dumpFn, void *dumpArg) { @@ -577,10 +589,15 @@ ArchiveEntry(Archive *AHX, const char *oid, const char *name, AH->toc->prev = newToc; newToc->id = AH->lastID; - newToc->oid = strdup(oid); - newToc->oidVal = atoi(oid); + newToc->name = strdup(name); newToc->desc = strdup(desc); + + newToc->oid = strdup(oid); + newToc->depOid = deps; + _fixupOidInfo(newToc); + + newToc->defn = strdup(defn); newToc->dropStmt = strdup(dropStmt); newToc->copyStmt = copyStmt ? strdup(copyStmt) : NULL; @@ -654,7 +671,7 @@ PrintTOCSummary(Archive *AHX, RestoreOptions *ropt) /* Called by a dumper to signal start of a BLOB */ int -StartBlob(Archive *AHX, int oid) +StartBlob(Archive *AHX, Oid oid) { ArchiveHandle *AH = (ArchiveHandle *) AHX; @@ -668,7 +685,7 @@ StartBlob(Archive *AHX, int oid) /* Called by a dumper to signal end of a BLOB */ int -EndBlob(Archive *AHX, int oid) +EndBlob(Archive *AHX, Oid oid) { ArchiveHandle *AH = (ArchiveHandle *) AHX; @@ -714,7 +731,7 @@ EndRestoreBlobs(ArchiveHandle *AH) * Called by a format handler to initiate restoration of a blob */ void -StartRestoreBlob(ArchiveHandle *AH, int oid) +StartRestoreBlob(ArchiveHandle *AH, Oid oid) { int loOid; @@ -756,7 +773,7 @@ StartRestoreBlob(ArchiveHandle *AH, int oid) } void -EndRestoreBlob(ArchiveHandle *AH, int oid) +EndRestoreBlob(ArchiveHandle *AH, Oid oid) { lo_close(AH->connection, AH->loFd); AH->writingBlob = 0; @@ -1331,7 +1348,7 @@ ReadInt(ArchiveHandle *AH) } int -WriteStr(ArchiveHandle *AH, char *c) +WriteStr(ArchiveHandle *AH, const char *c) { int res; @@ -1630,6 +1647,8 @@ void WriteToc(ArchiveHandle *AH) { TocEntry *te = AH->toc->next; + const char *dep; + int i; /* printf("%d TOC Entries to save\n", AH->tocCount); */ @@ -1639,12 +1658,25 @@ WriteToc(ArchiveHandle *AH) WriteInt(AH, te->id); WriteInt(AH, te->dataDumper ? 1 : 0); WriteStr(AH, te->oid); + WriteStr(AH, te->name); WriteStr(AH, te->desc); WriteStr(AH, te->defn); WriteStr(AH, te->dropStmt); WriteStr(AH, te->copyStmt); WriteStr(AH, te->owner); + + /* Dump list of dependencies */ + if (te->depOid != NULL) + { + i = 0; + while( (dep = (*te->depOid)[i++]) != NULL) + { + WriteStr(AH, dep); + } + } + WriteStr(AH, NULL); /* Terminate List */ + if (AH->WriteExtraTocPtr) (*AH->WriteExtraTocPtr) (AH, te); te = te->next; @@ -1655,6 +1687,9 @@ void ReadToc(ArchiveHandle *AH) { int i; + char *((*deps)[]); + int depIdx; + int depSize; TocEntry *te = AH->toc->next; @@ -1672,7 +1707,8 @@ ReadToc(ArchiveHandle *AH) te->hadDumper = ReadInt(AH); te->oid = ReadStr(AH); - te->oidVal = atoi(te->oid); + te->oidVal = atooid(te->oid); + te->name = ReadStr(AH); te->desc = ReadStr(AH); te->defn = ReadStr(AH); @@ -1683,6 +1719,40 @@ ReadToc(ArchiveHandle *AH) te->owner = ReadStr(AH); + /* Read TOC entry dependencies */ + if (AH->version >= K_VERS_1_5) + { + depSize = 100; + deps = malloc(sizeof(char*) * depSize); + depIdx = 0; + do + { + if (depIdx > depSize) + { + depSize *= 2; + deps = realloc(deps, sizeof(char*) * depSize); + } + (*deps)[depIdx] = ReadStr(AH); + /* + * if ((*deps)[depIdx]) + * fprintf(stderr, "Read Dependency for %s -> %s\n", te->name, (*deps)[depIdx]); + */ + } while ( (*deps)[depIdx++] != NULL); + + if (depIdx > 1) /* We have a non-null entry */ + { + /* Trim it */ + te->depOid = realloc(deps, sizeof(char*) * depIdx); + } else { /* No deps */ + te->depOid = NULL; + } + } else { + te->depOid = NULL; + } + + /* Set maxOidVal etc for use in sorting */ + _fixupOidInfo(te); + if (AH->ReadExtraTocPtr) (*AH->ReadExtraTocPtr) (AH, te); @@ -1984,17 +2054,50 @@ _tocSortCompareByOIDNum(const void *p1, const void *p2) { TocEntry *te1 = *(TocEntry **) p1; TocEntry *te2 = *(TocEntry **) p2; - int id1 = te1->oidVal; - int id2 = te2->oidVal; + Oid id1 = te1->maxOidVal; + Oid id2 = te2->maxOidVal; + int cmpval; /* printf("Comparing %d to %d\n", id1, id2); */ - if (id1 < id2) - return -1; - else if (id1 > id2) - return 1; - else - return _tocSortCompareByIDNum(te1, te2); + cmpval = oidcmp(id1, id2); + + /* If we have a deterministic answer, return it. */ + if (cmpval != 0) + return cmpval; + + /* More comparisons required */ + if ( oideq(id1, te1->maxDepOidVal) ) /* maxOid1 came from deps */ + { + if ( oideq(id2, te2->maxDepOidVal) ) /* maxOid2 also came from deps */ + { + cmpval = oidcmp(te1->oidVal, te2->oidVal); /* Just compare base OIDs */ + } + else /* MaxOid2 was entry OID */ + { + return 1; /* entry1 > entry2 */ + }; + } + else /* must have oideq(id1, te1->oidVal) => maxOid1 = Oid1 */ + { + if ( oideq(id2, te2->maxDepOidVal) ) /* maxOid2 came from deps */ + { + return -1; /* entry1 < entry2 */ + } + else /* MaxOid2 was entry OID - deps don't matter */ + { + cmpval = 0; + }; + }; + + /* If we get here, then we've done another comparison + * Once again, a 0 result means we require even more + */ + if (cmpval != 0) + return cmpval; + + /* Entire OID details match, so use ID number (ie. original pg_dump order) */ + return _tocSortCompareByIDNum(te1, te2); } static int @@ -2016,6 +2119,48 @@ _tocSortCompareByIDNum(const void *p1, const void *p2) } /* + * Assuming Oid and depOid are set, work out the various + * Oid values used in sorting. + */ +static void +_fixupOidInfo(TocEntry *te) +{ + te->oidVal = atooid(te->oid); + te->maxDepOidVal = _findMaxOID(te->depOid); + + /* For the purpose of sorting, find the max OID. */ + if (oidcmp(te->oidVal, te->maxDepOidVal) >= 0) + te->maxOidVal = te->oidVal; + else + te->maxOidVal = te->maxDepOidVal; +} + +/* + * Find the max OID value for a given list of string Oid values + */ +static Oid +_findMaxOID(const char *((*deps)[])) +{ + const char *dep; + int i; + Oid maxOid = (Oid)0; + Oid currOid; + + if (!deps) + return maxOid; + + i = 0; + while( (dep = (*deps)[i++]) != NULL) + { + currOid = atooid(dep); + if (oidcmp(maxOid, currOid) < 0) + maxOid = currOid; + } + + return maxOid; +} + +/* * Maybe I can use this somewhere... * *create table pgdump_blob_path(p text); |