Skip to content

Commit

Permalink
Merge pull request #5381 from pblottiere/bugfix_style_218
Browse files Browse the repository at this point in the history
[bugfix] Fixes #17234 save/load styles from Postgres when a service file is used
  • Loading branch information
pblottiere committed Oct 24, 2017
2 parents 2e87d32 + 6c6d837 commit 29a137d
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -4367,14 +4367,14 @@ void QgsVectorLayer::saveStyleToDatabase( const QString& name, const QString& de

QDomDocument qmlDocument, sldDocument;
this->exportNamedStyle( qmlDocument, msgError );
if ( !msgError.isNull() )
if ( !msgError.isEmpty() )
{
return;
}
qmlStyle = qmlDocument.toString();

this->exportSldStyle( sldDocument, msgError );
if ( !msgError.isNull() )
if ( !msgError.isEmpty() )
{
return;
}
Expand Down
24 changes: 21 additions & 3 deletions src/providers/postgres/qgspostgresconn.cpp
Expand Up @@ -956,7 +956,7 @@ QString QgsPostgresConn::quotedValue( const QVariant& value )
}
}

PGresult *QgsPostgresConn::PQexec( const QString& query, bool logError )
PGresult *QgsPostgresConn::PQexec( const QString& query, bool logError ) const
{
if ( PQstatus() != CONNECTION_OK )
{
Expand Down Expand Up @@ -1138,13 +1138,13 @@ void QgsPostgresConn::PQfinish()
mConn = nullptr;
}

int QgsPostgresConn::PQstatus()
int QgsPostgresConn::PQstatus() const
{
Q_ASSERT( mConn );
return ::PQstatus( mConn );
}

QString QgsPostgresConn::PQerrorMessage()
QString QgsPostgresConn::PQerrorMessage() const
{
Q_ASSERT( mConn );
return QString::fromUtf8( ::PQerrorMessage( mConn ) );
Expand Down Expand Up @@ -1795,3 +1795,21 @@ bool QgsPostgresConn::cancel()

return res == 0;
}

QString QgsPostgresConn::currentDatabase() const
{
QString database;
QString sql = "SELECT current_database()";
QgsPostgresResult res( PQexec( sql ) );

if ( res.PQresultStatus() == PGRES_TUPLES_OK )
{
database = res.PQgetvalue( 0, 0 );
}
else
{
QgsMessageLog::logMessage( tr( "SQL:%1\nresult:%2\nerror:%3\n" ).arg( sql ).arg( res.PQresultStatus() ).arg( res.PQresultErrorMessage() ), tr( "PostGIS" ) );
}

return database;
}
13 changes: 10 additions & 3 deletions src/providers/postgres/qgspostgresconn.h
Expand Up @@ -244,11 +244,11 @@ class QgsPostgresConn : public QObject
//

// run a query and check for errors
PGresult *PQexec( const QString& query, bool logError = true );
PGresult *PQexec( const QString& query, bool logError = true ) const;
void PQfinish();
QString PQerrorMessage();
QString PQerrorMessage() const;
int PQsendQuery( const QString& query );
int PQstatus();
int PQstatus() const;
PGresult *PQgetResult();
PGresult *PQprepare( const QString& stmtName, const QString& query, int nParams, const Oid *paramTypes );
PGresult *PQexecPrepared( const QString& stmtName, const QStringList &params );
Expand Down Expand Up @@ -310,6 +310,13 @@ class QgsPostgresConn : public QObject

QString connInfo() const { return mConnInfo; }

/**
* Returns the underlying database.
*
* @since QGIS 2.18
*/
QString currentDatabase() const;

static const int sGeomTypeSelectLimit;

static QString displayStringForWkbType( QGis::WkbType wkbType );
Expand Down
15 changes: 15 additions & 0 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -4073,6 +4073,11 @@ QGISEXTERN bool saveStyle( const QString& uri, const QString& qmlStyle, const QS
}
}

if ( dsUri.database().isEmpty() ) // typically when a service file is used
{
dsUri.setDatabase( conn->currentDatabase() );
}

QString uiFileColumn;
QString uiFileValue;
if ( !uiFileContent.isEmpty() )
Expand Down Expand Up @@ -4199,6 +4204,11 @@ QGISEXTERN QString loadStyle( const QString& uri, QString& errCause )
return "";
}

if ( dsUri.database().isEmpty() ) // typically when a service file is used
{
dsUri.setDatabase( conn->currentDatabase() );
}

QString selectQmlQuery = QString( "SELECT styleQML"
" FROM layer_styles"
" WHERE f_table_catalog=%1"
Expand Down Expand Up @@ -4232,6 +4242,11 @@ QGISEXTERN int listStyles( const QString &uri, QStringList &ids, QStringList &na
return -1;
}

if ( dsUri.database().isEmpty() ) // typically when a service file is used
{
dsUri.setDatabase( conn->currentDatabase() );
}

QString selectRelatedQuery = QString( "SELECT id,styleName,description"
" FROM layer_styles"
" WHERE f_table_catalog=%1"
Expand Down
16 changes: 16 additions & 0 deletions tests/src/python/test_provider_postgres.py
Expand Up @@ -391,6 +391,22 @@ def testKey(lyr, key, kfnames):
testKey(lyr, '"f1","F2","f3"', ['f1', 'F2', 'f3'])
testKey(lyr, None, ['id'])

def testStyleDatabaseWithService(self):
myconn = 'service=\'qgis_test\''
if 'QGIS_PGTEST_DB' in os.environ:
myconn = os.environ['QGIS_PGTEST_DB']
myvl = QgsVectorLayer(myconn + ' sslmode=disable key=\'pk\' srid=4326 type=POINT table="qgis_test"."someData" (geom) sql=', 'test', 'postgres')
self.assertTrue(myvl.isValid())

styles = myvl.listStylesInDatabase()
ids = styles[1]
self.assertEqual(len(ids), 0)

myvl.saveStyleToDatabase('mystyle', '', False, '', '')
styles = myvl.listStylesInDatabase()
ids = styles[1]
self.assertEqual(len(ids), 1)


if __name__ == '__main__':
unittest.main()

0 comments on commit 29a137d

Please sign in to comment.