mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
Merge pull request #9164 from elpaso/bugfix-21227-layer-rename-styles
Fix GPKG layer rename styles in browser
This commit is contained in:
commit
dabd649a6d
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -6574,4 +6574,3 @@ QGISEXTERN QgsTransaction *createTransaction( const QString &connString )
|
||||
return new QgsOgrTransaction( connString, ds );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <qgsproviderregistry.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
#include <qgsnetworkaccessmanager.h>
|
||||
#include <qgsgeopackagedataitems.h>
|
||||
#include <qgsdataitem.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@ -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"
|
||||
|
@ -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())):
|
||||
|
BIN
tests/testdata/provider/bug_21227-rename-styles.gpkg
vendored
Normal file
BIN
tests/testdata/provider/bug_21227-rename-styles.gpkg
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user