PostGIS  2.2.8dev-r@@SVN_REVISION@@

◆ ShpLoaderGenerateSQLRowStatement()

int ShpLoaderGenerateSQLRowStatement ( SHPLOADERSTATE state,
int  item,
char **  strrecord 
)

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

References _, shp_loader_state::col_names, shp_loader_state::config, DBFGetFieldCount(), DBFIsAttributeNULL(), DBFIsRecordDeleted(), DBFReadStringAttribute(), shp_loader_config::dump_format, shp_loader_config::encoding, escape_copy_string(), escape_insert_string(), free(), shp_loader_state::from_srid, GenerateLineStringGeometry(), GeneratePointGeometry(), GeneratePolygonGeometry(), shp_loader_config::geography, shp_loader_state::hDBFHandle, shp_loader_state::hSHPHandle, malloc(), MAXVALUELEN, shp_loader_state::message, SHPObject::nSHPType, shp_loader_config::null_policy, SHPObject::nVertices, POLICY_NULL_SKIP, shp_loader_config::readshape, window::res, shp_loader_config::schema, SHPDestroyObject(), SHPLOADERERR, SHPLOADERMSGLEN, SHPLOADEROK, SHPLOADERRECDELETED, SHPLOADERRECISNULL, SHPLOADERWARN, SHPReadObject(), SHPT_ARC, SHPT_ARCM, SHPT_ARCZ, SHPT_MULTIPOINT, SHPT_MULTIPOINTM, SHPT_MULTIPOINTZ, SHPT_POINT, SHPT_POINTM, SHPT_POINTZ, SHPT_POLYGON, SHPT_POLYGONM, SHPT_POLYGONZ, shp_loader_config::simple_geometries, stringbuffer_aprintf(), stringbuffer_clear(), stringbuffer_create(), stringbuffer_destroy(), stringbuffer_getstring(), shp_loader_config::table, shp_loader_state::to_srid, shp_loader_state::types, utf8(), UTF8_BAD_RESULT, UTF8_GOOD_RESULT, and UTF8_NO_RESULT.

Referenced by main(), and pgui_action_import().

1507 {
1508  SHPObject *obj = NULL;
1509  stringbuffer_t *sb;
1510  stringbuffer_t *sbwarn;
1511  char val[MAXVALUELEN];
1512  char *escval;
1513  char *geometry=NULL, *ret;
1514  char *utf8str;
1515  int res, i;
1516  int rv;
1517 
1518  /* Clear the stringbuffers */
1519  sbwarn = stringbuffer_create();
1520  stringbuffer_clear(sbwarn);
1521  sb = stringbuffer_create();
1522  stringbuffer_clear(sb);
1523 
1524  /* If we are reading the DBF only and the record has been marked deleted, return deleted record status */
1525  if (state->config->readshape == 0 && DBFIsRecordDeleted(state->hDBFHandle, item))
1526  {
1527  *strrecord = NULL;
1528  return SHPLOADERRECDELETED;
1529  }
1530 
1531  /* If we are reading the shapefile, open the specified record */
1532  if (state->config->readshape == 1)
1533  {
1534  obj = SHPReadObject(state->hSHPHandle, item);
1535  if (!obj)
1536  {
1537  snprintf(state->message, SHPLOADERMSGLEN, _("Error reading shape object %d"), item);
1538  return SHPLOADERERR;
1539  }
1540 
1541  /* If we are set to skip NULLs, return a NULL record status */
1542  if (state->config->null_policy == POLICY_NULL_SKIP && obj->nVertices == 0 )
1543  {
1544  SHPDestroyObject(obj);
1545 
1546  *strrecord = NULL;
1547  return SHPLOADERRECISNULL;
1548  }
1549  }
1550 
1551  /* If not in dump format, generate the INSERT string */
1552  if (!state->config->dump_format)
1553  {
1554  if (state->config->schema)
1555  {
1556  stringbuffer_aprintf(sb, "INSERT INTO \"%s\".\"%s\" %s VALUES (", state->config->schema,
1557  state->config->table, state->col_names);
1558  }
1559  else
1560  {
1561  stringbuffer_aprintf(sb, "INSERT INTO \"%s\" %s VALUES (", state->config->table,
1562  state->col_names);
1563  }
1564  }
1565 
1566 
1567  /* Read all of the attributes from the DBF file for this item */
1568  for (i = 0; i < DBFGetFieldCount(state->hDBFHandle); i++)
1569  {
1570  /* Special case for NULL attributes */
1571  if (DBFIsAttributeNULL(state->hDBFHandle, item, i))
1572  {
1573  if (state->config->dump_format)
1574  stringbuffer_aprintf(sb, "\\N");
1575  else
1576  stringbuffer_aprintf(sb, "NULL");
1577  }
1578  else
1579  {
1580  /* Attribute NOT NULL */
1581  switch (state->types[i])
1582  {
1583  case FTInteger:
1584  case FTDouble:
1585  rv = snprintf(val, MAXVALUELEN, "%s", DBFReadStringAttribute(state->hDBFHandle, item, i));
1586  if (rv >= MAXVALUELEN || rv == -1)
1587  {
1588  stringbuffer_aprintf(sbwarn, "Warning: field %d name truncated\n", i);
1589  val[MAXVALUELEN - 1] = '\0';
1590  }
1591 
1592  /* If the value is an empty string, change to 0 */
1593  if (val[0] == '\0')
1594  {
1595  val[0] = '0';
1596  val[1] = '\0';
1597  }
1598 
1599  /* If the value ends with just ".", remove the dot */
1600  if (val[strlen(val) - 1] == '.')
1601  val[strlen(val) - 1] = '\0';
1602  break;
1603 
1604  case FTString:
1605  case FTLogical:
1606  case FTDate:
1607  rv = snprintf(val, MAXVALUELEN, "%s", DBFReadStringAttribute(state->hDBFHandle, item, i));
1608  if (rv >= MAXVALUELEN || rv == -1)
1609  {
1610  stringbuffer_aprintf(sbwarn, "Warning: field %d name truncated\n", i);
1611  val[MAXVALUELEN - 1] = '\0';
1612  }
1613  break;
1614 
1615  default:
1616  snprintf(state->message, SHPLOADERMSGLEN, _("Error: field %d has invalid or unknown field type (%d)"), i, state->types[i]);
1617 
1618  /* clean up and return err */
1619  SHPDestroyObject(obj);
1620  stringbuffer_destroy(sbwarn);
1622  return SHPLOADERERR;
1623  }
1624 
1625  if (state->config->encoding)
1626  {
1627  char *encoding_msg = _("Try \"LATIN1\" (Western European), or one of the values described at http://www.postgresql.org/docs/current/static/multibyte.html.");
1628 
1629  rv = utf8(state->config->encoding, val, &utf8str);
1630 
1631  if (rv != UTF8_GOOD_RESULT)
1632  {
1633  if ( rv == UTF8_BAD_RESULT )
1634  snprintf(state->message, SHPLOADERMSGLEN, _("Unable to convert data value \"%s\" to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s"), utf8str, strerror(errno), state->config->encoding, encoding_msg);
1635  else if ( rv == UTF8_NO_RESULT )
1636  snprintf(state->message, SHPLOADERMSGLEN, _("Unable to convert data value to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s"), strerror(errno), state->config->encoding, encoding_msg);
1637  else
1638  snprintf(state->message, SHPLOADERMSGLEN, _("Unexpected return value from utf8()"));
1639 
1640  if ( rv == UTF8_BAD_RESULT )
1641  free(utf8str);
1642 
1643  /* clean up and return err */
1644  SHPDestroyObject(obj);
1645  stringbuffer_destroy(sbwarn);
1647  return SHPLOADERERR;
1648  }
1649  strncpy(val, utf8str, MAXVALUELEN);
1650  free(utf8str);
1651 
1652  }
1653 
1654  /* Escape attribute correctly according to dump format */
1655  if (state->config->dump_format)
1656  {
1657  escval = escape_copy_string(val);
1658  stringbuffer_aprintf(sb, "%s", escval);
1659  }
1660  else
1661  {
1662  escval = escape_insert_string(val);
1663  stringbuffer_aprintf(sb, "'%s'", escval);
1664  }
1665 
1666  /* Free the escaped version if required */
1667  if (val != escval)
1668  free(escval);
1669  }
1670 
1671  /* Only put in delimeter if not last field or a shape will follow */
1672  if (state->config->readshape == 1 || i < DBFGetFieldCount(state->hDBFHandle) - 1)
1673  {
1674  if (state->config->dump_format)
1675  stringbuffer_aprintf(sb, "\t");
1676  else
1677  stringbuffer_aprintf(sb, ",");
1678  }
1679 
1680  /* End of DBF attribute loop */
1681  }
1682 
1683 
1684  /* Add the shape attribute if we are reading it */
1685  if (state->config->readshape == 1)
1686  {
1687  /* Force the locale to C */
1688  char *oldlocale = setlocale(LC_NUMERIC, "C");
1689 
1690  /* Handle the case of a NULL shape */
1691  if (obj->nVertices == 0)
1692  {
1693  if (state->config->dump_format)
1694  stringbuffer_aprintf(sb, "\\N");
1695  else
1696  stringbuffer_aprintf(sb, "NULL");
1697  }
1698  else
1699  {
1700  /* Handle all other shape attributes */
1701  switch (obj->nSHPType)
1702  {
1703  case SHPT_POLYGON:
1704  case SHPT_POLYGONM:
1705  case SHPT_POLYGONZ:
1706  res = GeneratePolygonGeometry(state, obj, &geometry);
1707  break;
1708 
1709  case SHPT_POINT:
1710  case SHPT_POINTM:
1711  case SHPT_POINTZ:
1712  res = GeneratePointGeometry(state, obj, &geometry, 0);
1713  break;
1714 
1715  case SHPT_MULTIPOINT:
1716  case SHPT_MULTIPOINTM:
1717  case SHPT_MULTIPOINTZ:
1718  /* Force it to multi unless using -S */
1719  res = GeneratePointGeometry(state, obj, &geometry,
1720  state->config->simple_geometries ? 0 : 1);
1721  break;
1722 
1723  case SHPT_ARC:
1724  case SHPT_ARCM:
1725  case SHPT_ARCZ:
1726  res = GenerateLineStringGeometry(state, obj, &geometry);
1727  break;
1728 
1729  default:
1730  snprintf(state->message, SHPLOADERMSGLEN, _("Shape type is not supported, type id = %d"), obj->nSHPType);
1731  SHPDestroyObject(obj);
1732  stringbuffer_destroy(sbwarn);
1734 
1735  return SHPLOADERERR;
1736  }
1737  /* The default returns out of the function, so res will always have been set. */
1738  if (res != SHPLOADEROK)
1739  {
1740  /* Error message has already been set */
1741  SHPDestroyObject(obj);
1742  stringbuffer_destroy(sbwarn);
1744 
1745  return SHPLOADERERR;
1746  }
1747 
1748  /* Now generate the geometry string according to the current configuration */
1749  if (!state->config->dump_format)
1750  {
1751  if (state->to_srid != state->from_srid)
1752  {
1753  stringbuffer_aprintf(sb, "ST_Transform(");
1754  }
1755  stringbuffer_aprintf(sb, "'");
1756  }
1757 
1758  stringbuffer_aprintf(sb, "%s", geometry);
1759 
1760  if (!state->config->dump_format)
1761  {
1762  stringbuffer_aprintf(sb, "'");
1763 
1764  /* Close the ST_Transform if reprojecting. */
1765  if (state->to_srid != state->from_srid)
1766  {
1767  /* We need to add an explicit cast to geography/geometry to ensure that
1768  PostgreSQL doesn't get confused with the ST_Transform() raster
1769  function. */
1770  if (state->config->geography)
1771  stringbuffer_aprintf(sb, "::geometry, %d)::geography", state->to_srid);
1772  else
1773  stringbuffer_aprintf(sb, "::geometry, %d)", state->to_srid);
1774  }
1775  }
1776 
1777  free(geometry);
1778  }
1779 
1780  /* Tidy up everything */
1781  SHPDestroyObject(obj);
1782 
1783  setlocale(LC_NUMERIC, oldlocale);
1784  }
1785 
1786  /* Close the line correctly for dump/insert format */
1787  if (!state->config->dump_format)
1788  stringbuffer_aprintf(sb, ");");
1789 
1790 
1791  /* Copy the string buffer into a new string, destroying the string buffer */
1792  ret = (char *)malloc(strlen((char *)stringbuffer_getstring(sb)) + 1);
1793  strcpy(ret, (char *)stringbuffer_getstring(sb));
1795 
1796  *strrecord = ret;
1797 
1798  /* If any warnings occurred, set the returned message string and warning status */
1799  if (strlen((char *)stringbuffer_getstring(sbwarn)) > 0)
1800  {
1801  snprintf(state->message, SHPLOADERMSGLEN, "%s", stringbuffer_getstring(sbwarn));
1802  stringbuffer_destroy(sbwarn);
1803 
1804  return SHPLOADERWARN;
1805  }
1806  else
1807  {
1808  /* Everything went okay */
1809  stringbuffer_destroy(sbwarn);
1810 
1811  return SHPLOADEROK;
1812  }
1813 }
SHPLOADERCONFIG * config
#define SHPT_ARCM
Definition: shapefil.h:316
tuple res
Definition: window.py:78
DBFFieldType * types
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
Definition: stringbuffer.c:46
#define SHPT_POLYGONM
Definition: shapefil.h:317
int nVertices
Definition: shapefil.h:348
#define SHPLOADERRECISNULL
#define _(String)
Definition: shpcommon.h:24
const char SHPAPI_CALL1 * DBFReadStringAttribute(DBFHandle psDBF, int iRecord, int iField){ return((const char *) DBFReadAttribute(psDBF, iRecord, iField, 'C')
#define UTF8_BAD_RESULT
#define SHPLOADERWARN
#define SHPT_MULTIPOINT
Definition: shapefil.h:310
#define POLICY_NULL_SKIP
#define SHPLOADERRECDELETED
#define SHPT_POLYGON
Definition: shapefil.h:309
void SHPAPI_CALL SHPDestroyObject(SHPObject *psObject)
Definition: shpopen.c:2182
#define SHPT_MULTIPOINTZ
Definition: shapefil.h:314
int GeneratePointGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry, int force_multi)
Generate an allocated geometry string for shapefile object obj using the state parameters if "force_m...
int GeneratePolygonGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry)
Generate an allocated geometry string for shapefile object obj using the state parameters.
int GenerateLineStringGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry)
Generate an allocated geometry string for shapefile object obj using the state parameters.
DBFHandle hDBFHandle
#define UTF8_GOOD_RESULT
#define SHPT_ARCZ
Definition: shapefil.h:312
char * escape_insert_string(char *str)
Escape input string suitable for INSERT.
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:246
int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF)
Definition: dbfopen.c:1191
void stringbuffer_clear(stringbuffer_t *s)
Reset the stringbuffer_t.
Definition: stringbuffer.c:83
SHPObject SHPAPI_CALL1 * SHPReadObject(SHPHandle hSHP, int iShape);int SHPAPI_CALL SHPWriteObject(SHPHandle hSHP, int iShape, SHPObject *psObject
char * escape_copy_string(char *str)
Escape input string suitable for COPY.
#define SHPLOADEROK
#define UTF8_NO_RESULT
#define SHPT_MULTIPOINTM
Definition: shapefil.h:318
#define SHPT_POINTZ
Definition: shapefil.h:311
SHPHandle hSHPHandle
#define SHPT_POINTM
Definition: shapefil.h:315
#define SHPT_POLYGONZ
Definition: shapefil.h:313
char message[SHPLOADERMSGLEN]
#define SHPT_POINT
Definition: shapefil.h:307
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
Definition: stringbuffer.c:71
static int utf8(const char *fromcode, char *inputbuf, char **outputbuf)
const char * stringbuffer_getstring(stringbuffer_t *s)
Returns a reference to the internal string being managed by the stringbuffer.
Definition: stringbuffer.c:142
#define MAXVALUELEN
void free(void *)
void * malloc(YYSIZE_T)
int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle psDBF, int iRecord, int iField)
Definition: dbfopen.c:1171
#define SHPLOADERERR
int nSHPType
Definition: shapefil.h:340
#define SHPT_ARC
Definition: shapefil.h:308
#define SHPLOADERMSGLEN
int SHPAPI_CALL DBFIsRecordDeleted(DBFHandle psDBF, int iShape)
Definition: dbfopen.c:1728
Here is the call graph for this function:
Here is the caller graph for this function: