Skip to content

Commit dabd649

Browse files
authored
Merge pull request #9164 from elpaso/bugfix-21227-layer-rename-styles
Fix GPKG layer rename styles in browser
2 parents 88afe75 + 8639bcf commit dabd649

File tree

12 files changed

+91
-29
lines changed

12 files changed

+91
-29
lines changed

python/plugins/db_manager/db_manager.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ def itemChanged(self, item):
8888
with OverrideCursor(Qt.WaitCursor):
8989
try:
9090
self.reloadButtons()
91+
# Force-reload information on the layer
92+
self.info.setDirty()
9193
# clear preview, this will delete the layer in preview tab
9294
self.preview.loadPreview(None)
9395
self.refreshTabs()

python/plugins/db_manager/db_plugins/gpkg/connector.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
from ..plugin import ConnectionError, DbError, Table
3131

3232
from qgis.utils import spatialite_connect
33+
from qgis.core import QgsApplication
34+
3335
import sqlite3
3436

3537
from osgeo import gdal, ogr, osr
@@ -590,28 +592,26 @@ def emptyTable(self, table):
590592
self._execute_and_commit(sql)
591593

592594
def renameTable(self, table, new_table):
593-
""" rename a table """
594-
595-
if self.isRasterTable(table):
596-
return False
597-
598-
_, tablename = self.getSchemaTableName(table)
599-
if new_table == tablename:
600-
return True
601-
602-
if tablename.find('"') >= 0:
603-
tablename = self.quoteId(tablename)
604-
if new_table.find('"') >= 0:
605-
new_table = self.quoteId(new_table)
595+
"""Renames the table
596+
597+
:param table: tuple with schema and table names
598+
:type table: tuple (str, str)
599+
:param new_table: new table name
600+
:type new_table: str
601+
:return: true on success
602+
:rtype: bool
603+
"""
606604

607-
gdal.ErrorReset()
608-
self.gdal_ds.ExecuteSQL('ALTER TABLE %s RENAME TO %s' % (tablename, new_table))
609-
if gdal.GetLastErrorMsg() != '':
610-
return False
605+
table_name = table[1]
606+
provider = [p for p in QgsApplication.dataItemProviderRegistry().providers() if p.name() == 'OGR'][0]
607+
collection_item = provider.createDataItem(self.dbname, None)
608+
data_item = [c for c in collection_item.createChildren() if c.name() == table_name][0]
609+
result = data_item.rename(new_table)
611610
# we need to reopen after renaming since OGR doesn't update its
612611
# internal state
613-
self._opendb()
614-
return True
612+
if result:
613+
self._opendb()
614+
return result
615615

616616
def moveTable(self, table, new_table, new_schema=None):
617617
return self.renameTable(table, new_table)

python/plugins/db_manager/db_plugins/plugin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ def rename(self, new_name):
594594
ret = self.database().connector.renameSchema(self.name, new_name)
595595
if ret is not False:
596596
self.name = new_name
597+
# FIXME: refresh triggers
597598
self.refresh()
598599
return ret
599600

@@ -652,6 +653,9 @@ def rename(self, new_name):
652653
ret = self.database().connector.renameTable((self.schemaName(), self.name), new_name)
653654
if ret is not False:
654655
self.name = new_name
656+
self._triggers = None
657+
self._rules = None
658+
self._constraints = None
655659
self.refresh()
656660
return ret
657661

python/plugins/db_manager/layer_preview.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def __init__(self, parent=None):
4040

4141
self.item = None
4242
self.dirty = False
43-
self.currentLayer = None
43+
self.currentLayerId = None
4444

4545
# reuse settings from QGIS
4646
settings = QgsSettings()
@@ -118,9 +118,9 @@ def _loadTablePreview(self, table, limit=False):
118118
vl = None
119119

120120
# remove old layer (if any) and set new
121-
if self.currentLayer:
122-
if not QgsProject.instance().layerTreeRoot().findLayer(self.currentLayer.id()):
123-
QgsProject.instance().removeMapLayers([self.currentLayer.id()])
121+
if self.currentLayerId:
122+
if not QgsProject.instance().layerTreeRoot().findLayer(self.currentLayerId):
123+
QgsProject.instance().removeMapLayers([self.currentLayerId])
124124

