PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ ShpDumperOpenTable()

int ShpDumperOpenTable ( SHPDUMPERSTATE state)

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

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