Skip to content

Commit

Permalink
Use uuid instead of timestamp when generating layer ids
Browse files Browse the repository at this point in the history
Timestamps can result in duplicate layer ids when layers
are created rapidly or in different threads.

Fix #14390
  • Loading branch information
nyalldawson committed Jun 10, 2017
1 parent 326e442 commit 03bfe9b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
9 changes: 4 additions & 5 deletions src/core/qgsmaplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
***************************************************************************/


#include <QDateTime>
#include <QDir>
#include <QDomDocument>
#include <QDomElement>
Expand Down Expand Up @@ -56,7 +55,6 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
: mValid( false ) // assume the layer is invalid
, mDataSource( source )
, mLayerOrigName( lyrname ) // store the original name
, mID( QLatin1String( "" ) )
, mLayerType( type )
, mBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal blending
, mLegend( nullptr )
Expand All @@ -65,12 +63,13 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
// Set the display name = internal name
mLayerName = capitalizeLayerName( mLayerOrigName );

mShortName = QLatin1String( "" );
//mShortName.replace( QRegExp( "[\\W]" ), "_" );

// Generate the unique ID of this layer
QDateTime dt = QDateTime::currentDateTime();
mID = lyrname + dt.toString( QStringLiteral( "yyyyMMddhhmmsszzz" ) );
QString uuid = QUuid::createUuid().toString();
// trim { } from uuid
mID = lyrname + '_' + uuid.mid( 1, uuid.length() - 2 );

// Tidy the ID up to avoid characters that may cause problems
// elsewhere (e.g in some parts of XML). Replaces every non-word
// character (word characters are the alphabet, numbers and
Expand Down
20 changes: 20 additions & 0 deletions tests/src/python/test_qgsmaplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@

class TestQgsMapLayer(unittest.TestCase):

def testUniqueId(self):
"""
Test that layers created quickly with same name get a unique ID
"""

# make 1000 layers quickly
layers = []
for i in range(1000):
layer = QgsVectorLayer(
'Point?crs=epsg:4326&field=name:string(20)',
'test',
'memory')
layers.append(layer)

# make sure all ids are unique
ids = set()
for l in layers:
self.assertFalse(l.id() in ids)
ids.add(l.id())

def copyLayerViaXmlReadWrite(self, source, dest):
# write to xml
doc = QDomDocument("testdoc")
Expand Down

0 comments on commit 03bfe9b

Please sign in to comment.