PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ ShpLoaderGetSQLHeader()

int ShpLoaderGetSQLHeader ( SHPLOADERSTATE state,
char **  strheader 
)

TODO: if the table has more then one geometry column the DROP TABLE call will leave spurious records in geometry_columns.

If the geometry column in the table being dropped does not match 'the_geom' or the name specified with -g an error is returned by DropGeometryColumn.

The table to be dropped might not exist.

Definition at line 1282 of file shp2pgsql-core.c.

1283 {
1284  stringbuffer_t *sb;
1285  char *ret;
1286  int j;
1287 
1288  /* Create the stringbuffer containing the header; we use this API as it's easier
1289  for handling string resizing during append */
1290  sb = stringbuffer_create();
1291  stringbuffer_clear(sb);
1292 
1293  /* Set the client encoding if required */
1294  if (state->config->encoding)
1295  {
1296  stringbuffer_aprintf(sb, "SET CLIENT_ENCODING TO UTF8;\n");
1297  }
1298 
1299  /* Use SQL-standard string escaping rather than PostgreSQL standard */
1300  stringbuffer_aprintf(sb, "SET STANDARD_CONFORMING_STRINGS TO ON;\n");
1301 
1302  /* Drop table if requested */
1303  if (state->config->opt == 'd')
1304  {
1316  if (state->config->schema)
1317  {
1318  if (state->config->readshape == 1 && (! state->config->geography) )
1319  {
1320  stringbuffer_aprintf(sb, "SELECT DropGeometryColumn('%s','%s','%s');\n",
1321  state->config->schema, state->config->table, state->geo_col);
1322  }
1323 
1324  stringbuffer_aprintf(sb, "DROP TABLE IF EXISTS \"%s\".\"%s\";\n", state->config->schema,
1325  state->config->table);
1326  }
1327  else
1328  {
1329  if (state->config->readshape == 1 && (! state->config->geography) )
1330  {
1331  stringbuffer_aprintf(sb, "SELECT DropGeometryColumn('','%s','%s');\n",
1332  state->config->table, state->geo_col);
1333  }
1334 
1335  stringbuffer_aprintf(sb, "DROP TABLE IF EXISTS \"%s\";\n", state->config->table);
1336  }
1337  }
1338 
1339  /* Start of transaction if we are using one */
1340  if (state->config->usetransaction)
1341  {
1342  stringbuffer_aprintf(sb, "BEGIN;\n");
1343  }
1344 
1345  /* If not in 'append' mode create the spatial table */
1346  if (state->config->opt != 'a')
1347  {
1348  /*
1349  * Create a table for inserting the shapes into with appropriate
1350  * columns and types
1351  */
1352  if (state->config->schema)
1353  {
1354  stringbuffer_aprintf(sb, "CREATE TABLE \"%s\".\"%s\" (gid serial",
1355  state->config->schema, state->config->table);
1356  }
1357  else
1358  {
1359  stringbuffer_aprintf(sb, "CREATE TABLE \"%s\" (gid serial", state->config->table);
1360  }
1361 
1362  /* Generate the field types based upon the shapefile information */
1363  for (j = 0; j < state->num_fields; j++)
1364  {
1365  stringbuffer_aprintf(sb, ",\n\"%s\" ", state->field_names[j]);
1366 
1367  /* First output the raw field type string */
1368  stringbuffer_aprintf(sb, "%s", state->pgfieldtypes[j]);
1369 
1370  /* Some types do have typmods */
1371  /* Apply width typmod for varchar if there is positive width **/
1372  if (!strcmp("varchar", state->pgfieldtypes[j]) && state->widths[j] > 0)
1373  stringbuffer_aprintf(sb, "(%d)", state->widths[j]);
1374 
1375  if (!strcmp("numeric", state->pgfieldtypes[j]))
1376  {
1377  /* Doubles we just allow PostgreSQL to auto-detect the size */
1378  if (state->types[j] != FTDouble)
1379  stringbuffer_aprintf(sb, "(%d,0)", state->widths[j]);
1380  }
1381  }
1382 
1383  /* Add the geography column directly to the table definition, we don't
1384  need to do an AddGeometryColumn() call. */
1385  if (state->config->readshape == 1 && state->config->geography)
1386  {
1387  char *dimschar;
1388 
1389  if (state->pgdims == 4)
1390  dimschar = "ZM";
1391  else
1392  dimschar = "";
1393 
1394  if (state->to_srid != SRID_UNKNOWN && state->to_srid != 4326)
1395  {
1396  snprintf(state->message, SHPLOADERMSGLEN, _("Invalid SRID for geography type: %d"), state->to_srid);
1398  return SHPLOADERERR;
1399  }
1400  stringbuffer_aprintf(sb, ",\n\"%s\" geography(%s%s,%d)", state->geo_col, state->pgtype, dimschar, 4326);
1401  }
1402  stringbuffer_aprintf(sb, ")");
1403 
1404  /* Tablespace is optional. */
1405  if (state->config->tablespace != NULL)
1406  {
1407  stringbuffer_aprintf(sb, " TABLESPACE \"%s\"", state->config->tablespace);
1408  }
1409  stringbuffer_aprintf(sb, ";\n");
1410 
1411  /* Create the primary key. This is done separately because the index for the PK needs
1412  * to be in the correct tablespace. */
1413 
1414  /* TODO: Currently PostgreSQL does not allow specifying an index to use for a PK (so you get
1415  * a default one called table_pkey) and it does not provide a way to create a PK index
1416  * in a specific tablespace. So as a hacky solution we create the PK, then move the
1417  * index to the correct tablespace. Eventually this should be:
1418  * CREATE INDEX table_pkey on table(gid) TABLESPACE tblspc;
1419  * ALTER TABLE table ADD PRIMARY KEY (gid) USING INDEX table_pkey;
1420  * A patch has apparently been submitted to PostgreSQL to enable this syntax, see this thread:
1421  * http://archives.postgresql.org/pgsql-hackers/2011-01/msg01405.php */
1422  stringbuffer_aprintf(sb, "ALTER TABLE ");
1423 
1424  /* Schema is optional, include if present. */
1425  if (state->config->schema)
1426  {
1427  stringbuffer_aprintf(sb, "\"%s\".",state->config->schema);
1428  }
1429  stringbuffer_aprintf(sb, "\"%s\" ADD PRIMARY KEY (gid);\n", state->config->table);
1430 
1431  /* Tablespace is optional for the index. */
1432  if (state->config->idxtablespace != NULL)
1433  {
1434  stringbuffer_aprintf(sb, "ALTER INDEX ");
1435  if (state->config->schema)
1436  {
1437  stringbuffer_aprintf(sb, "\"%s\".",state->config->schema);
1438  }
1439 
1440  /* WARNING: We're assuming the default "table_pkey" name for the primary
1441  * key index. PostgreSQL may use "table_pkey1" or similar in the
1442  * case of a name conflict, so you may need to edit the produced
1443  * SQL in this rare case. */
1444  stringbuffer_aprintf(sb, "\"%s_pkey\" SET TABLESPACE \"%s\";\n",
1445  state->config->table, state->config->idxtablespace);
1446  }
1447 
1448  /* Create the geometry column with an addgeometry call */
1449  if (state->config->readshape == 1 && (!state->config->geography))
1450  {
1451  /* If they didn't specify a target SRID, see if they specified a source SRID. */
1452  int srid = state->to_srid;
1453  if (state->config->schema)
1454  {
1455  stringbuffer_aprintf(sb, "SELECT AddGeometryColumn('%s','%s','%s','%d',",
1456  state->config->schema, state->config->table, state->geo_col, srid);
1457  }
1458  else
1459  {
1460  stringbuffer_aprintf(sb, "SELECT AddGeometryColumn('','%s','%s','%d',",
1461  state->config->table, state->geo_col, srid);
1462  }
1463 
1464  stringbuffer_aprintf(sb, "'%s',%d);\n", state->pgtype, state->pgdims);
1465  }
1466  }
1467 
1468  /* Copy the string buffer into a new string, destroying the string buffer */
1469  ret = (char *)malloc(strlen((char *)stringbuffer_getstring(sb)) + 1);
1470  strcpy(ret, (char *)stringbuffer_getstring(sb));
1472 
1473  *strheader = ret;
1474 
1475  return SHPLOADEROK;
1476 }
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:188
void * malloc(YYSIZE_T)
#define SHPLOADERMSGLEN
#define SHPLOADERERR
#define SHPLOADEROK
#define _(String)
Definition: shpcommon.h:24
void stringbuffer_clear(stringbuffer_t *s)
Reset the stringbuffer_t.
Definition: stringbuffer.c:90
int stringbuffer_aprintf(stringbuffer_t *s, const char *fmt,...)
Appends a formatted string to the current string buffer, using the format and argument list provided.
Definition: stringbuffer.c:253
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
Definition: stringbuffer.c:35
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
Definition: stringbuffer.c:78
const char * stringbuffer_getstring(stringbuffer_t *s)
Returns a reference to the internal string being managed by the stringbuffer.
Definition: stringbuffer.c:149
char message[SHPLOADERMSGLEN]
DBFFieldType * types
SHPLOADERCONFIG * config

References _, shp_loader_state::config, shp_loader_config::encoding, shp_loader_state::field_names, shp_loader_state::geo_col, shp_loader_config::geography, shp_loader_config::idxtablespace, malloc(), shp_loader_state::message, shp_loader_state::num_fields, shp_loader_config::opt, shp_loader_state::pgdims, shp_loader_state::pgfieldtypes, shp_loader_state::pgtype, shp_loader_config::readshape, shp_loader_config::schema, SHPLOADERERR, SHPLOADERMSGLEN, SHPLOADEROK, SRID_UNKNOWN, stringbuffer_aprintf(), stringbuffer_clear(), stringbuffer_create(), stringbuffer_destroy(), stringbuffer_getstring(), shp_loader_config::table, shp_loader_config::tablespace, shp_loader_state::to_srid, shp_loader_state::types, shp_loader_config::usetransaction, and shp_loader_state::widths.

Referenced by pgui_action_import().

Here is the call graph for this function:
Here is the caller graph for this function: