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

◆ ShpLoaderGenerateSQLRowStatement()

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

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

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