Auxiliary data is cloned too

This commit is contained in:
Blottiere Paul 2017-09-02 18:47:36 +01:00
parent 9306226e94
commit baa2b968bc
5 changed files with 116 additions and 21 deletions

View File

@ -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; QgsVectorLayer *toSpatialLayer() const;
%Docstring %Docstring
An auxiliary layer is not spatial. This method returns a spatial An auxiliary layer is not spatial. This method returns a spatial
@ -348,10 +358,23 @@ class QgsAuxiliaryStorage
%Docstring %Docstring
Removes a table from the auxiliary storage. 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 :return: true if the table is well deleted, false otherwise
:rtype: bool :rtype: bool
%End %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(); static QString extension();
%Docstring %Docstring
Returns the extension used for auxiliary databases. Returns the extension used for auxiliary databases.

View File

@ -8873,6 +8873,9 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList )
} }
else if ( vlayer ) else if ( vlayer )
{ {
if ( vlayer->auxiliaryLayer() )
vlayer->auxiliaryLayer()->save();
dupLayer = vlayer->clone(); dupLayer = vlayer->clone();
} }
} }

View File

@ -181,6 +181,8 @@ QgsPropertyDefinition QgsAuxiliaryField::propertyDefinition() const
QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer ) 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" ) : QgsVectorLayer( QString( "%1|layername=%2" ).arg( filename, table ), QString( "%1_auxiliarystorage" ).arg( table ), "ogr" )
, mFileName( filename )
, mTable( table )
, mLayer( vlayer ) , mLayer( vlayer )
{ {
// init join info // init join info
@ -194,6 +196,12 @@ QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &fil
mJoinInfo.setJoinFieldNamesBlackList( QStringList() << QStringLiteral( "rowid" ) ); // introduced by ogr provider 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 *QgsAuxiliaryLayer::toSpatialLayer() const
{ {
QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() ); QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() );
@ -472,33 +480,18 @@ QgsAuxiliaryLayer *QgsAuxiliaryStorage::createAuxiliaryLayer( const QgsField &fi
return alayer; return alayer;
} }
bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &uri ) bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &ogrUri )
{ {
bool rc = false; bool rc = false;
QgsDataSourceUri uri = parseOgrUri( ogrUri );
// parsing for ogr style uri : if ( !uri.database().isEmpty() && !uri.table().isEmpty() )
// " filePath|layername='tableName' table="" sql="
QStringList uriParts = uri.uri().split( '|' );
if ( uriParts.count() < 2 )
return false;
const QString databasePath = uriParts[0].replace( ' ', "" );
const QString table = uriParts[1];
QStringList tableParts = table.split( ' ' );
if ( tableParts.count() < 1 )
return false;
const QString tableName = tableParts[0].replace( "layername=", "" );
if ( !databasePath.isEmpty() && !tableName.isEmpty() )
{ {
sqlite3 *handler = openDB( databasePath ); sqlite3 *handler = openDB( uri.database() );
if ( handler ) if ( handler )
{ {
QString sql = QString( "DROP TABLE %1" ).arg( tableName ); QString sql = QString( "DROP TABLE %1" ).arg( uri.table() );
rc = exec( sql, handler ); rc = exec( sql, handler );
sql = QString( "VACUUM" ); sql = QString( "VACUUM" );
@ -511,6 +504,27 @@ bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &uri )
return rc; return rc;
} }
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( uri.database() );
if ( handler )
{
QString sql = QString( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
rc = exec( sql, handler );
close( handler );
}
}
return rc;
}
bool QgsAuxiliaryStorage::saveAs( const QString &filename ) const bool QgsAuxiliaryStorage::saveAs( const QString &filename ) const
{ {
if ( QFile::exists( filename ) ) if ( QFile::exists( filename ) )
@ -680,3 +694,29 @@ QString QgsAuxiliaryStorage::currentFileName() const
else else
return mFileName; 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;
}

View File

@ -137,6 +137,15 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
QgsAuxiliaryLayer &operator=( QgsAuxiliaryLayer const &rhs ) = delete; 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 * An auxiliary layer is not spatial. This method returns a spatial
* representation of auxiliary data. * representation of auxiliary data.
@ -243,6 +252,8 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
private: private:
QgsVectorLayerJoinInfo mJoinInfo; QgsVectorLayerJoinInfo mJoinInfo;
QString mFileName;
QString mTable;
QgsVectorLayer *mLayer = nullptr; QgsVectorLayer *mLayer = nullptr;
}; };
@ -357,10 +368,22 @@ class CORE_EXPORT QgsAuxiliaryStorage
/** /**
* Removes a table from the auxiliary storage. * 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 * \returns true if the table is well deleted, false otherwise
*/ */
static bool deleteTable( const QgsDataSourceUri &uri ); 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. * Returns the extension used for auxiliary databases.
*/ */
@ -382,6 +405,8 @@ class CORE_EXPORT QgsAuxiliaryStorage
static bool exec( const QString &sql, sqlite3 *handler ); static bool exec( const QString &sql, sqlite3 *handler );
static void debugMsg( const QString &sql, sqlite3 *handler ); static void debugMsg( const QString &sql, sqlite3 *handler );
static QgsDataSourceUri parseOgrUri( const QgsDataSourceUri &uri );
bool mValid = false; bool mValid = false;
QString mFileName; // original filename QString mFileName; // original filename
QString mTmpFileName; // temporary filename used in copy mode QString mTmpFileName; // temporary filename used in copy mode

View File

@ -201,6 +201,8 @@ QgsVectorLayer *QgsVectorLayer::clone() const
QList<QgsVectorLayerJoinInfo> joins = vectorJoins(); QList<QgsVectorLayerJoinInfo> joins = vectorJoins();
Q_FOREACH ( const QgsVectorLayerJoinInfo &join, joins ) Q_FOREACH ( const QgsVectorLayerJoinInfo &join, joins )
{ {
// do not copy join information for auxiliary layer
if ( auxiliaryLayer() && auxiliaryLayer()->id() != join.joinLayerId() )
layer->addJoin( join ); layer->addJoin( join );
} }
@ -264,6 +266,8 @@ QgsVectorLayer *QgsVectorLayer::clone() const
layer->setEditFormConfig( editFormConfig() ); layer->setEditFormConfig( editFormConfig() );
layer->setAuxiliaryLayer( auxiliaryLayer()->clone( layer ) );
return layer; return layer;
} }