Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Enumerations | Functions

pg_backup.h File Reference

#include "postgres_fe.h"
#include "pg_dump.h"
#include "dumputils.h"
#include "libpq-fe.h"
Include dependency graph for pg_backup.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Archive
struct  _restoreOptions

Defines

#define atooid(x)   ((Oid) strtoul((x), NULL, 10))
#define oidcmp(x, y)   ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) )
#define oideq(x, y)   ( (x) == (y) )
#define oidle(x, y)   ( (x) <= (y) )
#define oidge(x, y)   ( (x) >= (y) )
#define oidzero(x)   ( (x) == 0 )
#define appendStringLiteralAH(buf, str, AH)   appendStringLiteral(buf, str, (AH)->encoding, (AH)->std_strings)

Typedefs

typedef enum _archiveFormat ArchiveFormat
typedef enum _archiveMode ArchiveMode
typedef enum _teSection teSection
typedef int(* DataDumperPtr )(Archive *AH, void *userArg)
typedef struct _restoreOptions RestoreOptions
typedef void(* SetupWorkerPtr )(Archive *AH, RestoreOptions *ropt)

Enumerations

enum  trivalue {
  TRI_DEFAULT, TRI_NO, TRI_YES, TRI_DEFAULT,
  TRI_NO, TRI_YES, TRI_DEFAULT, TRI_NO,
  TRI_YES, TRI_DEFAULT, TRI_NO, TRI_YES
}
enum  _archiveFormat {
  archUnknown = 0, archCustom = 1, archTar = 3, archNull = 4,
  archDirectory = 5
}
enum  _archiveMode { archModeAppend, archModeWrite, archModeRead }
enum  _teSection { SECTION_NONE = 1, SECTION_PRE_DATA, SECTION_DATA, SECTION_POST_DATA }

Functions

void ConnectDatabase (Archive *AH, const char *dbname, const char *pghost, const char *pgport, const char *username, enum trivalue prompt_password)
void DisconnectDatabase (Archive *AHX)
PGconnGetConnection (Archive *AHX)
void ArchiveEntry (Archive *AHX, CatalogId catalogId, DumpId dumpId, const char *tag, const char *namespace, const char *tablespace, const char *owner, bool withOids, const char *desc, teSection section, const char *defn, const char *dropStmt, const char *copyStmt, const DumpId *deps, int nDeps, DataDumperPtr dumpFn, void *dumpArg)
size_t WriteData (Archive *AH, const void *data, size_t dLen)
int StartBlob (Archive *AH, Oid oid)
int EndBlob (Archive *AH, Oid oid)
void CloseArchive (Archive *AH)
void SetArchiveRestoreOptions (Archive *AH, RestoreOptions *ropt)
void RestoreArchive (Archive *AH)
ArchiveOpenArchive (const char *FileSpec, const ArchiveFormat fmt)
ArchiveCreateArchive (const char *FileSpec, const ArchiveFormat fmt, const int compression, ArchiveMode mode, SetupWorkerPtr setupDumpWorker)
void PrintTOCSummary (Archive *AH, RestoreOptions *ropt)
RestoreOptionsNewRestoreOptions (void)
void SortTocFromFile (Archive *AHX, RestoreOptions *ropt)
int archputs (const char *s, Archive *AH)
int archprintf (Archive *AH, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE

Define Documentation

#define appendStringLiteralAH (   buf,
  str,
  AH 
)    appendStringLiteral(buf, str, (AH)->encoding, (AH)->std_strings)
#define atooid (   x  )     ((Oid) strtoul((x), NULL, 10))

Definition at line 34 of file pg_backup.h.

#define oidcmp (   x,
  y 
)    ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) )
#define oideq (   x,
  y 
)    ( (x) == (y) )

Definition at line 36 of file pg_backup.h.

#define oidge (   x,
  y 
)    ( (x) >= (y) )

Definition at line 38 of file pg_backup.h.

#define oidle (   x,
  y 
)    ( (x) <= (y) )

Definition at line 37 of file pg_backup.h.

#define oidzero (   x  )     ( (x) == 0 )

Definition at line 39 of file pg_backup.h.


Typedef Documentation

typedef enum _archiveMode ArchiveMode
typedef int(* DataDumperPtr)(Archive *AH, void *userArg)

Definition at line 101 of file pg_backup.h.

typedef void(* SetupWorkerPtr)(Archive *AH, RestoreOptions *ropt)

Definition at line 154 of file pg_backup.h.

typedef enum _teSection teSection

Enumeration Type Documentation

Enumerator:
archUnknown 
archCustom 
archTar 
archNull 
archDirectory 

Definition at line 48 of file pg_backup.h.

{
    archUnknown = 0,
    archCustom = 1,
    archTar = 3,
    archNull = 4,
    archDirectory = 5
} ArchiveFormat;

Enumerator:
archModeAppend 
archModeWrite 
archModeRead 

Definition at line 57 of file pg_backup.h.

{
    archModeAppend,
    archModeWrite,
    archModeRead
} ArchiveMode;

enum _teSection
Enumerator:
SECTION_NONE 
SECTION_PRE_DATA 
SECTION_DATA 
SECTION_POST_DATA 

Definition at line 64 of file pg_backup.h.

{
    SECTION_NONE = 1,           /* COMMENTs, ACLs, etc; can be anywhere */
    SECTION_PRE_DATA,           /* stuff to be processed before data */
    SECTION_DATA,               /* TABLE DATA, BLOBS, BLOB COMMENTS */
    SECTION_POST_DATA           /* stuff to be processed after data */
} teSection;

enum trivalue
Enumerator:
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 

Definition at line 41 of file pg_backup.h.

{
    TRI_DEFAULT,
    TRI_NO,
    TRI_YES
};


Function Documentation

void ArchiveEntry ( Archive AHX,
CatalogId  catalogId,
DumpId  dumpId,
const char *  tag,
const char *  namespace,
const char *  tablespace,
const char *  owner,
bool  withOids,
const char *  desc,
teSection  section,
const char *  defn,
const char *  dropStmt,
const char *  copyStmt,
const DumpId deps,
int  nDeps,
DataDumperPtr  dumpFn,
void *  dumpArg 
)

Definition at line 803 of file pg_backup_archiver.c.

References _archiveHandle::ArchiveEntryPtr, _tocEntry::catalogId, _tocEntry::dataDumper, _tocEntry::dataDumperArg, _tocEntry::dependencies, _tocEntry::dumpId, _tocEntry::formatData, _tocEntry::hadDumper, _archiveHandle::maxDumpId, _tocEntry::nDeps, _tocEntry::next, NULL, pg_malloc(), pg_malloc0(), pg_strdup(), _tocEntry::prev, _tocEntry::section, _tocEntry::tag, _archiveHandle::toc, and _archiveHandle::tocCount.

Referenced by dumpACL(), dumpAgg(), dumpAttrDef(), dumpBaseType(), dumpBlob(), dumpCast(), dumpCollation(), dumpComment(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConstraint(), dumpConversion(), dumpDatabase(), dumpDefaultACL(), dumpDomain(), dumpDumpableObject(), dumpEncoding(), dumpEnumType(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpProcLang(), dumpRangeType(), dumpRule(), dumpSecLabel(), dumpSequence(), dumpSequenceData(), dumpShellType(), dumpStdStrings(), dumpTableComment(), dumpTableData(), dumpTableSchema(), dumpTableSecLabel(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpUserMappings(), and refreshMatViewData().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;
    TocEntry   *newToc;

    newToc = (TocEntry *) pg_malloc0(sizeof(TocEntry));

    AH->tocCount++;
    if (dumpId > AH->maxDumpId)
        AH->maxDumpId = dumpId;

    newToc->prev = AH->toc->prev;
    newToc->next = AH->toc;
    AH->toc->prev->next = newToc;
    AH->toc->prev = newToc;

    newToc->catalogId = catalogId;
    newToc->dumpId = dumpId;
    newToc->section = 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->withOids = withOids;
    newToc->desc = pg_strdup(desc);
    newToc->defn = pg_strdup(defn);
    newToc->dropStmt = pg_strdup(dropStmt);
    newToc->copyStmt = copyStmt ? pg_strdup(copyStmt) : NULL;

    if (nDeps > 0)
    {
        newToc->dependencies = (DumpId *) pg_malloc(nDeps * sizeof(DumpId));
        memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId));
        newToc->nDeps = nDeps;
    }
    else
    {
        newToc->dependencies = NULL;
        newToc->nDeps = 0;
    }

    newToc->dataDumper = dumpFn;
    newToc->dataDumperArg = dumpArg;
    newToc->hadDumper = dumpFn ? true : false;

    newToc->formatData = NULL;

    if (AH->ArchiveEntryPtr !=NULL)
        (*AH->ArchiveEntryPtr) (AH, newToc);
}

