1314{
1316
1317 char buf[256];
1318 int gidfound = 0, i, j, ret, status;
1320 char *quoted = NULL;
1321
1322
1324 {
1328 }
1329
1330
1332 {
1336 "CREATE TEMP TABLE \"%s\" AS %s",
1340
1341
1342 if (PQresultStatus(res) != PGRES_COMMAND_OK)
1343 {
1345 PQclear(res);
1347 }
1348 PQclear(res);
1349 }
1350 else
1351 {
1352
1356 }
1357
1359
1361 {
1363 "SELECT a.attname, a.atttypid, "
1364 "a.atttypmod, a.attlen FROM "
1365 "pg_attribute a, pg_class c, pg_namespace n WHERE "
1366 "n.nspname = '%s' AND a.attrelid = c.oid AND "
1367 "n.oid = c.relnamespace AND "
1368 "a.atttypid != 0 AND "
1369 "a.attnum > 0 AND c.relname = '%s'",
1372 }
1373 else
1374 {
1376 "SELECT a.attname, a.atttypid, "
1377 "a.atttypmod, a.attlen FROM "
1378 "pg_attribute a, pg_class c WHERE "
1379 "a.attrelid = c.oid and a.attnum > 0 AND "
1380 "a.atttypid != 0 AND "
1381 "c.relname = '%s' AND "
1382 "pg_catalog.pg_table_is_visible(c.oid)",
1384 }
1385
1387
1390
1391 if (PQresultStatus(res) != PGRES_TUPLES_OK)
1392 {
1394 PQclear(res);
1396 }
1397
1398 if (!PQntuples(res))
1399 {
1401 PQclear(res);
1403 }
1404
1405
1408 else
1410
1411
1412
1413
1414 if ( getenv("PGCLIENTENCODING") )
1415 {
1417 if (!codepage)
1421 }
1422 else
1423 {
1425 }
1426
1428 {
1431 }
1432
1433
1435
1436
1437
1438
1439
1446 int tmpint = 1;
1447
1448 for (i = 0; i < PQntuples(res); i++)
1449 {
1450 char *ptr;
1451
1452 int pgfieldtype, pgtypmod, pgfieldlen;
1453 char *pgfieldname;
1454
1455 int dbffieldtype, dbffieldsize, dbffielddecs;
1456 char *dbffieldname;
1457
1458 pgfieldname = PQgetvalue(res, i, 0);
1459 pgfieldtype = atoi(PQgetvalue(res, i, 1));
1460 pgtypmod = atoi(PQgetvalue(res, i, 2));
1461 pgfieldlen = atoi(PQgetvalue(res, i, 3));
1462 dbffieldtype = -1;
1463 dbffieldsize = 0;
1464 dbffielddecs = 0;
1465
1466
1467
1468
1470 {
1471
1473 {
1474
1475
1476
1478 {
1479 dbffieldtype = 9;
1480
1482 }
1483 }
1484 }
1485
1486
1487
1488
1489
1490
1491
1492 if (!strcmp(pgfieldname, "gid") )
1493 {
1494 gidfound = 1;
1495
1497 continue;
1498 }
1499
1500
1501 ptr = pgfieldname;
1503 {
1504 if (*ptr == '_')
1505 ptr += 2;
1506 }
1507
1508
1509
1510
1511
1512
1513
1514 dbffieldname =
malloc(11);
1515 strncpy(dbffieldname, ptr, 10);
1516 dbffieldname[10] = '\0';
1517
1518
1519
1520
1521 {
1523 if (mapped)
1524 {
1525 strncpy(dbffieldname, mapped, 10);
1526 dbffieldname[10] = '\0';
1527 }
1528 }
1529
1530
1531
1532
1533 tmpint = 1;
1535 {
1536 if (!strncasecmp(dbffieldname, state->
dbffieldnames[j], 10))
1537 {
1538 sprintf(dbffieldname, "%.7s_%.2d", ptr, abs(tmpint) % 100);
1539 tmpint++;
1540 continue;
1541 }
1542 }
1543
1544
1546 {
1547 size_t nameit;
1548 for (nameit = 0; nameit < strlen(dbffieldname); nameit++)
1549 dbffieldname[nameit] = toupper(dbffieldname[nameit]);
1550 }
1551
1552
1553 if (strcasecmp(dbffieldname, pgfieldname))
1554 {
1555 snprintf(buf,
sizeof(buf),
_(
"Warning, field %s renamed to %s\n"), pgfieldname, dbffieldname);
1556
1559
1561 }
1562
1563
1564
1565
1566
1567
1568
1569 if (pgfieldtype == 21)
1570 {
1571
1572
1573
1574
1575
1577 dbffieldsize = 6;
1578 dbffielddecs = 0;
1579 }
1580
1581
1582 else if (pgfieldtype == 23)
1583 {
1584
1585
1586
1587
1588
1590 dbffieldsize = 11;
1591 dbffielddecs = 0;
1592 }
1593
1594
1595 else if (pgfieldtype == 20)
1596 {
1597
1598
1599
1600
1601
1603 dbffieldsize = 19;
1604 dbffielddecs = 0;
1605 }
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616 else if (pgfieldtype == 700 || pgfieldtype == 701 || pgfieldtype == 1700)
1617 {
1619 dbffieldsize = 32;
1620 dbffielddecs = 10;
1621 }
1622
1623
1624
1625
1626 else if (pgfieldtype == 16)
1627 {
1629 dbffieldsize = 1;
1630 dbffielddecs = 0;
1631 }
1632
1633
1634
1635
1636 else if (pgfieldtype == 1082)
1637 {
1639 dbffieldsize = 8;
1640 dbffielddecs = 0;
1641 }
1642
1643
1644
1645
1646 else if (pgfieldtype == 1083 || pgfieldtype == 1266 || pgfieldtype == 1114 || pgfieldtype == 1184)
1647 {
1648 int secondsize;
1649
1650 switch (pgtypmod)
1651 {
1652 case -1:
1653 secondsize = 6 + 1;
1654 break;
1655 case 0:
1656 secondsize = 0;
1657 break;
1658 default:
1659 secondsize = pgtypmod + 1;
1660 break;
1661 }
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671 if (pgfieldtype == 1083)
1672 {
1673 dbffieldsize = 8 + secondsize;
1674 }
1675
1676 else if (pgfieldtype == 1266)
1677 {
1678 dbffieldsize = 8 + secondsize + 9;
1679 }
1680
1681 else if (pgfieldtype == 1114)
1682 {
1683 dbffieldsize = 13 + 1 + 8 + secondsize;
1684 }
1685
1686 else if (pgfieldtype == 1184)
1687 {
1688 dbffieldsize = 13 + 1 + 8 + secondsize + 9;
1689 }
1690
1692 dbffielddecs = 0;
1693 }
1694
1695
1696
1697
1698 else if (pgfieldtype == 2950)
1699 {
1701 dbffieldsize = 36;
1702 dbffielddecs = 0;
1703 }
1704
1705
1706
1707
1708
1709
1710 else if ((pgfieldtype == 1042 || pgfieldtype == 1043) && pgtypmod != -1)
1711 {
1712
1713
1714
1715
1717 dbffieldsize = pgtypmod - 4;
1718 dbffielddecs = 0;
1719 }
1720
1721
1722 else if (dbffieldtype == -1)
1723 {
1724
1725
1726
1727
1728
1730 if (dbffieldsize == -1)
1731 {
1733 return 0;
1734 }
1735
1736 if (!dbffieldsize)
1737 dbffieldsize = 32;
1738
1739
1740
1742 dbffielddecs = 0;
1743
1744
1746 {
1747
1748 snprintf(buf,
sizeof(buf),
_(
"Warning: values of field '%s' exceeding maximum dbf field width (%d) "
1750
1753
1755
1757 }
1758 }
1759
1760 LWDEBUGF(3,
"DBF FIELD_NAME: %s, SIZE: %d\n", dbffieldname, dbffieldsize);
1761
1762 if (dbffieldtype != 9)
1763 {
1764
1765 if (
DBFAddField(state->
dbf, dbffieldname, dbffieldtype, dbffieldsize, dbffielddecs) == -1)
1766 {
1767 snprintf(state->
message,
SHPDUMPERMSGLEN,
_(
"Error: field %s of type %d could not be created."), dbffieldname, dbffieldtype);
1769
1771 }
1772
1773
1779
1781 }
1782 else
1783 {
1785 }
1786 }
1787
1788
1792
1796
1797
1799 {
1801 {
1802
1804
1806 }
1807 else
1808 {
1809
1810
1811 snprintf(buf,
sizeof(buf),
_(
"No geometry column found.\nThe DBF file will be created but not the shx or shp files.\n"));
1814
1816
1818 }
1819 }
1820 else
1821 {
1822
1825 {
1827
1829 }
1830 }
1831
1832
1833
1834 j = 0;
1835
1836
1839
1841
1845
1847
1849 {
1850
1851 if (i > 0) {
1853 }
1854
1857 {
1859 }
1860 else
1861 {
1863 }
1865 }
1866
1867
1869 {
1870
1873 }
1874
1876#ifndef WORDS_BIGENDIAN
1879 }
1880 else
1881 {
1883 }
1884#else
1886 {
1888 }
1889 else
1890 {
1892 }
1893#endif
1895 }
1896
1898 {
1900 " FROM \"%s\".\"%s\"",
1902 }
1903 else
1904 {
1906 " FROM \"%s\"",
1908 }
1909
1910
1911 if (gidfound)
1912 {
1914 }
1915
1916
1917 PQclear(res);
1918
1920
1921
1922
1923
1924
1925 res = PQexec(state->
conn,
"BEGIN");
1926 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
1927 {
1929 PQclear(res);
1931 }
1932
1933 PQclear(res);
1934
1935
1939 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
1940 {
1941 snprintf(state->
message,
SHPDUMPERMSGLEN,
_(
"Error executing main scan query: %s"), PQresultErrorMessage(res));
1942 PQclear(res);
1944 }
1945
1946 PQclear(res);
1947
1948
1953
1954
1956
1958}
int SHPAPI_CALL DBFAddField(DBFHandle psDBF, const char *pszFieldName, DBFFieldType eType, int nWidth, int nDecimals)
DBFHandle SHPAPI_CALL DBFCreateEx(const char *pszFilename, const char *pszCodePage)
void SHPAPI_CALL DBFSetWriteEndOfFileChar(DBFHandle psDBF, int bWriteFlag)
#define LWDEBUGF(level, msg,...)
static int getMaxFieldSize(PGconn *conn, char *schema, char *table, char *fname)
char * quote_identifier(const char *s)
static char * core_asprintf(const char *format,...) __attribute__((format(printf
static int getTableInfo(SHPDUMPERSTATE *state)
#define MAX_DBF_FIELD_SIZE
SHPHandle SHPAPI_CALL SHPCreate(const char *pszShapeFile, int nShapeType)
char * encoding2codepage(const char *encoding)
int colmap_read(const char *filename, colmap *map, char *errbuf, size_t errbuflen)
Read the content of filename into a symbol map.
const char * colmap_dbf_by_pg(colmap *map, const char *pgname)
void stringbuffer_release(stringbuffer_t *s)
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.
char * stringbuffer_getstringcopy(stringbuffer_t *s)
Returns a newly allocated string large enough to contain the current state of the string.
void stringbuffer_init(stringbuffer_t *s)
static void stringbuffer_append(stringbuffer_t *s, const char *a)
Append the specified string to the stringbuffer_t.
char * column_map_filename
char message[SHPDUMPERMSGLEN]