1 /*-------------------------------------------------------------------------
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
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 it's use.
22 *-------------------------------------------------------------------------
25 #include "pg_backup_archiver.h"
27 #include <unistd.h> /* for dup */
29 #include "libpq/libpq-fs.h"
32 static size_t _WriteData(ArchiveHandle
*AH
, const void *data
, size_t dLen
);
33 static size_t _WriteBlobData(ArchiveHandle
*AH
, const void *data
, size_t dLen
);
34 static void _EndData(ArchiveHandle
*AH
, TocEntry
*te
);
35 static int _WriteByte(ArchiveHandle
*AH
, const int i
);
36 static size_t _WriteBuf(ArchiveHandle
*AH
, const void *buf
, size_t len
);
37 static void _CloseArchive(ArchiveHandle
*AH
);
38 static void _PrintTocData(ArchiveHandle
*AH
, TocEntry
*te
, RestoreOptions
*ropt
);
39 static void _StartBlobs(ArchiveHandle
*AH
, TocEntry
*te
);
40 static void _StartBlob(ArchiveHandle
*AH
, TocEntry
*te
, Oid oid
);
41 static void _EndBlob(ArchiveHandle
*AH
, TocEntry
*te
, Oid oid
);
42 static void _EndBlobs(ArchiveHandle
*AH
, TocEntry
*te
);
49 InitArchiveFmt_Null(ArchiveHandle
*AH
)
51 /* Assuming static functions, this can be copied for each format. */
52 AH
->WriteDataPtr
= _WriteData
;
53 AH
->EndDataPtr
= _EndData
;
54 AH
->WriteBytePtr
= _WriteByte
;
55 AH
->WriteBufPtr
= _WriteBuf
;
56 AH
->ClosePtr
= _CloseArchive
;
57 AH
->PrintTocDataPtr
= _PrintTocData
;
59 AH
->StartBlobsPtr
= _StartBlobs
;
60 AH
->StartBlobPtr
= _StartBlob
;
61 AH
->EndBlobPtr
= _EndBlob
;
62 AH
->EndBlobsPtr
= _EndBlobs
;
64 /* Initialize LO buffering */
65 AH
->lo_buf_size
= LOBBUFSIZE
;
66 AH
->lo_buf
= (void *) malloc(LOBBUFSIZE
);
67 if (AH
->lo_buf
== NULL
)
68 die_horribly(AH
, NULL
, "out of memory\n");
71 * Now prevent reading...
73 if (AH
->mode
== archModeRead
)
74 die_horribly(AH
, NULL
, "this format cannot be read\n");
78 * - Start a new TOC entry
82 * Called by dumper via archiver from within a data dump routine
85 _WriteData(ArchiveHandle
*AH
, const void *data
, size_t dLen
)
87 /* Just send it to output */
88 ahwrite(data
, 1, dLen
, AH
);
93 * Called by dumper via archiver from within a data dump routine
94 * We substitute this for _WriteData while emitting a BLOB
97 _WriteBlobData(ArchiveHandle
*AH
, const void *data
, size_t dLen
)
104 str
= PQescapeBytea((const unsigned char *) data
, dLen
, &len
);
106 die_horribly(AH
, NULL
, "out of memory\n");
108 ahprintf(AH
, "SELECT lowrite(0, '%s');\n", str
);
116 _EndData(ArchiveHandle
*AH
, TocEntry
*te
)
118 ahprintf(AH
, "\n\n");
122 * Called by the archiver when starting to save all BLOB DATA (not schema).
123 * This routine should save whatever format-specific information is needed
124 * to read the BLOBs back into memory.
126 * It is called just prior to the dumper's DataDumper routine.
128 * Optional, but strongly recommended.
131 _StartBlobs(ArchiveHandle
*AH
, TocEntry
*te
)
133 ahprintf(AH
, "BEGIN;\n\n");
137 * Called by the archiver when the dumper calls StartBlob.
141 * Must save the passed OID for retrieval at restore-time.
144 _StartBlob(ArchiveHandle
*AH
, TocEntry
*te
, Oid oid
)
147 die_horribly(AH
, NULL
, "invalid OID for large object\n");
149 ahprintf(AH
, "SELECT lo_open(lo_create(%u), %d);\n", oid
, INV_WRITE
);
151 AH
->WriteDataPtr
= _WriteBlobData
;
155 * Called by the archiver when the dumper calls EndBlob.
160 _EndBlob(ArchiveHandle
*AH
, TocEntry
*te
, Oid oid
)
162 AH
->WriteDataPtr
= _WriteData
;
164 ahprintf(AH
, "SELECT lo_close(0);\n\n");
168 * Called by the archiver when finishing saving all BLOB DATA.
173 _EndBlobs(ArchiveHandle
*AH
, TocEntry
*te
)
175 ahprintf(AH
, "COMMIT;\n\n");
179 * Called as part of a RestoreArchive call; for the NULL archive, this
180 * just sends the data for a given TOC entry to the output.
184 _PrintTocData(ArchiveHandle
*AH
, TocEntry
*te
, RestoreOptions
*ropt
)
190 if (strcmp(te
->desc
, "BLOBS") == 0)
193 (*te
->dataDumper
) ((Archive
*) AH
, te
->dataDumperArg
);
195 if (strcmp(te
->desc
, "BLOBS") == 0)
203 _WriteByte(ArchiveHandle
*AH
, const int i
)
205 /* Don't do anything */
210 _WriteBuf(ArchiveHandle
*AH
, const void *buf
, size_t len
)
212 /* Don't do anything */
217 _CloseArchive(ArchiveHandle
*AH
)