int archprintf ( Archive AH,
const char *  fmt,
  ... 
)
int archputs ( const char *  s,
Archive AH 
)

Definition at line 1174 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

{
    return WriteData(AH, s, strlen(s));
}

void CloseArchive ( Archive AH  ) 

Definition at line 155 of file pg_backup_archiver.c.

References _archiveHandle::ClosePtr, exit_horribly(), GZCLOSE, _archiveHandle::gzOut, modulename, _archiveHandle::OF, and strerror().

Referenced by main().

{
    int         res = 0;
    ArchiveHandle *AH = (ArchiveHandle *) AHX;

    (*AH->ClosePtr) (AH);

    /* Close the output */
    if (AH->gzOut)
        res = GZCLOSE(AH->OF);
    else if (AH->OF != stdout)
        res = fclose(AH->OF);

    if (res != 0)
        exit_horribly(modulename, "could not close output file: %s\n",
                      strerror(errno));
}

void ConnectDatabase ( Archive AH,
const char *  dbname,
const char *  pghost,
const char *  pgport,
const char *  username,
enum trivalue  prompt_password 
)

Definition at line 215 of file pg_backup_db.c.

References _check_database_version(), _archiveHandle::connection, CONNECTION_BAD, exit_horribly(), free, modulename, notice_processor(), NULL, PARAMS_ARRAY_SIZE, pg_malloc(), PQconnectdbParams(), PQconnectionNeedsPassword(), PQdb(), PQerrorMessage(), PQfinish(), PQsetNoticeProcessor(), PQstatus(), progname, _archiveHandle::promptPassword, _archiveHandle::savedPassword, simple_prompt(), TRI_NO, TRI_YES, and values.

Referenced by CloneArchive(), main(), restore_toc_entries_postfork(), and RestoreArchive().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;
    char       *password = AH->savedPassword;
    bool        new_pass;

    if (AH->connection)
        exit_horribly(modulename, "already connected to a database\n");

    if (prompt_password == TRI_YES && password == NULL)
    {
        password = simple_prompt("Password: ", 100, false);
        if (password == NULL)
            exit_horribly(modulename, "out of memory\n");
    }
    AH->promptPassword = prompt_password;

    /*
     * Start the connection.  Loop until we have a password if requested by
     * backend.
     */
    do
    {
#define PARAMS_ARRAY_SIZE   7
        const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
        const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));

        keywords[0] = "host";
        values[0] = pghost;
        keywords[1] = "port";
        values[1] = pgport;
        keywords[2] = "user";
        values[2] = username;
        keywords[3] = "password";
        values[3] = password;
        keywords[4] = "dbname";
        values[4] = dbname;
        keywords[5] = "fallback_application_name";
        values[5] = progname;
        keywords[6] = NULL;
        values[6] = NULL;

        new_pass = false;
        AH->connection = PQconnectdbParams(keywords, values, true);

        free(keywords);
        free(values);

        if (!AH->connection)
            exit_horribly(modulename, "failed to connect to database\n");

        if (PQstatus(AH->connection) == CONNECTION_BAD &&
            PQconnectionNeedsPassword(AH->connection) &&
            password == NULL &&
            prompt_password != TRI_NO)
        {
            PQfinish(AH->connection);
            password = simple_prompt("Password: ", 100, false);
            if (password == NULL)
                exit_horribly(modulename, "out of memory\n");
            new_pass = true;
        }
    } while (new_pass);

    AH->savedPassword = password;

    /* check to see that the backend connection was successfully made */
    if (PQstatus(AH->connection) == CONNECTION_BAD)
        exit_horribly(modulename, "connection to database \"%s\" failed: %s",
                      PQdb(AH->connection) ? PQdb(AH->connection) : "",
                      PQerrorMessage(AH->connection));

    /* check for version mismatch */
    _check_database_version(AH);

    PQsetNoticeProcessor(AH->connection, notice_processor, NULL);
}

Archive* CreateArchive ( const char *  FileSpec,
const ArchiveFormat  fmt,
const int  compression,
ArchiveMode  mode,
SetupWorkerPtr  setupDumpWorker 
)

Definition at line 134 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

{
    ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, mode, setupDumpWorker);

    return (Archive *) AH;
}

void DisconnectDatabase ( Archive AHX  ) 

