Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * pg_backup_null.c
4 : *
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.
8 : *
9 : * See the headers to pg_restore for more details.
10 : *
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.
14 : *
15 : * The author is not responsible for loss or damages that may
16 : * result from its use.
17 : *
18 : *
19 : * IDENTIFICATION
20 : * src/bin/pg_dump/pg_backup_null.c
21 : *
22 : *-------------------------------------------------------------------------
23 : */
24 : #include "postgres_fe.h"
25 :
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"
30 :
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);
42 :
43 :
44 : /*
45 : * Initializer
46 : */
47 : void
8053 bruce 48 CBC 107 : InitArchiveFmt_Null(ArchiveHandle *AH)
49 : {
50 : /* Assuming static functions, this can be copied for each format. */
51 107 : AH->WriteDataPtr = _WriteData;
52 107 : AH->EndDataPtr = _EndData;
53 107 : AH->WriteBytePtr = _WriteByte;
54 107 : AH->WriteBufPtr = _WriteBuf;
55 107 : AH->ClosePtr = _CloseArchive;
5179 andrew 56 107 : AH->ReopenPtr = NULL;
8053 bruce 57 107 : AH->PrintTocDataPtr = _PrintTocData;
58 :
125 peter 59 GNC 107 : AH->StartLOsPtr = _StartLOs;
60 107 : AH->StartLOPtr = _StartLO;
61 107 : AH->EndLOPtr = _EndLO;
62 107 : AH->EndLOsPtr = _EndLOs;
5179 andrew 63 CBC 107 : AH->ClonePtr = NULL;
64 107 : AH->DeClonePtr = NULL;
65 :
66 : /* Initialize LO buffering */
6501 tgl 67 107 : AH->lo_buf_size = LOBBUFSIZE;
4153 bruce 68 107 : AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
69 :
70 : /*
71 : * Now prevent reading...
72 : */
8053 73 107 : if (AH->mode == archModeRead)
366 tgl 74 UBC 0 : pg_fatal("this format cannot be read");
8297 pjw 75 CBC 107 : }
76 :
77 : /*
78 : * - Start a new TOC entry
79 : */
80 :
81 : /*
82 : * Called by dumper via archiver from within a data dump routine
83 : */
84 : static void
7537 peter_e 85 1691755 : _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
86 : {
87 : /* Just send it to output, ahwrite() already errors on failure */
8053 bruce 88 1691755 : ahwrite(data, 1, dLen, AH);
8297 pjw 89 1691755 : }
90 :
91 : /*
92 : * Called by dumper via archiver from within a data dump routine
93 : * We substitute this for _WriteData while emitting a LO
94 : */
95 : static void
125 peter 96 GNC 92 : _WriteLOData(ArchiveHandle *AH, const void *data, size_t dLen)
97 : {
6501 tgl 98 CBC 92 : if (dLen > 0)
99 : {
4996 100 32 : PQExpBuffer buf = createPQExpBuffer();
101 :
102 32 : appendByteaLiteralAHX(buf,
103 : (const unsigned char *) data,
104 : dLen,
105 : AH);
106 :
107 32 : ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
108 :
109 32 : destroyPQExpBuffer(buf);
110 : }
6501 111 92 : }
112 :
113 : static void
8053 bruce 114 UBC 0 : _EndData(ArchiveHandle *AH, TocEntry *te)
115 : {
116 0 : ahprintf(AH, "\n\n");
8297 pjw 117 0 : }
118 :
119 : /*
120 : * Called by the archiver when starting to save all BLOB DATA (not schema).
121 : * This routine should save whatever format-specific information is needed
122 : * to read the LOs back into memory.
123 : *
124 : * It is called just prior to the dumper's DataDumper routine.
125 : *
126 : * Optional, but strongly recommended.
127 : */
128 : static void
125 peter 129 GNC 28 : _StartLOs(ArchiveHandle *AH, TocEntry *te)
130 : {
6501 tgl 131 CBC 28 : ahprintf(AH, "BEGIN;\n\n");
132 28 : }
133 :
134 : /*
135 : * Called by the archiver when the dumper calls StartLO.
136 : *
137 : * Mandatory.
138 : *
139 : * Must save the passed OID for retrieval at restore-time.
140 : */
141 : static void
125 peter 142 GNC 60 : _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
143 : {
144 60 : bool old_lo_style = (AH->version < K_VERS_1_12);
145 :
6501 tgl 146 CBC 60 : if (oid == 0)
366 tgl 147 UBC 0 : pg_fatal("invalid OID for large object");
148 :
149 : /* With an old archive we must do drop and create logic here */
125 peter 150 GNC 60 : if (old_lo_style && AH->public.ropt->dropSchema)
125 peter 151 UNC 0 : DropLOIfExists(AH, oid);
152 :
125 peter 153 GNC 60 : if (old_lo_style)
4798 tgl 154 UBC 0 : ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
155 : oid, INV_WRITE);
156 : else
4798 tgl 157 CBC 60 : ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n",
158 : oid, INV_WRITE);
159 :
125 peter 160 GNC 60 : AH->WriteDataPtr = _WriteLOData;
6501 tgl 161 CBC 60 : }
162 :
163 : /*
164 : * Called by the archiver when the dumper calls EndLO.
165 : *
166 : * Optional.
167 : */
168 : static void
125 peter 169 GNC 60 : _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
170 : {
6501 tgl 171 CBC 60 : AH->WriteDataPtr = _WriteData;
172 :
5010 173 60 : ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
6501 174 60 : }
175 :
176 : /*
177 : * Called by the archiver when finishing saving all BLOB DATA.
178 : *
179 : * Optional.
180 : */
181 : static void
125 peter 182 GNC 28 : _EndLOs(ArchiveHandle *AH, TocEntry *te)
183 : {
6501 tgl 184 CBC 28 : ahprintf(AH, "COMMIT;\n\n");
185 28 : }
186 :
187 : /*------
188 : * Called as part of a RestoreArchive call; for the NULL archive, this
189 : * just sends the data for a given TOC entry to the output.
190 : *------
191 : */
192 : static void
2643 193 2796 : _PrintTocData(ArchiveHandle *AH, TocEntry *te)
194 : {
8051 195 2796 : if (te->dataDumper)
196 : {
8297 pjw 197 2796 : AH->currToc = te;
198 :
6501 tgl 199 2796 : if (strcmp(te->desc, "BLOBS") == 0)
125 peter 200 GNC 28 : _StartLOs(AH, te);
201 :
2040 peter_e 202 CBC 2796 : te->dataDumper((Archive *) AH, te->dataDumperArg);
203 :
6501 tgl 204 2795 : if (strcmp(te->desc, "BLOBS") == 0)
125 peter 205 GNC 28 : _EndLOs(AH, te);
206 :
8297 pjw 207 CBC 2795 : AH->currToc = NULL;
208 : }
209 2795 : }
210 :
211 : static int
8053 bruce 212 UBC 0 : _WriteByte(ArchiveHandle *AH, const int i)
213 : {
214 : /* Don't do anything */
215 0 : return 0;
216 : }
217 :
218 : static void
7537 peter_e 219 0 : _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
220 : {
221 : /* Don't do anything */
8297 pjw 222 0 : }
223 :
224 : static void
2643 tgl 225 CBC 92 : _CloseArchive(ArchiveHandle *AH)
226 : {
227 : /* Nothing to do */
8297 pjw 228 92 : }
|