PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ ShpDumperOpenTable()

int ShpDumperOpenTable ( SHPDUMPERSTATE state)

Definition at line 1313 of file pgsql2shp-core.c.

1314 {
1315  PGresult *res;
1316 
1317  char buf[256];
1318  int gidfound = 0, i, j, ret, status;
1319  stringbuffer_t sb;
1320  char *quoted = NULL;
1321 
1322  /* Open the column map if one was specified */
1323  if (state->config->column_map_filename)
1324  {
1325  ret = colmap_read(state->config->column_map_filename,
1326  &state->column_map, state->message, SHPDUMPERMSGLEN);
1327  if (!ret) return SHPDUMPERERR;
1328  }
1329 
1330  /* If a user-defined query has been specified, create and point the state to our new table */
1331  if (state->config->usrquery)
1332  {
1333  state->table = core_asprintf("__pgsql2shp%lu_tmp_table", (long)getpid());
1334  stringbuffer_init(&sb);
1336  "CREATE TEMP TABLE \"%s\" AS %s",
1337  state->table, state->config->usrquery);
1338  res = PQexec(state->conn, stringbuffer_getstring(&sb));
1339  stringbuffer_release(&sb);
1340 
1341  /* Execute the code to create the table */
1342  if (PQresultStatus(res) != PGRES_COMMAND_OK)
1343  {
1344  snprintf(state->message, SHPDUMPERMSGLEN, _("Error executing user query: %s"), PQresultErrorMessage(res));
1345  PQclear(res);
1346  return SHPDUMPERERR;
1347  }
1348  PQclear(res);
1349  }
1350  else
1351  {
1352  /* Simply point the state to copies of the supplied schema and table */
1353  state->table = strdup(state->config->table);
1354  if (state->config->schema)
1355  state->schema = strdup(state->config->schema);
1356  }
1357 
1358  stringbuffer_init(&sb);
1359  /* Get the list of columns and their types for the selected table */
1360  if (state->schema)
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'",
1370  state->schema,
1371  state->table);
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)",
1383  state->table);
1384  }
1385 
1386  LWDEBUGF(3, "query is: %s\n", stringbuffer_getstring(&sb));
1387 
1388  res = PQexec(state->conn, stringbuffer_getstring(&sb));
1389  stringbuffer_release(&sb);
1390 
1391  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1392  {
1393  snprintf(state->message, SHPDUMPERMSGLEN, _("Error querying for attributes: %s"), PQresultErrorMessage(res));
1394  PQclear(res);
1395  return SHPDUMPERERR;
1396  }
1397 
1398  if (!PQntuples(res))
1399  {
1400  snprintf(state->message, SHPDUMPERMSGLEN, _("Table %s does not exist"), state->table);
1401  PQclear(res);
1402  return SHPDUMPERERR;
1403  }
1404 
1405  /* If a shapefile name was specified, use it. Otherwise simply use the table name. */
1406  if (state->config->shp_file != NULL)
1407  state->shp_file = state->config->shp_file;
1408  else
1409  state->shp_file = state->table;
1410 
1411  /* Create the dbf file: */
1412  /* If there's a user-specified encoding hanging around, try and use that. */
1413  /* Otherwise, just use UTF-8 encoding, since that's usually our client encoding. */
1414  if ( getenv("PGCLIENTENCODING") )
1415  {
1416  char *codepage = encoding2codepage(getenv("PGCLIENTENCODING"));
1417  if (!codepage)
1418  return SHPDUMPERERR;
1419  state->dbf = DBFCreateEx(state->shp_file, codepage);
1420  free(codepage);
1421  }
1422  else
1423  {
1424  state->dbf = DBFCreateEx(state->shp_file, "UTF-8");
1425  }
1426 
1427  if (!state->dbf)
1428  {
1429  snprintf(state->message, SHPDUMPERMSGLEN, _("Could not create dbf file %s"), state->shp_file);
1430  return SHPDUMPERERR;
1431  }
1432 
1433  /* Mimic old behaviour and skip the EOF character (1A) */
1434  DBFSetWriteEndOfFileChar(state->dbf, 0);
1435 
1436  /*
1437  * Scan the result setting fields to be returned in mainscan
1438  * query, filling the type_ary, and creating .dbf and .shp files.
1439  */
1440  state->dbffieldnames = malloc(sizeof(char *) * PQntuples(res));
1441  state->dbffieldtypes = malloc(sizeof(int) * PQntuples(res));
1442  state->pgfieldnames = malloc(sizeof(char *) * PQntuples(res));
1443  state->pgfieldlens = malloc(sizeof(int) * PQntuples(res));
1444  state->pgfieldtypmods = malloc(sizeof(int) * PQntuples(res));
1445  state->fieldcount = 0;
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  * This is a geometry/geography column
1468  */
1469  if (pgfieldtype == state->geom_oid || pgfieldtype == state->geog_oid)
1470  {
1471  /* If no geometry/geography column has been found yet... */
1472  if (!state->geo_col_name)
1473  {
1474  /* If either no geo* column name was provided (in which case this is
1475  the first match) or we match the provided column name, we have
1476  found our geo* column */
1477  if (!state->config->geo_col_name || !strcmp(state->config->geo_col_name, pgfieldname))
1478  {
1479  dbffieldtype = 9;
1480 
1481  state->geo_col_name = strdup(pgfieldname);
1482  }
1483  }
1484  }
1485 
1486  /*
1487  * Everything else (non geometries) will be
1488  * a DBF attribute.
1489  */
1490 
1491  /* Skip gid (if not asked to do otherwise */
1492  if (!strcmp(pgfieldname, "gid") )
1493  {
1494  gidfound = 1;
1495 
1496  if (!state->config->includegid)
1497  continue;
1498  }
1499 
1500  /* Unescape any reserved column names */
1501  ptr = pgfieldname;
1502  if (!state->config->unescapedattrs)
1503  {
1504  if (*ptr == '_')
1505  ptr += 2;
1506  }
1507 
1508  /*
1509  * This needs special handling since both xmin and _xmin
1510  * becomes __xmin when escaped
1511  */
1512 
1513  /* Limit dbf field name to 10-digits */
1514  dbffieldname = malloc(11);
1515  strncpy(dbffieldname, ptr, 10);
1516  dbffieldname[10] = '\0';
1517 
1518  /* If a column map file has been passed in,
1519  * use this to create the dbf field name from
1520  * the PostgreSQL column name */
1521  {
1522  const char *mapped = colmap_dbf_by_pg(&state->column_map, pgfieldname);
1523  if (mapped)
1524  {
1525  strncpy(dbffieldname, mapped, 10);
1526  dbffieldname[10] = '\0';
1527  }
1528  }
1529 
1530  /*
1531  * make sure the fields all have unique names,
1532  */
1533  tmpint = 1;
1534  for (j = 0; j < state->fieldcount; j++)
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  /* make UPPERCASE if keep_fieldname_case = 0 */
1545  if (!state->config->keep_fieldname_case)
1546  {
1547  size_t nameit;
1548  for (nameit = 0; nameit < strlen(dbffieldname); nameit++)
1549  dbffieldname[nameit] = toupper(dbffieldname[nameit]);
1550  }
1551 
1552  /* Issue warning if column has been renamed */
1553  if (strcasecmp(dbffieldname, pgfieldname))
1554  {
1555  snprintf(buf, sizeof(buf), _("Warning, field %s renamed to %s\n"), pgfieldname, dbffieldname);
1556  /* Note: we concatenate all warnings from the main loop as this is useful information */
1557  if (SHPDUMPERMSGLEN > (strlen(state->message) + 1))
1558  strncat(state->message, buf, SHPDUMPERMSGLEN - (strlen(state->message) + 1));
1559 
1560  ret = SHPDUMPERWARN;
1561  }
1562 
1563 
1564  /*
1565  * Find appropriate type of dbf attributes
1566  */
1567 
1568  /* int2 type */
1569  if (pgfieldtype == 21)
1570  {
1571  /*
1572  * Longest text representation for
1573  * an int2 type (16bit) is 6 bytes
1574  * (-32768)
1575  */
1576  dbffieldtype = FTInteger;
1577  dbffieldsize = 6;
1578  dbffielddecs = 0;
1579  }
1580 
1581  /* int4 type */
1582  else if (pgfieldtype == 23)
1583  {
1584  /*
1585  * Longest text representation for
1586  * an int4 type (32bit) is 11 bytes
1587  * (-2147483648)
1588  */
1589  dbffieldtype = FTInteger;
1590  dbffieldsize = 11;
1591  dbffielddecs = 0;
1592  }
1593 
1594  /* int8 type */
1595  else if (pgfieldtype == 20)
1596  {
1597  /*
1598  * Longest text representation for
1599  * an int8 type (64bit) is 20 bytes
1600  * (-9223372036854775808)
1601  */
1602  dbffieldtype = FTInteger;
1603  dbffieldsize = 19;
1604  dbffielddecs = 0;
1605  }
1606 
1607  /*
1608  * double or numeric types:
1609  * 700: float4
1610  * 701: float8
1611  * 1700: numeric
1612  *
1613  *
1614  * TODO: stricter handling of sizes
1615  */
1616  else if (pgfieldtype == 700 || pgfieldtype == 701 || pgfieldtype == 1700)
1617  {
1618  dbffieldtype = FTDouble;
1619  dbffieldsize = 32;
1620  dbffielddecs = 10;
1621  }
1622 
1623  /*
1624  * Boolean field, we use FTLogical
1625  */
1626  else if (pgfieldtype == 16)
1627  {
1628  dbffieldtype = FTLogical;
1629  dbffieldsize = 1;
1630  dbffielddecs = 0;
1631  }
1632 
1633  /*
1634  * Date field
1635  */
1636  else if (pgfieldtype == 1082)
1637  {
1638  dbffieldtype = FTDate;
1639  dbffieldsize = 8;
1640  dbffielddecs = 0;
1641  }
1642 
1643  /*
1644  * time, timetz, timestamp, or timestamptz field.
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  /* We assume the worst case scenario for all of these:
1664  * date = '5874897-12-31' = 13
1665  * date = '294276-11-20' = 12 (with --enable-interger-datetimes)
1666  * time = '00:00:00' = 8
1667  * zone = '+01:39:52' = 9 (see Europe/Helsinki around 1915)
1668  */
1669 
1670  /* time */
1671  if (pgfieldtype == 1083)
1672  {
1673  dbffieldsize = 8 + secondsize;
1674  }
1675  /* timetz */
1676  else if (pgfieldtype == 1266)
1677  {
1678  dbffieldsize = 8 + secondsize + 9;
1679  }
1680  /* timestamp */
1681  else if (pgfieldtype == 1114)
1682  {
1683  dbffieldsize = 13 + 1 + 8 + secondsize;
1684  }
1685  /* timestamptz */
1686  else if (pgfieldtype == 1184)
1687  {
1688  dbffieldsize = 13 + 1 + 8 + secondsize + 9;
1689  }
1690 
1691  dbffieldtype = FTString;
1692  dbffielddecs = 0;
1693  }
1694 
1695  /*
1696  * uuid type 36 bytes (12345678-9012-3456-7890-123456789012)
1697  */
1698  else if (pgfieldtype == 2950)
1699  {
1700  dbffieldtype = FTString;
1701  dbffieldsize = 36;
1702  dbffielddecs = 0;
1703  }
1704 
1705  /*
1706  * For variable-sized fields we know about, we use
1707  * the maximum allowed size.
1708  * 1042 is bpchar, 1043 is varchar
1709  */
1710  else if ((pgfieldtype == 1042 || pgfieldtype == 1043) && pgtypmod != -1)
1711  {
1712  /*
1713  * mod is maximum allowed size, including
1714  * header which contains *real* size.
1715  */
1716  dbffieldtype = FTString;
1717  dbffieldsize = pgtypmod - 4; /* 4 is header size */
1718  dbffielddecs = 0;
1719  }
1720 
1721  /* For all other valid non-geometry/geography fields... */
1722  else if (dbffieldtype == -1)
1723  {
1724  /*
1725  * For types we don't know anything about, all
1726  * we can do is query the table for the maximum field
1727  * size.
1728  */
1729  dbffieldsize = getMaxFieldSize(state->conn, state->schema, state->table, pgfieldname);
1730  if (dbffieldsize == -1)
1731  {
1732  free(dbffieldname);
1733  return 0;
1734  }
1735 
1736  if (!dbffieldsize)
1737  dbffieldsize = 32;
1738 
1739  /* might 0 be a good size ? */
1740 
1741  dbffieldtype = FTString;
1742  dbffielddecs = 0;
1743 
1744  /* Check to make sure the final field size isn't too large */
1745  if (dbffieldsize > MAX_DBF_FIELD_SIZE)
1746  {
1747  /* Note: we concatenate all warnings from the main loop as this is useful information */
1748  snprintf(buf, sizeof(buf), _("Warning: values of field '%s' exceeding maximum dbf field width (%d) "
1749  "will be truncated.\n"), dbffieldname, MAX_DBF_FIELD_SIZE);
1750 
1751  if (SHPDUMPERMSGLEN > (strlen(state->message) + 1))
1752  strncat(state->message, buf, SHPDUMPERMSGLEN - (strlen(state->message)+1));
1753 
1754  dbffieldsize = MAX_DBF_FIELD_SIZE;
1755 
1756  ret = SHPDUMPERWARN;
1757  }
1758  }
1759 
1760  LWDEBUGF(3, "DBF FIELD_NAME: %s, SIZE: %d\n", dbffieldname, dbffieldsize);
1761 
1762  if (dbffieldtype != 9)
1763  {
1764  /* Add the field to the DBF file */
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);
1768  free(dbffieldname);
1769 
1770  return SHPDUMPERERR;
1771  }
1772 
1773  /* Add the field information to our field arrays */
1774  state->dbffieldnames[state->fieldcount] = dbffieldname;
1775  state->dbffieldtypes[state->fieldcount] = dbffieldtype;
1776  state->pgfieldnames[state->fieldcount] = pgfieldname;
1777  state->pgfieldlens[state->fieldcount] = pgfieldlen;
1778  state->pgfieldtypmods[state->fieldcount] = pgtypmod;
1779 
1780  state->fieldcount++;
1781  }
1782  else
1783  {
1784  free(dbffieldname);
1785  }
1786  }
1787 
1788  /* Now we have generated the field lists, grab some info about the table */
1789  status = getTableInfo(state);
1790  if (status == SHPDUMPERERR)
1791  return SHPDUMPERERR;
1792 
1793  LWDEBUGF(3, "rows: %d\n", state->rowcount);
1794  LWDEBUGF(3, "shptype: %c\n", state->outtype);
1795  LWDEBUGF(3, "shpouttype: %d\n", state->outshptype);
1796 
1797  /* If we didn't find a geometry/geography column... */
1798  if (!state->geo_col_name)
1799  {
1800  if (state->config->geo_col_name)
1801  {
1802  /* A geo* column was specified, but not found */
1803  snprintf(state->message, SHPDUMPERMSGLEN, _("%s: no such attribute in table %s"), state->config->geo_col_name, state->table);
1804 
1805  return SHPDUMPERERR;
1806  }
1807  else
1808  {
1809  /* No geo* column specified so we can only create the DBF section -
1810  but let's issue a warning... */
1811  snprintf(buf, sizeof(buf), _("No geometry column found.\nThe DBF file will be created but not the shx or shp files.\n"));
1812  if (SHPDUMPERMSGLEN > (strlen(state->message) + 1))
1813  strncat(state->message, buf, SHPDUMPERMSGLEN - (strlen(state->message)+1));
1814 
1815  state->shp = NULL;
1816 
1817  ret = SHPDUMPERWARN;
1818  }
1819  }
1820  else
1821  {
1822  /* Since we have found a geo* column, open the shapefile */
1823  state->shp = SHPCreate(state->shp_file, state->outshptype);
1824  if (!state->shp)
1825  {
1826  snprintf(state->message, SHPDUMPERMSGLEN, _("Could not open shapefile %s!"), state->shp_file);
1827 
1828  return SHPDUMPERERR;
1829  }
1830  }
1831 
1832  /* Now we have the complete list of fieldnames, let's generate the SQL query. First let's make sure
1833  we reserve enough space for tables with lots of columns */
1834  j = 0;
1835 
1836  /*TODO: this really should be rewritten to use stringbuffer */
1837  for (i = 0; i < state->fieldcount; i++)
1838  j += strlen( state->pgfieldnames[i]) + 10; /*add extra space for the quotes to quote identify and any embedded quotes that may need escaping */
1839 
1840  stringbuffer_init(&sb);
1841 
1842  stringbuffer_append(&sb, "DECLARE cur ");
1843  if (state->config->binary)
1844  stringbuffer_append(&sb, "BINARY ");
1845 
1846  stringbuffer_append(&sb, "CURSOR FOR SELECT ");
1847 
1848  for (i = 0; i < state->fieldcount; i++)
1849  {
1850  /* Comma-separated column names */
1851  if (i > 0) {
1852  stringbuffer_append(&sb, ",");
1853  }
1854 
1855  quoted = quote_identifier(state->pgfieldnames[i]);
1856  if (state->config->binary)
1857  {
1858  stringbuffer_aprintf(&sb, "%s::text", quoted);
1859  }
1860  else
1861  {
1862  stringbuffer_append(&sb, quoted);
1863  }
1864  free(quoted);
1865  }
1866 
1867  /* If we found a valid geometry/geography column then use it */
1868  if (state->geo_col_name)
1869  {
1870  /* If this is the (only) column, no need for the initial comma */
1871  if (state->fieldcount > 0) {
1872  stringbuffer_append(&sb, ",");
1873  }
1874 
1875  quoted = quote_identifier(state->geo_col_name);
1876 #ifndef WORDS_BIGENDIAN
1877  if (state->pgis_major_version > 0) {
1878  stringbuffer_aprintf(&sb, "ST_asEWKB(ST_SetSRID(%s::geometry, 0), 'XDR') AS _geoX", quoted);
1879  }
1880  else
1881  {
1882  stringbuffer_aprintf(&sb, "asbinary(%s::geometry, 'XDR') AS _geoX", quoted);
1883  }
1884 #else
1885  if (state->pgis_major_version > 0)
1886  {
1887  stringbuffer_aprintf(&sb, "ST_AsEWKB(ST_SetSRID(%s::geometry, 0), 'NDR') AS _geoX", quoted);
1888  }
1889  else
1890  {
1891  stringbuffer_aprintf(&sb, "asbinary(%s::geometry, 'NDR') AS _geoX", quoted);
1892  }
1893 #endif
1894  free(quoted);
1895  }
1896 
1897  if (state->schema)
1898  {
1900  " FROM \"%s\".\"%s\"",
1901  state->schema, state->table);
1902  }
1903  else
1904  {
1906  " FROM \"%s\"",
1907  state->table);
1908  }
1909 
1910  /* Order by 'gid' (if found) */
1911  if (gidfound)
1912  {
1913  stringbuffer_append(&sb, " ORDER BY \"gid\"");
1914  }
1915 
1916  /* Now we've finished with the result set, we can dispose of it */
1917  PQclear(res);
1918 
1919  LWDEBUGF(3, "FINAL QUERY: %s\n", stringbuffer_getstring(&sb));
1920 
1921  /*
1922  * Begin the transaction
1923  * (a cursor can only be defined inside a transaction block)
1924  */
1925  res = PQexec(state->conn, "BEGIN");
1926  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
1927  {
1928  snprintf(state->message, SHPDUMPERMSGLEN, _("Error starting transaction: %s"), PQresultErrorMessage(res));
1929  PQclear(res);
1930  return SHPDUMPERERR;
1931  }
1932 
1933  PQclear(res);
1934 
1935  /* Execute the main scan query */
1937  stringbuffer_release(&sb);
1938  res = PQexec(state->conn, state->main_scan_query);
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);
1943  return SHPDUMPERERR;
1944  }
1945 
1946  PQclear(res);
1947 
1948  /* Setup initial scan state */
1949  state->currow = 0;
1950  state->curresrow = 0;
1951  state->currescount = 0;
1952  state->fetchres = NULL;
1953 
1954  /* Generate the fetch query */
1955  state->fetch_query = core_asprintf("FETCH %d FROM cur", state->config->fetchsize);
1956 
1957  return SHPDUMPEROK;
1958 }
int SHPAPI_CALL DBFAddField(DBFHandle psDBF, const char *pszFieldName, DBFFieldType eType, int nWidth, int nDecimals)
Definition: dbfopen.c:788
DBFHandle SHPAPI_CALL DBFCreateEx(const char *pszFilename, const char *pszCodePage)
Definition: dbfopen.c:662
void SHPAPI_CALL DBFSetWriteEndOfFileChar(DBFHandle psDBF, int bWriteFlag)
Definition: dbfopen.c:2297
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:106
void * malloc(YYSIZE_T)
void free(void *)
tuple res
Definition: window.py:79
static int getMaxFieldSize(PGconn *conn, char *schema, char *table, char *fname)
static char * core_asprintf(const char *format,...) __attribute__((format(printf
static int getTableInfo(SHPDUMPERSTATE *state)
char * quote_identifier(const char *s)
#define MAX_DBF_FIELD_SIZE
#define SHPDUMPERMSGLEN
#define SHPDUMPEROK
#define SHPDUMPERERR
#define SHPDUMPERWARN
SHPHandle SHPAPI_CALL SHPCreate(const char *pszShapeFile, int nShapeType)
Definition: shpopen.c:979
@ 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
char * encoding2codepage(const char *encoding)
Definition: shpcommon.c:357
int colmap_read(const char *filename, colmap *map, char *errbuf, size_t errbuflen)
Read the content of filename into a symbol map.
Definition: shpcommon.c:217
const char * colmap_dbf_by_pg(colmap *map, const char *pgname)
Definition: shpcommon.c:189
#define _(String)
Definition: shpcommon.h:24
void stringbuffer_release(stringbuffer_t *s)
Definition: stringbuffer.c:48
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.
Definition: stringbuffer.c:254
void stringbuffer_init(stringbuffer_t *s)
Definition: stringbuffer.c:54
char * stringbuffer_getstringcopy(stringbuffer_t *s)
Returns a newly allocated string large enough to contain the current state of the string.
Definition: stringbuffer.c:136
const char * stringbuffer_getstring(stringbuffer_t *s)
Returns a reference to the internal string being managed by the stringbuffer.
Definition: stringbuffer.c:125
static void stringbuffer_append(stringbuffer_t *s, const char *a)
Append the specified string to the stringbuffer_t.
Definition: stringbuffer.h:105
char * column_map_filename
SHPDUMPERCONFIG * config
PGresult * fetchres
char message[SHPDUMPERMSGLEN]

References _, shp_dumper_config::binary, colmap_dbf_by_pg(), colmap_read(), shp_dumper_state::column_map, shp_dumper_config::column_map_filename, shp_dumper_state::config, shp_dumper_state::conn, core_asprintf(), shp_dumper_state::currescount, shp_dumper_state::curresrow, shp_dumper_state::currow, shp_dumper_state::dbf, DBFAddField(), DBFCreateEx(), shp_dumper_state::dbffieldnames, shp_dumper_state::dbffieldtypes, DBFSetWriteEndOfFileChar(), encoding2codepage(), shp_dumper_state::fetch_query, shp_dumper_state::fetchres, shp_dumper_config::fetchsize, shp_dumper_state::fieldcount, free(), FTDate, FTDouble, FTInteger, FTLogical, FTString, shp_dumper_config::geo_col_name, shp_dumper_state::geo_col_name, shp_dumper_state::geog_oid, shp_dumper_state::geom_oid, getMaxFieldSize(), getTableInfo(), shp_dumper_config::includegid, shp_dumper_config::keep_fieldname_case, LWDEBUGF, shp_dumper_state::main_scan_query, malloc(), MAX_DBF_FIELD_SIZE, shp_dumper_state::message, shp_dumper_state::outshptype, shp_dumper_state::outtype, shp_dumper_state::pgfieldlens, shp_dumper_state::pgfieldnames, shp_dumper_state::pgfieldtypmods, shp_dumper_state::pgis_major_version, quote_identifier(), window::res, shp_dumper_state::rowcount, shp_dumper_config::schema, shp_dumper_state::schema, shp_dumper_state::shp, shp_dumper_config::shp_file, shp_dumper_state::shp_file, SHPCreate(), SHPDUMPERERR, SHPDUMPERMSGLEN, SHPDUMPEROK, SHPDUMPERWARN, stringbuffer_append(), stringbuffer_aprintf(), stringbuffer_getstring(), stringbuffer_getstringcopy(), stringbuffer_init(), stringbuffer_release(), shp_dumper_config::table, shp_dumper_state::table, shp_dumper_config::unescapedattrs, and shp_dumper_config::usrquery.

Referenced by main(), and pgui_action_export().

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