Definition at line 303 of file pg_backup_db.c.

References _archiveHandle::connection, PQcancel(), PQfinish(), PQfreeCancel(), PQgetCancel(), and PQtransactionStatus().

Referenced by archive_close_connection(), restore_toc_entries_prefork(), and RestoreArchive().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;
    PGcancel   *cancel;
    char        errbuf[1];

    if (!AH->connection)
        return;

    if (PQtransactionStatus(AH->connection) == PQTRANS_ACTIVE)
    {
        if ((cancel = PQgetCancel(AH->connection)))
        {
            PQcancel(cancel, errbuf, sizeof(errbuf));
            PQfreeCancel(cancel);
        }
    }

    PQfinish(AH->connection);
    AH->connection = NULL;
}

int EndBlob ( Archive AH,
Oid  oid 
)

Definition at line 954 of file pg_backup_archiver.c.

References _archiveHandle::currToc, and _archiveHandle::EndBlobPtr.

Referenced by dumpBlobs().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;

    if (AH->EndBlobPtr)
        (*AH->EndBlobPtr) (AH, AH->currToc, oid);

    return 1;
}

PGconn* GetConnection ( Archive AHX  ) 

Definition at line 326 of file pg_backup_db.c.

References _archiveHandle::connection.

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;

    return AH->connection;
}

RestoreOptions* NewRestoreOptions ( void   ) 

Definition at line 714 of file pg_backup_archiver.c.

References _restoreOptions::dumpSections, _restoreOptions::format, pg_malloc0(), and _restoreOptions::promptPassword.

Referenced by _CloseArchive(), and main().

{
    RestoreOptions *opts;

    opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));

    /* set any fields that shouldn't default to zeroes */
    opts->format = archUnknown;
    opts->promptPassword = TRI_DEFAULT;
    opts->dumpSections = DUMP_UNSECTIONED;

    return opts;
}

Archive* OpenArchive ( const char *  FileSpec,
const ArchiveFormat  fmt 
)

Definition at line 146 of file pg_backup_archiver.c.

References _allocAH(), archModeRead, and setupRestoreWorker().

Referenced by main().

{
    ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, archModeRead, setupRestoreWorker);

    return (Archive *) AH;
}

void PrintTOCSummary ( Archive AH,
RestoreOptions ropt 
)

Definition at line 867 of file pg_backup_archiver.c.

References _tocEntryRequired(), ahprintf(), archCustom, _archiveHandle::archdbname, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, archTar, _tocEntry::catalogId, _archiveHandle::compression, _archiveHandle::createDate, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, _restoreOptions::filename, _archiveHandle::format, i, _archiveHandle::intSize, _tocEntry::nDeps, _tocEntry::next, _archiveHandle::offSize, CatalogId::oid, _tocEntry::owner, REQ_DATA, REQ_SCHEMA, RestoreOutput(), SaveOutput(), _tocEntry::section, SECTION_NONE, SetOutput(), CatalogId::tableoid, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, _restoreOptions::verbose, _archiveHandle::vmaj, _archiveHandle::vmin, and _archiveHandle::vrev.

Referenced by main().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;
    TocEntry   *te;
    teSection   curSection;
    OutputContext sav;
    const char *fmtName;

    sav = SaveOutput(AH);
    if (ropt->filename)
        SetOutput(AH, ropt->filename, 0 /* no compression */ );

    ahprintf(AH, ";\n; Archive created at %s", ctime(&AH->createDate));
    ahprintf(AH, ";     dbname: %s\n;     TOC Entries: %d\n;     Compression: %d\n",
             AH->archdbname, AH->tocCount, AH->compression);

    switch (AH->format)
    {
        case archCustom:
            fmtName = "CUSTOM";
            break;
        case archTar:
            fmtName = "TAR";
            break;
        default:
            fmtName = "UNKNOWN";
    }

    ahprintf(AH, ";     Dump Version: %d.%d-%d\n", AH->vmaj, AH->vmin, AH->vrev);
    ahprintf(AH, ";     Format: %s\n", fmtName);
    ahprintf(AH, ";     Integer: %d bytes\n", (int) AH->intSize);
    ahprintf(AH, ";     Offset: %d bytes\n", (int) AH->offSize);
    if (AH->archiveRemoteVersion)
        ahprintf(AH, ";     Dumped from database version: %s\n",
                 AH->archiveRemoteVersion);
    if (AH->archiveDumpVersion)
        ahprintf(AH, ";     Dumped by pg_dump version: %s\n",
                 AH->archiveDumpVersion);

    ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");

    curSection = SECTION_PRE_DATA;
    for (te = AH->toc->next; te != AH->toc; te = te->next)
    {
        if (te->section != SECTION_NONE)
            curSection = te->section;
        if (ropt->verbose ||
            (_tocEntryRequired(te, curSection, ropt) & (REQ_SCHEMA | REQ_DATA)) != 0)
            ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
                     te->catalogId.tableoid, te->catalogId.oid,
                     te->desc, te->namespace ? te->namespace : "-",
                     te->tag, te->owner);
        if (ropt->verbose && te->nDeps > 0)
        {
            int         i;

            ahprintf(AH, ";\tdepends on:");
            for (i = 0; i < te->nDeps; i++)
                ahprintf(AH, " %d", te->dependencies[i]);
            ahprintf(AH, "\n");
        }
    }

    if (ropt->filename)
        RestoreOutput(AH, sav);
}

