* Original Author: Jeff Lounsbury <jeffloun@refractions.net>
* Contributions by: Sandro Santilli <strk@keybit.bet>
* Enhanced by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
+ * Enhanced by: Regina Obe <lr@pcorp.us>
*
**********************************************************************/
if (state->schema)
{
query = malloc(150 + 4 * strlen(state->geo_col_name) + strlen(state->schema) + strlen(state->table));
-
+
sprintf(query, "SELECT count(\"%s\"), max(ST_zmflag(\"%s\"::geometry)), geometrytype(\"%s\"::geometry) FROM \"%s\".\"%s\" GROUP BY geometrytype(\"%s\"::geometry)",
state->geo_col_name, state->geo_col_name, state->geo_col_name, state->schema, state->table, state->geo_col_name);
}
else
{
query = malloc(150 + 4 * strlen(state->geo_col_name) + strlen(state->table));
-
+
sprintf(query, "SELECT count(\"%s\"), max(ST_zmflag(\"%s\"::geometry)), geometrytype(\"%s\"::geometry) FROM \"%s\" GROUP BY geometrytype(\"%s\"::geometry)",
state->geo_col_name, state->geo_col_name, state->geo_col_name, state->table, state->geo_col_name);
}
if (state->schema)
{
query = malloc(40 + strlen(state->schema) + strlen(state->table));
-
+
sprintf(query, "SELECT count(1) FROM \"%s\".\"%s\"", state->schema, state->table);
}
else
typemismatch = 1;
else
typefound = MULTILINETYPE;
- break;
+ break;
case MULTIPOLYGONTYPE:
if (typefound != MULTIPOLYGONTYPE && typefound != POLYGONTYPE)
case 'z':
state->outshptype = SHPT_POINTZ;
break;
-
+
case 'm':
state->outshptype = SHPT_POINTM;
break;
-
+
default:
state->outshptype = SHPT_POINT;
}
case 'z':
state->outshptype = SHPT_MULTIPOINTZ;
break;
-
+
case 'm':
state->outshptype = SHPT_MULTIPOINTM;
break;
-
+
default:
state->outshptype = SHPT_MULTIPOINT;
}
case 'z':
state->outshptype = SHPT_ARCZ;
break;
-
+
case 'm':
state->outshptype = SHPT_ARCM;
break;
-
+
default:
state->outshptype = SHPT_ARC;
}
case 'z':
state->outshptype = SHPT_POLYGONZ;
break;
-
+
case 'm':
state->outshptype = SHPT_POLYGONM;
break;
-
+
default:
state->outshptype = SHPT_POLYGON;
}
state->pgfieldnames = NULL;
state->big_endian = is_bigendian();
colmap_init(&state->column_map);
-
+
return state;
}
{
char *connstring;
int connlen;
-
+
connlen = 64 +
(conn->host ? strlen(conn->host) : 0) + (conn->port ? strlen(conn->port) : 0) +
(conn->username ? strlen(conn->username) : 0) + (conn->password ? strlen(conn->password) : 0) +
}
if (conn->password)
- {
+ {
strcat(connstring, " password='");
strcat(connstring, conn->password);
strcat(connstring, "'");
snprintf(state->message, SHPDUMPERMSGLEN, "%s", PQresultErrorMessage(res));
PQclear(res);
free(connstring);
- return SHPDUMPERERR;
+ return SHPDUMPERERR;
}
tmpvalue = PQgetvalue(res, 0, 0);
snprintf(state->message, SHPDUMPERMSGLEN, _("Error looking up geometry oid: %s"), PQresultErrorMessage(res));
PQclear(res);
free(connstring);
- return SHPDUMPERERR;
+ return SHPDUMPERERR;
}
if (PQntuples(res) > 0)
snprintf(state->message, SHPDUMPERMSGLEN, _("Error looking up geography oid: %s"), PQresultErrorMessage(res));
PQclear(res);
free(connstring);
- return SHPDUMPERERR;
+ return SHPDUMPERERR;
}
if (PQntuples(res) > 0)
&state->column_map, state->message, SHPDUMPERMSGLEN);
if (!ret) return SHPDUMPERERR;
}
-
+
/* If a user-defined query has been specified, create and point the state to our new table */
if (state->config->usrquery)
{
{
state->dbf = DBFCreateEx(state->shp_file, "UTF-8");
}
-
+
if (!state->dbf)
{
snprintf(state->message, SHPDUMPERMSGLEN, _("Could not create dbf file %s"), state->shp_file);
if (!state->config->geo_col_name || !strcmp(state->config->geo_col_name, pgfieldname))
{
dbffieldtype = 9;
-
+
state->geo_col_name = strdup(pgfieldname);
}
}
dbffieldname[10] = '\0';
}
}
-
+
/*
* make sure the fields all have unique names,
*/
snprintf(buf, 256, _("Warning: values of field '%s' exceeding maximum dbf field width (%d) "
"will be truncated.\n"), dbffieldname, MAX_DBF_FIELD_SIZE);
strncat(state->message, buf, SHPDUMPERMSGLEN - strlen(state->message));
- dbffieldsize = MAX_DBF_FIELD_SIZE;
+ dbffieldsize = MAX_DBF_FIELD_SIZE;
ret = SHPDUMPERWARN;
}
}
LWDEBUGF(3, "DBF FIELD_NAME: %s, SIZE: %d\n", dbffieldname, dbffieldsize);
-
+
if (dbffieldtype != 9)
{
/* Add the field to the DBF file */
return SHPDUMPERERR;
}
-
+
/* Add the field information to our field arrays */
state->dbffieldnames[state->fieldcount] = dbffieldname;
state->dbffieldtypes[state->fieldcount] = dbffieldtype;
state->pgfieldnames[state->fieldcount] = pgfieldname;
state->pgfieldlens[state->fieldcount] = pgfieldlen;
state->pgfieldtypmods[state->fieldcount] = pgtypmod;
-
+
state->fieldcount++;
}
}
strncat(state->message, buf, SHPDUMPERMSGLEN - strlen(state->message));
state->shp = NULL;
-
+
ret = SHPDUMPERWARN;
}
}
return SHPDUMPERERR;
}
}
-
+
/* Now we have the complete list of fieldnames, let's generate the SQL query. First let's make sure
we reserve enough space for tables with lots of columns */
j = 0;
+ /*TODO: this really should be rewritten to use stringbuffer */
for (i = 0; i < state->fieldcount; i++)
- j += strlen(state->pgfieldnames[i] + 2); /* Add 2 for leading and trailing quotes */
-
+ j += strlen( state->pgfieldnames[i]) + 10; /*add extra space for the quotes to quote identify and any embedded quotes that may need escaping */
+
state->main_scan_query = malloc(1024 + j);
-
+
sprintf(state->main_scan_query, "DECLARE cur ");
if (state->config->binary)
strcat(state->main_scan_query, "BINARY ");
/* Comma-separated column names */
if (i > 0)
strcat(state->main_scan_query, ",");
-
+
if (state->config->binary)
- sprintf(buf, "\"%s\"::text", state->pgfieldnames[i]);
+ sprintf(buf, "%s::text", quote_identifier(state->pgfieldnames[i]) ) ;
else
- sprintf(buf, "\"%s\"", state->pgfieldnames[i]);
+ sprintf(buf, "%s", quote_identifier(state->pgfieldnames[i]) );
strcat(state->main_scan_query, buf);
}
/* If this is the (only) column, no need for the initial comma */
if (state->fieldcount > 0)
strcat(state->main_scan_query, ",");
-
+
if (state->big_endian)
{
if (state->pgis_major_version > 0)
{
- sprintf(buf, "ST_asEWKB(ST_SetSRID(\"%s\"::geometry, 0), 'XDR') AS _geoX", state->geo_col_name);
+ sprintf(buf, "ST_asEWKB(ST_SetSRID(%s::geometry, 0), 'XDR') AS _geoX", quote_identifier(state->geo_col_name) );
}
else
{
- sprintf(buf, "asbinary(\"%s\"::geometry, 'XDR') AS _geoX",
- state->geo_col_name);
+ sprintf(buf, "asbinary(%s::geometry, 'XDR') AS _geoX",
+ quote_identifier(state->geo_col_name) );
}
}
else /* little_endian */
{
if (state->pgis_major_version > 0)
{
- sprintf(buf, "ST_AsEWKB(ST_SetSRID(\"%s\"::geometry, 0), 'NDR') AS _geoX", state->geo_col_name);
+ sprintf(buf, "ST_AsEWKB(ST_SetSRID(%s::geometry, 0), 'NDR') AS _geoX", quote_identifier(state->geo_col_name) ) ;
}
else
{
- sprintf(buf, "asbinary(\"%s\"::geometry, 'NDR') AS _geoX",
- state->geo_col_name);
+ sprintf(buf, "asbinary(%s::geometry, 'NDR') AS _geoX",
+ quote_identifier(state->geo_col_name) );
}
}
PQclear(state->fetchres);
return SHPDUMPERERR;
}
-
+
/* Call the relevant method depending upon the geometry type */
LWDEBUGF(4, "geomtype: %s\n", lwtype_name(lwgeom->type));
-
+
switch (lwgeom->type)
{
case POINTTYPE:
obj = create_point(state, lwgeom_as_lwpoint(lwgeom));
break;
-
+
case MULTIPOINTTYPE:
obj = create_multipoint(state, lwgeom_as_lwmpoint(lwgeom));
break;
-
+
case POLYGONTYPE:
obj = create_polygon(state, lwgeom_as_lwpoly(lwgeom));
break;
-
+
case MULTIPOLYGONTYPE:
obj = create_multipolygon(state, lwgeom_as_lwmpoly(lwgeom));
break;
-
+
case LINETYPE:
obj = create_linestring(state, lwgeom_as_lwline(lwgeom));
break;
-
+
case MULTILINETYPE:
obj = create_multilinestring(state, lwgeom_as_lwmline(lwgeom));
break;
-
+
default:
snprintf(state->message, SHPDUMPERMSGLEN, _("Unknown WKB type (%d) for record %d"), lwgeom->type, state->currow);
PQclear(state->fetchres);
SHPDestroyObject(obj);
return SHPDUMPERERR;
}
-
+
/* Free both the original and geometries */
lwgeom_free(lwgeom);
/* If a geo column is present, generate the projection file */
if (state->geo_col_name)
- ret = projFileCreate(state);
+ ret = projFileCreate(state);
/* Close the DBF and SHP files */
if (state->dbf)
free(state->dbffieldnames[i]);
free(state->dbffieldnames);
}
-
+
if (state->dbffieldtypes)
free(state->dbffieldtypes);
-
+
if (state->pgfieldnames)
free(state->pgfieldnames);
/* Free any column map fieldnames if specified */
colmap_clean(&state->column_map);
-
+
/* Free other names */
if (state->table)
free(state->table);
free(state);
}
}
+
+/*
+ * quote_identifier()
+ * Properly double-quote a SQL identifier.
+ * Copied from PostgreSQL pg_upgrade/util.c
+ */
+char *
+quote_identifier(const char *s)
+{
+ char *result = malloc(strlen(s) * 2 + 3);
+ char *r = result;
+
+ *r++ = '"';
+ while (*s)
+ {
+ if (*s == '"')
+ *r++ = *s;
+ *r++ = *s;
+ s++;
+ }
+ *r++ = '"';
+ *r++ = '\0';
+
+ return result;
+}