Skip to content

Commit baa2b96

Browse files
committedOct 9, 2017
Auxiliary data is cloned too
1 parent 9306226 commit baa2b96

File tree

5 files changed

+114
-19
lines changed

5 files changed

+114
-19
lines changed
 

‎python/core/qgsauxiliarystorage.sip

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ class QgsAuxiliaryLayer : QgsVectorLayer
109109

110110

111111

112+
QgsAuxiliaryLayer *clone( QgsVectorLayer *layer ) const /Factory/;
113+
%Docstring
114+
Returns a new instance equivalent to this one. The underlying table
115+
is duplicate for the layer given in parameter. Note that the current
116+
auxiliary layer should be saved to have a proper duplicated table.
117+
118+
\param layer The layer for which the clone is made
119+
:rtype: QgsAuxiliaryLayer
120+
%End
121+
112122
QgsVectorLayer *toSpatialLayer() const;
113123
%Docstring
114124
An auxiliary layer is not spatial. This method returns a spatial
@@ -348,10 +358,23 @@ class QgsAuxiliaryStorage
348358
%Docstring
349359
Removes a table from the auxiliary storage.
350360

361+
\param uri The uri of the table to remove
362+
351363
:return: true if the table is well deleted, false otherwise
352364
:rtype: bool
353365
%End
354366

367+
static bool duplicateTable( const QgsDataSourceUri &uri, const QString &newTable );
368+
%Docstring
369+
Duplicates a table and its content.
370+
371+
\param uri The uri of the table to duplicate
372+
\param newTable The name of the new table
373+
374+
:return: true if the table is well duplicated, false otherwise
375+
:rtype: bool
376+
%End
377+
355378
static QString extension();
356379
%Docstring
357380
Returns the extension used for auxiliary databases.

‎src/app/qgisapp.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8873,6 +8873,9 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList )
88738873
}
88748874
else if ( vlayer )
88758875
{
8876+
if ( vlayer->auxiliaryLayer() )
8877+
vlayer->auxiliaryLayer()->save();
8878+
88768879
dupLayer = vlayer->clone();
88778880
}
88788881
}

‎src/core/qgsauxiliarystorage.cpp

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ QgsPropertyDefinition QgsAuxiliaryField::propertyDefinition() const
181181

182182
QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer )
183183
: QgsVectorLayer( QString( "%1|layername=%2" ).arg( filename, table ), QString( "%1_auxiliarystorage" ).arg( table ), "ogr" )
184+
, mFileName( filename )
185+
, mTable( table )
184186
, mLayer( vlayer )
185187
{
186188
// init join info
@@ -194,6 +196,12 @@ QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &fil
194196
mJoinInfo.setJoinFieldNamesBlackList( QStringList() << QStringLiteral( "rowid" ) ); // introduced by ogr provider
195197
}
196198

199+
QgsAuxiliaryLayer *QgsAuxiliaryLayer::clone( QgsVectorLayer *target ) const
200+
{
201+
QgsAuxiliaryStorage::duplicateTable( source(), target->id() );
202+
return new QgsAuxiliaryLayer( mJoinInfo.targetFieldName(), mFileName, target->id(), target );
203+
}
204+
197205
QgsVectorLayer *QgsAuxiliaryLayer::toSpatialLayer() const
198206
{
199207
QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() );
@@ -472,36 +480,42 @@ QgsAuxiliaryLayer *QgsAuxiliaryStorage::createAuxiliaryLayer( const QgsField &fi
472480
return alayer;
473481
}
474482

475-
bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &uri )
483+
bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &ogrUri )
476484
{
477485
bool rc = false;
486+
QgsDataSourceUri uri = parseOgrUri( ogrUri );
478487

479-
// parsing for ogr style uri :
480-
// " filePath|layername='tableName' table="" sql="
481-
QStringList uriParts = uri.uri().split( '|' );
482-
if ( uriParts.count() < 2 )
483-
return false;
488+
if ( !uri.database().isEmpty() && !uri.table().isEmpty() )
489+
{
490+
sqlite3 *handler = openDB( uri.database() );
484491

485-
const QString databasePath = uriParts[0].replace( ' ', "" );
492+
if ( handler )
493+
{
494+
QString sql = QString( "DROP TABLE %1" ).arg( uri.table() );
495+
rc = exec( sql, handler );
486496

487-
const QString table = uriParts[1];
488-
QStringList tableParts = table.split( ' ' );
497+
sql = QString( "VACUUM" );
498+
rc = exec( sql, handler );
489499

490-
if ( tableParts.count() < 1 )
491-
return false;
500+
close( handler );
501+
}
502+
}
492503

493-
const QString tableName = tableParts[0].replace( "layername=", "" );
504+
return rc;
505+
}
494506