void RestoreArchive ( Archive AH  ) 

Definition at line 230 of file pg_backup_archiver.c.

References _becomeOwner(), _doSetFixedOutputState(), _printTocEntry(), _selectOutputSchema(), ahlog(), ahprintf(), _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, Assert, buildTocEntryArrays(), _archiveHandle::ClonePtr, CommitTransaction(), _restoreOptions::compression, _archiveHandle::compression, ConnectDatabase(), _archiveHandle::connection, _archiveHandle::createDate, _restoreOptions::createDB, _archiveHandle::currentTE, _archiveHandle::currSchema, _restoreOptions::dataOnly, _restoreOptions::dbname, _tocEntry::desc, DisconnectDatabase(), _restoreOptions::dropSchema, _tocEntry::dropStmt, dumpTimestamp(), exit_horribly(), _restoreOptions::filename, free, _tocEntry::hadDumper, K_VERS_1_3, K_VERS_1_8, Archive::maxRemoteVersion, Archive::minRemoteVersion, modulename, _tocEntry::next, _archiveHandle::noTocComments, NULL, Archive::numWorkers, par_list_header_init(), ParallelBackupEnd(), ParallelBackupStart(), _restoreOptions::pghost, _restoreOptions::pgport, _tocEntry::prev, _archiveHandle::PrintTocDataPtr, _restoreOptions::promptPassword, _archiveHandle::public, _archiveHandle::ReopenPtr, REQ_DATA, REQ_SCHEMA, _tocEntry::reqs, restore_toc_entries_parallel(), restore_toc_entries_postfork(), restore_toc_entries_prefork(), restore_toc_entry(), RestoreOutput(), _archiveHandle::ropt, SaveOutput(), SetOutput(), _restoreOptions::single_txn, _archiveHandle::stage, StartTransaction(), _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocsByDumpId, _restoreOptions::useDB, _restoreOptions::username, Archive::verbose, and _archiveHandle::version.

Referenced by _CloseArchive(), and main().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;
    RestoreOptions *ropt = AH->ropt;
    bool        parallel_mode;
    TocEntry   *te;
    OutputContext sav;

    AH->stage = STAGE_INITIALIZING;

    /*
     * Check for nonsensical option combinations.
     *
     * -C is not compatible with -1, because we can't create a database inside
     * a transaction block.
     */
    if (ropt->createDB && ropt->single_txn)
        exit_horribly(modulename, "-C and -1 are incompatible options\n");

    /*
     * If we're going to do parallel restore, there are some restrictions.
     */
    parallel_mode = (AH->public.numWorkers > 1 && ropt->useDB);
    if (parallel_mode)
    {
        /* We haven't got round to making this work for all archive formats */
        if (AH->ClonePtr == NULL || AH->ReopenPtr == NULL)
            exit_horribly(modulename, "parallel restore is not supported with this archive file format\n");

        /* Doesn't work if the archive represents dependencies as OIDs */
        if (AH->version < K_VERS_1_8)
            exit_horribly(modulename, "parallel restore is not supported with archives made by pre-8.0 pg_dump\n");

        /*
         * It's also not gonna work if we can't reopen the input file, so
         * let's try that immediately.
         */
        (AH->ReopenPtr) (AH);
    }

    /*
     * Make sure we won't need (de)compression we haven't got
     */
#ifndef HAVE_LIBZ
    if (AH->compression != 0 && AH->PrintTocDataPtr !=NULL)
    {
        for (te = AH->toc->next; te != AH->toc; te = te->next)
        {
            if (te->hadDumper && (te->reqs & REQ_DATA) != 0)
                exit_horribly(modulename, "cannot restore from compressed archive (compression not supported in this installation)\n");
        }
    }
#endif

    /*
     * Prepare index arrays, so we can assume we have them throughout restore.
     * It's possible we already did this, though.
     */
    if (AH->tocsByDumpId == NULL)
        buildTocEntryArrays(AH);

    /*
     * If we're using a DB connection, then connect it.
     */
    if (ropt->useDB)
    {
        ahlog(AH, 1, "connecting to database for restore\n");
        if (AH->version < K_VERS_1_3)
            exit_horribly(modulename, "direct database connections are not supported in pre-1.3 archives\n");

        /* XXX Should get this from the archive */
        AHX->minRemoteVersion = 070100;
        AHX->maxRemoteVersion = 999999;

        ConnectDatabase(AHX, ropt->dbname,
                        ropt->pghost, ropt->pgport, ropt->username,
                        ropt->promptPassword);

        /*
         * If we're talking to the DB directly, don't send comments since they
         * obscure SQL when displaying errors
         */
        AH->noTocComments = 1;
    }

    /*
     * Work out if we have an implied data-only restore. This can happen if
     * the dump was data only or if the user has used a toc list to exclude
     * all of the schema data. All we do is look for schema entries - if none
     * are found then we set the dataOnly flag.
     *
     * We could scan for wanted TABLE entries, but that is not the same as
     * dataOnly. At this stage, it seems unnecessary (6-Mar-2001).
     */
    if (!ropt->dataOnly)
    {
        int         impliedDataOnly = 1;

        for (te = AH->toc->next; te != AH->toc; te = te->next)
        {
            if ((te->reqs & REQ_SCHEMA) != 0)
            {                   /* It's schema, and it's wanted */
                impliedDataOnly = 0;
                break;
            }
        }
        if (impliedDataOnly)
        {
            ropt->dataOnly = impliedDataOnly;
            ahlog(AH, 1, "implied data-only restore\n");
        }
    }

    /*
     * Setup the output file if necessary.
     */
    sav = SaveOutput(AH);
    if (ropt->filename || ropt->compression)
        SetOutput(AH, ropt->filename, ropt->compression);

    ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n");

    if (AH->public.verbose)
    {
        if (AH->archiveRemoteVersion)
            ahprintf(AH, "-- Dumped from database version %s\n",
                     AH->archiveRemoteVersion);
        if (AH->archiveDumpVersion)
            ahprintf(AH, "-- Dumped by pg_dump version %s\n",
                     AH->archiveDumpVersion);
        dumpTimestamp(AH, "Started on", AH->createDate);
    }

    if (ropt->single_txn)
    {
        if (AH->connection)
            StartTransaction(AH);
        else
            ahprintf(AH, "BEGIN;\n\n");
    }

    /*
     * Establish important parameter values right away.
     */
    _doSetFixedOutputState(AH);

    AH->stage = STAGE_PROCESSING;

    /*
     * Drop the items at the start, in reverse order
     */
    if (ropt->dropSchema)
    {
        for (te = AH->toc->prev; te != AH->toc; te = te->prev)
        {
            AH->currentTE = te;

            /*
             * In createDB mode, issue a DROP *only* for the database as a
             * whole.  Issuing drops against anything else would be wrong,
             * because at this point we're connected to the wrong database.
             * Conversely, if we're not in createDB mode, we'd better not
             * issue a DROP against the database at all.
             */
            if (ropt->createDB)
            {
                if (strcmp(te->desc, "DATABASE") != 0)
                    continue;
            }
            else
            {
                if (strcmp(te->desc, "DATABASE") == 0)
                    continue;
            }

            /* Otherwise, drop anything that's selected and has a dropStmt */
            if (((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0) && te->dropStmt)
            {
                ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag);
                /* Select owner and schema as necessary */
                _becomeOwner(AH, te);
                _selectOutputSchema(AH, te->namespace);
                /* Drop it */
                ahprintf(AH, "%s", te->dropStmt);
            }
        }

        /*
         * _selectOutputSchema may have set currSchema to reflect the effect
         * of a "SET search_path" command it emitted.  However, by now we may
         * have dropped that schema; or it might not have existed in the first
         * place.  In either case the effective value of search_path will not
         * be what we think.  Forcibly reset currSchema so that we will
         * re-establish the search_path setting when needed (after creating
         * the schema).
         *
         * If we treated users as pg_dump'able objects then we'd need to reset
         * currUser here too.
         */
        if (AH->currSchema)
            free(AH->currSchema);
        AH->currSchema = NULL;
    }

    /*
     * In serial mode, we now process each non-ACL TOC entry.
     *
     * In parallel mode, turn control over to the parallel-restore logic.
     */
    if (parallel_mode)
    {
        ParallelState *pstate;
        TocEntry    pending_list;

        par_list_header_init(&pending_list);

        /* This runs PRE_DATA items and then disconnects from the database */
        restore_toc_entries_prefork(AH);
        Assert(AH->connection == NULL);

        /* ParallelBackupStart() will actually fork the processes */
        pstate = ParallelBackupStart(AH, ropt);
        restore_toc_entries_parallel(AH, pstate, &pending_list);
        ParallelBackupEnd(AH, pstate);

        /* reconnect the master and see if we missed something */
        restore_toc_entries_postfork(AH, &pending_list);
        Assert(AH->connection != NULL);
    }
    else
    {
        for (te = AH->toc->next; te != AH->toc; te = te->next)
            (void) restore_toc_entry(AH, te, ropt, false);
    }

    /*
     * Scan TOC again to output ownership commands and ACLs
     */
    for (te = AH->toc->next; te != AH->toc; te = te->next)
    {
        AH->currentTE = te;

        /* Both schema and data objects might now have ownership/ACLs */
        if ((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0)
        {
            ahlog(AH, 1, "setting owner and privileges for %s %s\n",
                  te->desc, te->tag);
            _printTocEntry(AH, te, ropt, false, true);
        }
    }

    if (ropt->single_txn)
    {
        if (AH->connection)
            CommitTransaction(AH);
        else
            ahprintf(AH, "COMMIT;\n\n");
    }

    if (AH->public.verbose)
        dumpTimestamp(AH, "Completed on", time(NULL));

    ahprintf(AH, "--\n-- PostgreSQL database dump complete\n--\n\n");

    /*
     * Clean up & we're done.
     */
    AH->stage = STAGE_FINALIZING;

    if (ropt->filename || ropt->compression)
        RestoreOutput(AH, sav);

    if (ropt->useDB)
        DisconnectDatabase(&AH->public);
}

void SetArchiveRestoreOptions ( Archive AH,
RestoreOptions ropt 
)

Definition at line 175 of file pg_backup_archiver.c.

References _tocEntryRequired(), archModeRead, exit_horribly(), _archiveHandle::mode, modulename, _tocEntry::next, _tocEntry::reqs, _archiveHandle::ropt, _tocEntry::section, SECTION_DATA, SECTION_NONE, SECTION_POST_DATA, SECTION_PRE_DATA, _archiveHandle::toc, and write_msg().

Referenced by main().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;
    TocEntry   *te;
    teSection   curSection;

    /* Save options for later access */
    AH->ropt = ropt;

    /* Decide which TOC entries will be dumped/restored, and mark them */
    curSection = SECTION_PRE_DATA;
    for (te = AH->toc->next; te != AH->toc; te = te->next)
    {
        /*
         * When writing an archive, we also take this opportunity to check
         * that we have generated the entries in a sane order that respects
         * the section divisions.  When reading, don't complain, since buggy
         * old versions of pg_dump might generate out-of-order archives.
         */
        if (AH->mode != archModeRead)
        {
            switch (te->section)
            {
                case SECTION_NONE:
                    /* ok to be anywhere */
                    break;
                case SECTION_PRE_DATA:
                    if (curSection != SECTION_PRE_DATA)
                        write_msg(modulename,
                                  "WARNING: archive items not in correct section order\n");
                    break;
                case SECTION_DATA:
                    if (curSection == SECTION_POST_DATA)
                        write_msg(modulename,
                                  "WARNING: archive items not in correct section order\n");
                    break;
                case SECTION_POST_DATA:
                    /* ok no matter which section we were in */
                    break;
                default:
                    exit_horribly(modulename, "unexpected section code %d\n",
                                  (int) te->section);
                    break;
            }
        }

        if (te->section != SECTION_NONE)
            curSection = te->section;

        te->reqs = _tocEntryRequired(te, curSection, ropt);
    }
}

