]> granicus.if.org Git - postgresql/blob - src/bin/pg_dump/pg_backup_null.c
Create libpgcommon, and move pg_malloc et al to it
[postgresql] / src / bin / pg_dump / pg_backup_null.c
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 it's use.
17  *
18  *
19  * IDENTIFICATION
20  *              src/bin/pg_dump/pg_backup_null.c
21  *
22  *-------------------------------------------------------------------------
23  */
24
25 #include "pg_backup_archiver.h"
26 #include "dumputils.h"
27
28 #include <unistd.h>                             /* for dup */
29
30 #include "libpq/libpq-fs.h"
31
32
33 static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
34 static size_t _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen);
35 static void _EndData(ArchiveHandle *AH, TocEntry *te);
36 static int      _WriteByte(ArchiveHandle *AH, const int i);
37 static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
38 static void _CloseArchive(ArchiveHandle *AH);
39 static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
40 static void _StartBlobs(ArchiveHandle *AH, TocEntry *te);
41 static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid);
42 static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid);
43 static void _EndBlobs(ArchiveHandle *AH, TocEntry *te);
44
45
46 /*
47  *      Initializer
48  */
49 void
50 InitArchiveFmt_Null(ArchiveHandle *AH)
51 {
52         /* Assuming static functions, this can be copied for each format. */
53         AH->WriteDataPtr = _WriteData;
54         AH->EndDataPtr = _EndData;
55         AH->WriteBytePtr = _WriteByte;
56         AH->WriteBufPtr = _WriteBuf;
57         AH->ClosePtr = _CloseArchive;
58         AH->ReopenPtr = NULL;
59         AH->PrintTocDataPtr = _PrintTocData;
60
61         AH->StartBlobsPtr = _StartBlobs;
62         AH->StartBlobPtr = _StartBlob;
63         AH->EndBlobPtr = _EndBlob;
64         AH->EndBlobsPtr = _EndBlobs;
65         AH->ClonePtr = NULL;
66         AH->DeClonePtr = NULL;
67
68         /* Initialize LO buffering */
69         AH->lo_buf_size = LOBBUFSIZE;
70         AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
71
72         /*
73          * Now prevent reading...
74          */
75         if (AH->mode == archModeRead)
76                 exit_horribly(NULL, "this format cannot be read\n");
77 }
78
79 /*
80  * - Start a new TOC entry
81  */
82
83 /*
84  * Called by dumper via archiver from within a data dump routine
85  */
86 static size_t
87 _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
88 {
89         /* Just send it to output */
90         ahwrite(data, 1, dLen, AH);
91         return dLen;
92 }
93
94 /*
95  * Called by dumper via archiver from within a data dump routine
96  * We substitute this for _WriteData while emitting a BLOB
97  */
98 static size_t
99 _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
100 {
101         if (dLen > 0)
102         {
103                 PQExpBuffer buf = createPQExpBuffer();
104
105                 appendByteaLiteralAHX(buf,
106                                                           (const unsigned char *) data,
107                                                           dLen,
108                                                           AH);
109
110                 ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
111
112                 destroyPQExpBuffer(buf);
113         }
114         return dLen;
115 }
116
117 static void
118 _EndData(ArchiveHandle *AH, TocEntry *te)
119 {
120         ahprintf(AH, "\n\n");
121 }
122
123 /*
124  * Called by the archiver when starting to save all BLOB DATA (not schema).
125  * This routine should save whatever format-specific information is needed
126  * to read the BLOBs back into memory.
127  *
128  * It is called just prior to the dumper's DataDumper routine.
129  *
130  * Optional, but strongly recommended.
131  */
132 static void
133 _StartBlobs(ArchiveHandle *AH, TocEntry *te)
134 {
135         ahprintf(AH, "BEGIN;\n\n");
136 }
137
138 /*
139  * Called by the archiver when the dumper calls StartBlob.
140  *
141  * Mandatory.
142  *
143  * Must save the passed OID for retrieval at restore-time.
144  */
145 static void
146 _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
147 {
148         bool            old_blob_style = (AH->version < K_VERS_1_12);
149
150         if (oid == 0)
151                 exit_horribly(NULL, "invalid OID for large object\n");
152
153         /* With an old archive we must do drop and create logic here */
154         if (old_blob_style && AH->ropt->dropSchema)
155                 DropBlobIfExists(AH, oid);
156
157         if (old_blob_style)
158                 ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
159                                  oid, INV_WRITE);
160         else
161                 ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n",
162                                  oid, INV_WRITE);
163
164         AH->WriteDataPtr = _WriteBlobData;
165 }
166
167 /*
168  * Called by the archiver when the dumper calls EndBlob.
169  *
170  * Optional.
171  */
172 static void
173 _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
174 {
175         AH->WriteDataPtr = _WriteData;
176
177         ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
178 }
179
180 /*
181  * Called by the archiver when finishing saving all BLOB DATA.
182  *
183  * Optional.
184  */
185 static void
186 _EndBlobs(ArchiveHandle *AH, TocEntry *te)
187 {
188         ahprintf(AH, "COMMIT;\n\n");
189 }
190
191 /*------
192  * Called as part of a RestoreArchive call; for the NULL archive, this
193  * just sends the data for a given TOC entry to the output.
194  *------
195  */
196 static void
197 _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
198 {
199         if (te->dataDumper)
200         {
201                 AH->currToc = te;
202
203                 if (strcmp(te->desc, "BLOBS") == 0)
204                         _StartBlobs(AH, te);
205
206                 (*te->dataDumper) ((Archive *) AH, te->dataDumperArg);
207
208                 if (strcmp(te->desc, "BLOBS") == 0)
209                         _EndBlobs(AH, te);
210
211                 AH->currToc = NULL;
212         }
213 }
214
215 static int
216 _WriteByte(ArchiveHandle *AH, const int i)
217 {
218         /* Don't do anything */
219         return 0;
220 }
221
222 static size_t
223 _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
224 {
225         /* Don't do anything */
226         return len;
227 }
228
229 static void
230 _CloseArchive(ArchiveHandle *AH)
231 {
232         /* Nothing to do */
233 }