mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-04 00:02:52 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			296 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			296 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* -------------------------------------------------------------------------
 | 
						|
 * pg_dumplo
 | 
						|
 *
 | 
						|
 * $PostgreSQL: pgsql/contrib/pg_dumplo/main.c,v 1.19 2003/11/29 19:51:35 pgsql Exp $
 | 
						|
 *
 | 
						|
 *					Karel Zak 1999-2000
 | 
						|
 * -------------------------------------------------------------------------
 | 
						|
 */
 | 
						|
 | 
						|
#include "postgres_fe.h"
 | 
						|
 | 
						|
#include <errno.h>
 | 
						|
#include <unistd.h>
 | 
						|
 | 
						|
#include "libpq-fe.h"
 | 
						|
#include "libpq/libpq-fs.h"
 | 
						|
 | 
						|
#include "pg_dumplo.h"
 | 
						|
 | 
						|
#ifndef HAVE_STRDUP
 | 
						|
#include "strdup.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#include "getopt_long.h"
 | 
						|
 | 
						|
#ifndef HAVE_OPTRESET
 | 
						|
int			optreset;
 | 
						|
#endif
 | 
						|
 | 
						|
char	   *progname = NULL;
 | 
						|
 | 
						|
int			main(int argc, char **argv);
 | 
						|
static void usage(void);
 | 
						|
static void parse_lolist(LODumpMaster * pgLO);
 | 
						|
 | 
						|
 | 
						|
/*-----
 | 
						|
 *	The mother of all C functions
 | 
						|
 *-----
 | 
						|
 */
 | 
						|
int
 | 
						|
main(int argc, char **argv)
 | 
						|
{
 | 
						|
	LODumpMaster _pgLO,
 | 
						|
			   *pgLO = &_pgLO;
 | 
						|
	char	   *pwd = NULL;
 | 
						|
 | 
						|
	pgLO->argv = argv;
 | 
						|
	pgLO->argc = argc;
 | 
						|
	pgLO->action = 0;
 | 
						|
	pgLO->lolist = NULL;
 | 
						|
	pgLO->user = NULL;
 | 
						|
	pgLO->db = NULL;
 | 
						|
	pgLO->host = NULL;
 | 
						|
	pgLO->port = NULL;
 | 
						|
	pgLO->space = NULL;
 | 
						|
	pgLO->index = NULL;
 | 
						|
	pgLO->remove = FALSE;
 | 
						|
	pgLO->quiet = FALSE;
 | 
						|
	pgLO->counter = 0;
 | 
						|
	pgLO->lolist_start = 0;
 | 
						|
 | 
						|
	progname = argv[0];
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Parse ARGV
 | 
						|
	 */
 | 
						|
	if (argc > 1)
 | 
						|
	{
 | 
						|
		int			arg;
 | 
						|
		extern int	optind;
 | 
						|
		int			l_index = 0;
 | 
						|
		static struct option l_opt[] = {
 | 
						|
			{"help", no_argument, 0, 'h'},
 | 
						|
			{"user", required_argument, 0, 'u'},
 | 
						|
			{"pwd", required_argument, 0, 'p'},
 | 
						|
			{"db", required_argument, 0, 'd'},
 | 
						|
			{"host", required_argument, 0, 'h'},
 | 
						|
			{"port", required_argument, 0, 'o'},
 | 
						|
			{"space", required_argument, 0, 's'},
 | 
						|
			{"import", no_argument, 0, 'i'},
 | 
						|
			{"export", no_argument, 0, 'e'},
 | 
						|
			{"remove", no_argument, 0, 'r'},
 | 
						|
			{"quiet", no_argument, 0, 'q'},
 | 
						|
			{"all", no_argument, 0, 'a'},
 | 
						|
			{"show", no_argument, 0, 'w'},
 | 
						|
			{NULL, 0, 0, 0}
 | 
						|
		};
 | 
						|
 | 
						|
		while ((arg = getopt_long(argc, argv, "?aeho:u:p:qd:l:t:irs:w", l_opt, &l_index)) != -1)
 | 
						|
		{
 | 
						|
			switch (arg)
 | 
						|
			{
 | 
						|
				case '?':
 | 
						|
				case 'h':
 | 
						|
					usage();
 | 
						|
					exit(RE_OK);
 | 
						|
				case 'u':
 | 
						|
					pgLO->user = strdup(optarg);
 | 
						|
					break;
 | 
						|
				case 't':
 | 
						|
					pgLO->host = strdup(optarg);
 | 
						|
					break;
 | 
						|
				case 'o':
 | 
						|
					pgLO->port = strdup(optarg);
 | 
						|
					break;
 | 
						|
				case 'p':
 | 
						|
					pwd = strdup(optarg);
 | 
						|
					break;
 | 
						|
				case 'd':
 | 
						|
					pgLO->db = strdup(optarg);
 | 
						|
					break;
 | 
						|
				case 's':
 | 
						|
					pgLO->space = strdup(optarg);
 | 
						|
					break;
 | 
						|
				case 'i':
 | 
						|
					pgLO->action = ACTION_IMPORT;
 | 
						|
					break;
 | 
						|
				case 'l':
 | 
						|
					pgLO->action = ACTION_EXPORT_ATTR;
 | 
						|
					pgLO->lolist_start = optind - 1;
 | 
						|
					parse_lolist(pgLO);
 | 
						|
					break;
 | 
						|
				case 'e':
 | 
						|
				case 'a':
 | 
						|
					pgLO->action = ACTION_EXPORT_ALL;
 | 
						|
					break;
 | 
						|
				case 'w':
 | 
						|
					pgLO->action = ACTION_SHOW;
 | 
						|
					break;
 | 
						|
				case 'r':
 | 
						|
					pgLO->remove = TRUE;
 | 
						|
					break;
 | 
						|
				case 'q':
 | 
						|
					pgLO->quiet = TRUE;
 | 
						|
					break;
 | 
						|
				default:
 | 
						|
					fprintf(stderr, "%s: bad arg -%c\n", progname, arg);
 | 
						|
					usage();
 | 
						|
					exit(RE_ERROR);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		usage();
 | 
						|
		exit(RE_ERROR);
 | 
						|
	}
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Check space
 | 
						|
	 */
 | 
						|
	if (!pgLO->space && !pgLO->action == ACTION_SHOW)
 | 
						|
	{
 | 
						|
		if (!(pgLO->space = getenv("PWD")))
 | 
						|
		{
 | 
						|
			fprintf(stderr, "%s: not set space for dump-tree (option '-s' or $PWD).\n", progname);
 | 
						|
			exit(RE_ERROR);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if (!pgLO->action)
 | 
						|
	{
 | 
						|
		fprintf(stderr, "%s: What do you want - export or import?\n", progname);
 | 
						|
		exit(RE_ERROR);
 | 
						|
	}
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Make connection
 | 
						|
	 */
 | 
						|
	pgLO->conn = PQsetdbLogin(pgLO->host, pgLO->port, NULL, NULL, pgLO->db,
 | 
						|
							  pgLO->user, pwd);
 | 
						|
 | 
						|
	if (PQstatus(pgLO->conn) == CONNECTION_BAD)
 | 
						|
	{
 | 
						|
		fprintf(stderr, "%s (connection): %s\n", progname, PQerrorMessage(pgLO->conn));
 | 
						|
		exit(RE_ERROR);
 | 
						|
	}
 | 
						|
	pgLO->host = PQhost(pgLO->conn) ? PQhost(pgLO->conn) : "localhost";
 | 
						|
	pgLO->db = PQdb(pgLO->conn);
 | 
						|
	pgLO->user = PQuser(pgLO->conn);
 | 
						|
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Init index file
 | 
						|
	 */
 | 
						|
	if (pgLO->action != ACTION_SHOW)
 | 
						|
		index_file(pgLO);
 | 
						|
 | 
						|
	PQexec(pgLO->conn, "SET search_path = public");
 | 
						|
 | 
						|
	PQexec(pgLO->conn, "BEGIN");
 | 
						|
 | 
						|
	switch (pgLO->action)
 | 
						|
	{
 | 
						|
 | 
						|
		case ACTION_SHOW:
 | 
						|
		case ACTION_EXPORT_ALL:
 | 
						|
			load_lolist(pgLO);
 | 
						|
			/* FALL THROUGH */
 | 
						|
 | 
						|
		case ACTION_EXPORT_ATTR:
 | 
						|
			pglo_export(pgLO);
 | 
						|
			if (!pgLO->quiet)
 | 
						|
			{
 | 
						|
				if (pgLO->action == ACTION_SHOW)
 | 
						|
					printf("\nDatabase '%s' contains %d large objects.\n\n", pgLO->db, pgLO->counter);
 | 
						|
				else
 | 
						|
					printf("\nExported %d large objects.\n\n", pgLO->counter);
 | 
						|
			}
 | 
						|
			break;
 | 
						|
 | 
						|
		case ACTION_IMPORT:
 | 
						|
			pglo_import(pgLO);
 | 
						|
			if (!pgLO->quiet)
 | 
						|
				printf("\nImported %d large objects.\n\n", pgLO->counter);
 | 
						|
			break;
 | 
						|
	}
 | 
						|
 | 
						|
	PQexec(pgLO->conn, "COMMIT");
 | 
						|
	PQfinish(pgLO->conn);
 | 
						|
 | 
						|
	if (pgLO->action != ACTION_SHOW)
 | 
						|
		fclose(pgLO->index);
 | 
						|
 | 
						|
	exit(RE_OK);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
parse_lolist(LODumpMaster * pgLO)
 | 
						|
{
 | 
						|
	LOlist	   *ll;
 | 
						|
	char	  **d,
 | 
						|
			   *loc,
 | 
						|
				buff[MAX_TABLE_NAME + MAX_ATTR_NAME + 1];
 | 
						|
 | 
						|
	pgLO->lolist = (LOlist *) malloc(pgLO->argc * sizeof(LOlist));
 | 
						|
 | 
						|
	if (!pgLO->lolist)
 | 
						|
	{
 | 
						|
		fprintf(stderr, "%s: can't allocate memory\n", progname);
 | 
						|
		exit(RE_ERROR);
 | 
						|
	}
 | 
						|
 | 
						|
	for (d = pgLO->argv + pgLO->lolist_start, ll = pgLO->lolist;
 | 
						|
		 *d != NULL;
 | 
						|
		 d++, ll++)
 | 
						|
	{
 | 
						|
 | 
						|
		strncpy(buff, *d, MAX_TABLE_NAME + MAX_ATTR_NAME);
 | 
						|
 | 
						|
		if ((loc = strchr(buff, '.')) == NULL)
 | 
						|
		{
 | 
						|
			fprintf(stderr, "%s: '%s' is bad 'table.attr'\n", progname, buff);
 | 
						|
			exit(RE_ERROR);
 | 
						|
		}
 | 
						|
		*loc = '\0';
 | 
						|
		ll->lo_table = strdup(buff);
 | 
						|
		ll->lo_attr = strdup(++loc);
 | 
						|
	}
 | 
						|
	ll++;
 | 
						|
	ll->lo_table = ll->lo_attr = (char *) NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
usage()
 | 
						|
{
 | 
						|
	printf("\npg_dumplo %s - PostgreSQL large objects dump\n", PG_VERSION);
 | 
						|
	puts("pg_dumplo [option]\n\n"
 | 
						|
		 "-h --help                    this help\n"
 | 
						|
	   "-u --user=<username>         username for connection to server\n"
 | 
						|
	   "-p --password=<password>     password for connection to server\n"
 | 
						|
		 "-d --db=<database>           database name\n"
 | 
						|
		 "-t --host=<hostname>         server hostname\n"
 | 
						|
	"-o --port=<port>             database server port (default: 5432)\n"
 | 
						|
		 "-s --space=<dir>             directory with dump tree (for export/import)\n"
 | 
						|
		 "-i --import                  import large obj dump tree to DB\n"
 | 
						|
	"-e --export                  export (dump) large obj to dump tree\n"
 | 
						|
		 "-l <table.attr ...>          dump attribute (columns) with LO to dump tree\n"
 | 
						|
		 "-a --all                     dump all LO in DB (default)\n"
 | 
						|
		 "-r --remove                  if is set '-i' try remove old LO\n"
 | 
						|
		 "-q --quiet                   run quietly\n"
 | 
						|
		 "-w --show                    not dump, but show all LO in DB\n"
 | 
						|
		 "\n"
 | 
						|
		 "Example (dump):   pg_dumplo -d my_db -s /my_dump/dir -l t1.a t1.b t2.a\n"
 | 
						|
		 "                  pg_dumplo -a -d my_db -s /my_dump/dir\n"
 | 
						|
		 "Example (import): pg_dumplo -i -d my_db -s /my_dump/dir\n"
 | 
						|
		 "Example (show):   pg_dumplo -w -d my_db\n\n"
 | 
						|
		 "Note:  * option '-l' must be last option!\n"
 | 
						|
	"       * option '-i' without option '-r' make new large obj in DB\n"
 | 
						|
		 "         not rewrite old, the '-i' UPDATE oid numbers in table.attr only!\n"
 | 
						|
		 "       * if option -s is not set, pg_dumplo uses $PWD\n"
 | 
						|
		);						/* puts() */
 | 
						|
}
 |