void SortTocFromFile ( Archive AHX,
RestoreOptions ropt 
)

Definition at line 1080 of file pg_backup_archiver.c.

References _moveBefore(), buf, exit_horribly(), getTocEntryByDumpId(), _restoreOptions::idWanted, _archiveHandle::maxDumpId, modulename, NULL, PG_BINARY_R, pg_malloc(), strerror(), _archiveHandle::toc, _restoreOptions::tocFile, and write_msg().

Referenced by main().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;
    FILE       *fh;
    char        buf[100];
    bool        incomplete_line;

    /* Allocate space for the 'wanted' array, and init it */
    ropt->idWanted = (bool *) pg_malloc(sizeof(bool) * AH->maxDumpId);
    memset(ropt->idWanted, 0, sizeof(bool) * AH->maxDumpId);

    /* Setup the file */
    fh = fopen(ropt->tocFile, PG_BINARY_R);
    if (!fh)
        exit_horribly(modulename, "could not open TOC file \"%s\": %s\n",
                      ropt->tocFile, strerror(errno));

    incomplete_line = false;
    while (fgets(buf, sizeof(buf), fh) != NULL)
    {
        bool        prev_incomplete_line = incomplete_line;
        int         buflen;
        char       *cmnt;
        char       *endptr;
        DumpId      id;
        TocEntry   *te;

        /*
         * Some lines in the file might be longer than sizeof(buf).  This is
         * no problem, since we only care about the leading numeric ID which
         * can be at most a few characters; but we have to skip continuation
         * bufferloads when processing a long line.
         */
        buflen = strlen(buf);
        if (buflen > 0 && buf[buflen - 1] == '\n')
            incomplete_line = false;
        else
            incomplete_line = true;
        if (prev_incomplete_line)
            continue;

        /* Truncate line at comment, if any */
        cmnt = strchr(buf, ';');
        if (cmnt != NULL)
            cmnt[0] = '\0';

        /* Ignore if all blank */
        if (strspn(buf, " \t\r\n") == strlen(buf))
            continue;

        /* Get an ID, check it's valid and not already seen */
        id = strtol(buf, &endptr, 10);
        if (endptr == buf || id <= 0 || id > AH->maxDumpId ||
            ropt->idWanted[id - 1])
        {
            write_msg(modulename, "WARNING: line ignored: %s\n", buf);
            continue;
        }

        /* Find TOC entry */
        te = getTocEntryByDumpId(AH, id);
        if (!te)
            exit_horribly(modulename, "could not find entry for ID %d\n",
                          id);

        /* Mark it wanted */
        ropt->idWanted[id - 1] = true;

        /*
         * Move each item to the end of the list as it is selected, so that
         * they are placed in the desired order.  Any unwanted items will end
         * up at the front of the list, which may seem unintuitive but it's
         * what we need.  In an ordinary serial restore that makes no
         * difference, but in a parallel restore we need to mark unrestored
         * items' dependencies as satisfied before we start examining
         * restorable items.  Otherwise they could have surprising
         * side-effects on the order in which restorable items actually get
         * restored.
         */
        _moveBefore(AH, AH->toc, te);
    }

    if (fclose(fh) != 0)
        exit_horribly(modulename, "could not close TOC file: %s\n",
                      strerror(errno));
}

int StartBlob ( Archive AH,
Oid  oid 
)

Definition at line 940 of file pg_backup_archiver.c.

References _archiveHandle::currToc, exit_horribly(), modulename, and _archiveHandle::StartBlobPtr.

Referenced by dumpBlobs().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;

    if (!AH->StartBlobPtr)
        exit_horribly(modulename, "large-object output not supported in chosen format\n");

    (*AH->StartBlobPtr) (AH, AH->currToc, oid);

    return 1;
}

size_t WriteData ( Archive AH,
const void *  data,
size_t  dLen 
)

Definition at line 786 of file pg_backup_archiver.c.

References _archiveHandle::currToc, exit_horribly(), modulename, and _archiveHandle::WriteDataPtr.

Referenced by archprintf(), archputs(), dumpBlobs(), and dumpTableData_copy().

{
    ArchiveHandle *AH = (ArchiveHandle *) AHX;

    if (!AH->currToc)
        exit_horribly(modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n");

    return (*AH->WriteDataPtr) (AH, data, dLen);
}