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
;
58 AH
->PrintTocDataPtr
= _PrintTocData
;
60 AH
->StartBlobsPtr
= _StartBlobs
;
61 AH
->StartBlobPtr
= _StartBlob
;
62 AH
->EndBlobPtr
= _EndBlob
;
63 AH
->EndBlobsPtr
= _EndBlobs
;
65 AH
->DeClonePtr
= NULL
;
67 /* Initialize LO buffering */
68 AH
->lo_buf_size
= LOBBUFSIZE
;
69 AH
->lo_buf
= (void *) malloc(LOBBUFSIZE
);
70 if (AH
->lo_buf
== NULL
)
71 die_horribly(AH
, NULL
, "out of memory\n");
74 * Now prevent reading...
76 if (AH
->mode
== archModeRead
)
77 die_horribly(AH
, NULL
, "this format cannot be read\n");
81 * - Start a new TOC entry
85 * Called by dumper via archiver from within a data dump routine
88 _WriteData(ArchiveHandle
*AH
, const void *data
, size_t dLen
)
90 /* Just send it to output */
91 ahwrite(data
, 1, dLen
, AH
);
96 * Called by dumper via archiver from within a data dump routine
97 * We substitute this for _WriteData while emitting a BLOB
100 _WriteBlobData(ArchiveHandle
*AH
, const void *data
, size_t dLen
)
107 str
= PQescapeBytea((const unsigned char *) data
, dLen
, &len
);
109 die_horribly(AH
, NULL
, "out of memory\n");
111 ahprintf(AH
, "SELECT lowrite(0, '%s');\n", str
);
119 _EndData(ArchiveHandle
*AH
, TocEntry
*te
)
121 ahprintf(AH
, "\n\n");
125 * Called by the archiver when starting to save all BLOB DATA (not schema).
126 * This routine should save whatever format-specific information is needed
127 * to read the BLOBs back into memory.
129 * It is called just prior to the dumper's DataDumper routine.
131 * Optional, but strongly recommended.
134 _StartBlobs(ArchiveHandle
*AH
, TocEntry
*te
)
136 ahprintf(AH
, "BEGIN;\n\n");
140 * Called by the archiver when the dumper calls StartBlob.
144 * Must save the passed OID for retrieval at restore-time.
147 _StartBlob(ArchiveHandle
*AH
, TocEntry
*te
, Oid oid
)
150 die_horribly(AH
, NULL
, "invalid OID for large object\n");
152 ahprintf(AH
, "SELECT lo_open(lo_create(%u), %d);\n", oid
, INV_WRITE
);
154 AH
->WriteDataPtr
= _WriteBlobData
;
158 * Called by the archiver when the dumper calls EndBlob.
163 _EndBlob(ArchiveHandle
*AH
, TocEntry
*te
, Oid oid
)
165 AH
->WriteDataPtr
= _WriteData
;
167 ahprintf(AH
, "SELECT lo_close(0);\n\n");
171 * Called by the archiver when finishing saving all BLOB DATA.
176 _EndBlobs(ArchiveHandle
*AH
, TocEntry
*te
)
178 ahprintf(AH
, "COMMIT;\n\n");
182 * Called as part of a RestoreArchive call; for the NULL archive, this
183 * just sends the data for a given TOC entry to the output.
187 _PrintTocData(ArchiveHandle
*AH
, TocEntry
*te
, RestoreOptions
*ropt
)
193 if (strcmp(te
->desc
, "BLOBS") == 0)
196 (*te
->dataDumper
) ((Archive
*) AH
, te
->dataDumperArg
);
198 if (strcmp(te
->desc
, "BLOBS") == 0)
206 _WriteByte(ArchiveHandle
*AH
, const int i
)
208 /* Don't do anything */
213 _WriteBuf(ArchiveHandle
*AH
, const void *buf
, size_t len
)
215 /* Don't do anything */
220 _CloseArchive(ArchiveHandle
*AH
)