]> granicus.if.org Git - postgresql/blob - contrib/pg_dumplo/main.c
1f092743141ab096862e7c8edbf61ceb63138b75
[postgresql] / contrib / pg_dumplo / main.c
1 /* -------------------------------------------------------------------------
2  * pg_dumplo
3  *
4  * $PostgreSQL: pgsql/contrib/pg_dumplo/main.c,v 1.20 2004/10/25 02:15:00 tgl Exp $
5  *
6  *                                      Karel Zak 1999-2000
7  * -------------------------------------------------------------------------
8  */
9
10 #include "postgres_fe.h"
11
12 #include <errno.h>
13 #include <unistd.h>
14
15 #include "libpq-fe.h"
16 #include "libpq/libpq-fs.h"
17
18 #include "pg_dumplo.h"
19
20 #ifndef HAVE_STRDUP
21 #include "strdup.h"
22 #endif
23
24 #include "getopt_long.h"
25
26 #ifndef HAVE_OPTRESET
27 int                     optreset;
28 #endif
29
30 char       *progname = NULL;
31
32 int                     main(int argc, char **argv);
33 static void usage(void);
34 static void parse_lolist(LODumpMaster * pgLO);
35
36
37 /*-----
38  *      The mother of all C functions
39  *-----
40  */
41 int
42 main(int argc, char **argv)
43 {
44         LODumpMaster _pgLO,
45                            *pgLO = &_pgLO;
46         char       *pwd = NULL;
47
48         pgLO->argv = argv;
49         pgLO->argc = argc;
50         pgLO->action = 0;
51         pgLO->lolist = NULL;
52         pgLO->user = NULL;
53         pgLO->db = NULL;
54         pgLO->host = NULL;
55         pgLO->port = NULL;
56         pgLO->space = NULL;
57         pgLO->index = NULL;
58         pgLO->remove = FALSE;
59         pgLO->quiet = FALSE;
60         pgLO->counter = 0;
61         pgLO->lolist_start = 0;
62
63         progname = argv[0];
64
65         /*
66          * Parse ARGV
67          */
68         if (argc > 1)
69         {
70                 int                     arg;
71                 extern int      optind;
72                 int                     l_index = 0;
73                 static struct option l_opt[] = {
74                         {"help", no_argument, 0, 'h'},
75                         {"user", required_argument, 0, 'u'},
76                         {"pwd", required_argument, 0, 'p'},
77                         {"db", required_argument, 0, 'd'},
78                         {"host", required_argument, 0, 'h'},
79                         {"port", required_argument, 0, 'o'},
80                         {"space", required_argument, 0, 's'},
81                         {"import", no_argument, 0, 'i'},
82                         {"export", no_argument, 0, 'e'},
83                         {"remove", no_argument, 0, 'r'},
84                         {"quiet", no_argument, 0, 'q'},
85                         {"all", no_argument, 0, 'a'},
86                         {"show", no_argument, 0, 'w'},
87                         {NULL, 0, 0, 0}
88                 };
89
90                 while ((arg = getopt_long(argc, argv, "?aeho:u:p:qd:l:t:irs:w", l_opt, &l_index)) != -1)
91                 {
92                         switch (arg)
93                         {
94                                 case '?':
95                                 case 'h':
96                                         usage();
97                                         exit(RE_OK);
98                                 case 'u':
99                                         pgLO->user = strdup(optarg);
100                                         break;
101                                 case 't':
102                                         pgLO->host = strdup(optarg);
103                                         break;
104                                 case 'o':
105                                         pgLO->port = strdup(optarg);
106                                         break;
107                                 case 'p':
108                                         pwd = strdup(optarg);
109                                         break;
110                                 case 'd':
111                                         pgLO->db = strdup(optarg);
112                                         break;
113                                 case 's':
114                                         pgLO->space = strdup(optarg);
115                                         break;
116                                 case 'i':
117                                         pgLO->action = ACTION_IMPORT;
118                                         break;
119                                 case 'l':
120                                         pgLO->action = ACTION_EXPORT_ATTR;
121                                         pgLO->lolist_start = optind - 1;
122                                         parse_lolist(pgLO);
123                                         break;
124                                 case 'e':
125                                 case 'a':
126                                         pgLO->action = ACTION_EXPORT_ALL;
127                                         break;
128                                 case 'w':
129                                         pgLO->action = ACTION_SHOW;
130                                         break;
131                                 case 'r':
132                                         pgLO->remove = TRUE;
133                                         break;
134                                 case 'q':
135                                         pgLO->quiet = TRUE;
136                                         break;
137                                 default:
138                                         fprintf(stderr, "%s: bad arg -%c\n", progname, arg);
139                                         usage();
140                                         exit(RE_ERROR);
141                         }
142                 }
143         }
144         else
145         {
146                 usage();
147                 exit(RE_ERROR);
148         }
149
150         /*
151          * Check space
152          */
153         if (!pgLO->space && !pgLO->action == ACTION_SHOW)
154         {
155                 if (!(pgLO->space = getenv("PWD")))
156                 {
157                         fprintf(stderr, "%s: not set space for dump-tree (option '-s' or $PWD).\n", progname);
158                         exit(RE_ERROR);
159                 }
160         }
161
162         if (!pgLO->action)
163         {
164                 fprintf(stderr, "%s: What do you want - export or import?\n", progname);
165                 exit(RE_ERROR);
166         }
167
168         /*
169          * Make connection
170          */
171         pgLO->conn = PQsetdbLogin(pgLO->host, pgLO->port, NULL, NULL, pgLO->db,
172                                                           pgLO->user, pwd);
173
174         if (PQstatus(pgLO->conn) == CONNECTION_BAD)
175         {
176                 fprintf(stderr, "%s (connection): %s\n", progname, PQerrorMessage(pgLO->conn));
177                 exit(RE_ERROR);
178         }
179         pgLO->host = PQhost(pgLO->conn) ? PQhost(pgLO->conn) : "localhost";
180         pgLO->db = PQdb(pgLO->conn);
181         pgLO->user = PQuser(pgLO->conn);
182
183
184         /*
185          * Init index file
186          */
187         if (pgLO->action != ACTION_SHOW)
188                 index_file(pgLO);
189
190         PQexec(pgLO->conn, "SET search_path = public");
191
192         PQexec(pgLO->conn, "BEGIN");
193
194         switch (pgLO->action)
195         {
196
197                 case ACTION_SHOW:
198                 case ACTION_EXPORT_ALL:
199                         load_lolist(pgLO);
200                         /* FALL THROUGH */
201
202                 case ACTION_EXPORT_ATTR:
203                         pglo_export(pgLO);
204                         if (!pgLO->quiet)
205                         {
206                                 if (pgLO->action == ACTION_SHOW)
207                                         printf("\nDatabase '%s' contains %d large objects.\n\n", pgLO->db, pgLO->counter);
208                                 else
209                                         printf("\nExported %d large objects.\n\n", pgLO->counter);
210                         }
211                         break;
212
213                 case ACTION_IMPORT:
214                         pglo_import(pgLO);
215                         if (!pgLO->quiet)
216                                 printf("\nImported %d large objects.\n\n", pgLO->counter);
217                         break;
218         }
219
220         PQexec(pgLO->conn, "COMMIT");
221         PQfinish(pgLO->conn);
222
223         if (pgLO->action != ACTION_SHOW)
224                 fclose(pgLO->index);
225
226         exit(RE_OK);
227 }
228
229 static void
230 parse_lolist(LODumpMaster * pgLO)
231 {
232         LOlist     *ll;
233         char      **d,
234                            *loc,
235                                 buff[MAX_TABLE_NAME + MAX_ATTR_NAME + 1];
236
237         pgLO->lolist = (LOlist *) malloc(pgLO->argc * sizeof(LOlist));
238
239         if (!pgLO->lolist)
240         {
241                 fprintf(stderr, "%s: can't allocate memory\n", progname);
242                 exit(RE_ERROR);
243         }
244
245         for (d = pgLO->argv + pgLO->lolist_start, ll = pgLO->lolist;
246                  *d != NULL;
247                  d++, ll++)
248         {
249
250                 strncpy(buff, *d, MAX_TABLE_NAME + MAX_ATTR_NAME);
251
252                 if ((loc = strchr(buff, '.')) == NULL)
253                 {
254                         fprintf(stderr, "%s: '%s' is bad 'table.attr'\n", progname, buff);
255                         exit(RE_ERROR);
256                 }
257                 *loc = '\0';
258                 ll->lo_table = strdup(buff);
259                 ll->lo_attr = strdup(++loc);
260         }
261         ll++;
262         ll->lo_table = ll->lo_attr = (char *) NULL;
263 }
264
265
266 static void
267 usage(void)
268 {
269         printf("\npg_dumplo %s - PostgreSQL large objects dump\n", PG_VERSION);
270         puts("pg_dumplo [option]\n\n"
271                  "-h --help                    this help\n"
272            "-u --user=<username>         username for connection to server\n"
273            "-p --password=<password>     password for connection to server\n"
274                  "-d --db=<database>           database name\n"
275                  "-t --host=<hostname>         server hostname\n"
276         "-o --port=<port>             database server port (default: 5432)\n"
277                  "-s --space=<dir>             directory with dump tree (for export/import)\n"
278                  "-i --import                  import large obj dump tree to DB\n"
279         "-e --export                  export (dump) large obj to dump tree\n"
280                  "-l <table.attr ...>          dump attribute (columns) with LO to dump tree\n"
281                  "-a --all                     dump all LO in DB (default)\n"
282                  "-r --remove                  if is set '-i' try remove old LO\n"
283                  "-q --quiet                   run quietly\n"
284                  "-w --show                    not dump, but show all LO in DB\n"
285                  "\n"
286                  "Example (dump):   pg_dumplo -d my_db -s /my_dump/dir -l t1.a t1.b t2.a\n"
287                  "                  pg_dumplo -a -d my_db -s /my_dump/dir\n"
288                  "Example (import): pg_dumplo -i -d my_db -s /my_dump/dir\n"
289                  "Example (show):   pg_dumplo -w -d my_db\n\n"
290                  "Note:  * option '-l' must be last option!\n"
291         "       * option '-i' without option '-r' make new large obj in DB\n"
292                  "         not rewrite old, the '-i' UPDATE oid numbers in table.attr only!\n"
293                  "       * if option -s is not set, pg_dumplo uses $PWD\n"
294                 );                                              /* puts() */
295 }