aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/pg_backup_archiver.h
blob: fdf70f716f70938b991b4b86d89091a2b23512e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*-------------------------------------------------------------------------
 *
 * pg_backup_archiver.h
 *
 *	Private interface to the pg_dump archiver routines.
 *	It is NOT intended that these routines be called by any 
 *	dumper directly.
 *
 *	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 it's use.
 *
 *
 * IDENTIFICATION
 *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.26 2001/03/19 02:35:28 pjw Exp $
 *
 * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
 *
 *		Initial version. 
 *
 * Modifications - 15-Sep-2000 - pjw@rhyme.com.au
 *	-	Added braceDepth to sqlparseInfo to handle braces in rule definitions.
 *
 *-------------------------------------------------------------------------
 */

#ifndef __PG_BACKUP_ARCHIVE__
#define __PG_BACKUP_ARCHIVE__

#include "postgres_fe.h"

#include <time.h>

#include "pqexpbuffer.h"

#ifdef HAVE_LIBZ
#include <zlib.h>
#define GZCLOSE(fh) gzclose(fh)
#define GZWRITE(p, s, n, fh) gzwrite(fh, p, n * s)
#define GZREAD(p, s, n, fh) gzread(fh, p, n * s)
#else
#define GZCLOSE(fh) fclose(fh)
#define GZWRITE(p, s, n, fh) (fwrite(p, s, n, fh) * s)
#define GZREAD(p, s, n, fh) fread(p, s, n, fh)
#define Z_DEFAULT_COMPRESSION -1

typedef struct _z_stream {
    void	*next_in;
    void	*next_out;
    int		avail_in;
    int		avail_out;
} z_stream;
typedef z_stream *z_streamp;
#endif

#include "pg_backup.h"
#include "libpq-fe.h"

#define K_VERS_MAJOR 1
#define K_VERS_MINOR 4 
#define K_VERS_REV 30 

/* Data block types */
#define BLK_DATA 1
#define BLK_BLOB 2
#define BLK_BLOBS 3

/* Some important version numbers (checked in code) */
#define K_VERS_1_0 (( (1 * 256 + 0) * 256 + 0) * 256 + 0)
#define K_VERS_1_2 (( (1 * 256 + 2) * 256 + 0) * 256 + 0) /* Allow No ZLIB */
#define K_VERS_1_3 (( (1 * 256 + 3) * 256 + 0) * 256 + 0) /* BLOBs */
#define K_VERS_1_4 (( (1 * 256 + 4) * 256 + 0) * 256 + 0) /* Date & name in header */
#define K_VERS_MAX (( (1 * 256 + 4) * 256 + 255) * 256 + 0)

/* No of BLOBs to restore in 1 TX */
#define BLOB_BATCH_SIZE	100

struct _archiveHandle;
struct _tocEntry;
struct _restoreList;

typedef void    (*ClosePtr)		(struct _archiveHandle* AH);
typedef void	(*ArchiveEntryPtr)	(struct _archiveHandle* AH, struct _tocEntry* te);
 
typedef void	(*StartDataPtr)		(struct _archiveHandle* AH, struct _tocEntry* te);
typedef int 	(*WriteDataPtr)		(struct _archiveHandle* AH, const void* data, int dLen);
typedef void	(*EndDataPtr)		(struct _archiveHandle* AH, struct _tocEntry* te);

typedef void	(*StartBlobsPtr)	(struct _archiveHandle* AH, struct _tocEntry* te);
typedef void    (*StartBlobPtr)		(struct _archiveHandle* AH, struct _tocEntry* te, int oid);
typedef void	(*EndBlobPtr)		(struct _archiveHandle* AH, struct _tocEntry* te, int oid);
typedef void	(*EndBlobsPtr)		(struct _archiveHandle* AH, struct _tocEntry* te);