125125
if vl and vl.isValid():
126126
self.setLayers([vl])
@@ -129,7 +129,7 @@ def _loadTablePreview(self, table, limit=False):
129129
else:
130130
self.setLayers([])
131131

132-
self.currentLayer = vl
132+
self.currentLayerId = vl.id()
133133

134134
self.freeze(False)
135135
super().refresh()

src/providers/ogr/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,26 @@ INCLUDE_DIRECTORIES(SYSTEM
6464

6565

6666
ADD_LIBRARY(ogrprovider MODULE ${OGR_SRCS} ${OGR_MOC_SRCS})
67+
ADD_LIBRARY(ogrprovider_a STATIC ${OGR_SRCS} ${OGR_MOC_SRCS})
6768

6869
TARGET_LINK_LIBRARIES(ogrprovider
6970
qgis_core
7071
)
7172

73+
TARGET_LINK_LIBRARIES(ogrprovider_a
74+
qgis_core
75+
)
7276

7377
IF (WITH_GUI)
7478
TARGET_LINK_LIBRARIES (ogrprovider
7579
qgis_gui
7680
)
81+
TARGET_LINK_LIBRARIES (ogrprovider_a
82+
qgis_gui
83+
)
7784
ENDIF ()
7885

86+
7987
IF (MSVC)
8088
#needed for linking to gdal which needs odbc
8189
SET(TARGET_LINK_LIBRARIES ${TARGET_LINK_LIBRARIE} odbc32 odbccp32)

src/providers/ogr/qgsgeopackagedataitems.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "qgstaskmanager.h"
4242
#include "qgsproviderregistry.h"
4343
#include "qgsproxyprogresstask.h"
44+
#include "qgssqliteutils.h"
4445

4546

4647
QGISEXTERN bool deleteLayer( const QString &uri, const QString &errCause );
@@ -887,12 +888,23 @@ bool QgsGeoPackageVectorLayerItem::rename( const QString &name )
887888
GDALDatasetH hDS = GDALOpenEx( filePath.toUtf8().constData(), GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr );
888889
if ( hDS )
889890
{
890-
QString sql( QStringLiteral( "ALTER TABLE \"%1\" RENAME TO \"%2\"" ).arg( oldName, name ) );
891+
QString sql( QStringLiteral( "ALTER TABLE %1 RENAME TO %2" )
892+
.arg( QgsSqliteUtils::quotedIdentifier( oldName ),
893+
QgsSqliteUtils::quotedIdentifier( name ) ) );
891894
OGRLayerH ogrLayer( GDALDatasetExecuteSQL( hDS, sql.toUtf8().constData(), nullptr, nullptr ) );
892895
if ( ogrLayer )
893896
GDALDatasetReleaseResultSet( hDS, ogrLayer );
894-
GDALClose( hDS );
895897
errCause = CPLGetLastErrorMsg( );
898+
if ( errCause.isEmpty() )
899+
{
900+
sql = QStringLiteral( "UPDATE layer_styles SET f_table_name = %2 WHERE f_table_name = %1" )
901+
.arg( QgsSqliteUtils::quotedString( oldName ),
902+
QgsSqliteUtils::quotedString( name ) );
903+
ogrLayer = GDALDatasetExecuteSQL( hDS, sql.toUtf8().constData(), nullptr, nullptr );
904+
if ( ogrLayer )
905+
GDALDatasetReleaseResultSet( hDS, ogrLayer );
906+
}
907+
GDALClose( hDS );
896908
}
897909
else
898910
{

src/providers/ogr/qgsogrprovider.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6574,4 +6574,3 @@ QGISEXTERN QgsTransaction *createTransaction( const QString &connString )
65746574
return new QgsOgrTransaction( connString, ds );
65756575
}
65766576

6577-

tests/src/providers/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
1717
${CMAKE_SOURCE_DIR}/src/providers/postgres
1818
${CMAKE_SOURCE_DIR}/src/providers/arcgisrest
1919
${CMAKE_SOURCE_DIR}/src/providers/mdal
20+
${CMAKE_SOURCE_DIR}/src/providers/ogr
2021
${CMAKE_SOURCE_DIR}/src/test
2122
${CMAKE_BINARY_DIR}/src/core
2223
)
@@ -74,6 +75,7 @@ ADD_QGIS_TEST(gdalprovidertest testqgsgdalprovider.cpp)
7475

