[QGIS Commit] r13922 - in trunk/qgis/src: app/postgres
providers/postgres
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sat Jul 17 07:22:30 EDT 2010
Author: jef
Date: 2010-07-17 11:22:30 +0000 (Sat, 17 Jul 2010)
New Revision: 13922
Modified:
trunk/qgis/src/app/postgres/qgspgsourceselect.cpp
trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
trunk/qgis/src/providers/postgres/qgspostgresprovider.h
Log:
apply #2730
Modified: trunk/qgis/src/app/postgres/qgspgsourceselect.cpp
===================================================================
--- trunk/qgis/src/app/postgres/qgspgsourceselect.cpp 2010-07-17 11:19:04 UTC (rev 13921)
+++ trunk/qgis/src/app/postgres/qgspgsourceselect.cpp 2010-07-17 11:22:30 UTC (rev 13922)
@@ -606,66 +606,105 @@
bool QgsPgSourceSelect::getTableInfo( PGconn *pg, bool searchGeometryColumnsOnly, bool searchPublicOnly )
{
- int n = 0;
+ int nColumns = 0;
+ int nGTables = 0;
QApplication::setOverrideCursor( Qt::WaitCursor );
- // The following query returns only tables that exist and the user has SELECT privilege on.
- // Can't use regclass here because table must exist, else error occurs.
- QString sql = "select "
- "f_table_name,"
- "f_table_schema,"
- "f_geometry_column,"
- "type,"
- "pg_class.relkind"
- " from "
- "geometry_columns,"
- "pg_class,"
- "pg_namespace"
- " where "
- "relname=f_table_name"
- " and f_table_schema=nspname"
- " and pg_namespace.oid=pg_class.relnamespace"
- " and has_schema_privilege(pg_namespace.nspname,'usage')"
- " and has_table_privilege('\"'||pg_namespace.nspname||'\".\"'||pg_class.relname||'\"','select')" // user has select privilege
- " order by "
- "f_table_schema,f_table_name,f_geometry_column";
+ PGresult *result = 0;
- PGresult *result = PQexec( pg, sql.toUtf8() );
- if ( result )
+ for ( int i = 0; i < 2; i++ )
{
- if ( PQresultStatus( result ) != PGRES_TUPLES_OK )
+ QString gtableName, columnName;
+
+ if ( i == 0 )
{
- QMessageBox::warning( this,
- tr( "Accessible tables could not be determined" ),
- tr( "Database connection was successful, but the accessible tables could not be determined.\n\n"
- "The error message from the database was:\n%1\n" )
- .arg( QString::fromUtf8( PQresultErrorMessage( result ) ) ) );
- n = -1;
+ gtableName = "geometry_columns";
+ columnName = "f_geometry_column";
}
- else if ( PQntuples( result ) > 0 )
+ else if ( i == 1 )
{
- for ( int idx = 0; idx < PQntuples( result ); idx++ )
+ gtableName = "geography_columns";
+ columnName = "f_geography_column";
+ }
+
+ // The following query returns only tables that exist and the user has SELECT privilege on.
+ // Can't use regclass here because table must exist, else error occurs.
+ QString sql = QString( "select "
+ "f_table_name,"
+ "f_table_schema,"
+ "%2,"
+ "upper(type),"
+ "pg_class.relkind"
+ " from "
+ "%1,"
+ "pg_class,"
+ "pg_namespace"
+ " where "
+ "relname=f_table_name"
+ " and f_table_schema=nspname"
+ " and pg_namespace.oid=pg_class.relnamespace"
+ " and has_schema_privilege(pg_namespace.nspname,'usage')"
+ " and has_table_privilege('\"'||pg_namespace.nspname||'\".\"'||pg_class.relname||'\"','select')" // user has select privilege
+ " order by "
+ "f_table_schema,f_table_name,%2" ).arg( gtableName ).arg( columnName );
+
+ QgsDebugMsg( "sql: " + sql );
+
+ result = PQexec( pg, sql.toUtf8() );
+ if ( result )
+ {
+ if ( PQresultStatus( result ) != PGRES_TUPLES_OK )
{
- QString tableName = QString::fromUtf8( PQgetvalue( result, idx, 0 ) );
- QString schemaName = QString::fromUtf8( PQgetvalue( result, idx, 1 ) );
- QString column = QString::fromUtf8( PQgetvalue( result, idx, 2 ) );
- QString type = QString::fromUtf8( PQgetvalue( result, idx, 3 ) );
- QString relkind = QString::fromUtf8( PQgetvalue( result, idx, 4 ) );
+ PGresult *r = PQexec( pg, "COMMIT" );
+ if ( r )
+ PQclear( r );
+ }
+ else
+ {
+ nGTables++;
- QString as = "";
- if ( type == "GEOMETRY" && !searchGeometryColumnsOnly )
+ if ( PQntuples( result ) > 0 )
{
- addSearchGeometryColumn( schemaName, tableName, column );
- as = type = "WAITING";
+
+ for ( int idx = 0; idx < PQntuples( result ); idx++ )
+ {
+ QString tableName = QString::fromUtf8( PQgetvalue( result, idx, 0 ) );
+ QString schemaName = QString::fromUtf8( PQgetvalue( result, idx, 1 ) );
+ QString column = QString::fromUtf8( PQgetvalue( result, idx, 2 ) );
+ QString type = QString::fromUtf8( PQgetvalue( result, idx, 3 ) );
+ QString relkind = QString::fromUtf8( PQgetvalue( result, idx, 4 ) );
+
+ QgsDebugMsg( QString( "%1 %2.%3.%4: %5 %6" )
+ .arg( gtableName )
+ .arg( schemaName ).arg( tableName ).arg( column )
+ .arg( type )
+ .arg( relkind ) );
+
+ QString as = "";
+ if ( type == "GEOMETRY" && !searchGeometryColumnsOnly )
+ {
+ addSearchGeometryColumn( schemaName, tableName, column );
+ as = type = "WAITING";
+ }
+
+ mTableModel.addTableEntry( type, schemaName, tableName, column, relkind == "v" ? pkCandidates( pg, schemaName, tableName ) : QStringList(), "" );
+ nColumns++;
+ }
}
-
- mTableModel.addTableEntry( type, schemaName, tableName, column, relkind == "v" ? pkCandidates( pg, schemaName, tableName ) : QStringList(), "" );
- n++;
}
}
+
+ PQclear( result );
+ result = 0;
}
- PQclear( result );
+ if ( nColumns == 0 )
+ {
+ QMessageBox::warning( this,
+ tr( "Accessible tables could not be determined" ),
+ tr( "Database connection was successful, but the accessible tables could not be determined." ) );
+ nColumns = -1;
+ }
//search for geometry columns in tables that are not in the geometry_columns metatable
QApplication::restoreOverrideCursor();
@@ -676,39 +715,47 @@
// geometry_columns table. This code is specific to postgresql,
// but an equivalent query should be possible in other
// databases.
- sql = "select "
- "pg_class.relname,"
- "pg_namespace.nspname,"
- "pg_attribute.attname,"
- "pg_class.relkind"
- " from "
- "pg_attribute,"
- "pg_class,"
- "pg_namespace"
- " where "
- "pg_namespace.oid = pg_class.relnamespace"
- " and pg_attribute.attrelid = pg_class.oid "
- " and ("
- "pg_attribute.atttypid = regtype('geometry')"
- " or pg_attribute.atttypid IN (select oid FROM pg_type WHERE typbasetype=regtype('geometry'))"
- ")"
- " and has_schema_privilege(pg_namespace.nspname,'usage')"
- " and has_table_privilege('\"'||pg_namespace.nspname||'\".\"'||pg_class.relname||'\"','select')";
+ QString sql = "select "
+ "pg_class.relname"
+ ",pg_namespace.nspname"
+ ",pg_attribute.attname"
+ ",pg_class.relkind"
+ " from "
+ "pg_attribute"
+ ",pg_class"
+ ",pg_namespace"
+ " where "
+ "pg_namespace.oid=pg_class.relnamespace"
+ " and pg_attribute.attrelid = pg_class.oid"
+ " and ("
+ "pg_attribute.atttypid::regtype::text IN ('geometry','geography')"
+ " or pg_attribute.atttypid IN (select oid FROM pg_type WHERE typbasetype::regtype::text IN ('geometry','geography'))"
+ ")"
+ " and has_schema_privilege( pg_namespace.nspname, 'usage' )"
+ " and has_table_privilege( '\"' || pg_namespace.nspname || '\".\"' || pg_class.relname || '\"', 'select' )";
+
// user has select privilege
if ( searchPublicOnly )
sql += " and pg_namespace.nspname = 'public'";
- if ( n > 0 )
+ if ( nColumns > 0 )
{
sql += " and not exists (select * from geometry_columns WHERE pg_namespace.nspname=f_table_schema AND pg_class.relname=f_table_name)";
+
+ if ( nGTables > 1 )
+ {
+ sql += " and not exists (select * from geography_columns WHERE pg_namespace.nspname=f_table_schema AND pg_class.relname=f_table_name)";
+ }
}
else
{
- n = 0;
+ nColumns = 0;
}
- sql += " and pg_class.relkind in ('v', 'r')"; // only from views and relations (tables)
+ sql += " and pg_class.relkind in( 'v', 'r' )"; // only from views and relations (tables)
+ QgsDebugMsg( "sql: " + sql );
+
result = PQexec( pg, sql.toUtf8() );
if ( PQresultStatus( result ) != PGRES_TUPLES_OK )
@@ -718,8 +765,8 @@
tr( "Database connection was successful, but the accessible tables could not be determined.\n\n"
"The error message from the database was:\n%1\n" )
.arg( QString::fromUtf8( PQresultErrorMessage( result ) ) ) );
- if ( n == 0 )
- n = -1;
+ if ( nColumns == 0 )
+ nColumns = -1;
}
else if ( PQntuples( result ) > 0 )
{
@@ -737,17 +784,20 @@
QString column = QString::fromUtf8( PQgetvalue( result, i, 2 ) ); // attname
QString relkind = QString::fromUtf8( PQgetvalue( result, i, 3 ) ); // relation kind
+ QgsDebugMsg( QString( "%1.%2.%3: %4" ).arg( schema ).arg( table ).arg( column ).arg( relkind ) );
+
addSearchGeometryColumn( schema, table, column );
//details.push_back(geomPair(fullDescription(schema, table, column, "WAITING"), "WAITING"));
- mTableModel.addTableEntry( "Waiting", schema, table, column, relkind == "v" ? pkCandidates( pg, schema, table ) : QStringList(), "" );
- n++;
+ mTableModel.addTableEntry( tr( "Waiting" ), schema, table, column, relkind == "v" ? pkCandidates( pg, schema, table ) : QStringList(), "" );
+ nColumns++;
}
}
PQclear( result );
+ result = 0;
}
- if ( n == 0 )
+ if ( nColumns == 0 )
{
QMessageBox::warning( this,
tr( "No accessible tables found" ),
@@ -756,7 +806,7 @@
"geometry." ) );
}
- return n > 0;
+ return nColumns > 0;
}
QString QgsPgSourceSelect::fullDescription( QString schema, QString table,
@@ -852,7 +902,9 @@
query += "\"" + schemas[i] + "\".\"" + tables[i] + "\"";
}
- PGresult* gresult = PQexec( pd, query.toUtf8() );
+ QgsDebugMsg( "sql: " + query );
+
+ PGresult *gresult = PQexec( pd, query.toUtf8() );
QString type;
if ( PQresultStatus( gresult ) == PGRES_TUPLES_OK )
{
Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2010-07-17 11:19:04 UTC (rev 13921)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2010-07-17 11:22:30 UTC (rev 13922)
@@ -68,7 +68,6 @@
providerId = providerIds++;
- QgsDebugMsg( "Postgresql Layer Creation" );
QgsDebugMsg( "URI: " + uri );
mUri = QgsDataSourceURI( uri );
@@ -78,6 +77,7 @@
mTableName = mUri.table();
geometryColumn = mUri.geometryColumn();
sqlWhereClause = mUri.sql();
+ isGeography = false;
if ( mSchemaName.isEmpty() &&
mTableName.startsWith( "(select", Qt::CaseInsensitive ) &&
@@ -374,6 +374,10 @@
{
return QString( "asewkt(%1)" ).arg( quotedIdentifier( fld.name() ) );
}
+ else if ( type == "geography" )
+ {
+ return QString( "st_astext(%1)" ).arg( quotedIdentifier( fld.name() ) );
+ }
else
{
return quotedIdentifier( fld.name() ) + "::text";
@@ -392,9 +396,16 @@
if ( fetchGeometry )
{
- query += QString( ",asbinary(%1,'%2')" )
- .arg( quotedIdentifier( geometryColumn ) )
- .arg( endianString() );
+ if ( isGeography )
+ {
+ query += QString( ",st_asbinary(%1)" ).arg( quotedIdentifier( geometryColumn ) );
+ }
+ else
+ {
+ query += QString( ",asbinary(%1,'%2')" )
+ .arg( quotedIdentifier( geometryColumn ) )
+ .arg( endianString() );
+ }
}
for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it )
@@ -539,21 +550,32 @@
if ( !rect.isEmpty() )
{
- if ( useIntersect )
+ if ( isGeography )
{
- // Contributed by #qgis irc "creeping"
- // This version actually invokes PostGIS's use of spatial indexes
- whereClause = QString( "%1 && setsrid('BOX3D(%2)'::box3d,%3) and intersects(%1,setsrid('BOX3D(%2)'::box3d,%3))" )
- .arg( quotedIdentifier( geometryColumn ) )
- .arg( rect.asWktCoordinates() )
- .arg( srid );
+ rect = QgsRectangle( -180.0, -90.0, 180.0, 90.0 ).intersect( &rect );
+ if ( !rect.isFinite() )
+ whereClause = "false";
}
- else
+
+ if ( whereClause.isEmpty() )
{
- whereClause = QString( "%1 && setsrid('BOX3D(%2)'::box3d,%3)" )
- .arg( quotedIdentifier( geometryColumn ) )
- .arg( rect.asWktCoordinates() )
- .arg( srid );
+
+ if ( useIntersect )
+ {
+ // Contributed by #qgis irc "creeping"
+ // This version actually invokes PostGIS's use of spatial indexes
+ whereClause = QString( "%1 && setsrid('BOX3D(%2)'::box3d,%3) and intersects(%1,setsrid('BOX3D(%2)'::box3d,%3))" )
+ .arg( quotedIdentifier( geometryColumn ) )
+ .arg( rect.asWktCoordinates() )
+ .arg( srid );
+ }
+ else
+ {
+ whereClause = QString( "%1 && setsrid('BOX3D(%2)'::box3d,%3)" )
+ .arg( quotedIdentifier( geometryColumn ) )
+ .arg( rect.asWktCoordinates() )
+ .arg( srid );
+ }
}
}
@@ -2305,6 +2327,10 @@
{
values += QString( ",geomfromewkt(%1)" ).arg( quotedValue( it->toString() ) );
}
+ else if ( fit->typeName() == "geography" )
+ {
+ values += QString( ",st_geographyfromewkt(%1)" ).arg( quotedValue( it->toString() ) );
+ }
else
{
values += "," + quotedValue( it->toString() );
@@ -2317,6 +2343,10 @@
{
values += QString( ",geomfromewkt($%1)" ).arg( defaultValues.size() + offset );
}
+ else if ( fit->typeName() == "geography" )
+ {
+ values += QString( ",st_geographyfromewkt($%1)" ).arg( defaultValues.size() + offset );
+ }
else
{
values += QString( ",$%1" ).arg( defaultValues.size() + offset );
@@ -2576,7 +2606,9 @@
else
first = false;
- sql += QString( fld.typeName() != "geometry" ? "%1=%2" : "%1=geomfromewkt(%2)" )
+ sql += QString( fld.typeName() == "geometry" ? "%1=geomfromewkt(%2)" :
+ fld.typeName() == "geography" ? "%1=st_geographyfromewkt(%2)" :
+ "%1=%2" )
.arg( quotedIdentifier( fld.name() ) )
.arg( quotedValue( siter->toString() ) );
}
@@ -2779,6 +2811,9 @@
QgsRectangle QgsPostgresProvider::extent()
{
+ if ( isGeography )
+ return QgsRectangle( -180.0, -90.0, 180.0, 90.0 );
+
if ( layerExtent.isEmpty() )
{
QString sql;
@@ -2986,7 +3021,6 @@
.arg( quotedValue( schemaName ) );
QgsDebugMsg( "Getting geometry column: " + sql );
-
result = connectionRO->PQexec( sql );
QgsDebugMsg( "geometry column query returned " + QString::number( PQntuples( result ) ) );
@@ -2999,6 +3033,28 @@
if ( srid.isEmpty() || fType.isEmpty() )
{
+ sql = QString( "select upper(type),srid from geography_columns"
+ " where f_table_name=%1 and f_geography_column=%2 and f_table_schema=%3" )
+ .arg( quotedValue( tableName ) )
+ .arg( quotedValue( geomCol ) )
+ .arg( quotedValue( schemaName ) );
+
+ QgsDebugMsg( "Getting geography column: " + sql );
+ result = connectionRO->PQexec( sql );
+
+ QgsDebugMsg( "geography column query returned " + QString::number( PQntuples( result ) ) );
+
+ if ( PQntuples( result ) > 0 )
+ {
+ fType = QString::fromUtf8( PQgetvalue( result, 0, 0 ) );
+ srid = QString::fromUtf8( PQgetvalue( result, 0, 1 ) );
+
+ isGeography = true;
+ }
+ }
+
+ if ( srid.isEmpty() || fType.isEmpty() )
+ {
// Didn't find what we need in the geometry_columns table, so
// get stuff from the relevant column instead. This may (will?)
// fail if there is no data in the relevant table.
@@ -3116,6 +3172,7 @@
QgsDebugMsg( "type is " + fType );
QgsDebugMsg( "Feature type is " + QString::number( geomType ) );
QgsDebugMsg( "Feature type name is " + QString( QGis::qgisFeatureTypes[geomType] ) );
+ QgsDebugMsg( "Geometry is geography " + isGeography );
}
else
{
Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.h
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.h 2010-07-17 11:19:04 UTC (rev 13921)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.h 2010-07-17 11:22:30 UTC (rev 13922)
@@ -383,6 +383,11 @@
bool isQuery;
/**
+ * geometry is geography
+ */
+ bool isGeography;
+
+ /**
* Name of the table with no schema
*/
QString mTableName;
More information about the QGIS-commit
mailing list