PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ ShpLoaderGenerateSQLRowStatement()

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

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

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