diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 13:44:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 13:44:03 +0000 |
commit | 293913568e6a7a86fd1479e1cff8e2ecb58d6568 (patch) | |
tree | fc3b469a3ec5ab71b36ea97cc7aaddb838423a0c /src/bin/pg_dump/pg_backup_null.c | |
parent | Initial commit. (diff) | |
download | postgresql-16-293913568e6a7a86fd1479e1cff8e2ecb58d6568.tar.xz postgresql-16-293913568e6a7a86fd1479e1cff8e2ecb58d6568.zip |
Adding upstream version 16.2.upstream/16.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bin/pg_dump/pg_backup_null.c')
-rw-r--r-- | src/bin/pg_dump/pg_backup_null.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c new file mode 100644 index 0000000..08f0962 --- /dev/null +++ b/src/bin/pg_dump/pg_backup_null.c @@ -0,0 +1,228 @@ +/*------------------------------------------------------------------------- + * + * pg_backup_null.c + * + * Implementation of an archive that is never saved; it is used by + * pg_dump to output a plain text SQL script instead of saving + * a real archive. + * + * See the headers to pg_restore for more details. + * + * Copyright (c) 2000, Philip Warner + * Rights are granted to use this software in any way so long + * as this notice is not removed. + * + * The author is not responsible for loss or damages that may + * result from its use. + * + * + * IDENTIFICATION + * src/bin/pg_dump/pg_backup_null.c + * + *------------------------------------------------------------------------- + */ +#include "postgres_fe.h" + +#include "fe_utils/string_utils.h" +#include "libpq/libpq-fs.h" +#include "pg_backup_archiver.h" +#include "pg_backup_utils.h" + +static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen); +static void _WriteLOData(ArchiveHandle *AH, const void *data, size_t dLen); +static void _EndData(ArchiveHandle *AH, TocEntry *te); +static int _WriteByte(ArchiveHandle *AH, const int i); +static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len); +static void _CloseArchive(ArchiveHandle *AH); +static void _PrintTocData(ArchiveHandle *AH, TocEntry *te); +static void _StartLOs(ArchiveHandle *AH, TocEntry *te); +static void _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid); +static void _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid); +static void _EndLOs(ArchiveHandle *AH, TocEntry *te); + + +/* + * Initializer + */ +void +InitArchiveFmt_Null(ArchiveHandle *AH) +{ + /* Assuming static functions, this can be copied for each format. */ + AH->WriteDataPtr = _WriteData; + AH->EndDataPtr = _EndData; + AH->WriteBytePtr = _WriteByte; + AH->WriteBufPtr = _WriteBuf; + AH->ClosePtr = _CloseArchive; + AH->ReopenPtr = NULL; + AH->PrintTocDataPtr = _PrintTocData; + + AH->StartLOsPtr = _StartLOs; + AH->StartLOPtr = _StartLO; + AH->EndLOPtr = _EndLO; + AH->EndLOsPtr = _EndLOs; + AH->ClonePtr = NULL; + AH->DeClonePtr = NULL; + + /* Initialize LO buffering */ + AH->lo_buf_size = LOBBUFSIZE; + AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE); + + /* + * Now prevent reading... + */ + if (AH->mode == archModeRead) + pg_fatal("this format cannot be read"); +} + +/* + * - Start a new TOC entry + */ + +/* + * Called by dumper via archiver from within a data dump routine + */ +static void +_WriteData(ArchiveHandle *AH, const void *data, size_t dLen) +{ + /* Just send it to output, ahwrite() already errors on failure */ + ahwrite(data, 1, dLen, AH); +} + +/* + * Called by dumper via archiver from within a data dump routine + * We substitute this for _WriteData while emitting a LO + */ +static void +_WriteLOData(ArchiveHandle *AH, const void *data, size_t dLen) +{ + if (dLen > 0) + { + PQExpBuffer buf = createPQExpBuffer(); + + appendByteaLiteralAHX(buf, + (const unsigned char *) data, + dLen, + AH); + + ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data); + + destroyPQExpBuffer(buf); + } +} + +static void +_EndData(ArchiveHandle *AH, TocEntry *te) +{ + ahprintf(AH, "\n\n"); +} + +/* + * Called by the archiver when starting to save all BLOB DATA (not schema). + * This routine should save whatever format-specific information is needed + * to read the LOs back into memory. + * + * It is called just prior to the dumper's DataDumper routine. + * + * Optional, but strongly recommended. + */ +static void +_StartLOs(ArchiveHandle *AH, TocEntry *te) +{ + ahprintf(AH, "BEGIN;\n\n"); +} + +/* + * Called by the archiver when the dumper calls StartLO. + * + * Mandatory. + * + * Must save the passed OID for retrieval at restore-time. + */ +static void +_StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid) +{ + bool old_lo_style = (AH->version < K_VERS_1_12); + + if (oid == 0) + pg_fatal("invalid OID for large object"); + + /* With an old archive we must do drop and create logic here */ + if (old_lo_style && AH->public.ropt->dropSchema) + DropLOIfExists(AH, oid); + + if (old_lo_style) + ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n", + oid, INV_WRITE); + else + ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n", + oid, INV_WRITE); + + AH->WriteDataPtr = _WriteLOData; +} + +/* + * Called by the archiver when the dumper calls EndLO. + * + * Optional. + */ +static void +_EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid) +{ + AH->WriteDataPtr = _WriteData; + + ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n"); +} + +/* + * Called by the archiver when finishing saving all BLOB DATA. + * + * Optional. + */ +static void +_EndLOs(ArchiveHandle *AH, TocEntry *te) +{ + ahprintf(AH, "COMMIT;\n\n"); +} + +/*------ + * Called as part of a RestoreArchive call; for the NULL archive, this + * just sends the data for a given TOC entry to the output. + *------ + */ +static void +_PrintTocData(ArchiveHandle *AH, TocEntry *te) +{ + if (te->dataDumper) + { + AH->currToc = te; + + if (strcmp(te->desc, "BLOBS") == 0) + _StartLOs(AH, te); + + te->dataDumper((Archive *) AH, te->dataDumperArg); + + if (strcmp(te->desc, "BLOBS") == 0) + _EndLOs(AH, te); + + AH->currToc = NULL; + } +} + +static int +_WriteByte(ArchiveHandle *AH, const int i) +{ + /* Don't do anything */ + return 0; +} + +static void +_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len) +{ + /* Don't do anything */ +} + +static void +_CloseArchive(ArchiveHandle *AH) +{ + /* Nothing to do */ +} |