| | 184 | pszName = CPLStrdup( pszNewName ); |
|---|
| | 185 | |
|---|
| | 186 | /* -------------------------------------------------------------------- */ |
|---|
| | 187 | /* Determine if the connection string contains an optional */ |
|---|
| | 188 | /* TABLES portion. If so, parse it out. The expected */ |
|---|
| | 189 | /* connection string in this case will be, e.g.: */ |
|---|
| | 190 | /* */ |
|---|
| | 191 | /* 'PG:dbname=warmerda user=warmerda tables=s1.t1,[s2.t2,...] */ |
|---|
| | 192 | /* - where sN is schema and tN is table name */ |
|---|
| | 193 | /* We must also strip this information from the connection */ |
|---|
| | 194 | /* string; PQconnectdb() does not like unknown directives */ |
|---|
| | 195 | /* -------------------------------------------------------------------- */ |
|---|
| | 196 | char **papszTableNames=NULL; |
|---|
| | 197 | char **papszSchemaNames=NULL; |
|---|
| | 198 | |
|---|
| | 199 | char *pszTableStart; |
|---|
| | 200 | pszTableStart = strstr(pszName, "tables="); |
|---|
| | 201 | if (pszTableStart == NULL) |
|---|
| | 202 | pszTableStart = strstr(pszName, "TABLES="); |
|---|
| | 203 | |
|---|
| | 204 | if( pszTableStart != NULL ) |
|---|
| | 205 | { |
|---|
| | 206 | char **papszTableList; |
|---|
| | 207 | char *pszTableSpec; |
|---|
| | 208 | const char *pszEnd = NULL; |
|---|
| | 209 | int i; |
|---|
| | 210 | |
|---|
| | 211 | pszTableSpec = CPLStrdup( pszTableStart + 7 ); |
|---|
| | 212 | |
|---|
| | 213 | for( i = 0; pszTableStart[i] != '\0'; i++ ) |
|---|
| | 214 | { |
|---|
| | 215 | if( pszTableStart[i] == ' ' ) |
|---|
| | 216 | { |
|---|
| | 217 | pszEnd = pszTableStart + i; |
|---|
| | 218 | break; |
|---|
| | 219 | } |
|---|
| | 220 | } |
|---|
| | 221 | |
|---|
| | 222 | if( pszEnd == NULL ) |
|---|
| | 223 | pszEnd = pszName + strlen(pszName); |
|---|
| | 224 | |
|---|
| | 225 | // Remove TABLES=xxxxx from pszName string |
|---|
| | 226 | memmove( pszTableStart, pszEnd, strlen(pszEnd) + 1 ); |
|---|
| | 227 | |
|---|
| | 228 | pszTableSpec[pszEnd - pszTableStart - 7] = '\0'; |
|---|
| | 229 | papszTableList = CSLTokenizeString2( pszTableSpec, ",", 0 ); |
|---|
| | 230 | |
|---|
| | 231 | for( i = 0; i < CSLCount(papszTableList); i++ ) |
|---|
| | 232 | { |
|---|
| | 233 | char **papszQualifiedParts; |
|---|
| | 234 | |
|---|
| | 235 | // Get schema and table name |
|---|
| | 236 | papszQualifiedParts = CSLTokenizeString2( papszTableList[i], |
|---|
| | 237 | ".", 0 ); |
|---|
| | 238 | |
|---|
| | 239 | if( CSLCount( papszQualifiedParts ) == 2 ) |
|---|
| | 240 | { |
|---|
| | 241 | papszSchemaNames = CSLAddString( papszSchemaNames, |
|---|
| | 242 | papszQualifiedParts[0] ); |
|---|
| | 243 | papszTableNames = CSLAddString( papszTableNames, |
|---|
| | 244 | papszQualifiedParts[1] ); |
|---|
| | 245 | } |
|---|
| | 246 | else if( CSLCount( papszQualifiedParts ) == 1 ) |
|---|
| | 247 | { |
|---|
| | 248 | papszSchemaNames = CSLAddString( papszSchemaNames, "public"); |
|---|
| | 249 | papszTableNames = CSLAddString( papszTableNames, |
|---|
| | 250 | papszQualifiedParts[0] ); |
|---|
| | 251 | } |
|---|
| | 252 | |
|---|
| | 253 | CSLDestroy(papszQualifiedParts); |
|---|
| | 254 | } |
|---|
| | 255 | |
|---|
| | 256 | CSLDestroy(papszTableList); |
|---|
| | 257 | CPLFree(pszTableSpec); |
|---|
| | 258 | } |
|---|
| | 259 | |
|---|
| 406 | | /* Get a list of available tables. */ |
|---|
| 407 | | /* -------------------------------------------------------------------- */ |
|---|
| 408 | | hResult = PQexec(hPGConn, "BEGIN"); |
|---|
| 409 | | |
|---|
| 410 | | if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) |
|---|
| 411 | | { |
|---|
| 412 | | OGRPGClearResult( hResult ); |
|---|
| 413 | | |
|---|
| 414 | | if ( bHavePostGIS ) |
|---|
| 415 | | hResult = PQexec(hPGConn, |
|---|
| 416 | | "DECLARE mycursor CURSOR for " |
|---|
| 417 | | "SELECT c.relname, n.nspname FROM pg_class c, pg_namespace n, geometry_columns g " |
|---|
| 418 | | "WHERE (c.relkind in ('r','v') AND c.relname !~ '^pg' AND c.relnamespace=n.oid " |
|---|
| 419 | | "AND c.relname::TEXT = g.f_table_name::TEXT AND n.nspname = g.f_table_schema)" ); |
|---|
| 420 | | else |
|---|
| 421 | | hResult = PQexec(hPGConn, |
|---|
| 422 | | "DECLARE mycursor CURSOR for " |
|---|
| 423 | | "SELECT c.relname, n.nspname FROM pg_class c, pg_namespace n " |
|---|
| 424 | | "WHERE (c.relkind in ('r','v') AND c.relname !~ '^pg' AND c.relnamespace=n.oid)" ); |
|---|
| 425 | | } |
|---|
| 426 | | |
|---|
| 427 | | if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) |
|---|
| 428 | | { |
|---|
| 429 | | OGRPGClearResult( hResult ); |
|---|
| 430 | | hResult = PQexec(hPGConn, "FETCH ALL in mycursor" ); |
|---|
| 431 | | } |
|---|
| 432 | | |
|---|
| 433 | | if( !hResult || PQresultStatus(hResult) != PGRES_TUPLES_OK ) |
|---|
| 434 | | { |
|---|
| 435 | | OGRPGClearResult( hResult ); |
|---|
| 436 | | |
|---|
| 437 | | CPLError( CE_Failure, CPLE_AppDefined, |
|---|
| 438 | | "%s", PQerrorMessage(hPGConn) ); |
|---|
| 439 | | return FALSE; |
|---|
| 440 | | } |
|---|
| 441 | | |
|---|
| 442 | | /* -------------------------------------------------------------------- */ |
|---|
| 443 | | /* Parse the returned table list */ |
|---|
| 444 | | /* -------------------------------------------------------------------- */ |
|---|
| 445 | | char **papszTableNames=NULL; |
|---|
| 446 | | char **papszSchemaNames=NULL; |
|---|
| 447 | | int iRecord; |
|---|
| 448 | | |
|---|
| 449 | | for( iRecord = 0; iRecord < PQntuples(hResult); iRecord++ ) |
|---|
| 450 | | { |
|---|
| 451 | | const char *pszTable = PQgetvalue(hResult, iRecord, 0); |
|---|
| 452 | | |
|---|
| 453 | | if( EQUAL(pszTable,"spatial_ref_sys") |
|---|
| 454 | | || EQUAL(pszTable,"geometry_columns") ) |
|---|
| 455 | | continue; |
|---|
| 456 | | |
|---|
| 457 | | papszTableNames = CSLAddString(papszTableNames, |
|---|
| 458 | | PQgetvalue(hResult, iRecord, 0)); |
|---|
| 459 | | papszSchemaNames = CSLAddString(papszSchemaNames, |
|---|
| 460 | | PQgetvalue(hResult, iRecord, 1)); |
|---|
| 461 | | |
|---|
| 462 | | } |
|---|
| 463 | | |
|---|
| 464 | | /* -------------------------------------------------------------------- */ |
|---|
| 465 | | /* Cleanup */ |
|---|
| 466 | | /* -------------------------------------------------------------------- */ |
|---|
| 467 | | OGRPGClearResult( hResult ); |
|---|
| 468 | | |
|---|
| 469 | | hResult = PQexec(hPGConn, "CLOSE mycursor"); |
|---|
| 470 | | OGRPGClearResult( hResult ); |
|---|
| 471 | | |
|---|
| 472 | | hResult = PQexec(hPGConn, "COMMIT"); |
|---|
| 473 | | OGRPGClearResult( hResult ); |
|---|
| | 483 | /* Get a list of available tables if they have not been */ |
|---|
| | 484 | /* specified through the TABLES connection string param */ |
|---|
| | 485 | /* -------------------------------------------------------------------- */ |
|---|
| | 486 | |
|---|
| | 487 | if (papszTableNames == NULL) |
|---|
| | 488 | { |
|---|
| | 489 | hResult = PQexec(hPGConn, "BEGIN"); |
|---|
| | 490 | |
|---|
| | 491 | if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) |
|---|
| | 492 | { |
|---|
| | 493 | OGRPGClearResult( hResult ); |
|---|
| | 494 | |
|---|
| | 495 | if ( bHavePostGIS ) |
|---|
| | 496 | hResult = PQexec(hPGConn, |
|---|
| | 497 | "DECLARE mycursor CURSOR for " |
|---|
| | 498 | "SELECT c.relname, n.nspname FROM pg_class c, pg_namespace n, geometry_columns g " |
|---|
| | 499 | "WHERE (c.relkind in ('r','v') AND c.relname !~ '^pg' AND c.relnamespace=n.oid " |
|---|
| | 500 | "AND c.relname::TEXT = g.f_table_name::TEXT AND n.nspname = g.f_table_schema)" ); |
|---|
| | 501 | else |
|---|
| | 502 | hResult = PQexec(hPGConn, |
|---|
| | 503 | "DECLARE mycursor CURSOR for " |
|---|
| | 504 | "SELECT c.relname, n.nspname FROM pg_class c, pg_namespace n " |
|---|
| | 505 | "WHERE (c.relkind in ('r','v') AND c.relname !~ '^pg' AND c.relnamespace=n.oid)" ); |
|---|
| | 506 | } |
|---|
| | 507 | |
|---|
| | 508 | if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) |
|---|
| | 509 | { |
|---|
| | 510 | OGRPGClearResult( hResult ); |
|---|
| | 511 | hResult = PQexec(hPGConn, "FETCH ALL in mycursor" ); |
|---|
| | 512 | } |
|---|
| | 513 | |
|---|
| | 514 | if( !hResult || PQresultStatus(hResult) != PGRES_TUPLES_OK ) |
|---|
| | 515 | { |
|---|
| | 516 | OGRPGClearResult( hResult ); |
|---|
| | 517 | |
|---|
| | 518 | CPLError( CE_Failure, CPLE_AppDefined, |
|---|
| | 519 | "%s", PQerrorMessage(hPGConn) ); |
|---|
| | 520 | return FALSE; |
|---|
| | 521 | } |
|---|
| | 522 | |
|---|
| | 523 | /* -------------------------------------------------------------------- */ |
|---|
| | 524 | /* Parse the returned table list */ |
|---|
| | 525 | /* -------------------------------------------------------------------- */ |
|---|
| | 526 | for( int iRecord = 0; iRecord < PQntuples(hResult); iRecord++ ) |
|---|
| | 527 | { |
|---|
| | 528 | const char *pszTable = PQgetvalue(hResult, iRecord, 0); |
|---|
| | 529 | |
|---|
| | 530 | if( EQUAL(pszTable,"spatial_ref_sys") |
|---|
| | 531 | || EQUAL(pszTable,"geometry_columns") ) |
|---|
| | 532 | continue; |
|---|
| | 533 | |
|---|
| | 534 | papszTableNames = CSLAddString(papszTableNames, |
|---|
| | 535 | PQgetvalue(hResult, iRecord, 0)); |
|---|
| | 536 | papszSchemaNames = CSLAddString(papszSchemaNames, |
|---|
| | 537 | PQgetvalue(hResult, iRecord, 1)); |
|---|
| | 538 | |
|---|
| | 539 | } |
|---|
| | 540 | |
|---|
| | 541 | /* -------------------------------------------------------------------- */ |
|---|
| | 542 | /* Cleanup */ |
|---|
| | 543 | /* -------------------------------------------------------------------- */ |
|---|
| | 544 | OGRPGClearResult( hResult ); |
|---|
| | 545 | |
|---|
| | 546 | hResult = PQexec(hPGConn, "CLOSE mycursor"); |
|---|
| | 547 | OGRPGClearResult( hResult ); |
|---|
| | 548 | |
|---|
| | 549 | hResult = PQexec(hPGConn, "COMMIT"); |
|---|
| | 550 | OGRPGClearResult( hResult ); |
|---|
| | 551 | } |
|---|