PostGIS  2.4.9dev-r@@SVN_REVISION@@
pgsql2shp-cli.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  * Copyright 2001-2003 Refractions Research Inc.
6  *
7  * This is free software; you can redistribute and/or modify it under
8  * the terms of the GNU General Public Licence. See the COPYING file.
9  *
10  **********************************************************************
11  *
12  * PostGIS to Shapefile converter
13  *
14  * Original Author: Jeff Lounsbury <jeffloun@refractions.net>
15  * Maintainer: Sandro Santilli <strk@keybit.bet>
16  *
17  **********************************************************************/
18 
19 #include "pgsql2shp-core.h"
20 #include "../postgis_config.h"
21 
22 
23 static void
24 usage(int status)
25 {
26  /* TODO: if status != 0 print all to stderr */
27 
28  printf(_( "RELEASE: %s (r%d)\n" ), POSTGIS_LIB_VERSION, POSTGIS_SVN_REVISION);
29  printf(_("USAGE: pgsql2shp [<options>] <database> [<schema>.]<table>\n"
30  " pgsql2shp [<options>] <database> <query>\n"
31  "\n"
32  "OPTIONS:\n" ));
33  printf(_(" -f <filename> Use this option to specify the name of the file to create.\n" ));
34  printf(_(" -h <host> Allows you to specify connection to a database on a\n"
35  " machine other than the default.\n" ));
36  printf(_(" -p <port> Allows you to specify a database port other than the default.\n" ));
37  printf(_(" -P <password> Connect to the database with the specified password.\n" ));
38  printf(_(" -u <user> Connect to the database as the specified user.\n" ));
39  printf(_(" -g <geometry_column> Specify the geometry column to be exported.\n" ));
40  printf(_(" -b Use a binary cursor.\n" ));
41  printf(_(" -r Raw mode. Do not assume table has been created by the loader. This would\n"
42  " not unescape attribute names and will not skip the 'gid' attribute.\n" ));
43  printf(_(" -k Keep PostgreSQL identifiers case.\n" ));
44  printf(_(" -m <filename> Specify a file containing a set of mappings of (long) column\n"
45  " names to 10 character DBF column names. The content of the file is one or\n"
46  " more lines of two names separated by white space and no trailing or\n"
47  " leading space. For example:\n"
48  " COLUMNNAME DBFFIELD1\n"
49  " AVERYLONGCOLUMNNAME DBFFIELD2\n" ));
50  printf(_(" -? Display this help screen.\n\n" ));
51  exit(status);
52 }
53 
54 int
55 main(int argc, char **argv)
56 {
57  SHPDUMPERCONFIG *config;
58  SHPDUMPERSTATE *state;
59 
60  int ret, c, i;
61 
62  /* If no options are specified, display usage */
63  if (argc == 1)
64  {
65  usage(0); /* TODO: should this exit with error ? */
66  }
67 
68  /* Parse command line options and set configuration */
69  config = malloc(sizeof(SHPDUMPERCONFIG));
71 
72  while ((c = pgis_getopt(argc, argv, "bf:h:du:p:P:g:rkm:")) != EOF)
73  {
74  switch (c)
75  {
76  case 'b':
77  config->binary = 1;
78  break;
79  case 'f':
80  config->shp_file = pgis_optarg;
81  break;
82  case 'h':
83  config->conn->host = pgis_optarg;
84  break;
85  case 'd':
86  config->dswitchprovided = 1;
87  break;
88  case 'r':
89  config->includegid = 1;
90  config->unescapedattrs = 1;
91  break;
92  case 'u':
93  config->conn->username = pgis_optarg;
94  break;
95  case 'p':
96  config->conn->port = pgis_optarg;
97  break;
98  case 'P':
99  config->conn->password = pgis_optarg;
100  break;
101  case 'g':
102  config->geo_col_name = pgis_optarg;
103  break;
104  case 'm':
106  break;
107  case 'k':
108  config->keep_fieldname_case = 1;
109  break;
110  default:
111  usage(pgis_optopt == '?' ? 0 : 1);
112  }
113  }
114 
115 
116  /* Determine the database name from the next argument, if no database, exit. */
117  if (pgis_optind < argc)
118  {
119  config->conn->database = argv[pgis_optind];
120  pgis_optind++;
121  }
122  else
123  {
124  usage(1);
125  }
126 
127 
128  /* Determine the table and schema names from the next argument if supplied, otherwise if
129  it's a user-defined query then set that instead */
130  if (pgis_optind < argc)
131  {
132  /* User-defined queries begin with SELECT */
133  if (!strncmp(argv[pgis_optind], "SELECT ", 7) ||
134  !strncmp(argv[pgis_optind], "select ", 7))
135  {
136  config->usrquery = argv[pgis_optind];
137  }
138  else
139  {
140  /* Schema qualified table name */
141  char *strptr = argv[pgis_optind];
142  char *chrptr = strchr(strptr, '.');
143 
144  /* OK, this is a schema-qualified table name... */
145  if (chrptr)
146  {
147  if ( chrptr == strptr )
148  {
149  /* table is ".something" display help */
150  usage(0);
151  exit(0);
152  }
153  /* Null terminate at the '.' */
154  *chrptr = '\0';
155  /* Copy in the parts */
156  config->schema = strdup(strptr);
157  config->table = strdup(chrptr+1);
158  }
159  else
160  {
161  config->table = strdup(strptr);
162  }
163  }
164  }
165  else
166  {
167  usage(1);
168  }
169 
170  state = ShpDumperCreate(config);
171 
172  ret = ShpDumperConnectDatabase(state);
173  if (ret != SHPDUMPEROK)
174  {
175  fprintf(stderr, "%s\n", state->message);
176  fflush(stderr);
177  exit(1);
178  }
179 
180  /* Display a warning if the -d switch is used with PostGIS >= 1.0 */
181  if (state->pgis_major_version > 0 && state->config->dswitchprovided)
182  {
183  fprintf(stderr, _("WARNING: -d switch is useless when dumping from postgis-1.0.0+\n"));
184  fflush(stderr);
185  }
186 
187  /* Open the table ready to return rows */
188  fprintf(stdout, _("Initializing... \n"));
189  fflush(stdout);
190 
191  ret = ShpDumperOpenTable(state);
192  if (ret != SHPDUMPEROK)
193  {
194  fprintf(stderr, "%s\n", state->message);
195  fflush(stderr);
196 
197  if (ret == SHPDUMPERERR)
198  exit(1);
199  }
200 
201  fprintf(stdout, _("Done (postgis major version: %d).\n"), state->pgis_major_version);
202  fprintf(stdout, _("Output shape: %s\n"), shapetypename(state->outshptype));
203  fprintf(stdout, _("Dumping: "));
204  fflush(stdout);
205 
206  for (i = 0; i < ShpDumperGetRecordCount(state); i++)
207  {
208  /* Mimic existing behaviour */
209  if (!(state->currow % state->config->fetchsize))
210  {
211  fprintf(stdout, "X");
212  fflush(stdout);
213  }
214 
215  ret = ShpLoaderGenerateShapeRow(state);
216  if (ret != SHPDUMPEROK)
217  {
218  fprintf(stderr, "%s\n", state->message);
219  fflush(stderr);
220 
221  if (ret == SHPDUMPERERR)
222  exit(1);
223  }
224  }
225 
226  fprintf(stdout, _(" [%d rows].\n"), ShpDumperGetRecordCount(state));
227  fflush(stdout);
228 
229  ret = ShpDumperCloseTable(state);
230  if (ret != SHPDUMPEROK)
231  {
232  fprintf(stderr, "%s\n", state->message);
233  fflush(stderr);
234 
235  if (ret == SHPDUMPERERR)
236  exit(1);
237  }
238 
239  ShpDumperDestroy(state);
240 
241  return 0;
242 }
char * column_map_filename
int ShpDumperOpenTable(SHPDUMPERSTATE *state)
#define _(String)
Definition: shpcommon.h:24
static void usage(int status)
Definition: pgsql2shp-cli.c:24
SHPDUMPERCONFIG * config
#define POSTGIS_LIB_VERSION
Definition: sqldefines.h:12
int ShpLoaderGenerateShapeRow(SHPDUMPERSTATE *state)
SHPDUMPERSTATE * ShpDumperCreate(SHPDUMPERCONFIG *config)
int ShpDumperCloseTable(SHPDUMPERSTATE *state)
int pgis_optopt
Definition: getopt.c:40
void set_dumper_config_defaults(SHPDUMPERCONFIG *config)
int pgis_optind
Definition: getopt.c:39
#define SHPDUMPERERR
SHPCONNECTIONCONFIG * conn
void ShpDumperDestroy(SHPDUMPERSTATE *state)
int ShpDumperGetRecordCount(SHPDUMPERSTATE *state)
int main(int argc, char **argv)
Definition: pgsql2shp-cli.c:55
#define SHPDUMPEROK
void * malloc(YYSIZE_T)
int ShpDumperConnectDatabase(SHPDUMPERSTATE *state)
char * pgis_optarg
Definition: getopt.c:41
int pgis_getopt(int argc, char **argv, char *opts)
Definition: getopt.c:44
char message[SHPDUMPERMSGLEN]
char * shapetypename(int num)