From 287a3b0ebc34d8485b41808eee6f4cadb0c05ccb Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Tue, 12 Feb 2019 18:25:43 +0100 Subject: [PATCH 1/3] Renamed test db for consistency (minor change) --- tests/src/python/test_provider_ogr_gpkg.py | 4 ++-- ..._names.gpkg => bug_21100-wierd_field_names.gpkg} | Bin 2 files changed, 2 insertions(+), 2 deletions(-) rename tests/testdata/{bug21100-wierd_field_names.gpkg => bug_21100-wierd_field_names.gpkg} (100%) diff --git a/tests/src/python/test_provider_ogr_gpkg.py b/tests/src/python/test_provider_ogr_gpkg.py index a82bb0cc3bc..3e4abde6459 100644 --- a/tests/src/python/test_provider_ogr_gpkg.py +++ b/tests/src/python/test_provider_ogr_gpkg.py @@ -1296,8 +1296,8 @@ class TestPyQgsOGRProviderGpkg(unittest.TestCase): def test_quote_identifier(self): """Regression #21100""" - tmpfile = os.path.join(self.basetestpath, 'bug21100-wierd_field_names.gpkg') # spellok - shutil.copy(os.path.join(unitTestDataPath(''), 'bug21100-wierd_field_names.gpkg'), tmpfile) # spellok + tmpfile = os.path.join(self.basetestpath, 'bug_21100-wierd_field_names.gpkg') # spellok + shutil.copy(os.path.join(unitTestDataPath(''), 'bug_21100-wierd_field_names.gpkg'), tmpfile) # spellok vl = QgsVectorLayer('{}|layerid=0'.format(tmpfile), 'foo', 'ogr') self.assertTrue(vl.isValid()) for i in range(1, len(vl.fields())): diff --git a/tests/testdata/bug21100-wierd_field_names.gpkg b/tests/testdata/bug_21100-wierd_field_names.gpkg similarity index 100% rename from tests/testdata/bug21100-wierd_field_names.gpkg rename to tests/testdata/bug_21100-wierd_field_names.gpkg From 61d361d6746e2e6d668616b70597f1c81bb5486d Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Tue, 12 Feb 2019 19:37:01 +0100 Subject: [PATCH 2/3] GPKG: Rename styles when layers are renamed Partially fixes #21227 TODO: - DB manager - Other providers --- src/providers/ogr/CMakeLists.txt | 8 ++++ src/providers/ogr/qgsgeopackagedataitems.cpp | 16 +++++++- src/providers/ogr/qgsogrprovider.cpp | 1 - tests/src/providers/CMakeLists.txt | 2 + tests/src/providers/testqgsogrprovider.cpp | 35 ++++++++++++++++++ .../provider/bug_21227-rename-styles.gpkg | Bin 0 -> 159744 bytes 6 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 tests/testdata/provider/bug_21227-rename-styles.gpkg diff --git a/src/providers/ogr/CMakeLists.txt b/src/providers/ogr/CMakeLists.txt index bb3f8345b0b..ccd08b1c7f4 100644 --- a/src/providers/ogr/CMakeLists.txt +++ b/src/providers/ogr/CMakeLists.txt @@ -64,18 +64,26 @@ INCLUDE_DIRECTORIES(SYSTEM ADD_LIBRARY(ogrprovider MODULE ${OGR_SRCS} ${OGR_MOC_SRCS}) +ADD_LIBRARY(ogrprovider_a STATIC ${OGR_SRCS} ${OGR_MOC_SRCS}) TARGET_LINK_LIBRARIES(ogrprovider qgis_core ) +TARGET_LINK_LIBRARIES(ogrprovider_a + qgis_core +) IF (WITH_GUI) TARGET_LINK_LIBRARIES (ogrprovider qgis_gui ) + TARGET_LINK_LIBRARIES (ogrprovider_a + qgis_gui + ) ENDIF () + IF (MSVC) #needed for linking to gdal which needs odbc SET(TARGET_LINK_LIBRARIES ${TARGET_LINK_LIBRARIE} odbc32 odbccp32) diff --git a/src/providers/ogr/qgsgeopackagedataitems.cpp b/src/providers/ogr/qgsgeopackagedataitems.cpp index fb07b9c9d2b..4ff99a472b1 100644 --- a/src/providers/ogr/qgsgeopackagedataitems.cpp +++ b/src/providers/ogr/qgsgeopackagedataitems.cpp @@ -41,6 +41,7 @@ #include "qgstaskmanager.h" #include "qgsproviderregistry.h" #include "qgsproxyprogresstask.h" +#include "qgssqliteutils.h" QGISEXTERN bool deleteLayer( const QString &uri, const QString &errCause ); @@ -887,12 +888,23 @@ bool QgsGeoPackageVectorLayerItem::rename( const QString &name ) GDALDatasetH hDS = GDALOpenEx( filePath.toUtf8().constData(), GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr ); if ( hDS ) { - QString sql( QStringLiteral( "ALTER TABLE \"%1\" RENAME TO \"%2\"" ).arg( oldName, name ) ); + QString sql( QStringLiteral( "ALTER TABLE %1 RENAME TO %2" ) + .arg( QgsSqliteUtils::quotedIdentifier( oldName ), + QgsSqliteUtils::quotedIdentifier( name ) ) ); OGRLayerH ogrLayer( GDALDatasetExecuteSQL( hDS, sql.toUtf8().constData(), nullptr, nullptr ) ); if ( ogrLayer ) GDALDatasetReleaseResultSet( hDS, ogrLayer ); - GDALClose( hDS ); errCause = CPLGetLastErrorMsg( ); + if ( errCause.isEmpty() ) + { + sql = QStringLiteral( "UPDATE layer_styles SET f_table_name = %2 WHERE f_table_name = %1" ) + .arg( QgsSqliteUtils::quotedString( oldName ), + QgsSqliteUtils::quotedString( name ) ); + ogrLayer = GDALDatasetExecuteSQL( hDS, sql.toUtf8().constData(), nullptr, nullptr ); + if ( ogrLayer ) + GDALDatasetReleaseResultSet( hDS, ogrLayer ); + } + GDALClose( hDS ); } else { diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp index c0adcbe473e..7855e2dc9c6 100644 --- a/src/providers/ogr/qgsogrprovider.cpp +++ b/src/providers/ogr/qgsogrprovider.cpp @@ -6574,4 +6574,3 @@ QGISEXTERN QgsTransaction *createTransaction( const QString &connString ) return new QgsOgrTransaction( connString, ds ); } - diff --git a/tests/src/providers/CMakeLists.txt b/tests/src/providers/CMakeLists.txt index 404bb18b530..2d55c0901ac 100644 --- a/tests/src/providers/CMakeLists.txt +++ b/tests/src/providers/CMakeLists.txt @@ -17,6 +17,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src/providers/postgres ${CMAKE_SOURCE_DIR}/src/providers/arcgisrest ${CMAKE_SOURCE_DIR}/src/providers/mdal + ${CMAKE_SOURCE_DIR}/src/providers/ogr ${CMAKE_SOURCE_DIR}/src/test ${CMAKE_BINARY_DIR}/src/core ) @@ -74,6 +75,7 @@ ADD_QGIS_TEST(gdalprovidertest testqgsgdalprovider.cpp) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") ADD_QGIS_TEST(ogrprovidertest testqgsogrprovider.cpp) +TARGET_LINK_LIBRARIES(qgis_ogrprovidertest ogrprovider_a) ADD_QGIS_TEST(wmscapabilitiestest testqgswmscapabilities.cpp) diff --git a/tests/src/providers/testqgsogrprovider.cpp b/tests/src/providers/testqgsogrprovider.cpp index ebf9bfeedde..5a529fb4b3a 100644 --- a/tests/src/providers/testqgsogrprovider.cpp +++ b/tests/src/providers/testqgsogrprovider.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include @@ -47,6 +49,8 @@ class TestQgsOgrProvider : public QObject void setupProxy(); void decodeUri(); void testThread(); + //! Test GPKG data items rename + void testGpkgDataItemRename(); private: QString mTestDataDir; @@ -213,6 +217,37 @@ void TestQgsOgrProvider::testThread() } +void TestQgsOgrProvider::testGpkgDataItemRename() +{ + QTemporaryFile f( QStringLiteral( "qgis-XXXXXX.gpkg" ) ); + f.open(); + f.close(); + QString fileName { f.fileName( ) }; + f.remove(); + QVERIFY( QFile::copy( QStringLiteral( "%1/provider/bug_21227-rename-styles.gpkg" ).arg( mTestDataDir ), fileName ) ); + QgsGeoPackageVectorLayerItem item( nullptr, + QStringLiteral( "Layer 1" ), + QStringLiteral( "gpkg:/%1|layername=layer 1" ) + .arg( fileName ), + QStringLiteral( "%1|layername=layer 1" ).arg( fileName ), + QgsLayerItem::LayerType::TableLayer ); + item.rename( "layer 3" ); + // Check that the style is still available + QgsVectorLayer metadataLayer( QStringLiteral( "/%1|layername=layer_styles" ).arg( fileName ) ); + QVERIFY( metadataLayer.isValid() ); + QgsFeature feature; + QgsFeatureIterator it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 3'" ) ) ) ); + QVERIFY( it.nextFeature( feature ) ); + QVERIFY( feature.isValid() ); + QCOMPARE( feature.attribute( QStringLiteral( "styleName" ) ).toString(), QString( "style for layer 1" ) ); + it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 1' " ) ) ) ); + QVERIFY( !it.nextFeature( feature ) ); + it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 2' " ) ) ) ); + QVERIFY( it.nextFeature( feature ) ); + QVERIFY( feature.isValid() ); + QCOMPARE( feature.attribute( QStringLiteral( "styleName" ) ).toString(), QString( "style for layer 2" ) ); +} + QGSTEST_MAIN( TestQgsOgrProvider ) #include "testqgsogrprovider.moc" diff --git a/tests/testdata/provider/bug_21227-rename-styles.gpkg b/tests/testdata/provider/bug_21227-rename-styles.gpkg new file mode 100644 index 0000000000000000000000000000000000000000..1c4bea247a720506faedc2ea6ad212937b6ba102 GIT binary patch literal 159744 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 T6Q}$({F(XVv*GVPmGJ)oPAc_Q literal 0 HcmV?d00001 From 8639bcf85369e6533d0d1bc2f6130d9c4520c853 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Wed, 13 Feb 2019 12:49:55 +0100 Subject: [PATCH 3/3] [db-manager] Use QgsDataItem implementation for GPKG layer rename - Removes code duplication - Uses a tested and robust implementation (from OGR) - Takes care of renaming QGIS styles - Updates the information view in the plugin Fixes #21227 --- python/plugins/db_manager/db_manager.py | 2 ++ .../db_manager/db_plugins/gpkg/connector.py | 36 +++++++++---------- .../plugins/db_manager/db_plugins/plugin.py | 4 +++ python/plugins/db_manager/layer_preview.py | 10 +++--- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/python/plugins/db_manager/db_manager.py b/python/plugins/db_manager/db_manager.py index ee597028dbc..f1539964621 100644 --- a/python/plugins/db_manager/db_manager.py +++ b/python/plugins/db_manager/db_manager.py @@ -88,6 +88,8 @@ class DBManager(QMainWindow): with OverrideCursor(Qt.WaitCursor): try: self.reloadButtons() + # Force-reload information on the layer + self.info.setDirty() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) self.refreshTabs() diff --git a/python/plugins/db_manager/db_plugins/gpkg/connector.py b/python/plugins/db_manager/db_plugins/gpkg/connector.py index 3fe36d67bd2..a73af66ed37 100644 --- a/python/plugins/db_manager/db_plugins/gpkg/connector.py +++ b/python/plugins/db_manager/db_plugins/gpkg/connector.py @@ -30,6 +30,8 @@ from ..connector import DBConnector from ..plugin import ConnectionError, DbError, Table from qgis.utils import spatialite_connect +from qgis.core import QgsApplication + import sqlite3 from osgeo import gdal, ogr, osr @@ -590,28 +592,26 @@ class GPKGDBConnector(DBConnector): self._execute_and_commit(sql) def renameTable(self, table, new_table): - """ rename a table """ + """Renames the table - if self.isRasterTable(table): - return False + :param table: tuple with schema and table names + :type table: tuple (str, str) + :param new_table: new table name + :type new_table: str + :return: true on success + :rtype: bool + """ - _, tablename = self.getSchemaTableName(table) - if new_table == tablename: - return True - - if tablename.find('"') >= 0: - tablename = self.quoteId(tablename) - if new_table.find('"') >= 0: - new_table = self.quoteId(new_table) - - gdal.ErrorReset() - self.gdal_ds.ExecuteSQL('ALTER TABLE %s RENAME TO %s' % (tablename, new_table)) - if gdal.GetLastErrorMsg() != '': - return False + table_name = table[1] + provider = [p for p in QgsApplication.dataItemProviderRegistry().providers() if p.name() == 'OGR'][0] + collection_item = provider.createDataItem(self.dbname, None) + data_item = [c for c in collection_item.createChildren() if c.name() == table_name][0] + result = data_item.rename(new_table) # we need to reopen after renaming since OGR doesn't update its # internal state - self._opendb() - return True + if result: + self._opendb() + return result def moveTable(self, table, new_table, new_schema=None): return self.renameTable(table, new_table) diff --git a/python/plugins/db_manager/db_plugins/plugin.py b/python/plugins/db_manager/db_plugins/plugin.py index b5a081f9bb2..8ec34f1ce8e 100644 --- a/python/plugins/db_manager/db_plugins/plugin.py +++ b/python/plugins/db_manager/db_plugins/plugin.py @@ -594,6 +594,7 @@ class Schema(DbItemObject): ret = self.database().connector.renameSchema(self.name, new_name) if ret is not False: self.name = new_name + # FIXME: refresh triggers self.refresh() return ret @@ -652,6 +653,9 @@ class Table(DbItemObject): ret = self.database().connector.renameTable((self.schemaName(), self.name), new_name) if ret is not False: self.name = new_name + self._triggers = None + self._rules = None + self._constraints = None self.refresh() return ret diff --git a/python/plugins/db_manager/layer_preview.py b/python/plugins/db_manager/layer_preview.py index 419d787763a..9b9ea8c87b4 100644 --- a/python/plugins/db_manager/layer_preview.py +++ b/python/plugins/db_manager/layer_preview.py @@ -40,7 +40,7 @@ class LayerPreview(QgsMapCanvas): self.item = None self.dirty = False - self.currentLayer = None + self.currentLayerId = None # reuse settings from QGIS settings = QgsSettings() @@ -118,9 +118,9 @@ class LayerPreview(QgsMapCanvas): vl = None # remove old layer (if any) and set new - if self.currentLayer: - if not QgsProject.instance().layerTreeRoot().findLayer(self.currentLayer.id()): - QgsProject.instance().removeMapLayers([self.currentLayer.id()]) + if self.currentLayerId: + if not QgsProject.instance().layerTreeRoot().findLayer(self.currentLayerId): + QgsProject.instance().removeMapLayers([self.currentLayerId]) if vl and vl.isValid(): self.setLayers([vl]) @@ -129,7 +129,7 @@ class LayerPreview(QgsMapCanvas): else: self.setLayers([]) - self.currentLayer = vl + self.currentLayerId = vl.id() self.freeze(False) super().refresh()