7576
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
7677
ADD_QGIS_TEST(ogrprovidertest testqgsogrprovider.cpp)
78+
TARGET_LINK_LIBRARIES(qgis_ogrprovidertest ogrprovider_a)
7779

7880
ADD_QGIS_TEST(wmscapabilitiestest
7981
testqgswmscapabilities.cpp)

tests/src/providers/testqgsogrprovider.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <qgsproviderregistry.h>
2525
#include <qgsvectorlayer.h>
2626
#include <qgsnetworkaccessmanager.h>
27+
#include <qgsgeopackagedataitems.h>
28+
#include <qgsdataitem.h>
2729

2830
#include <QObject>
2931

@@ -47,6 +49,8 @@ class TestQgsOgrProvider : public QObject
4749
void setupProxy();
4850
void decodeUri();
4951
void testThread();
52+
//! Test GPKG data items rename
53+
void testGpkgDataItemRename();
5054

5155
private:
5256
QString mTestDataDir;
@@ -213,6 +217,37 @@ void TestQgsOgrProvider::testThread()
213217

214218
}
215219

220+
void TestQgsOgrProvider::testGpkgDataItemRename()
221+
{
222+
QTemporaryFile f( QStringLiteral( "qgis-XXXXXX.gpkg" ) );
223+
f.open();
224+
f.close();
225+
QString fileName { f.fileName( ) };
226+
f.remove();
227+
QVERIFY( QFile::copy( QStringLiteral( "%1/provider/bug_21227-rename-styles.gpkg" ).arg( mTestDataDir ), fileName ) );
228+
QgsGeoPackageVectorLayerItem item( nullptr,
229+
QStringLiteral( "Layer 1" ),
230+
QStringLiteral( "gpkg:/%1|layername=layer 1" )
231+
.arg( fileName ),
232+
QStringLiteral( "%1|layername=layer 1" ).arg( fileName ),
233+
QgsLayerItem::LayerType::TableLayer );
234+
item.rename( "layer 3" );
235+
// Check that the style is still available
236+
QgsVectorLayer metadataLayer( QStringLiteral( "/%1|layername=layer_styles" ).arg( fileName ) );
237+
QVERIFY( metadataLayer.isValid() );
238+
QgsFeature feature;
239+
QgsFeatureIterator it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 3'" ) ) ) );
240+
QVERIFY( it.nextFeature( feature ) );
241+
QVERIFY( feature.isValid() );
242+
QCOMPARE( feature.attribute( QStringLiteral( "styleName" ) ).toString(), QString( "style for layer 1" ) );
243+
it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 1' " ) ) ) );
244+
QVERIFY( !it.nextFeature( feature ) );
245+
it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 2' " ) ) ) );
246+
QVERIFY( it.nextFeature( feature ) );
247+
QVERIFY( feature.isValid() );
248+
QCOMPARE( feature.attribute( QStringLiteral( "styleName" ) ).toString(), QString( "style for layer 2" ) );
249+
}
250+
216251

217252
QGSTEST_MAIN( TestQgsOgrProvider )
218253
#include "testqgsogrprovider.moc"

tests/src/python/test_provider_ogr_gpkg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,8 +1296,8 @@ def testJson(self):
12961296
def test_quote_identifier(self):
12971297
"""Regression #21100"""
12981298

1299-
tmpfile = os.path.join(self.basetestpath, 'bug21100-wierd_field_names.gpkg') # spellok
1300-
shutil.copy(os.path.join(unitTestDataPath(''), 'bug21100-wierd_field_names.gpkg'), tmpfile) # spellok
1299+
tmpfile = os.path.join(self.basetestpath, 'bug_21100-wierd_field_names.gpkg') # spellok
1300+
shutil.copy(os.path.join(unitTestDataPath(''), 'bug_21100-wierd_field_names.gpkg'), tmpfile) # spellok
13011301
vl = QgsVectorLayer('{}|layerid=0'.format(tmpfile), 'foo', 'ogr')
13021302
self.assertTrue(vl.isValid())
13031303
for i in range(1, len(vl.fields())):
Binary file not shown.

0 commit comments

Comments
 (0)