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

Definition at line 1487 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(), shp_loader_state::from_srid, GenerateLineStringGeometry(), GeneratePointGeometry(), GeneratePolygonGeometry(), shp_loader_config::geography, shp_loader_state::hDBFHandle, shp_loader_state::hSHPHandle, 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().

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

Here is the call graph for this function:

Here is the caller graph for this function: