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

◆ ShpLoaderGenerateSQLRowStatement()

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

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

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