PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ ShpLoaderGenerateSQLRowStatement()

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

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

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