PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ ShpLoaderGenerateSQLRowStatement()

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

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

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