Header And Logo

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

pg_backup_null.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * pg_backup_null.c
00004  *
00005  *  Implementation of an archive that is never saved; it is used by
00006  *  pg_dump to output a plain text SQL script instead of saving
00007  *  a real archive.
00008  *
00009  *  See the headers to pg_restore for more details.
00010  *
00011  * Copyright (c) 2000, Philip Warner
00012  *      Rights are granted to use this software in any way so long
00013  *      as this notice is not removed.
00014  *
00015  *  The author is not responsible for loss or damages that may
00016  *  result from it's use.
00017  *
00018  *
00019  * IDENTIFICATION
00020  *      src/bin/pg_dump/pg_backup_null.c
00021  *
00022  *-------------------------------------------------------------------------
00023  */
00024 
00025 #include "pg_backup_archiver.h"
00026 #include "pg_backup_utils.h"
00027 #include "parallel.h"
00028 
00029 #include <unistd.h>             /* for dup */
00030 
00031 #include "libpq/libpq-fs.h"
00032 
00033 
00034 static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
00035 static size_t _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen);
00036 static void _EndData(ArchiveHandle *AH, TocEntry *te);
00037 static int  _WriteByte(ArchiveHandle *AH, const int i);
00038 static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
00039 static void _CloseArchive(ArchiveHandle *AH);
00040 static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
00041 static void _StartBlobs(ArchiveHandle *AH, TocEntry *te);
00042 static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid);
00043 static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid);
00044 static void _EndBlobs(ArchiveHandle *AH, TocEntry *te);
00045 
00046 
00047 /*
00048  *  Initializer
00049  */
00050 void
00051 InitArchiveFmt_Null(ArchiveHandle *AH)
00052 {
00053     /* Assuming static functions, this can be copied for each format. */
00054     AH->WriteDataPtr = _WriteData;
00055     AH->EndDataPtr = _EndData;
00056     AH->WriteBytePtr = _WriteByte;
00057     AH->WriteBufPtr = _WriteBuf;
00058     AH->ClosePtr = _CloseArchive;
00059     AH->ReopenPtr = NULL;
00060     AH->PrintTocDataPtr = _PrintTocData;
00061 
00062     AH->StartBlobsPtr = _StartBlobs;
00063     AH->StartBlobPtr = _StartBlob;
00064     AH->EndBlobPtr = _EndBlob;
00065     AH->EndBlobsPtr = _EndBlobs;
00066     AH->ClonePtr = NULL;
00067     AH->DeClonePtr = NULL;
00068 
00069     /* Initialize LO buffering */
00070     AH->lo_buf_size = LOBBUFSIZE;
00071     AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
00072 
00073     /*
00074      * Now prevent reading...
00075      */
00076     if (AH->mode == archModeRead)
00077         exit_horribly(NULL, "this format cannot be read\n");
00078 }
00079 
00080 /*
00081  * - Start a new TOC entry
00082  */
00083 
00084 /*
00085  * Called by dumper via archiver from within a data dump routine
00086  */
00087 static size_t
00088 _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
00089 {
00090     /* Just send it to output */
00091     ahwrite(data, 1, dLen, AH);
00092     return dLen;
00093 }
00094 
00095 /*
00096  * Called by dumper via archiver from within a data dump routine
00097  * We substitute this for _WriteData while emitting a BLOB
00098  */
00099 static size_t
00100 _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
00101 {
00102     if (dLen > 0)
00103     {
00104         PQExpBuffer buf = createPQExpBuffer();
00105 
00106         appendByteaLiteralAHX(buf,
00107                               (const unsigned char *) data,
00108                               dLen,
00109                               AH);
00110 
00111         ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
00112 
00113         destroyPQExpBuffer(buf);
00114     }
00115     return dLen;
00116 }
00117 
00118 static void
00119 _EndData(ArchiveHandle *AH, TocEntry *te)
00120 {
00121     ahprintf(AH, "\n\n");
00122 }
00123 
00124 /*
00125  * Called by the archiver when starting to save all BLOB DATA (not schema).
00126  * This routine should save whatever format-specific information is needed
00127  * to read the BLOBs back into memory.
00128  *
00129  * It is called just prior to the dumper's DataDumper routine.
00130  *
00131  * Optional, but strongly recommended.
00132  */
00133 static void
00134 _StartBlobs(ArchiveHandle *AH, TocEntry *te)
00135 {
00136     ahprintf(AH, "BEGIN;\n\n");
00137 }
00138 
00139 /*
00140  * Called by the archiver when the dumper calls StartBlob.
00141  *
00142  * Mandatory.
00143  *
00144  * Must save the passed OID for retrieval at restore-time.
00145  */
00146 static void
00147 _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
00148 {
00149     bool        old_blob_style = (AH->version < K_VERS_1_12);
00150 
00151     if (oid == 0)
00152         exit_horribly(NULL, "invalid OID for large object\n");
00153 
00154     /* With an old archive we must do drop and create logic here */
00155     if (old_blob_style && AH->ropt->dropSchema)
00156         DropBlobIfExists(AH, oid);
00157 
00158     if (old_blob_style)
00159         ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
00160                  oid, INV_WRITE);
00161     else
00162         ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n",
00163                  oid, INV_WRITE);
00164 
00165     AH->WriteDataPtr = _WriteBlobData;
00166 }
00167 
00168 /*
00169  * Called by the archiver when the dumper calls EndBlob.
00170  *
00171  * Optional.
00172  */
00173 static void
00174 _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
00175 {
00176     AH->WriteDataPtr = _WriteData;
00177 
00178     ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
00179 }
00180 
00181 /*
00182  * Called by the archiver when finishing saving all BLOB DATA.
00183  *
00184  * Optional.
00185  */
00186 static void
00187 _EndBlobs(ArchiveHandle *AH, TocEntry *te)
00188 {
00189     ahprintf(AH, "COMMIT;\n\n");
00190 }
00191 
00192 /*------
00193  * Called as part of a RestoreArchive call; for the NULL archive, this
00194  * just sends the data for a given TOC entry to the output.
00195  *------
00196  */
00197 static void
00198 _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
00199 {
00200     if (te->dataDumper)
00201     {
00202         AH->currToc = te;
00203 
00204         if (strcmp(te->desc, "BLOBS") == 0)
00205             _StartBlobs(AH, te);
00206 
00207         (*te->dataDumper) ((Archive *) AH, te->dataDumperArg);
00208 
00209         if (strcmp(te->desc, "BLOBS") == 0)
00210             _EndBlobs(AH, te);
00211 
00212         AH->currToc = NULL;
00213     }
00214 }
00215 
00216 static int
00217 _WriteByte(ArchiveHandle *AH, const int i)
00218 {
00219     /* Don't do anything */
00220     return 0;
00221 }
00222 
00223 static size_t
00224 _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
00225 {
00226     /* Don't do anything */
00227     return len;
00228 }
00229 
00230 static void
00231 _CloseArchive(ArchiveHandle *AH)
00232 {
00233     /* Nothing to do */
00234 }