LCOV - code coverage report
Current view: top level - core/providers/ogr - qgsgeopackagedataitems.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 4 227 1.8 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :     qgsgeopackagedataitems.h
       3                 :            :     ---------------------
       4                 :            :     begin                : August 2017
       5                 :            :     copyright            : (C) 2017 by Alessandro Pasotti
       6                 :            :     email                : apasotti at boundlessgeo dot com
       7                 :            :  ***************************************************************************
       8                 :            :  *                                                                         *
       9                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      10                 :            :  *   it under the terms of the GNU General Public License as published by  *
      11                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      12                 :            :  *   (at your option) any later version.                                   *
      13                 :            :  *                                                                         *
      14                 :            :  ***************************************************************************/
      15                 :            : #include "qgsgeopackagedataitems.h"
      16                 :            : ///@cond PRIVATE
      17                 :            : 
      18                 :            : #include "qgssqliteutils.h"
      19                 :            : #include "qgsgeopackagedataitems.h"
      20                 :            : #include "qgsogrdbconnection.h"
      21                 :            : #include "qgslogger.h"
      22                 :            : #include "qgssettings.h"
      23                 :            : #include "qgsproject.h"
      24                 :            : #include "qgsvectorlayer.h"
      25                 :            : #include "qgsrasterlayer.h"
      26                 :            : #include "qgsogrprovider.h"
      27                 :            : #include "qgsogrdataitems.h"
      28                 :            : #include "qgsapplication.h"
      29                 :            : #include "qgsmessageoutput.h"
      30                 :            : #include "qgsvectorlayerexporter.h"
      31                 :            : #include "qgsgeopackagerasterwritertask.h"
      32                 :            : #include "qgstaskmanager.h"
      33                 :            : #include "qgsproviderregistry.h"
      34                 :            : #include "qgsproxyprogresstask.h"
      35                 :            : #include "qgsprojectstorageregistry.h"
      36                 :            : #include "qgsgeopackageprojectstorage.h"
      37                 :            : #include "qgsgeopackageproviderconnection.h"
      38                 :            : 
      39                 :          3 : QString QgsGeoPackageDataItemProvider::name()
      40                 :            : {
      41                 :          6 :   return QStringLiteral( "GPKG" );
      42                 :            : }
      43                 :            : 
      44                 :          6 : QString QgsGeoPackageDataItemProvider::dataProviderKey() const
      45                 :            : {
      46                 :         12 :   return QStringLiteral( "ogr" );
      47                 :            : }
      48                 :            : 
      49                 :          0 : int QgsGeoPackageDataItemProvider::capabilities() const
      50                 :            : {
      51                 :          0 :   return QgsDataProvider::Database;
      52                 :            : }
      53                 :            : 
      54                 :          0 : QgsDataItem *QgsGeoPackageDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
      55                 :            : {
      56                 :          0 :   QgsDebugMsgLevel( "path = " + path, 2 );
      57                 :          0 :   if ( path.isEmpty() )
      58                 :            :   {
      59                 :          0 :     return new QgsGeoPackageRootItem( parentItem, QStringLiteral( "GeoPackage" ), QStringLiteral( "gpkg:" ) );
      60                 :            :   }
      61                 :          0 :   return nullptr;
      62                 :          0 : }
      63                 :            : 
      64                 :          0 : QgsGeoPackageRootItem::QgsGeoPackageRootItem( QgsDataItem *parent, const QString &name, const QString &path )
      65                 :          0 :   : QgsConnectionsRootItem( parent, name, path, QStringLiteral( "GPKG" ) )
      66                 :          0 : {
      67                 :          0 :   mCapabilities |= Fast;
      68                 :          0 :   mIconName = QStringLiteral( "mGeoPackage.svg" );
      69                 :          0 :   populate();
      70                 :          0 : }
      71                 :            : 
      72                 :          0 : QVector<QgsDataItem *> QgsGeoPackageRootItem::createChildren()
      73                 :            : {
      74                 :          0 :   QVector<QgsDataItem *> connections;
      75                 :          0 :   const QStringList connList( QgsOgrDbConnection::connectionList( QStringLiteral( "GPKG" ) ) );
      76                 :          0 :   for ( const QString &connName : connList )
      77                 :            :   {
      78                 :          0 :     QgsOgrDbConnection connection( connName, QStringLiteral( "GPKG" ) );
      79                 :          0 :     QgsDataItem *conn = new QgsGeoPackageConnectionItem( this, connection.name(), mPath + '/' + connection.path() );
      80                 :            : 
      81                 :          0 :     connections.append( conn );
      82                 :          0 :   }
      83                 :          0 :   return connections;
      84                 :          0 : }
      85                 :            : 
      86                 :          0 : void QgsGeoPackageRootItem::onConnectionsChanged()
      87                 :            : {
      88                 :          0 :   refresh();
      89                 :          0 : }
      90                 :            : 
      91                 :          0 : void QgsGeoPackageRootItem::newConnection()
      92                 :            : {
      93                 :          0 :   if ( QgsOgrDataCollectionItem::createConnection( QStringLiteral( "GeoPackage" ),  QStringLiteral( "GeoPackage Database (*.gpkg)" ),  QStringLiteral( "GPKG" ) ) )
      94                 :            :   {
      95                 :          0 :     refreshConnections();
      96                 :          0 :   }
      97                 :          0 : }
      98                 :            : 
      99                 :          0 : QgsGeoPackageCollectionItem::QgsGeoPackageCollectionItem( QgsDataItem *parent, const QString &name, const QString &path )
     100                 :          0 :   : QgsDataCollectionItem( parent, name, path, QStringLiteral( "GPKG" ) )
     101                 :          0 : {
     102                 :          0 :   mToolTip = QString( path ).remove( QLatin1String( "gpkg:/" ) );
     103                 :          0 :   mCapabilities |= Collapse;
     104                 :          0 : }
     105                 :            : 
     106                 :            : 
     107                 :          0 : QVector<QgsDataItem *> QgsGeoPackageCollectionItem::createChildren()
     108                 :            : {
     109                 :          0 :   QVector<QgsDataItem *> children;
     110                 :            :   try
     111                 :            :   {
     112                 :          0 :     const auto layers = QgsOgrLayerItem::subLayers( mPath.remove( QLatin1String( "gpkg:/" ) ), QStringLiteral( "GPKG" ) );
     113                 :          0 :     for ( const QgsOgrDbLayerInfo *info : layers )
     114                 :            :     {
     115                 :          0 :       if ( info->layerType() == QgsLayerItem::LayerType::Raster )
     116                 :            :       {
     117                 :          0 :         children.append( new QgsGeoPackageRasterLayerItem( this, info->name(), info->path(), info->uri() ) );
     118                 :          0 :       }
     119                 :            :       else
     120                 :            :       {
     121                 :          0 :         children.append( new QgsGeoPackageVectorLayerItem( this, info->name(), info->path(), info->uri(), info->layerType( ) ) );
     122                 :            :       }
     123                 :            :     }
     124                 :          0 :     qDeleteAll( layers );
     125                 :          0 :     QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromType( "geopackage" );
     126                 :          0 :     if ( storage )
     127                 :            :     {
     128                 :          0 :       const QStringList projectNames = storage->listProjects( mPath );
     129                 :          0 :       for ( const QString &projectName : projectNames )
     130                 :            :       {
     131                 :          0 :         QgsGeoPackageProjectUri projectUri { true, mPath, projectName };
     132                 :          0 :         children.append( new QgsProjectItem( this, projectName, QgsGeoPackageProjectStorage::encodeUri( projectUri ) ) );
     133                 :          0 :       }
     134                 :          0 :     }
     135                 :          0 :   }
     136                 :            :   catch ( QgsOgrLayerNotValidException &ex )
     137                 :            :   {
     138                 :          0 :     children.append( new QgsErrorItem( this, ex.what(), mPath + "/error" ) );
     139                 :          0 :   }
     140                 :          0 :   return children;
     141                 :          0 : }
     142                 :            : 
     143                 :          0 : bool QgsGeoPackageCollectionItem::equal( const QgsDataItem *other )
     144                 :            : {
     145                 :          0 :   if ( type() != other->type() )
     146                 :            :   {
     147                 :          0 :     return false;
     148                 :            :   }
     149                 :          0 :   const QgsGeoPackageCollectionItem *o = qobject_cast<const QgsGeoPackageCollectionItem *>( other );
     150                 :          0 :   return o && mPath == o->mPath && mName == o->mName;
     151                 :            : 
     152                 :          0 : }
     153                 :            : 
     154                 :          0 : bool QgsGeoPackageCollectionItem::deleteRasterLayer( const QString &layerName, QString &errCause )
     155                 :            : {
     156                 :          0 :   QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "ogr" ) ) };
     157                 :          0 :   std::unique_ptr<QgsGeoPackageProviderConnection> conn( static_cast<QgsGeoPackageProviderConnection *>( md->createConnection( path(), QVariantMap() ) ) );
     158                 :          0 :   if ( conn )
     159                 :            :   {
     160                 :            :     try
     161                 :            :     {
     162                 :          0 :       conn->dropRasterTable( QString(), layerName );
     163                 :          0 :     }
     164                 :            :     catch ( QgsProviderConnectionException &ex )
     165                 :            :     {
     166                 :          0 :       errCause = ex.what();
     167                 :          0 :       return false;
     168                 :          0 :     }
     169                 :          0 :   }
     170                 :            :   else
     171                 :            :   {
     172                 :          0 :     errCause = QObject::tr( "There was an error retrieving the connection %1!" ).arg( path() );
     173                 :          0 :     return false;
     174                 :            :   }
     175                 :          0 :   return true;
     176                 :          0 : }
     177                 :            : 
     178                 :          0 : bool QgsGeoPackageCollectionItem::deleteVectorLayer( const QString &layerName, QString &errCause )
     179                 :            : {
     180                 :          0 :   QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "ogr" ) ) };
     181                 :          0 :   std::unique_ptr<QgsGeoPackageProviderConnection> conn( static_cast<QgsGeoPackageProviderConnection *>( md->createConnection( path(), QVariantMap() ) ) );
     182                 :          0 :   if ( conn )
     183                 :            :   {
     184                 :            :     try
     185                 :            :     {
     186                 :          0 :       conn->dropVectorTable( QString(), layerName );
     187                 :          0 :     }
     188                 :            :     catch ( QgsProviderConnectionException &ex )
     189                 :            :     {
     190                 :          0 :       errCause = ex.what();
     191                 :          0 :       return false;
     192                 :          0 :     }
     193                 :          0 :   }
     194                 :            :   else
     195                 :            :   {
     196                 :          0 :     errCause = QObject::tr( "There was an error retrieving the connection %1!" ).arg( path() );
     197                 :          0 :     return false;
     198                 :            :   }
     199                 :          0 :   return true;
     200                 :          0 : }
     201                 :            : 
     202                 :          0 : QWidget *QgsGeoPackageRootItem::paramWidget()
     203                 :            : {
     204                 :          0 :   return nullptr;
     205                 :            : }
     206                 :            : 
     207                 :          0 : void QgsGeoPackageCollectionItem::addConnection()
     208                 :            : {
     209                 :          0 :   QgsOgrDbConnection connection( mName, QStringLiteral( "GPKG" ) );
     210                 :          0 :   connection.setPath( mPath );
     211                 :          0 :   connection.save();
     212                 :          0 :   mParent->refreshConnections( QStringLiteral( "GPKG" ) );
     213                 :          0 : }
     214                 :            : 
     215                 :          0 : void QgsGeoPackageCollectionItem::deleteConnection()
     216                 :            : {
     217                 :          0 :   QgsOgrDbConnection::deleteConnection( name(), QStringLiteral( "GPKG" ) );
     218                 :          0 :   mParent->refreshConnections( QStringLiteral( "GPKG" ) );
     219                 :          0 : }
     220                 :            : 
     221                 :          0 : bool QgsGeoPackageCollectionItem::vacuumGeoPackageDb( const QString &name, const QString &path, QString &errCause )
     222                 :            : {
     223                 :          0 :   QgsScopedProxyProgressTask task( tr( "Vacuuming %1" ).arg( name ) );
     224                 :          0 :   QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "ogr" ) ) };
     225                 :          0 :   std::unique_ptr<QgsGeoPackageProviderConnection> conn( static_cast<QgsGeoPackageProviderConnection *>( md->createConnection( path, QVariantMap() ) ) );
     226                 :          0 :   if ( conn )
     227                 :            :   {
     228                 :            :     try
     229                 :            :     {
     230                 :          0 :       conn->vacuum( QString(), QString() );
     231                 :          0 :     }
     232                 :            :     catch ( QgsProviderConnectionException &ex )
     233                 :            :     {
     234                 :          0 :       errCause = ex.what();
     235                 :          0 :       return false;
     236                 :          0 :     }
     237                 :          0 :   }
     238                 :            :   else
     239                 :            :   {
     240                 :          0 :     errCause = QObject::tr( "There was an error retrieving the connection %1!" ).arg( name );
     241                 :          0 :     return false;
     242                 :            :   }
     243                 :          0 :   return true;
     244                 :          0 : }
     245                 :            : 
     246                 :          0 : QgsGeoPackageConnectionItem::QgsGeoPackageConnectionItem( QgsDataItem *parent, const QString &name, const QString &path )
     247                 :          0 :   : QgsGeoPackageCollectionItem( parent, name, path )
     248                 :          0 : {
     249                 :            : 
     250                 :          0 : }
     251                 :            : 
     252                 :          0 : bool QgsGeoPackageConnectionItem::equal( const QgsDataItem *other )
     253                 :            : {
     254                 :          0 :   if ( type() != other->type() )
     255                 :            :   {
     256                 :          0 :     return false;
     257                 :            :   }
     258                 :          0 :   const QgsGeoPackageConnectionItem *o = qobject_cast<const QgsGeoPackageConnectionItem *>( other );
     259                 :          0 :   return o && mPath == o->mPath && mName == o->mName;
     260                 :            : 
     261                 :          0 : }
     262                 :            : 
     263                 :          0 : QgsGeoPackageAbstractLayerItem::QgsGeoPackageAbstractLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &uri, QgsLayerItem::LayerType layerType, const QString &providerKey )
     264                 :          0 :   : QgsLayerItem( parent, name, path, uri, layerType, providerKey )
     265                 :          0 :   , mCollection( qobject_cast<QgsGeoPackageCollectionItem*>( parent ) )
     266                 :          0 : {
     267                 :          0 :   mCapabilities |= Delete;
     268                 :          0 :   mToolTip = uri;
     269                 :          0 :   setState( Populated ); // no children are expected
     270                 :          0 : }
     271                 :            : 
     272                 :            : 
     273                 :          0 : QStringList QgsGeoPackageAbstractLayerItem::tableNames() const
     274                 :            : {
     275                 :          0 :   QStringList names;
     276                 :            :   // note: not using providerKey() because GPKG methods are implemented in OGR
     277                 :          0 :   QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "ogr" ) ) };
     278                 :          0 :   QgsGeoPackageProviderConnection *conn { static_cast<QgsGeoPackageProviderConnection *>( md->findConnection( parent()->name() ) ) };
     279                 :          0 :   if ( conn )
     280                 :            :   {
     281                 :          0 :     for ( const QgsGeoPackageProviderConnection::TableProperty &p : conn->tables( ) )
     282                 :            :     {
     283                 :          0 :       names.push_back( p.tableName() );
     284                 :            :     }
     285                 :          0 :   }
     286                 :          0 :   return  names;
     287                 :          0 : }
     288                 :            : 
     289                 :            : 
     290                 :          0 : QList<QgsMapLayer *> QgsGeoPackageAbstractLayerItem::layersInProject() const
     291                 :            : {
     292                 :            :   // Check if the layer(s) are in the registry
     293                 :          0 :   QList<QgsMapLayer *> layersList;
     294                 :          0 :   const auto mapLayers( QgsProject::instance()->mapLayers() );
     295                 :          0 :   for ( QgsMapLayer *layer :  mapLayers )
     296                 :            :   {
     297                 :          0 :     if ( layer->publicSource() == mUri )
     298                 :            :     {
     299                 :          0 :       layersList << layer;
     300                 :          0 :     }
     301                 :            :   }
     302                 :          0 :   return layersList;
     303                 :          0 : }
     304                 :            : 
     305                 :          0 : QgsGeoPackageCollectionItem *QgsGeoPackageAbstractLayerItem::collection() const
     306                 :            : {
     307                 :          0 :   return mCollection;
     308                 :            : }
     309                 :            : 
     310                 :          0 : QgsGeoPackageVectorLayerItem::QgsGeoPackageVectorLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &uri, LayerType layerType )
     311                 :          0 :   : QgsGeoPackageAbstractLayerItem( parent, name, path, uri, layerType, QStringLiteral( "ogr" ) )
     312                 :          0 : {
     313                 :          0 :   mCapabilities |= ( Rename | Fertile );
     314                 :          0 :   setState( QgsDataItem::State::NotPopulated );
     315                 :          0 : }
     316                 :            : 
     317                 :            : 
     318                 :          0 : QVector<QgsDataItem *> QgsGeoPackageVectorLayerItem::createChildren()
     319                 :            : {
     320                 :          0 :   QVector<QgsDataItem *> children;
     321                 :          0 :   children.push_back( new QgsFieldsItem( this, collection()->path() + QStringLiteral( "/columns/ " ), collection()->path(), providerKey(), QString(), name() ) );
     322                 :          0 :   return children;
     323                 :          0 : }
     324                 :            : 
     325                 :            : 
     326                 :          0 : QgsGeoPackageRasterLayerItem::QgsGeoPackageRasterLayerItem( QgsDataItem *parent, const QString &name, const QString &path, const QString &uri )
     327                 :          0 :   : QgsGeoPackageAbstractLayerItem( parent, name, path, uri, QgsLayerItem::LayerType::Raster, QStringLiteral( "gdal" ) )
     328                 :          0 : {
     329                 :          0 : }
     330                 :            : 
     331                 :          0 : bool QgsGeoPackageRasterLayerItem::executeDeleteLayer( QString &errCause )
     332                 :            : {
     333                 :          0 :   QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "ogr" ) ) };
     334                 :          0 :   std::unique_ptr<QgsGeoPackageProviderConnection> conn( static_cast<QgsGeoPackageProviderConnection *>( md->createConnection( collection()->path(), QVariantMap() ) ) );
     335                 :          0 :   QString tableName = name();
     336                 :          0 :   if ( conn->tableExists( QString(), tableName ) )
     337                 :            :   {
     338                 :            :     try
     339                 :            :     {
     340                 :          0 :       conn->dropRasterTable( QString(), tableName );
     341                 :          0 :     }
     342                 :            :     catch ( QgsProviderConnectionException &ex )
     343                 :            :     {
     344                 :          0 :       errCause = ex.what();
     345                 :          0 :       return false;
     346                 :          0 :     }
     347                 :          0 :   }
     348                 :            :   else
     349                 :            :   {
     350                 :          0 :     errCause = QObject::tr( "There was an error deleting '%1' on '%2'!" )
     351                 :          0 :                .arg( tableName )
     352                 :          0 :                .arg( collection()->path() );
     353                 :          0 :     return false;
     354                 :            :   }
     355                 :          0 :   return true;
     356                 :          0 : }
     357                 :            : 
     358                 :          0 : bool QgsGeoPackageVectorLayerItem::executeDeleteLayer( QString &errCause )
     359                 :            : {
     360                 :          0 :   QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "ogr" ) ) };
     361                 :          0 :   std::unique_ptr<QgsGeoPackageProviderConnection> conn( static_cast<QgsGeoPackageProviderConnection *>( md->createConnection( collection()->path(), QVariantMap() ) ) );
     362                 :          0 :   QString tableName = name();
     363                 :          0 :   if ( conn )
     364                 :            :   {
     365                 :            :     try
     366                 :            :     {
     367                 :          0 :       conn->dropVectorTable( QString(), tableName );
     368                 :          0 :     }
     369                 :            :     catch ( QgsProviderConnectionException &ex )
     370                 :            :     {
     371                 :          0 :       errCause = ex.what();
     372                 :          0 :       return false;
     373                 :          0 :     }
     374                 :          0 :   }
     375                 :            :   else
     376                 :            :   {
     377                 :          0 :     errCause = QObject::tr( "There was an error deleting '%1' on '%2'!" )
     378                 :          0 :                .arg( tableName, parent()->path() );
     379                 :          0 :     return false;
     380                 :            :   }
     381                 :          0 :   return true;
     382                 :          0 : }
     383                 :            : 
     384                 :            : ///@endcond
     385                 :            : 
     386                 :            : 
     387                 :          0 : bool QgsGeoPackageCollectionItem::layerCollection() const
     388                 :            : {
     389                 :          0 :   return true;
     390                 :            : }
     391                 :            : 
     392                 :          0 : bool QgsGeoPackageCollectionItem::hasDragEnabled() const
     393                 :            : {
     394                 :          0 :   return true;
     395                 :            : }
     396                 :            : 
     397                 :          0 : QgsMimeDataUtils::UriList QgsGeoPackageCollectionItem::mimeUris() const
     398                 :            : {
     399                 :          0 :   QgsMimeDataUtils::Uri vectorUri;
     400                 :          0 :   vectorUri.providerKey = QStringLiteral( "ogr" );
     401                 :          0 :   vectorUri.uri = path();
     402                 :          0 :   vectorUri.layerType = QStringLiteral( "vector" );
     403                 :          0 :   QgsMimeDataUtils::Uri rasterUri { vectorUri };
     404                 :          0 :   rasterUri.layerType = QStringLiteral( "raster" );
     405                 :          0 :   rasterUri.providerKey = QStringLiteral( "gdal" );
     406                 :          0 :   return { vectorUri, rasterUri };
     407                 :          0 : }

Generated by: LCOV version 1.14