00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "pg_backup_archiver.h"
00026 #include "pg_backup_utils.h"
00027 #include "parallel.h"
00028
00029 #include <unistd.h>
00030
00031 #include "libpq/libpq-fs.h"
00032
00033
00034 static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
00035 static size_t _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen);
00036 static void _EndData(ArchiveHandle *AH, TocEntry *te);
00037 static int _WriteByte(ArchiveHandle *AH, const int i);
00038 static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
00039 static void _CloseArchive(ArchiveHandle *AH);
00040 static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
00041 static void _StartBlobs(ArchiveHandle *AH, TocEntry *te);
00042 static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid);
00043 static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid);
00044 static void _EndBlobs(ArchiveHandle *AH, TocEntry *te);
00045
00046
00047
00048
00049
00050 void
00051 InitArchiveFmt_Null(ArchiveHandle *AH)
00052 {
00053
00054 AH->WriteDataPtr = _WriteData;
00055 AH->EndDataPtr = _EndData;
00056 AH->WriteBytePtr = _WriteByte;
00057 AH->WriteBufPtr = _WriteBuf;
00058 AH->ClosePtr = _CloseArchive;
00059 AH->ReopenPtr = NULL;
00060 AH->PrintTocDataPtr = _PrintTocData;
00061
00062 AH->StartBlobsPtr = _StartBlobs;
00063 AH->StartBlobPtr = _StartBlob;
00064 AH->EndBlobPtr = _EndBlob;
00065 AH->EndBlobsPtr = _EndBlobs;
00066 AH->ClonePtr = NULL;
00067 AH->DeClonePtr = NULL;
00068
00069
00070 AH->lo_buf_size = LOBBUFSIZE;
00071 AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
00072
00073
00074
00075
00076 if (AH->mode == archModeRead)
00077 exit_horribly(NULL, "this format cannot be read\n");
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087 static size_t
00088 _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
00089 {
00090
00091 ahwrite(data, 1, dLen, AH);
00092 return dLen;
00093 }
00094
00095
00096
00097
00098
00099 static size_t
00100 _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
00101 {
00102 if (dLen > 0)
00103 {
00104 PQExpBuffer buf = createPQExpBuffer();
00105
00106 appendByteaLiteralAHX(buf,
00107 (const unsigned char *) data,
00108 dLen,
00109 AH);
00110
00111 ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
00112
00113 destroyPQExpBuffer(buf);
00114 }
00115 return dLen;
00116 }
00117
00118 static void
00119 _EndData(ArchiveHandle *AH, TocEntry *te)
00120 {
00121 ahprintf(AH, "\n\n");
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 static void
00134 _StartBlobs(ArchiveHandle *AH, TocEntry *te)
00135 {
00136 ahprintf(AH, "BEGIN;\n\n");
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 static void
00147 _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
00148 {
00149 bool old_blob_style = (AH->version < K_VERS_1_12);
00150
00151 if (oid == 0)
00152 exit_horribly(NULL, "invalid OID for large object\n");
00153
00154
00155 if (old_blob_style && AH->ropt->dropSchema)
00156 DropBlobIfExists(AH, oid);
00157
00158 if (old_blob_style)
00159 ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
00160 oid, INV_WRITE);
00161 else
00162 ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n",
00163 oid, INV_WRITE);
00164
00165 AH->WriteDataPtr = _WriteBlobData;
00166 }
00167
00168
00169
00170
00171
00172
00173 static void
00174 _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
00175 {
00176 AH->WriteDataPtr = _WriteData;
00177
00178 ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
00179 }
00180
00181
00182
00183
00184
00185
00186 static void
00187 _EndBlobs(ArchiveHandle *AH, TocEntry *te)
00188 {
00189 ahprintf(AH, "COMMIT;\n\n");
00190 }
00191
00192
00193
00194
00195
00196
00197 static void
00198 _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
00199 {
00200 if (te->dataDumper)
00201 {
00202 AH->currToc = te;
00203
00204 if (strcmp(te->desc, "BLOBS") == 0)
00205 _StartBlobs(AH, te);
00206
00207 (*te->dataDumper) ((Archive *) AH, te->dataDumperArg);
00208
00209 if (strcmp(te->desc, "BLOBS") == 0)
00210 _EndBlobs(AH, te);
00211
00212 AH->currToc = NULL;
00213 }
00214 }
00215
00216 static int
00217 _WriteByte(ArchiveHandle *AH, const int i)
00218 {
00219
00220 return 0;
00221 }
00222
00223 static size_t
00224 _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
00225 {
00226
00227 return len;
00228 }
00229
00230 static void
00231 _CloseArchive(ArchiveHandle *AH)
00232 {
00233
00234 }