PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ ShpLoaderGenerateSQLRowStatement()

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

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

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