*
**********************************************************************
* $Log$
+ * Revision 1.47 2004/04/21 09:13:15 strk
+ * Attribute names escaping mechanism added. You should now
+ * be able to dump a shapefile equal to the one loaded.
+ *
* Revision 1.46 2004/04/21 07:38:34 strk
* Memory allocated for main_scan_query was not enough when using binary cursor. Fixed
*
int geotype;
int outshptype;
int is3d;
+int includegid;
+int unescapedattrs;
int binary;
#ifdef USE_WKB
SHPObject * (*shape_creator)(byte *, int);
exit(1);
}
-//main
-//USAGE: pgsql2shp [<options>] <database> <table>
-//OPTIONS:
-// -d Set the dump file to 3 dimensions, if this option is not used
-// all dumping will be 2d only.
-// -f <filename> Use this option to specify the name of the file
-// to create.
-// -h <host> Allows you to specify connection to a database on a
-// machine other than the localhost.
-// -p <port> Allows you to specify a database port other than 5432.
-// -P <password> Connect to the database with the specified password.
-// -u <user> Connect to the database as the specified user.
-// -g <geometry_column> Specify the geometry column to be exported.
-
int main(int ARGC, char **ARGV){
char *query=NULL;
int row;
main_scan_query = NULL;
rowbuflen=100;
is3d = 0;
+ includegid=0;
+ unescapedattrs=0;
binary = 0;
#ifdef DEBUG
FILE *debug;
} else {
sprintf(query, "DECLARE cur CURSOR FOR %s", main_scan_query);
}
-//fprintf(stderr, "MAINSCAN: %s\n", main_scan_query);
+fprintf(stderr, "MAINSCAN: %s\n", main_scan_query);
res = PQexec(conn, query);
free(query);
if ( ! res || PQresultStatus(res) != PGRES_COMMAND_OK ) {
printf(" -u <user> Connect to the database as the specified user.\n");
printf(" -g <geometry_column> Specify the geometry column to be exported.\n");
printf(" -b Use a binary cursor.\n");
+ printf(" -r Raw mode. Do not assume table has been created by \n");
+ printf(" the loader. This would not unescape attribute names\n");
+ printf(" and will not skip the 'gid' attribute.");
printf("\n");
exit (status);
}
buf[255] = '\0'; // just in case...
/* Parse command line */
- while ((c = getopt(ARGC, ARGV, "bf:h:du:p:P:g:")) != EOF){
+ while ((c = getopt(ARGC, ARGV, "bf:h:du:p:P:g:r")) != EOF){
switch (c) {
case 'b':
binary = 1;
case 'd':
is3d = 1;
break;
+ case 'r':
+ includegid = 1;
+ unescapedattrs = 1;
+ break;
case 'u':
//setenv("PGUSER", optarg, 1);
snprintf(buf, 255, "PGUSER=%s", optarg);
char *mainscan_flds[256];
int mainscan_nflds=0;
int size;
+ int gidfound=0;
/* Detect host endiannes */
big_endian = is_bigendian();
int j;
int type, size;
char *fname; // pgsql attribute name
+ char *ptr;
char field_name[32]; // dbf version of field name
fname = PQgetvalue(res, i, 0);
* a DBF attribute.
*/
- if(strlen(fname) <32) strcpy(field_name, fname);
- else {
- printf("field name %s is too long, must be "
- "less than 32 characters.\n", fname);
+ /* Skip gid (if not asked to do otherwise */
+ if ( ! strcmp(fname, "gid") )
+ {
+ gidfound = 1;
+ if ( ! includegid ) continue;
+ }
+
+ /* Unescape field name */
+ ptr = fname;
+ if ( ! unescapedattrs )
+ {
+ if (*ptr=='_') ptr+=2;
+ }
+ /*
+ * This needs special handling since both xmin and _xmin
+ * becomes __xmin when escaped
+ */
+
+
+ if(strlen(ptr) <32) strcpy(field_name, ptr);
+ else
+ {
+ /*
+ * TODO: you find an appropriate name if
+ * running in RAW mode
+ */
+ printf("dbf attribute name %s is too long, must be "
+ "less than 32 characters.\n", ptr);
return 0;
}
+
/* make UPPERCASE */
for(j=0; j < strlen(field_name); j++)
field_name[j] = toupper(field_name[j]);
strcat(main_scan_query, buf);
+ // Order by 'gid' (if found)
+ if ( gidfound )
+ {
+ sprintf(buf, " ORDER BY \"gid\"");
+ strcat(main_scan_query, buf);
+ }
+
PQclear(res);
return 1;
*
**********************************************************************
* $Log$
+ * Revision 1.53 2004/04/21 09:13:15 strk
+ * Attribute names escaping mechanism added. You should now
+ * be able to dump a shapefile equal to the one loaded.
+ *
* Revision 1.52 2004/03/10 17:35:16 strk
* removed just-introduced bug
*
double padminbound[8], padmaxbound[8];
int u,j,z,tot_rings,curindex;
SHPObject *obj=NULL;
- char name[32];
+ char name[64];
+ char name2[64];
char *sr_id,*shp_file,*table,*schema,*ptr;
char **names;
DBFFieldType type = -1;
/*
* Make field names lowercase unless asked to
- * quote identifiers
+ * keep identifiers case.
*/
if ( ! quoteidentifiers ) {
for(z=0; z<strlen(name) ;z++)
name[z] = tolower(name[z]);
}
+ /*
+ * Escape names starting with the
+ * escape char (_)
+ */
+ if( name[0]=='_' )
+ {
+ strcpy(name2+2, name);
+ name2[0] = '_';
+ name2[1] = '_';
+ strcpy(name, name2);
+ }
+
+ /*
+ * Escape attributes named 'gid'
+ * and pgsql reserved attribute names
+ */
+ else if(
+ ! strcmp(name,"gid") ||
+ ! strcmp(name, "tableoid") ||
+ ! strcmp(name, "cmax") ||
+ ! strcmp(name, "xmax") ||
+ ! strcmp(name, "cmin") ||
+ ! strcmp(name, "primary") ||
+ ! strcmp(name, "oid") ||
+ ! strcmp(name, "ctid")
+ ) {
+ strcpy(name2+2, name);
+ name2[0] = '_';
+ name2[1] = '_';
+ strcpy(name, name2);
+ }
+
/* Avoid duplicating field names */
for(z=0; z < j ; z++){
if(strcmp(names[z],name)==0){
}
}
- /*
- * Avoid duplicating system fields
- * (currently only gid is handled)
- */
- if( strcmp(name,"gid")==0 )
- {
- strcat(name,"__2");
- }
names[j] = malloc ( strlen(name)+3 );
strcpy(names[j], name);