PostGIS  2.5.0dev-r@@SVN_REVISION@@
int ShpLoaderGenerateSQLRowStatement ( SHPLOADERSTATE state,
int  item,
char **  strrecord 
)

Definition at line 1510 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().

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

Here is the call graph for this function:

Here is the caller graph for this function: