[QGIS Commit] r15284 - in trunk/qgis/src: app/postgres plugins/spit
providers/postgres
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Mon Feb 28 12:01:14 EST 2011
Author: jef
Date: 2011-02-28 09:01:13 -0800 (Mon, 28 Feb 2011)
New Revision: 15284
Modified:
trunk/qgis/src/app/postgres/qgspgnewconnection.cpp
trunk/qgis/src/app/postgres/qgspgsourceselect.cpp
trunk/qgis/src/app/postgres/qgspgsourceselect.h
trunk/qgis/src/plugins/spit/qgsspit.cpp
trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
Log:
postgres provider: use set application_name (fixes r15280) and verify that pg_is_in_recovery() is false
Modified: trunk/qgis/src/app/postgres/qgspgnewconnection.cpp
===================================================================
--- trunk/qgis/src/app/postgres/qgspgnewconnection.cpp 2011-02-28 17:00:46 UTC (rev 15283)
+++ trunk/qgis/src/app/postgres/qgspgnewconnection.cpp 2011-02-28 17:01:13 UTC (rev 15284)
@@ -178,7 +178,7 @@
QString conninfo = uri.connectionInfo();
QgsDebugMsg( "PQconnectdb(\"" + conninfo + "\");" );
- PGconn *pd = PQconnectdb(( conninfo + " application_name='Quantum GIS'" ).toLocal8Bit() ); // use what is set based on locale; after connecting, use Utf8
+ PGconn *pd = PQconnectdb( conninfo.toLocal8Bit() ); // use what is set based on locale; after connecting, use Utf8
// check the connection status
if ( PQstatus( pd ) != CONNECTION_OK )
{
@@ -205,7 +205,7 @@
uri.setPassword( password );
QgsDebugMsg( "PQconnectdb(\"" + uri.connectionInfo() + "\");" );
- pd = PQconnectdb(( uri.connectionInfo() + " application_name='Quantum GIS'" ).toLocal8Bit() );
+ pd = PQconnectdb( uri.connectionInfo().toLocal8Bit() );
}
if ( PQstatus( pd ) == CONNECTION_OK )
Modified: trunk/qgis/src/app/postgres/qgspgsourceselect.cpp
===================================================================
--- trunk/qgis/src/app/postgres/qgspgsourceselect.cpp 2011-02-28 17:00:46 UTC (rev 15283)
+++ trunk/qgis/src/app/postgres/qgspgsourceselect.cpp 2011-02-28 17:01:13 UTC (rev 15284)
@@ -51,11 +51,18 @@
{
setupUi( this );
+ mBuildQueryButton = new QPushButton( tr( "&Build query" ) );
+ mBuildQueryButton->setToolTip( tr( "Build query" ) );
+ buttonBox->addButton( mBuildQueryButton, QDialogButtonBox::ActionRole );
+ connect( mBuildQueryButton, SIGNAL( clicked() ), this, SLOT( buildQuery() ) );
+ mBuildQueryButton->setDisabled( true );
+
mAddButton = new QPushButton( tr( "&Add" ) );
buttonBox->addButton( mAddButton, QDialogButtonBox::ActionRole );
connect( mAddButton, SIGNAL( clicked() ), this, SLOT( addTables() ) );
- QPushButton *pb = new QPushButton( tr( "&Save" ) );
+ QPushButton *pb;
+ pb = new QPushButton( tr( "&Save" ) );
pb->setToolTip( tr( "Save connections" ) );
buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
connect( pb, SIGNAL( clicked() ), this, SLOT( saveClicked() ) );
@@ -208,14 +215,14 @@
on_btnConnect_clicked();
}
-void QgsPgSourceSelect::on_btnBuildQuery_clicked()
+void QgsPgSourceSelect::buildQuery()
{
setSql( mTablesTreeView->currentIndex() );
}
void QgsPgSourceSelect::on_mTablesTreeView_clicked( const QModelIndex &index )
{
- btnBuildQuery->setEnabled( index.parent().isValid() );
+ mBuildQueryButton->setEnabled( index.parent().isValid() );
}
void QgsPgSourceSelect::on_mTablesTreeView_doubleClicked( const QModelIndex &index )
@@ -472,7 +479,7 @@
m_privConnInfo = m_connInfo;
- pd = PQconnectdb(( m_privConnInfo + " application_name='Quantum GIS'" ).toLocal8Bit() ); // use what is set based on locale; after connecting, use Utf8
+ pd = PQconnectdb( m_privConnInfo.toLocal8Bit() ); // use what is set based on locale; after connecting, use Utf8
// check the connection status
if ( PQstatus( pd ) != CONNECTION_OK )
{
@@ -493,7 +500,7 @@
m_privConnInfo = uri.connectionInfo();
QgsDebugMsg( "connecting " + m_privConnInfo );
- pd = PQconnectdb(( m_privConnInfo + " application_name='Quantum GIS'" ).toLocal8Bit() );
+ pd = PQconnectdb( m_privConnInfo.toLocal8Bit() );
}
if ( PQstatus( pd ) == CONNECTION_OK )
@@ -508,6 +515,16 @@
// tell the DB that we want text encoded in UTF8
PQsetClientEncoding( pd, QString( "UNICODE" ).toLocal8Bit() );
+ PGresult *res = PQexec( pd, "SET application_name='Quantum GIS'" );
+
+ if ( !res || PQresultStatus( res ) != PGRES_COMMAND_OK )
+ {
+ PQclear( res );
+ res = PQexec( pd, "ROLLBACK" );
+ }
+
+ PQclear( res );
+
// get the list of suitable tables and columns and populate the UI
geomCol details;
@@ -963,11 +980,19 @@
{
mStopped = false;
- PGconn *pd = PQconnectdb(( mConnInfo + " application_name='Quantum GIS'" ).toLocal8Bit() );
+ PGconn *pd = PQconnectdb( mConnInfo.toLocal8Bit() );
if ( PQstatus( pd ) == CONNECTION_OK )
{
PQsetClientEncoding( pd, QString( "UNICODE" ).toLocal8Bit() );
+ PGresult *res = PQexec( pd, "SET application_name='Quantum GIS'" );
+ if ( !res || PQresultStatus( res ) != PGRES_COMMAND_OK )
+ {
+ PQclear( res );
+ res = PQexec( pd, "ROLLBACK" );
+ }
+ PQclear( res );
+
for ( uint i = 0; i < schemas.size() && !mStopped; i++ )
{
QString query = QString( "select distinct "
Modified: trunk/qgis/src/app/postgres/qgspgsourceselect.h
===================================================================
--- trunk/qgis/src/app/postgres/qgspgsourceselect.h 2011-02-28 17:00:46 UTC (rev 15283)
+++ trunk/qgis/src/app/postgres/qgspgsourceselect.h 2011-02-28 17:01:13 UTC (rev 15284)
@@ -119,6 +119,7 @@
public slots:
//! Determines the tables the user selected and closes the dialog
void addTables();
+ void buildQuery();
/*! Connects to the database using the stored connection parameters.
* Once connected, available layers are displayed.
@@ -129,7 +130,6 @@
void on_btnNew_clicked();
//! Opens a dialog to edit an existing connection
void on_btnEdit_clicked();
- void on_btnBuildQuery_clicked();
//! Deletes the selected connection
void on_btnDelete_clicked();
//! Saves the selected connections to file
@@ -187,6 +187,7 @@
QgsDbFilterProxyModel mProxyModel;
QString layerURI( const QModelIndex &index );
+ QPushButton *mBuildQueryButton;
QPushButton *mAddButton;
};
Modified: trunk/qgis/src/plugins/spit/qgsspit.cpp
===================================================================
--- trunk/qgis/src/plugins/spit/qgsspit.cpp 2011-02-28 17:00:46 UTC (rev 15283)
+++ trunk/qgis/src/plugins/spit/qgsspit.cpp 2011-02-28 17:01:13 UTC (rev 15284)
@@ -410,7 +410,7 @@
password,
( QgsDataSourceURI::SSLmode ) settings.value( key + "/sslmode", QgsDataSourceURI::SSLprefer ).toInt() );
- conn = PQconnectdb(( uri.connectionInfo() + " application_name='Quantum GIS'" ).toUtf8() );
+ conn = PQconnectdb( uri.connectionInfo().toUtf8() );
}
if ( conn == NULL || PQstatus( conn ) != CONNECTION_OK )
@@ -423,6 +423,17 @@
}
}
+ if ( conn )
+ {
+ PGresult *res = PQexec( conn, "SET application_name='Quantum GIS'" );
+ if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
+ {
+ PQclear( res );
+ res = PQexec( conn, "ROLLBACK" );
+ }
+ PQclear( res );
+ }
+
schema_list.clear();
schema_list << "public";
Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2011-02-28 17:00:46 UTC (rev 15283)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2011-02-28 17:01:13 UTC (rev 15284)
@@ -213,7 +213,7 @@
QgsDebugMsg( QString( "New postgres connection for " ) + conninfo );
- PGconn *pd = PQconnectdb(( conninfo + " application_name='Quantum GIS'" ).toLocal8Bit() ); // use what is set based on locale; after connecting, use Utf8
+ PGconn *pd = PQconnectdb( conninfo.toLocal8Bit() ); // use what is set based on locale; after connecting, use Utf8
// check the connection status
if ( PQstatus( pd ) != CONNECTION_OK )
{
@@ -236,7 +236,7 @@
uri.setPassword( password );
QgsDebugMsg( "Connecting to " + uri.connectionInfo() );
- pd = PQconnectdb(( uri.connectionInfo() + " application_name='Quantum GIS'" ).toLocal8Bit() );
+ pd = PQconnectdb( uri.connectionInfo().toLocal8Bit() );
}
if ( PQstatus( pd ) == CONNECTION_OK )
@@ -284,6 +284,11 @@
connections.insert( conninfo, conn );
+ if ( !conn->PQexecNR( "SET application_name='Quantum GIS'" ) )
+ {
+ conn->PQexecNR( "ROLLBACK" );
+ }
+
/* Check to see if we have GEOS support and if not, warn the user about
the problems they will see :) */
QgsDebugMsg( "Checking for GEOS support" );
@@ -989,91 +994,108 @@
return false;
}
- if ( connectionRO->pgVersion() >= 80400 )
- {
- sql = QString( "SELECT "
- "has_table_privilege(%1,'DELETE'),"
- "has_any_column_privilege(%1,'UPDATE'),"
- "%2"
- "has_table_privilege(%1,'INSERT'),"
- "current_schema()" )
- .arg( quotedValue( mQuery ) )
- .arg( geometryColumn.isNull()
- ? QString( "'f'," )
- : QString( "has_column_privilege(%1,%2,'UPDATE')," )
- .arg( quotedValue( mQuery ) )
- .arg( quotedValue( geometryColumn ) )
- );
- }
- else
- {
- sql = QString( "SELECT "
- "has_table_privilege(%1,'DELETE'),"
- "has_table_privilege(%1,'UPDATE'),"
- "has_table_privilege(%1,'UPDATE'),"
- "has_table_privilege(%1,'INSERT'),"
- "current_schema()" )
- .arg( quotedValue( mQuery ) );
- }
+ bool inRecovery = false;
- testAccess = connectionRO->PQexec( sql );
- if ( PQresultStatus( testAccess ) != PGRES_TUPLES_OK )
+ if ( connectionRO->pgVersion() >= 90000 )
{
- showMessageBox( tr( "Unable to access relation" ),
- tr( "Unable to determine table access privileges for the %1 relation.\nThe error message from the database was:\n%2.\nSQL: %3" )
- .arg( mQuery )
- .arg( QString::fromUtf8( PQresultErrorMessage( testAccess ) ) )
- .arg( sql ) );
- return false;
+ testAccess = connectionRO->PQexec( "SELECT pg_is_in_recovery()" );
+ if ( PQresultStatus( testAccess ) != PGRES_TUPLES_OK || QString::fromUtf8( PQgetvalue( testAccess, 0, 0 ) ) == "t" )
+ {
+ showMessageBox( tr( "PostgreSQL in recovery" ),
+ tr( "PostgreSQL is still in recovery after a database crash\n(or you are connected to a (read-only) slave).\nWrite accesses will be denied." ) );
+ inRecovery = true;
+ }
}
// postgres has fast access to features at id (thanks to primary key / unique index)
// the latter flag is here just for compatibility
enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
- if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 0 ) ) == "t" )
+ if ( !inRecovery )
{
- // DELETE
- enabledCapabilities |= QgsVectorDataProvider::DeleteFeatures;
- }
+ if ( connectionRO->pgVersion() >= 80400 )
+ {
+ sql = QString( "SELECT "
+ "has_table_privilege(%1,'DELETE'),"
+ "has_any_column_privilege(%1,'UPDATE'),"
+ "%2"
+ "has_table_privilege(%1,'INSERT'),"
+ "current_schema()" )
+ .arg( quotedValue( mQuery ) )
+ .arg( geometryColumn.isNull()
+ ? QString( "'f'," )
+ : QString( "has_column_privilege(%1,%2,'UPDATE')," )
+ .arg( quotedValue( mQuery ) )
+ .arg( quotedValue( geometryColumn ) )
+ );
+ }
+ else
+ {
+ sql = QString( "SELECT "
+ "has_table_privilege(%1,'DELETE'),"
+ "has_table_privilege(%1,'UPDATE'),"
+ "has_table_privilege(%1,'UPDATE'),"
+ "has_table_privilege(%1,'INSERT'),"
+ "current_schema()" )
+ .arg( quotedValue( mQuery ) );
+ }
- if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 1 ) ) == "t" )
- {
- // UPDATE
- enabledCapabilities |= QgsVectorDataProvider::ChangeAttributeValues;
- }
+ testAccess = connectionRO->PQexec( sql );
+ if ( PQresultStatus( testAccess ) != PGRES_TUPLES_OK )
+ {
+ showMessageBox( tr( "Unable to access relation" ),
+ tr( "Unable to determine table access privileges for the %1 relation.\nThe error message from the database was:\n%2.\nSQL: %3" )
+ .arg( mQuery )
+ .arg( QString::fromUtf8( PQresultErrorMessage( testAccess ) ) )
+ .arg( sql ) );
+ return false;
+ }
- if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 2 ) ) == "t" )
- {
- // UPDATE
- enabledCapabilities |= QgsVectorDataProvider::ChangeGeometries;
- }
- if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 3 ) ) == "t" )
- {
- // INSERT
- enabledCapabilities |= QgsVectorDataProvider::AddFeatures;
- }
+ if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 0 ) ) == "t" )
+ {
+ // DELETE
+ enabledCapabilities |= QgsVectorDataProvider::DeleteFeatures;
+ }
- mCurrentSchema = QString::fromUtf8( PQgetvalue( testAccess, 0, 4 ) );
- if ( mCurrentSchema == mSchemaName )
- {
- mUri.clearSchema();
- }
+ if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 1 ) ) == "t" )
+ {
+ // UPDATE
+ enabledCapabilities |= QgsVectorDataProvider::ChangeAttributeValues;
+ }
- if ( mSchemaName == "" )
- mSchemaName = mCurrentSchema;
+ if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 2 ) ) == "t" )
+ {
+ // UPDATE
+ enabledCapabilities |= QgsVectorDataProvider::ChangeGeometries;
+ }
- sql = QString( "SELECT 1 FROM pg_class,pg_namespace WHERE "
- "pg_class.relnamespace=pg_namespace.oid AND "
- "pg_get_userbyid(relowner)=current_user AND "
- "relname=%1 AND nspname=%2" )
- .arg( quotedValue( mTableName ) )
- .arg( quotedValue( mSchemaName ) );
- testAccess = connectionRO->PQexec( sql );
- if ( PQresultStatus( testAccess ) == PGRES_TUPLES_OK && PQntuples( testAccess ) == 1 )
- {
- enabledCapabilities |= QgsVectorDataProvider::AddAttributes | QgsVectorDataProvider::DeleteAttributes;
+ if ( QString::fromUtf8( PQgetvalue( testAccess, 0, 3 ) ) == "t" )
+ {
+ // INSERT
+ enabledCapabilities |= QgsVectorDataProvider::AddFeatures;
+ }
+
+ mCurrentSchema = QString::fromUtf8( PQgetvalue( testAccess, 0, 4 ) );
+ if ( mCurrentSchema == mSchemaName )
+ {
+ mUri.clearSchema();
+ }
+
+ if ( mSchemaName == "" )
+ mSchemaName = mCurrentSchema;
+
+ sql = QString( "SELECT 1 FROM pg_class,pg_namespace WHERE "
+ "pg_class.relnamespace=pg_namespace.oid AND "
+ "pg_get_userbyid(relowner)=current_user AND "
+ "relname=%1 AND nspname=%2" )
+ .arg( quotedValue( mTableName ) )
+ .arg( quotedValue( mSchemaName ) );
+ testAccess = connectionRO->PQexec( sql );
+ if ( PQresultStatus( testAccess ) == PGRES_TUPLES_OK && PQntuples( testAccess ) == 1 )
+ {
+ enabledCapabilities |= QgsVectorDataProvider::AddAttributes | QgsVectorDataProvider::DeleteAttributes;
+ }
}
}
else
More information about the QGIS-commit
mailing list