Skip to content

Commit

Permalink
Auxiliary data is cloned too
Browse files Browse the repository at this point in the history
  • Loading branch information
pblottiere committed Oct 9, 2017
1 parent 9306226 commit baa2b96
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 19 deletions.
23 changes: 23 additions & 0 deletions python/core/qgsauxiliarystorage.sip
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ class QgsAuxiliaryLayer : QgsVectorLayer



QgsAuxiliaryLayer *clone( QgsVectorLayer *layer ) const /Factory/;
%Docstring
Returns a new instance equivalent to this one. The underlying table
is duplicate for the layer given in parameter. Note that the current
auxiliary layer should be saved to have a proper duplicated table.

\param layer The layer for which the clone is made
:rtype: QgsAuxiliaryLayer
%End

QgsVectorLayer *toSpatialLayer() const;
%Docstring
An auxiliary layer is not spatial. This method returns a spatial
Expand Down Expand Up @@ -348,10 +358,23 @@ class QgsAuxiliaryStorage
%Docstring
Removes a table from the auxiliary storage.

\param uri The uri of the table to remove

:return: true if the table is well deleted, false otherwise
:rtype: bool
%End

static bool duplicateTable( const QgsDataSourceUri &uri, const QString &newTable );
%Docstring
Duplicates a table and its content.

\param uri The uri of the table to duplicate
\param newTable The name of the new table

:return: true if the table is well duplicated, false otherwise
:rtype: bool
%End

static QString extension();
%Docstring
Returns the extension used for auxiliary databases.
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8873,6 +8873,9 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList )
}
else if ( vlayer )
{
if ( vlayer->auxiliaryLayer() )
vlayer->auxiliaryLayer()->save();

dupLayer = vlayer->clone();
}
}
Expand Down
76 changes: 58 additions & 18 deletions src/core/qgsauxiliarystorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ QgsPropertyDefinition QgsAuxiliaryField::propertyDefinition() const

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

QgsAuxiliaryLayer *QgsAuxiliaryLayer::clone( QgsVectorLayer *target ) const
{
QgsAuxiliaryStorage::duplicateTable( source(), target->id() );
return new QgsAuxiliaryLayer( mJoinInfo.targetFieldName(), mFileName, target->id(), target );
}

QgsVectorLayer *QgsAuxiliaryLayer::toSpatialLayer() const
{
QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() );
Expand Down Expand Up @@ -472,36 +480,42 @@ QgsAuxiliaryLayer *QgsAuxiliaryStorage::createAuxiliaryLayer( const QgsField &fi
return alayer;
}

bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &uri )
bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &ogrUri )
{
bool rc = false;
QgsDataSourceUri uri = parseOgrUri( ogrUri );

// parsing for ogr style uri :
// " filePath|layername='tableName' table="" sql="
QStringList uriParts = uri.uri().split( '|' );
if ( uriParts.count() < 2 )
return false;
if ( !uri.database().isEmpty() && !uri.table().isEmpty() )
{
sqlite3 *handler = openDB( uri.database() );

const QString databasePath = uriParts[0].replace( ' ', "" );
if ( handler )
{
QString sql = QString( "DROP TABLE %1" ).arg( uri.table() );
rc = exec( sql, handler );

const QString table = uriParts[1];
QStringList tableParts = table.split( ' ' );
sql = QString( "VACUUM" );
rc = exec( sql, handler );

if ( tableParts.count() < 1 )
return false;
close( handler );
}
}

const QString tableName = tableParts[0].replace( "layername=", "" );
return rc;
}

if ( !databasePath.isEmpty() && !tableName.isEmpty() )
bool QgsAuxiliaryStorage::duplicateTable( const QgsDataSourceUri &ogrUri, const QString &newTable )
{
QgsDataSourceUri uri = parseOgrUri( ogrUri );
bool rc = false;

if ( !uri.table().isEmpty() && !uri.database().isEmpty() )
{
sqlite3 *handler = openDB( databasePath );
sqlite3 *handler = openDB( uri.database() );

if ( handler )
{
QString sql = QString( "DROP TABLE %1" ).arg( tableName );
rc = exec( sql, handler );

sql = QString( "VACUUM" );
QString sql = QString( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
rc = exec( sql, handler );

close( handler );
Expand Down Expand Up @@ -680,3 +694,29 @@ QString QgsAuxiliaryStorage::currentFileName() const
else
return mFileName;
}

QgsDataSourceUri QgsAuxiliaryStorage::parseOgrUri( const QgsDataSourceUri &uri )
{
QgsDataSourceUri newUri;

// parsing for ogr style uri :
// " filePath|layername='tableName' table="" sql="
QStringList uriParts = uri.uri().split( '|' );
if ( uriParts.count() < 2 )
return newUri;

const QString databasePath = uriParts[0].replace( ' ', "" );

const QString table = uriParts[1];
QStringList tableParts = table.split( ' ' );

if ( tableParts.count() < 1 )
return newUri;

const QString tableName = tableParts[0].replace( "layername=", "" );

newUri.setDataSource( QString(), tableName, QString() );
newUri.setDatabase( databasePath );

return newUri;
}
25 changes: 25 additions & 0 deletions src/core/qgsauxiliarystorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer

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

/**
* Returns a new instance equivalent to this one. The underlying table
* is duplicate for the layer given in parameter. Note that the current
* auxiliary layer should be saved to have a proper duplicated table.
*
* \param layer The layer for which the clone is made
*/
QgsAuxiliaryLayer *clone( QgsVectorLayer *layer ) const SIP_FACTORY;

/**
* An auxiliary layer is not spatial. This method returns a spatial
* representation of auxiliary data.
Expand Down Expand Up @@ -243,6 +252,8 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer

private:
QgsVectorLayerJoinInfo mJoinInfo;
QString mFileName;
QString mTable;
QgsVectorLayer *mLayer = nullptr;
};

Expand Down Expand Up @@ -357,10 +368,22 @@ class CORE_EXPORT QgsAuxiliaryStorage
/**
* Removes a table from the auxiliary storage.
*
* \param uri The uri of the table to remove
*
* \returns true if the table is well deleted, false otherwise
*/
static bool deleteTable( const QgsDataSourceUri &uri );

/**
* Duplicates a table and its content.
*
* \param uri The uri of the table to duplicate
* \param newTable The name of the new table
*
* \returns true if the table is well duplicated, false otherwise
*/
static bool duplicateTable( const QgsDataSourceUri &uri, const QString &newTable );

/**
* Returns the extension used for auxiliary databases.
*/
Expand All @@ -382,6 +405,8 @@ class CORE_EXPORT QgsAuxiliaryStorage
static bool exec( const QString &sql, sqlite3 *handler );
static void debugMsg( const QString &sql, sqlite3 *handler );

static QgsDataSourceUri parseOgrUri( const QgsDataSourceUri &uri );

bool mValid = false;
QString mFileName; // original filename
QString mTmpFileName; // temporary filename used in copy mode
Expand Down
6 changes: 5 additions & 1 deletion src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ QgsVectorLayer *QgsVectorLayer::clone() const
QList<QgsVectorLayerJoinInfo> joins = vectorJoins();
Q_FOREACH ( const QgsVectorLayerJoinInfo &join, joins )
{
layer->addJoin( join );
// do not copy join information for auxiliary layer
if ( auxiliaryLayer() && auxiliaryLayer()->id() != join.joinLayerId() )
layer->addJoin( join );
}

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

layer->setEditFormConfig( editFormConfig() );

layer->setAuxiliaryLayer( auxiliaryLayer()->clone( layer ) );

return layer;
}

Expand Down

0 comments on commit baa2b96

Please sign in to comment.