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
48 284 : InitArchiveFmt_Null(ArchiveHandle *AH)
49 : {
50 : /* Assuming static functions, this can be copied for each format. */
51 284 : AH->WriteDataPtr = _WriteData;
52 284 : AH->EndDataPtr = _EndData;
53 284 : AH->WriteBytePtr = _WriteByte;
54 284 : AH->WriteBufPtr = _WriteBuf;
55 284 : AH->ClosePtr = _CloseArchive;
56 284 : AH->ReopenPtr = NULL;
57 284 : AH->PrintTocDataPtr = _PrintTocData;
58 :
59 284 : AH->StartLOsPtr = _StartLOs;
60 284 : AH->StartLOPtr = _StartLO;
61 284 : AH->EndLOPtr = _EndLO;
62 284 : AH->EndLOsPtr = _EndLOs;
63 284 : AH->ClonePtr = NULL;
64 284 : AH->DeClonePtr = NULL;
65 :
66 : /*
67 : * Now prevent reading...
68 : */
69 284 : if (AH->mode == archModeRead)
70 0 : pg_fatal("this format cannot be read");
71 284 : }
72 :
73 : /*
74 : * - Start a new TOC entry
75 : */
76 :
77 : /*
78 : * Called by dumper via archiver from within a data dump routine
79 : */
80 : static void
81 3595884 : _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
82 : {
83 : /* Just send it to output, ahwrite() already errors on failure */
84 3595884 : ahwrite(data, 1, dLen, AH);
85 3595884 : }
86 :
87 : /*
88 : * Called by dumper via archiver from within a data dump routine
89 : * We substitute this for _WriteData while emitting a LO
90 : */
91 : static void
92 178 : _WriteLOData(ArchiveHandle *AH, const void *data, size_t dLen)
93 : {
94 178 : if (dLen > 0)
95 : {
96 62 : PQExpBuffer buf = createPQExpBuffer();
97 :
98 62 : appendByteaLiteralAHX(buf,
99 : (const unsigned char *) data,
100 : dLen,
101 : AH);
102 :
103 62 : ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
104 :
105 62 : destroyPQExpBuffer(buf);
106 : }
107 178 : }
108 :
109 : static void
110 0 : _EndData(ArchiveHandle *AH, TocEntry *te)
111 : {
112 0 : ahprintf(AH, "\n\n");
113 0 : }
114 :
115 : /*
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.
119 : *
120 : * It is called just prior to the dumper's DataDumper routine.
121 : *
122 : * Optional, but strongly recommended.
123 : */
124 : static void
125 100 : _StartLOs(ArchiveHandle *AH, TocEntry *te)
126 : {
127 100 : ahprintf(AH, "BEGIN;\n\n");
128 100 : }
129 :
130 : /*
131 : * Called by the archiver when the dumper calls StartLO.
132 : *
133 : * Mandatory.
134 : *
135 : * Must save the passed OID for retrieval at restore-time.
136 : */
137 : static void
138 116 : _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
139 : {
140 116 : bool old_lo_style = (AH->version < K_VERS_1_12);
141 :
142 116 : if (oid == 0)
143 0 : pg_fatal("invalid OID for large object");
144 :
145 : /* With an old archive we must do drop and create logic here */
146 116 : if (old_lo_style && AH->public.ropt->dropSchema)
147 0 : DropLOIfExists(AH, oid);
148 :
149 116 : if (old_lo_style)
150 0 : ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
151 : oid, INV_WRITE);
152 : else
153 116 : ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n",
154 : oid, INV_WRITE);
155 :
156 116 : AH->WriteDataPtr = _WriteLOData;
157 116 : }
158 :
159 : /*
160 : * Called by the archiver when the dumper calls EndLO.
161 : *
162 : * Optional.
163 : */
164 : static void
165 116 : _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
166 : {
167 116 : AH->WriteDataPtr = _WriteData;
168 :
169 116 : ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
170 116 : }
171 :
172 : /*
173 : * Called by the archiver when finishing saving BLOB DATA.
174 : *
175 : * Optional.
176 : */
177 : static void
178 100 : _EndLOs(ArchiveHandle *AH, TocEntry *te)
179 : {
180 100 : ahprintf(AH, "COMMIT;\n\n");
181 100 : }
182 :
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 : *------
187 : */
188 : static void
189 6690 : _PrintTocData(ArchiveHandle *AH, TocEntry *te)
190 : {
191 6690 : if (te->dataDumper)
192 : {
193 6690 : AH->currToc = te;
194 :
195 6690 : if (strcmp(te->desc, "BLOBS") == 0)
196 100 : _StartLOs(AH, te);
197 :
198 6690 : te->dataDumper((Archive *) AH, te->dataDumperArg);
199 :
200 6688 : if (strcmp(te->desc, "BLOBS") == 0)
201 100 : _EndLOs(AH, te);
202 :
203 6688 : AH->currToc = NULL;
204 : }
205 6688 : }
206 :
207 : static int
208 0 : _WriteByte(ArchiveHandle *AH, const int i)
209 : {
210 : /* Don't do anything */
211 0 : return 0;
212 : }
213 :
214 : static void
215 0 : _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
216 : {
217 : /* Don't do anything */
218 0 : }
219 :
220 : static void
221 244 : _CloseArchive(ArchiveHandle *AH)
222 : {
223 : /* Nothing to do */
224 244 : }
|