PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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();
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
1730done_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
const char SHPAPI_CALL1 * DBFReadStringAttribute(DBFHandle psDBF, int iRecord, int iField){ return STATIC_CAST(const char *, DBFReadAttribute(psDBF, iRecord, iField, 'C')
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
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
#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
SHPObject SHPAPI_CALL1 * SHPReadObject(SHPHandle hSHP, int iShape);int SHPAPI_CALL SHPWriteObject(SHPHandle hSHP, int iShape, SHPObject *psObject
Definition shpopen.c:1842
#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
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
void stringbuffer_clear(stringbuffer_t *s)
Reset the stringbuffer_t.
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.
const char * stringbuffer_getstring(stringbuffer_t *s)
Returns a reference to the internal string being managed by the stringbuffer.
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
char message[SHPLOADERMSGLEN]
DBFFieldType * types
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, 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, 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 main(), and pgui_action_import().

Here is the call graph for this function:
Here is the caller graph for this function: