PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ ShpLoaderGenerateSQLRowStatement()

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

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

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

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, FTDate, FTDouble, FTInteger, FTLogical, FTString, GenerateLineStringGeometry(), GeneratePointGeometry(), GeneratePolygonGeometry(), shp_loader_config::geography, shp_loader_state::hDBFHandle, shp_loader_state::hSHPHandle, malloc(), MAXVALUELEN, shp_loader_state::message, tagSHPObject::nSHPType, shp_loader_config::null_policy, tagSHPObject::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: