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