Skip to content

Commit 63c71fe

Browse files
committedApr 26, 2016
Merge pull request #2991 from manisandro/ogr_options
Pass the full ogr data source URI as connInfo in qgsConnectionPool_ConnectionCreate
2 parents 2ba252b + 6b88ec8 commit 63c71fe

File tree

6 files changed

+151
-8
lines changed

6 files changed

+151
-8
lines changed
 

‎src/core/qgsapplication.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,15 +877,15 @@ void QgsApplication::initQgis()
877877

878878
void QgsApplication::exitQgis()
879879
{
880-
delete QgsProviderRegistry::instance();
881-
882880
delete QgsAuthManager::instance();
883881

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

887+
delete QgsProviderRegistry::instance();
888+
889889
//delete all registered functions from expression engine (see above comment)
890890
QgsExpression::cleanRegisteredFunctions();
891891

‎src/providers/ogr/qgsogrconnpool.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ inline QString qgsConnectionPool_ConnectionToName( QgsOgrConn* c )
3535
inline void qgsConnectionPool_ConnectionCreate( QString connInfo, QgsOgrConn*& c )
3636
{
3737
c = new QgsOgrConn;
38-
c->ds = OGROpen( connInfo.toUtf8().constData(), false, nullptr );
38+
QString filePath = connInfo.left( connInfo.indexOf( "|" ) );
39+
c->ds = OGROpen( filePath.toUtf8().constData(), false, nullptr );
3940
c->path = connInfo;
4041
c->valid = true;
4142
}

‎src/providers/ogr/qgsogrfeatureiterator.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
4444
{
4545
mFeatureFetched = false;
4646

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

4949
if ( mSource->mLayerName.isNull() )
5050
{
@@ -348,20 +348,20 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
348348
QgsOgrFeatureSource::QgsOgrFeatureSource( const QgsOgrProvider* p )
349349
: mProvider( p )
350350
{
351-
mFilePath = p->filePath();
351+
mDataSource = p->dataSourceUri();
352352
mLayerName = p->layerName();
353353
mLayerIndex = p->layerIndex();
354354
mSubsetString = p->mSubsetString;
355355
mEncoding = p->mEncoding; // no copying - this is a borrowed pointer from Qt
356356
mFields = p->mAttributeFields;
357357
mDriverName = p->ogrDriverName;
358358
mOgrGeometryTypeFilter = wkbFlatten( p->mOgrGeometryTypeFilter );
359-
QgsOgrConnPool::instance()->ref( mFilePath );
359+
QgsOgrConnPool::instance()->ref( mDataSource );
360360
}
361361

362362
QgsOgrFeatureSource::~QgsOgrFeatureSource()
363363
{
364-
QgsOgrConnPool::instance()->unref( mFilePath );
364+
QgsOgrConnPool::instance()->unref( mDataSource );
365365
}
366366

367367
QgsFeatureIterator QgsOgrFeatureSource::getFeatures( const QgsFeatureRequest& request )

‎src/providers/ogr/qgsogrfeatureiterator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class QgsOgrFeatureSource : public QgsAbstractFeatureSource
3434

3535
protected:
3636
const QgsOgrProvider* mProvider;
37-
QString mFilePath;
37+
QString mDataSource;
3838
QString mLayerName;
3939
int mLayerIndex;
4040
QString mSubsetString;

‎tests/src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ ADD_QGIS_TEST(composershapestest testqgscomposershapes.cpp)
116116
ADD_QGIS_TEST(composertabletest testqgscomposertable.cpp)
117117
ADD_QGIS_TEST(composertablev2test testqgscomposertablev2.cpp)
118118
ADD_QGIS_TEST(composerutils testqgscomposerutils.cpp)
119+
ADD_QGIS_TEST(connectionpooltest testqgsconnectionpool.cpp)
119120
ADD_QGIS_TEST(contrastenhancementtest testcontrastenhancements.cpp)
120121
ADD_QGIS_TEST(coordinatereferencesystemtest testqgscoordinatereferencesystem.cpp)
121122
ADD_QGIS_TEST(coordinatetransformtest testqgscoordinatetransform.cpp)
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/***************************************************************************
2+
testqgsconnectionpool.cpp
3+
-----------------------
4+
begin : April 2016
5+
copyright : (C) 2016 by Sandro Mani
6+
email : manisandro@gmail.com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
#include "qgsapplication.h"
18+
#include "qgsgeometry.h"
19+
#include "qgspointv2.h"
20+
#include "qgslinestringv2.h"
21+
#include "qgsvectorlayer.h"
22+
#include <QEventLoop>
23+
#include <QObject>
24+
#include <QTemporaryFile>
25+
#include <QtConcurrentMap>
26+
#include <QtTest/QtTest>
27+
28+
class TestQgsConnectionPool: public QObject
29+
{
30+
Q_OBJECT
31+
32+
private slots:
33+
void initTestCase();
34+
void cleanupTestCase();
35+
void layersFromSameDatasetGPX();
36+
37+
private:
38+
struct ReadJob
39+
{
40+
ReadJob( QgsVectorLayer* _layer ) : layer( _layer ) {}
41+
QgsVectorLayer* layer;
42+
QList<QgsFeature> features;
43+
};
44+
45+
static void processJob( ReadJob& job )
46+
{
47+
QgsFeatureIterator it = job.layer->getFeatures();
48+
QgsFeature f;
49+
while ( it.nextFeature( f ) )
50+
{
51+
job.features.append( f );
52+
}
53+
}
54+
55+
};
56+
57+
void TestQgsConnectionPool::initTestCase()
58+
{
59+
QgsApplication::init();
60+
QgsApplication::initQgis();
61+
62+
}
63+
64+
void TestQgsConnectionPool::cleanupTestCase()
65+
{
66+
QgsApplication::exitQgis();
67+
}
68+
69+
void TestQgsConnectionPool::layersFromSameDatasetGPX()
70+
{
71+
// Tests whether features are correctly retrevied from different layers which are
72+
// loaded from the same dataset. See issue #14560
73+
int nWaypoints = 100000;
74+
int nRoutes = 100000;
75+
int nRoutePts = 10;
76+
QTemporaryFile testFile( "testXXXXXX.gpx" );
77+
testFile.setAutoRemove( false );
78+
testFile.open();
79+
testFile.write( "<gpx version=\"1.1\" creator=\"qgis\">\n" );
80+
for ( int i = 0; i < nWaypoints; ++i )
81+
{
82+
testFile.write( QString( "<wpt lon=\"%1\" lat=\"%1\"><name></name></wpt>\n" ).arg( i ).toLocal8Bit() );
83+
}
84+
for ( int i = 0; i < nRoutes; ++i )
85+
{
86+
testFile.write( "<rte><name></name><number></number>\n" );
87+
for ( int j = 0; j < nRoutePts; ++j )
88+
{
89+
testFile.write( QString( "<rtept lon=\"%1\" lat=\"%2\"/>\n" ).arg( j ).arg( i ).toLocal8Bit() );
90+
}
91+
testFile.write( "</rte>\n" );
92+
}
93+
testFile.write( "</gpx>\n" );
94+
testFile.close();
95+
96+
QgsVectorLayer* layer1 = new QgsVectorLayer( testFile.fileName() + "|layername=waypoints", "Waypoints", "ogr" );
97+
QVERIFY( layer1->isValid() );
98+
QgsVectorLayer* layer2 = new QgsVectorLayer( testFile.fileName() + "|layername=routes", "Routes", "ogr" );
99+
QVERIFY( layer2->isValid() );
100+
101+
QList<ReadJob> jobs = QList<ReadJob>() << ReadJob( layer1 ) << ReadJob( layer2 );
102+
103+
QEventLoop evLoop;
104+
QFutureWatcher<void> futureWatcher;
105+
connect( &futureWatcher, SIGNAL( finished() ), &evLoop, SLOT( quit() ) );
106+
futureWatcher.setFuture( QtConcurrent::map( jobs, processJob ) );
107+
evLoop.exec();
108+
109+
QList<QgsFeature>& layer1Features = jobs[0].features;
110+
QList<QgsFeature>& layer2Features = jobs[1].features;
111+
112+
QVERIFY( layer1Features.count() == nWaypoints );
113+
QVERIFY( layer2Features.count() == nRoutes );
114+
115+
for ( int i = 0, n = layer1Features.count(); i < n; ++i )
116+
{
117+
const QgsPointV2* geom = dynamic_cast<const QgsPointV2*>( layer1Features[i].geometry()->geometry() );
118+
QVERIFY( geom != nullptr );
119+
QVERIFY( qFuzzyCompare( geom->x(), i ) );
120+
QVERIFY( qFuzzyCompare( geom->y(), i ) );
121+
}
122+
for ( int i = 0, n = layer2Features.count(); i < n; ++i )
123+
{
124+
const QgsLineStringV2* geom = dynamic_cast<const QgsLineStringV2*>( layer2Features[i].geometry()->geometry() );
125+
QVERIFY( geom != nullptr );
126+
int nVtx = geom->vertexCount();
127+
QVERIFY( nVtx == nRoutePts );
128+
for ( int j = 0; j < nVtx; ++j )
129+
{
130+
QgsPointV2 p = geom->vertexAt( QgsVertexId( 0, 0, j ) );
131+
QVERIFY( qFuzzyCompare( p.x(), j ) );
132+
QVERIFY( qFuzzyCompare( p.y(), i ) );
133+
}
134+
}
135+
delete layer1;
136+
delete layer2;
137+
QFile( testFile.fileName() ).remove();
138+
}
139+
140+
QTEST_MAIN( TestQgsConnectionPool )
141+
#include "testqgsconnectionpool.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.