Rearrange pg_dump's handling of large objects for better efficiency.
[pgsql.git] / src / bin / pg_dump / pg_backup_null.c
bloba3257f4fc84dc6283a1d123db9dc8eea38cf916e
1 /*-------------------------------------------------------------------------
3 * pg_backup_null.c
5 * Implementation of an archive that is never saved; it is used by
6 * pg_dump to output a plain text SQL script instead of saving
7 * a real archive.
9 * See the headers to pg_restore for more details.
11 * Copyright (c) 2000, Philip Warner
12 * Rights are granted to use this software in any way so long
13 * as this notice is not removed.
15 * The author is not responsible for loss or damages that may
16 * result from its use.
19 * IDENTIFICATION
20 * src/bin/pg_dump/pg_backup_null.c
22 *-------------------------------------------------------------------------
24 #include "postgres_fe.h"
26 #include "fe_utils/string_utils.h"
27 #include "libpq/libpq-fs.h"
28 #include "pg_backup_archiver.h"
29 #include "pg_backup_utils.h"
31 static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
32 static void _WriteLOData(ArchiveHandle *AH, const void *data, size_t dLen);
33 static void _EndData(ArchiveHandle *AH, TocEntry *te);
34 static int _WriteByte(ArchiveHandle *AH, const int i);
35 static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
36 static void _CloseArchive(ArchiveHandle *AH);
37 static void _PrintTocData(ArchiveHandle *AH, TocEntry *te);
38 static void _StartLOs(ArchiveHandle *AH, TocEntry *te);
39 static void _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid);
40 static void _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid);
41 static void _EndLOs(ArchiveHandle *AH, TocEntry *te);
45 * Initializer
47 void
48 InitArchiveFmt_Null(ArchiveHandle *AH)
50 /* Assuming static functions, this can be copied for each format. */
51 AH->WriteDataPtr = _WriteData;
52 AH->EndDataPtr = _EndData;
53 AH->WriteBytePtr = _WriteByte;
54 AH->WriteBufPtr = _WriteBuf;
55 AH->ClosePtr = _CloseArchive;
56 AH->ReopenPtr = NULL;
57 AH->PrintTocDataPtr = _PrintTocData;
59 AH->StartLOsPtr = _StartLOs;
60 AH->StartLOPtr = _StartLO;
61 AH->EndLOPtr = _EndLO;
62 AH->EndLOsPtr = _EndLOs;
63 AH->ClonePtr = NULL;
64 AH->DeClonePtr = NULL;
67 * Now prevent reading...
69 if (AH->mode == archModeRead)
70 pg_fatal("this format cannot be read");
74 * - Start a new TOC entry
78 * Called by dumper via archiver from within a data dump routine
80 static void
81 _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
83 /* Just send it to output, ahwrite() already errors on failure */
84 ahwrite(data, 1, dLen, AH);
88 * Called by dumper via archiver from within a data dump routine
89 * We substitute this for _WriteData while emitting a LO
91 static void
92 _WriteLOData(ArchiveHandle *AH, const void *data, size_t dLen)
94 if (dLen > 0)
96 PQExpBuffer buf = createPQExpBuffer();
98 appendByteaLiteralAHX(buf,
99 (const unsigned char *) data,
100 dLen,
101 AH);
103 ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
105 destroyPQExpBuffer(buf);
109 static void
110 _EndData(ArchiveHandle *AH, TocEntry *te)
112 ahprintf(AH, "\n\n");
116 * Called by the archiver when starting to save BLOB DATA (not schema).
117 * This routine should save whatever format-specific information is needed
118 * to read the LOs back into memory.
120 * It is called just prior to the dumper's DataDumper routine.
122 * Optional, but strongly recommended.
124 static void
125 _StartLOs(ArchiveHandle *AH, TocEntry *te)
127 ahprintf(AH, "BEGIN;\n\n");
131 * Called by the archiver when the dumper calls StartLO.
133 * Mandatory.
135 * Must save the passed OID for retrieval at restore-time.
137 static void
138 _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
140 bool old_lo_style = (AH->version < K_VERS_1_12);
142 if (oid == 0)
143 pg_fatal("invalid OID for large object");
145 /* With an old archive we must do drop and create logic here */
146 if (old_lo_style && AH->public.ropt->dropSchema)
147 DropLOIfExists(AH, oid);
149 if (old_lo_style)
150 ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
151 oid, INV_WRITE);
152 else
153 ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n",
154 oid, INV_WRITE);
156 AH->WriteDataPtr = _WriteLOData;
160 * Called by the archiver when the dumper calls EndLO.
162 * Optional.
164 static void
165 _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
167 AH->WriteDataPtr = _WriteData;
169 ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
173 * Called by the archiver when finishing saving BLOB DATA.
175 * Optional.
177 static void
178 _EndLOs(ArchiveHandle *AH, TocEntry *te)
180 ahprintf(AH, "COMMIT;\n\n");
183 /*------
184 * Called as part of a RestoreArchive call; for the NULL archive, this
185 * just sends the data for a given TOC entry to the output.
186 *------
188 static void
189 _PrintTocData(ArchiveHandle *AH, TocEntry *te)
191 if (te->dataDumper)
193 AH->currToc = te;
195 if (strcmp(te->desc, "BLOBS") == 0)
196 _StartLOs(AH, te);
198 te->dataDumper((Archive *) AH, te->dataDumperArg);
200 if (strcmp(te->desc, "BLOBS") == 0)
201 _EndLOs(AH, te);
203 AH->currToc = NULL;
207 static int
208 _WriteByte(ArchiveHandle *AH, const int i)
210 /* Don't do anything */
211 return 0;
214 static void
215 _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
217 /* Don't do anything */
220 static void
221 _CloseArchive(ArchiveHandle *AH)
223 /* Nothing to do */