]> granicus.if.org Git - postgis/commitdiff
Attribute names escaping mechanism added. You should now
authorSandro Santilli <strk@keybit.net>
Wed, 21 Apr 2004 09:13:15 +0000 (09:13 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 21 Apr 2004 09:13:15 +0000 (09:13 +0000)
be able to dump a shapefile equal to the one loaded.

git-svn-id: http://svn.osgeo.org/postgis/trunk@506 b70326c6-7e19-0410-871a-916f4a2858ee

loader/pgsql2shp.c
loader/shp2pgsql.c

index a4ff706dae8728d71c6a29f78d81e01ae5f22ad4..b2d4a90da92978d1b7a56efb12314657ba608d4c 100644 (file)
  * 
  **********************************************************************
  * $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
  *
@@ -158,6 +162,8 @@ SHPHandle shp;
 int geotype;
 int outshptype;
 int is3d;
+int includegid;
+int unescapedattrs;
 int binary;
 #ifdef USE_WKB
 SHPObject * (*shape_creator)(byte *, int);
@@ -224,20 +230,6 @@ static void exit_nicely(PGconn *conn){
        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;
@@ -255,6 +247,8 @@ int main(int ARGC, char **ARGV){
        main_scan_query = NULL;
        rowbuflen=100;
        is3d = 0;
+       includegid=0;
+       unescapedattrs=0;
        binary = 0;
 #ifdef DEBUG
        FILE *debug;
@@ -312,7 +306,7 @@ int main(int ARGC, char **ARGV){
        } 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 ) {
@@ -2295,6 +2289,9 @@ usage(status)
                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);
 }
@@ -2308,7 +2305,7 @@ int parse_commandline(int ARGC, char **ARGV)
        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;
@@ -2324,6 +2321,10 @@ int parse_commandline(int ARGC, char **ARGV)
                case 'd':
                    is3d = 1;
                     break;               
+               case 'r':
+                   includegid = 1;
+                   unescapedattrs = 1;
+                    break;               
                case 'u':
                    //setenv("PGUSER", optarg, 1);
                    snprintf(buf, 255, "PGUSER=%s", optarg);
@@ -2387,6 +2388,7 @@ initialize()
        char *mainscan_flds[256];
        int mainscan_nflds=0;
        int size;
+       int gidfound=0;
 
        /* Detect host endiannes */
        big_endian = is_bigendian();
@@ -2457,6 +2459,7 @@ initialize()
                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);
@@ -2504,13 +2507,38 @@ initialize()
                 * 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]);
@@ -2735,6 +2763,13 @@ initialize()
 
        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;
index b6162ba268b61babd8f39645517f9651a05bd444..69f29c4bbc0c593ee4e220afe9bdcadb38eeeb1f 100644 (file)
  * 
  **********************************************************************
  * $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
  *
@@ -603,7 +607,8 @@ int main (int ARGC, char **ARGV){
        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;
@@ -772,13 +777,45 @@ int main (int ARGC, char **ARGV){
 
                /*
                 * 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){
@@ -788,14 +825,6 @@ int main (int ARGC, char **ARGV){
                        }
                }       
 
-               /*
-                * 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);