495-
if ( !databasePath.isEmpty() && !tableName.isEmpty() )
507+
bool QgsAuxiliaryStorage::duplicateTable( const QgsDataSourceUri &ogrUri, const QString &newTable )
508+
{
509+
QgsDataSourceUri uri = parseOgrUri( ogrUri );
510+
bool rc = false;
511+
512+
if ( !uri.table().isEmpty() && !uri.database().isEmpty() )
496513
{
497-
sqlite3 *handler = openDB( databasePath );
514+
sqlite3 *handler = openDB( uri.database() );
498515

499516
if ( handler )
500517
{
501-
QString sql = QString( "DROP TABLE %1" ).arg( tableName );
502-
rc = exec( sql, handler );
503-
504-
sql = QString( "VACUUM" );
518+
QString sql = QString( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
505519
rc = exec( sql, handler );
506520

507521
close( handler );
@@ -680,3 +694,29 @@ QString QgsAuxiliaryStorage::currentFileName() const
680694
else
681695
return mFileName;
682696
}
697+
698+
QgsDataSourceUri QgsAuxiliaryStorage::parseOgrUri( const QgsDataSourceUri &uri )
699+
{
700+
QgsDataSourceUri newUri;
701+
702+
// parsing for ogr style uri :
703+
// " filePath|layername='tableName' table="" sql="
704+
QStringList uriParts = uri.uri().split( '|' );
705+
if ( uriParts.count() < 2 )
706+
return newUri;
707+
708+
const QString databasePath = uriParts[0].replace( ' ', "" );
709+
710+
const QString table = uriParts[1];
711+
QStringList tableParts = table.split( ' ' );
712+
713+
if ( tableParts.count() < 1 )
714+
return newUri;
715+
716+
const QString tableName = tableParts[0].replace( "layername=", "" );
717+
718+
newUri.setDataSource( QString(), tableName, QString() );
719+
newUri.setDatabase( databasePath );
720+
721+
return newUri;
722+
}

‎src/core/qgsauxiliarystorage.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,15 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
137137

138138
QgsAuxiliaryLayer &operator=( QgsAuxiliaryLayer const &rhs ) = delete;
139139

140+
/**
141+
* Returns a new instance equivalent to this one. The underlying table
142+
* is duplicate for the layer given in parameter. Note that the current
143+
* auxiliary layer should be saved to have a proper duplicated table.
144+
*
145+
* \param layer The layer for which the clone is made
146+
*/
147+
QgsAuxiliaryLayer *clone( QgsVectorLayer *layer ) const SIP_FACTORY;
148+
140149
/**
141150
* An auxiliary layer is not spatial. This method returns a spatial
142151
* representation of auxiliary data.
@@ -243,6 +252,8 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
243252

244253
private:
245254
QgsVectorLayerJoinInfo mJoinInfo;
255+
QString mFileName;
256+
QString mTable;
246257
QgsVectorLayer *mLayer = nullptr;
247258
};
248259

@@ -357,10 +368,22 @@ class CORE_EXPORT QgsAuxiliaryStorage
357368
/**
358369
* Removes a table from the auxiliary storage.
359370
*
371+
* \param uri The uri of the table to remove
372+
*
360373
* \returns true if the table is well deleted, false otherwise
361374
*/
362375
static bool deleteTable( const QgsDataSourceUri &uri );
363376

377+
/**
378+
* Duplicates a table and its content.
379+
*
380+
* \param uri The uri of the table to duplicate
381+
* \param newTable The name of the new table
382+
*
383+
* \returns true if the table is well duplicated, false otherwise
384+
*/
385+
static bool duplicateTable( const QgsDataSourceUri &uri, const QString &newTable );
386+
364387
/**
365388
* Returns the extension used for auxiliary databases.
366389
*/
@@ -382,6 +405,8 @@ class CORE_EXPORT QgsAuxiliaryStorage
382405
static bool exec( const QString &sql, sqlite3 *handler );
383406
static void debugMsg( const QString &sql, sqlite3 *handler );
384407

408+
static QgsDataSourceUri parseOgrUri( const QgsDataSourceUri &uri );
409+
385410
bool mValid = false;
386411
QString mFileName; // original filename
387412
QString mTmpFileName; // temporary filename used in copy mode

‎src/core/qgsvectorlayer.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,9 @@ QgsVectorLayer *QgsVectorLayer::clone() const
201201
QList<QgsVectorLayerJoinInfo> joins = vectorJoins();
202202
Q_FOREACH ( const QgsVectorLayerJoinInfo &join, joins )
203203
{
204-
layer->addJoin( join );
204+
// do not copy join information for auxiliary layer
205+
if ( auxiliaryLayer() && auxiliaryLayer()->id() != join.joinLayerId() )
206+
layer->addJoin( join );
205207
}
206208

207209
layer->setProviderEncoding( dataProvider()->encoding() );
@@ -264,6 +266,8 @@ QgsVectorLayer *QgsVectorLayer::clone() const
264266

265267
layer->setEditFormConfig( editFormConfig() );
266268

269+
layer->setAuxiliaryLayer( auxiliaryLayer()->clone( layer ) );
270+
267271
return layer;
268272
}
269273

0 commit comments

Comments
 (0)
Please sign in to comment.