Skip to content

Commit

Permalink
Merge pull request #2991 from manisandro/ogr_options
Browse files Browse the repository at this point in the history
Pass the full ogr data source URI as connInfo in qgsConnectionPool_ConnectionCreate
  • Loading branch information
manisandro committed Apr 26, 2016
2 parents 2ba252b + 6b88ec8 commit 63c71fe
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/core/qgsapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -877,15 +877,15 @@ void QgsApplication::initQgis()

void QgsApplication::exitQgis()
{
delete QgsProviderRegistry::instance();

delete QgsAuthManager::instance();

//Ensure that all remaining deleteLater QObjects are actually deleted before we exit.
//This isn't strictly necessary (since we're exiting anyway) but doing so prevents a lot of
//LeakSanitiser noise which hides real issues
QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );

delete QgsProviderRegistry::instance();

//delete all registered functions from expression engine (see above comment)
QgsExpression::cleanRegisteredFunctions();

Expand Down
3 changes: 2 additions & 1 deletion src/providers/ogr/qgsogrconnpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ inline QString qgsConnectionPool_ConnectionToName( QgsOgrConn* c )
inline void qgsConnectionPool_ConnectionCreate( QString connInfo, QgsOgrConn*& c )
{
c = new QgsOgrConn;
c->ds = OGROpen( connInfo.toUtf8().constData(), false, nullptr );
QString filePath = connInfo.left( connInfo.indexOf( "|" ) );
c->ds = OGROpen( filePath.toUtf8().constData(), false, nullptr );
c->path = connInfo;
c->valid = true;
}
Expand Down
8 changes: 4 additions & 4 deletions src/providers/ogr/qgsogrfeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
{
mFeatureFetched = false;

mConn = QgsOgrConnPool::instance()->acquireConnection( mSource->mFilePath );
mConn = QgsOgrConnPool::instance()->acquireConnection( mSource->mProvider->dataSourceUri() );

if ( mSource->mLayerName.isNull() )
{
Expand Down Expand Up @@ -348,20 +348,20 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
QgsOgrFeatureSource::QgsOgrFeatureSource( const QgsOgrProvider* p )
: mProvider( p )
{
mFilePath = p->filePath();
mDataSource = p->dataSourceUri();
mLayerName = p->layerName();
mLayerIndex = p->layerIndex();
mSubsetString = p->mSubsetString;
mEncoding = p->mEncoding; // no copying - this is a borrowed pointer from Qt
mFields = p->mAttributeFields;
mDriverName = p->ogrDriverName;
mOgrGeometryTypeFilter = wkbFlatten( p->mOgrGeometryTypeFilter );
QgsOgrConnPool::instance()->ref( mFilePath );
QgsOgrConnPool::instance()->ref( mDataSource );
}

QgsOgrFeatureSource::~QgsOgrFeatureSource()
{
QgsOgrConnPool::instance()->unref( mFilePath );
QgsOgrConnPool::instance()->unref( mDataSource );
}

QgsFeatureIterator QgsOgrFeatureSource::getFeatures( const QgsFeatureRequest& request )
Expand Down
2 changes: 1 addition & 1 deletion src/providers/ogr/qgsogrfeatureiterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class QgsOgrFeatureSource : public QgsAbstractFeatureSource

protected:
const QgsOgrProvider* mProvider;
QString mFilePath;
QString mDataSource;
QString mLayerName;
int mLayerIndex;
QString mSubsetString;
Expand Down
1 change: 1 addition & 0 deletions tests/src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ ADD_QGIS_TEST(composershapestest testqgscomposershapes.cpp)
ADD_QGIS_TEST(composertabletest testqgscomposertable.cpp)
ADD_QGIS_TEST(composertablev2test testqgscomposertablev2.cpp)
ADD_QGIS_TEST(composerutils testqgscomposerutils.cpp)
ADD_QGIS_TEST(connectionpooltest testqgsconnectionpool.cpp)
ADD_QGIS_TEST(contrastenhancementtest testcontrastenhancements.cpp)
ADD_QGIS_TEST(coordinatereferencesystemtest testqgscoordinatereferencesystem.cpp)
ADD_QGIS_TEST(coordinatetransformtest testqgscoordinatetransform.cpp)
Expand Down
141 changes: 141 additions & 0 deletions tests/src/core/testqgsconnectionpool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/***************************************************************************
testqgsconnectionpool.cpp
-----------------------
begin : April 2016
copyright : (C) 2016 by Sandro Mani
email : manisandro@gmail.com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsapplication.h"
#include "qgsgeometry.h"
#include "qgspointv2.h"
#include "qgslinestringv2.h"
#include "qgsvectorlayer.h"
#include <QEventLoop>
#include <QObject>
#include <QTemporaryFile>
#include <QtConcurrentMap>
#include <QtTest/QtTest>

class TestQgsConnectionPool: public QObject
{
Q_OBJECT

private slots:
void initTestCase();
void cleanupTestCase();
void layersFromSameDatasetGPX();

private:
struct ReadJob
{
ReadJob( QgsVectorLayer* _layer ) : layer( _layer ) {}
QgsVectorLayer* layer;
QList<QgsFeature> features;
};

static void processJob( ReadJob& job )
{
QgsFeatureIterator it = job.layer->getFeatures();
QgsFeature f;
while ( it.nextFeature( f ) )
{
job.features.append( f );
}
}

};

void TestQgsConnectionPool::initTestCase()
{
QgsApplication::init();
QgsApplication::initQgis();

}

void TestQgsConnectionPool::cleanupTestCase()
{
QgsApplication::exitQgis();
}

void TestQgsConnectionPool::layersFromSameDatasetGPX()
{
// Tests whether features are correctly retrevied from different layers which are
// loaded from the same dataset. See issue #14560
int nWaypoints = 100000;
int nRoutes = 100000;
int nRoutePts = 10;
QTemporaryFile testFile( "testXXXXXX.gpx" );
testFile.setAutoRemove( false );
testFile.open();
testFile.write( "<gpx version=\"1.1\" creator=\"qgis\">\n" );
for ( int i = 0; i < nWaypoints; ++i )
{
testFile.write( QString( "<wpt lon=\"%1\" lat=\"%1\"><name></name></wpt>\n" ).arg( i ).toLocal8Bit() );
}
for ( int i = 0; i < nRoutes; ++i )
{
testFile.write( "<rte><name></name><number></number>\n" );
for ( int j = 0; j < nRoutePts; ++j )
{
testFile.write( QString( "<rtept lon=\"%1\" lat=\"%2\"/>\n" ).arg( j ).arg( i ).toLocal8Bit() );
}
testFile.write( "</rte>\n" );
}
testFile.write( "</gpx>\n" );
testFile.close();

QgsVectorLayer* layer1 = new QgsVectorLayer( testFile.fileName() + "|layername=waypoints", "Waypoints", "ogr" );
QVERIFY( layer1->isValid() );
QgsVectorLayer* layer2 = new QgsVectorLayer( testFile.fileName() + "|layername=routes", "Routes", "ogr" );
QVERIFY( layer2->isValid() );

QList<ReadJob> jobs = QList<ReadJob>() << ReadJob( layer1 ) << ReadJob( layer2 );

QEventLoop evLoop;
QFutureWatcher<void> futureWatcher;
connect( &futureWatcher, SIGNAL( finished() ), &evLoop, SLOT( quit() ) );
futureWatcher.setFuture( QtConcurrent::map( jobs, processJob ) );
evLoop.exec();

QList<QgsFeature>& layer1Features = jobs[0].features;
QList<QgsFeature>& layer2Features = jobs[1].features;

QVERIFY( layer1Features.count() == nWaypoints );
QVERIFY( layer2Features.count() == nRoutes );

for ( int i = 0, n = layer1Features.count(); i < n; ++i )
{
const QgsPointV2* geom = dynamic_cast<const QgsPointV2*>( layer1Features[i].geometry()->geometry() );
QVERIFY( geom != nullptr );
QVERIFY( qFuzzyCompare( geom->x(), i ) );
QVERIFY( qFuzzyCompare( geom->y(), i ) );
}
for ( int i = 0, n = layer2Features.count(); i < n; ++i )
{
const QgsLineStringV2* geom = dynamic_cast<const QgsLineStringV2*>( layer2Features[i].geometry()->geometry() );
QVERIFY( geom != nullptr );
int nVtx = geom->vertexCount();
QVERIFY( nVtx == nRoutePts );
for ( int j = 0; j < nVtx; ++j )
{
QgsPointV2 p = geom->vertexAt( QgsVertexId( 0, 0, j ) );
QVERIFY( qFuzzyCompare( p.x(), j ) );
QVERIFY( qFuzzyCompare( p.y(), i ) );
}
}
delete layer1;
delete layer2;
QFile( testFile.fileName() ).remove();
}

QTEST_MAIN( TestQgsConnectionPool )
#include "testqgsconnectionpool.moc"

0 comments on commit 63c71fe

Please sign in to comment.