1334{
1336
1337 char buf[256];
1338 char *query;
1339 int gidfound = 0, i, j, ret, status;
1340
1341
1342
1344 {
1348 }
1349
1350
1352 {
1354 sprintf(state->
table,
"__pgsql2shp%lu_tmp_table", (
long)getpid());
1355
1357
1359 res = PQexec(state->
conn, query);
1361
1362
1363 if (PQresultStatus(res) != PGRES_COMMAND_OK)
1364 {
1366 PQclear(res);
1368 }
1369 }
1370 else
1371 {
1372
1376 }
1377
1378
1379
1381 {
1383
1384 sprintf(query, "SELECT a.attname, a.atttypid, "
1385 "a.atttypmod, a.attlen FROM "
1386 "pg_attribute a, pg_class c, pg_namespace n WHERE "
1387 "n.nspname = '%s' AND a.attrelid = c.oid AND "
1388 "n.oid = c.relnamespace AND "
1389 "a.atttypid != 0 AND "
1390 "a.attnum > 0 AND c.relname = '%s'", state->
schema, state->
table);
1391 }
1392 else
1393 {
1395
1396 sprintf(query, "SELECT a.attname, a.atttypid, "
1397 "a.atttypmod, a.attlen FROM "
1398 "pg_attribute a, pg_class c WHERE "
1399 "a.attrelid = c.oid and a.attnum > 0 AND "
1400 "a.atttypid != 0 AND "
1401 "c.relname = '%s' AND "
1402 "pg_catalog.pg_table_is_visible(c.oid)", state->
table);
1403 }
1404
1405 LWDEBUGF(3,
"query is: %s\n", query);
1406
1407 res = PQexec(state->
conn, query);
1409
1410 if (PQresultStatus(res) != PGRES_TUPLES_OK)
1411 {
1413 PQclear(res);
1415 }
1416
1417 if (!PQntuples(res))
1418 {
1420 PQclear(res);
1422 }
1423
1424
1427 else
1429
1430
1431
1432
1433 if ( getenv("PGCLIENTENCODING") )
1434 {
1437 }
1438 else
1439 {
1441 }
1442
1444 {
1447 }
1448
1449
1450
1451
1452
1459 int tmpint = 1;
1460
1461 for (i = 0; i < PQntuples(res); i++)
1462 {
1463 char *ptr;
1464
1465 int pgfieldtype, pgtypmod, pgfieldlen;
1466 char *pgfieldname;
1467
1468 int dbffieldtype, dbffieldsize, dbffielddecs;
1469 char *dbffieldname;
1470
1471 pgfieldname = PQgetvalue(res, i, 0);
1472 pgfieldtype = atoi(PQgetvalue(res, i, 1));
1473 pgtypmod = atoi(PQgetvalue(res, i, 2));
1474 pgfieldlen = atoi(PQgetvalue(res, i, 3));
1475 dbffieldtype = -1;
1476 dbffieldsize = 0;
1477 dbffielddecs = 0;
1478
1479
1480
1481
1483 {
1484
1486 {
1487
1488
1489
1491 {
1492 dbffieldtype = 9;
1493
1495 }
1496 }
1497 }
1498
1499
1500
1501
1502
1503
1504
1505 if (!strcmp(pgfieldname, "gid") )
1506 {
1507 gidfound = 1;
1508
1510 continue;
1511 }
1512
1513
1514 ptr = pgfieldname;
1516 {
1517 if (*ptr == '_')
1518 ptr += 2;
1519 }
1520
1521
1522
1523
1524
1525
1526
1527 dbffieldname =
malloc(11);
1528 strncpy(dbffieldname, ptr, 10);
1529 dbffieldname[10] = '\0';
1530
1531
1532
1533
1534 {
1536 if (mapped)
1537 {
1538 strncpy(dbffieldname, mapped, 10);
1539 dbffieldname[10] = '\0';
1540 }
1541 }
1542
1543
1544
1545
1546 tmpint = 1;
1548 {
1549 if (!strncasecmp(dbffieldname, state->
dbffieldnames[j], 10))
1550 {
1551 sprintf(dbffieldname, "%.7s_%.2d", ptr, abs(tmpint) % 100);
1552 tmpint++;
1553 continue;
1554 }
1555 }
1556
1557
1559 {
1560 size_t nameit;
1561 for (nameit = 0; nameit < strlen(dbffieldname); nameit++)
1562 dbffieldname[nameit] = toupper(dbffieldname[nameit]);
1563 }
1564
1565
1566 if (strcasecmp(dbffieldname, pgfieldname))
1567 {
1568 if ( snprintf(buf, 256,
_(
"Warning, field %s renamed to %s\n"),
1569 pgfieldname, dbffieldname) >= 256 )
1570 {
1571 buf[255] = '\0';
1572 }
1573
1575
1577 }
1578
1579
1580
1581
1582
1583
1584
1585 if (pgfieldtype == 21)
1586 {
1587
1588
1589
1590
1591
1592 dbffieldtype = FTInteger;
1593 dbffieldsize = 6;
1594 dbffielddecs = 0;
1595 }
1596
1597
1598 else if (pgfieldtype == 23)
1599 {
1600
1601
1602
1603
1604
1605 dbffieldtype = FTInteger;
1606 dbffieldsize = 11;
1607 dbffielddecs = 0;
1608 }
1609
1610
1611 else if (pgfieldtype == 20)
1612 {
1613
1614
1615
1616
1617
1618 dbffieldtype = FTInteger;
1619 dbffieldsize = 19;
1620 dbffielddecs = 0;
1621 }
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632 else if (pgfieldtype == 700 || pgfieldtype == 701 || pgfieldtype == 1700)
1633 {
1634 dbffieldtype = FTDouble;
1635 dbffieldsize = 32;
1636 dbffielddecs = 10;
1637 }
1638
1639
1640
1641
1642 else if (pgfieldtype == 16)
1643 {
1644 dbffieldtype = FTLogical;
1645 dbffieldsize = 1;
1646 dbffielddecs = 0;
1647 }
1648
1649
1650
1651
1652 else if (pgfieldtype == 1082)
1653 {
1654 dbffieldtype = FTDate;
1655 dbffieldsize = 8;
1656 dbffielddecs = 0;
1657 }
1658
1659
1660
1661
1662 else if (pgfieldtype == 1083 || pgfieldtype == 1266 || pgfieldtype == 1114 || pgfieldtype == 1184)
1663 {
1664 int secondsize;
1665
1666 switch (pgtypmod)
1667 {
1668 case -1:
1669 secondsize = 6 + 1;
1670 break;
1671 case 0:
1672 secondsize = 0;
1673 break;
1674 default:
1675 secondsize = pgtypmod + 1;
1676 break;
1677 }
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687 if (pgfieldtype == 1083)
1688 {
1689 dbffieldsize = 8 + secondsize;
1690 }
1691
1692 else if (pgfieldtype == 1266)
1693 {
1694 dbffieldsize = 8 + secondsize + 9;
1695 }
1696
1697 else if (pgfieldtype == 1114)
1698 {
1699 dbffieldsize = 13 + 1 + 8 + secondsize;
1700 }
1701
1702 else if (pgfieldtype == 1184)
1703 {
1704 dbffieldsize = 13 + 1 + 8 + secondsize + 9;
1705 }
1706
1707 dbffieldtype = FTString;
1708 dbffielddecs = 0;
1709 }
1710
1711
1712
1713
1714 else if (pgfieldtype == 2950)
1715 {
1716 dbffieldtype = FTString;
1717 dbffieldsize = 36;
1718 dbffielddecs = 0;
1719 }
1720
1721
1722
1723
1724
1725
1726 else if ((pgfieldtype == 1042 || pgfieldtype == 1043) && pgtypmod != -1)
1727 {
1728
1729
1730
1731
1732 dbffieldtype = FTString;
1733 dbffieldsize = pgtypmod - 4;
1734 dbffielddecs = 0;
1735 }
1736
1737
1738 else if (dbffieldtype == -1)
1739 {
1740
1741
1742
1743
1744
1746 if (dbffieldsize == -1)
1747 {
1749 return 0;
1750 }
1751
1752 if (!dbffieldsize)
1753 dbffieldsize = 32;
1754
1755
1756
1757 dbffieldtype = FTString;
1758 dbffielddecs = 0;
1759
1760
1762 {
1763
1764 snprintf(buf, 256,
_(
"Warning: values of field '%s' exceeding maximum dbf field width (%d) "
1768
1770 }
1771 }
1772
1773 LWDEBUGF(3,
"DBF FIELD_NAME: %s, SIZE: %d\n", dbffieldname, dbffieldsize);
1774
1775 if (dbffieldtype != 9)
1776 {
1777
1778 if (
DBFAddField(state->
dbf, dbffieldname, dbffieldtype, dbffieldsize, dbffielddecs) == -1)
1779 {
1780 snprintf(state->
message,
SHPDUMPERMSGLEN,
_(
"Error: field %s of type %d could not be created."), dbffieldname, dbffieldtype);
1781
1783 }
1784
1785
1791
1793 }
1794 }
1795
1796
1800
1804
1805
1807 {
1809 {
1810
1812
1814 }
1815 else
1816 {
1817
1818
1819 snprintf(buf, 256,
_(
"No geometry column found.\nThe DBF file will be created but not the shx or shp files.\n"));
1821
1823
1825 }
1826 }
1827 else
1828 {
1829
1832 {
1834
1836 }
1837 }
1838
1839
1840
1841
1842 j = 0;
1843
1846
1848
1852
1854
1856 {
1857
1858 if (i > 0)
1860
1863 else
1865
1867 }
1868
1869
1871 {
1872
1875
1876#ifdef WORDS_BIGENDIAN
1878 {
1880 }
1881 else
1882 {
1883 sprintf(buf, "asbinary(%s::geometry, 'XDR') AS _geoX",
1885 }
1886#else
1888 {
1890 }
1891 else
1892 {
1893 sprintf(buf, "asbinary(%s::geometry, 'NDR') AS _geoX",
1895 }
1896#endif
1897
1899 }
1900
1902 {
1903 sprintf(buf,
" FROM \"%s\".\"%s\"", state->
schema, state->
table);
1904 }
1905 else
1906 {
1907 sprintf(buf,
" FROM \"%s\"", state->
table);
1908 }
1909
1911
1912
1913 if (gidfound)
1914 {
1915 sprintf(buf, " ORDER BY \"gid\"");
1917 }
1918
1919
1920 PQclear(res);
1921
1923
1924
1925
1926
1927
1928 res = PQexec(state->
conn,
"BEGIN");
1929 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
1930 {
1932 PQclear(res);
1934 }
1935
1936 PQclear(res);
1937
1938
1940 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
1941 {
1942 snprintf(state->
message,
SHPDUMPERMSGLEN,
_(
"Error executing main scan query: %s"), PQresultErrorMessage(res));
1943 PQclear(res);
1945 }
1946
1947 PQclear(res);
1948
1949
1954
1955
1958
1960}
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)
#define LWDEBUGF(level, msg,...)
static int getMaxFieldSize(PGconn *conn, char *schema, char *table, char *fname)
char * quote_identifier(const char *s)
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)
char * column_map_filename
char message[SHPDUMPERMSGLEN]