PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ ShpLoaderGenerateSQLRowStatement()

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

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

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

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 pgui_action_import().

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