typedef int		(*WriteBytePtr)		(struct _archiveHandle* AH, const int i);
typedef int    	(*ReadBytePtr)		(struct _archiveHandle* AH);
typedef int		(*WriteBufPtr)		(struct _archiveHandle* AH, const void* c, int len);
typedef int		(*ReadBufPtr)		(struct _archiveHandle* AH, void* buf, int len);
typedef void	(*SaveArchivePtr)	(struct _archiveHandle* AH);
typedef void 	(*WriteExtraTocPtr)	(struct _archiveHandle* AH, struct _tocEntry* te);
typedef void	(*ReadExtraTocPtr)	(struct _archiveHandle* AH, struct _tocEntry* te);
typedef void	(*PrintExtraTocPtr)	(struct _archiveHandle* AH, struct _tocEntry* te);
typedef void	(*PrintTocDataPtr)	(struct _archiveHandle* AH, struct _tocEntry* te, RestoreOptions *ropt);

typedef int		(*CustomOutPtr)		(struct _archiveHandle* AH, const void* buf, int len);

typedef int	(*TocSortCompareFn)	(const void* te1, const void *te2); 

typedef enum _archiveMode {
    archModeWrite,
    archModeRead
} ArchiveMode;

typedef struct _outputContext {
	void		*OF;
	int		gzOut;
} OutputContext;

typedef enum { 
	SQL_SCAN = 0,
	SQL_IN_SQL_COMMENT,
	SQL_IN_EXT_COMMENT,
	SQL_IN_QUOTE} sqlparseState;
	
typedef struct {
	int					backSlash;
	sqlparseState		state;
	char				lastChar;
	char				quoteChar;
	int					braceDepth;
} sqlparseInfo;

typedef struct _archiveHandle {
	Archive				public;				/* Public part of archive */
	char				vmaj;				/* Version of file */
	char				vmin;
	char				vrev;
	int					version;			/* Conveniently formatted version */

	int					debugLevel;			/* Used for logging (currently only by --verbose) */
	int					intSize;			/* Size of an integer in the archive */
	ArchiveFormat		format;				/* Archive format */

	sqlparseInfo		sqlparse;
	PQExpBuffer			sqlBuf;

	time_t				createDate;			/* Date archive created */

	/*
	 * Fields used when discovering header.
	 * A format can always get the previous read bytes from here...
	 */
	int					readHeader;			/* Used if file header has been read already */
	char				*lookahead;			/* Buffer used when reading header to discover format */
	int					lookaheadSize;		/* Size of allocated buffer */
	int					lookaheadLen;		/* Length of data in lookahead */
	int					lookaheadPos;		/* Current read position in lookahead buffer */

	ArchiveEntryPtr		ArchiveEntryPtr;	/* Called for each metadata object */
	StartDataPtr		StartDataPtr; 		/* Called when table data is about to be dumped */
	WriteDataPtr		WriteDataPtr; 		/* Called to send some table data to the archive */
	EndDataPtr			EndDataPtr; 		/* Called when table data dump is finished */
	WriteBytePtr		WriteBytePtr;		/* Write a byte to output */
	ReadBytePtr			ReadBytePtr;		/* Read a byte from an archive */
	WriteBufPtr			WriteBufPtr;		/* Write a buffer of output to the archive */
	ReadBufPtr			ReadBufPtr;			/* Read a buffer of input from the archive */
	ClosePtr			ClosePtr;			/* Close the archive */
	WriteExtraTocPtr	WriteExtraTocPtr;	/* Write extra TOC entry data associated with */
											/* the current archive format */
	ReadExtraTocPtr		ReadExtraTocPtr;	/* Read extr info associated with archie format */
	PrintExtraTocPtr	PrintExtraTocPtr;	/* Extra TOC info for format */
	PrintTocDataPtr		PrintTocDataPtr;	

	StartBlobsPtr		StartBlobsPtr;
	EndBlobsPtr			EndBlobsPtr;
	StartBlobPtr		StartBlobPtr;
	EndBlobPtr			EndBlobPtr;

	CustomOutPtr		CustomOutPtr;		/* Alternate script output routine */

	/* Stuff for direct DB connection */
	char				username[100];
	char				*dbname;			/* Name of db for connection */
	char				*archdbname;		/* DB name *read* from archive */
	char				*pghost;
	char				*pgport;
	PGconn				*connection;
	PGconn				*blobConnection;	/* Connection for BLOB xref */
	int					txActive;			/* Flag set if TX active on connection */
	int					blobTxActive;		/* Flag set if TX active on blobConnection */
	int					connectToDB;		/* Flag to indicate if direct DB connection is required */
	int					pgCopyIn;			/* Currently in libpq 'COPY IN' mode. */
	PQExpBuffer			pgCopyBuf;			/* Left-over data from incomplete lines in COPY IN */

	int					loFd;				/* BLOB fd */
	int					writingBlob;		/* Flag */
	int					createdBlobXref;	/* Flag */
	int					blobCount;			/* # of blobs restored */

	int					lastID;				/* Last internal ID for a TOC entry */
	char*				fSpec;				/* Archive File Spec */
	FILE				*FH;				/* General purpose file handle */
	void				*OF;
	int					gzOut;				/* Output file */

	struct _tocEntry*		toc;			/* List of TOC entries */
	int						tocCount;		/* Number of TOC entries */
	struct _tocEntry*		currToc; 		/* Used when dumping data */
	char					*currUser;		/* Restore: current username in script */
	int						compression;	/* Compression requested on open */
	ArchiveMode				mode;			/* File mode - r or w */
	void*					formatData;		/* Header data specific to file format */

	RestoreOptions			*ropt;			/* Used to check restore options in ahwrite etc */
} ArchiveHandle;

typedef struct _tocEntry {
	struct _tocEntry* 	prev;
	struct _tocEntry*	next;
	int					id;
	int					hadDumper;		/* Archiver was passed a dumper routine (used in restore) */
	char*				oid;
	int					oidVal;
	char*				name;
	char*				desc;
	char*				defn;
	char*				dropStmt;
	char*				copyStmt;
	char*				owner;
	char**				depOid;
	int					printed;		/* Indicates if entry defn has been dumped */
	DataDumperPtr		dataDumper;		/* Routine to dump data for object */
	void*				dataDumperArg;		/* Arg for above routine */
	void*				formatData;		/* TOC Entry data specific to file format */

	int					_moved;			/* Marker used when rearranging TOC */

} TocEntry;

/* Used everywhere */
extern void die_horribly(ArchiveHandle *AH, const char *fmt, ...);

extern void WriteTOC(ArchiveHandle* AH);
extern void ReadTOC(ArchiveHandle* AH);
extern void WriteHead(ArchiveHandle* AH);
extern void ReadHead(ArchiveHandle* AH);
extern void WriteToc(ArchiveHandle* AH);
extern void ReadToc(ArchiveHandle* AH);
extern void WriteDataChunks(ArchiveHandle* AH);

extern int TocIDRequired(ArchiveHandle* AH, int id, RestoreOptions *ropt);

/*
 * Mandatory routines for each supported format
 */

extern int 				WriteInt(ArchiveHandle* AH, int i);
extern int 				ReadInt(ArchiveHandle* AH);
extern char* 			ReadStr(ArchiveHandle* AH);
extern int 				WriteStr(ArchiveHandle* AH, char* s);

extern void				StartRestoreBlobs(ArchiveHandle* AH);
extern void 			StartRestoreBlob(ArchiveHandle* AH, int oid);
extern void 			EndRestoreBlob(ArchiveHandle* AH, int oid);
extern void				EndRestoreBlobs(ArchiveHandle* AH);

extern void 			InitArchiveFmt_Custom(ArchiveHandle* AH);
extern void 			InitArchiveFmt_Files(ArchiveHandle* AH);
extern void 			InitArchiveFmt_Null(ArchiveHandle* AH);
extern void 			InitArchiveFmt_Tar(ArchiveHandle* AH);

extern int 				isValidTarHeader(char *header);

extern OutputContext	SetOutput(ArchiveHandle* AH, char *filename, int compression);
extern void 			ResetOutput(ArchiveHandle* AH, OutputContext savedContext);
extern int 				RestoringToDB(ArchiveHandle* AH);
extern int				ReconnectDatabase(ArchiveHandle *AH, const char* dbname, char *newUser);
extern int				UserIsSuperuser(ArchiveHandle *AH, char* user);
extern char*			ConnectedUser(ArchiveHandle *AH);
extern int				ConnectedUserIsSuperuser(ArchiveHandle *AH);

int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle* AH);
int ahprintf(ArchiveHandle* AH, const char *fmt, ...);

void ahlog(ArchiveHandle* AH, int level, const char *fmt, ...);

#endif