22
22
23
23
#include < QObject>
24
24
25
- QgsOracleFeatureIterator::QgsOracleFeatureIterator ( QgsOracleProvider *p, const QgsFeatureRequest &request )
26
- : QgsAbstractFeatureIterator( request )
27
- , P( p )
25
+ QgsOracleFeatureIterator::QgsOracleFeatureIterator ( QgsOracleFeatureSource* source, bool ownSource, const QgsFeatureRequest &request )
26
+ : QgsAbstractFeatureIteratorFromSource( source, ownSource, request )
28
27
, mRewind( false )
29
28
{
30
- P->mActiveIterators << this ;
29
+ mConnection = QgsOracleConn::connectDb ( mSource ->mUri .connectionInfo () );
30
+ if ( !mConnection )
31
+ {
32
+ close ();
33
+ return ;
34
+ }
31
35
32
- mQry = QSqlQuery ( *P-> mConnection );
36
+ mQry = QSqlQuery ( *mConnection );
33
37
34
38
if ( mRequest .flags () & QgsFeatureRequest::SubsetOfAttributes )
35
39
{
36
40
mAttributeList = mRequest .subsetOfAttributes ();
37
41
if ( mAttributeList .isEmpty () )
38
- mAttributeList = P-> attributeIndexes ();
42
+ mAttributeList = mSource -> mFields . allAttributesList ();
39
43
}
40
44
else
41
- mAttributeList = P-> attributeIndexes ();
45
+ mAttributeList = mSource -> mFields . allAttributesList ();
42
46
43
47
QString whereClause;
44
48
45
49
switch ( request.filterType () )
46
50
{
47
51
case QgsFeatureRequest::FilterRect:
48
- if ( !P ->mGeometryColumn .isNull () )
52
+ if ( !mSource ->mGeometryColumn .isNull () )
49
53
{
50
54
QgsRectangle rect ( mRequest .filterRect () );
51
55
QString bbox = QString ( " mdsys.sdo_geometry(2003,%1,NULL,"
52
56
" mdsys.sdo_elem_info_array(1,1003,3),"
53
57
" mdsys.sdo_ordinate_array(%2,%3,%4,%5)"
54
58
" )" )
55
- .arg ( P ->mSrid < 1 ? " NULL" : QString::number ( P ->mSrid ) )
59
+ .arg ( mSource ->mSrid < 1 ? " NULL" : QString::number ( mSource ->mSrid ) )
56
60
.arg ( qgsDoubleToString ( rect.xMinimum () ) )
57
61
.arg ( qgsDoubleToString ( rect.yMinimum () ) )
58
62
.arg ( qgsDoubleToString ( rect.xMaximum () ) )
59
63
.arg ( qgsDoubleToString ( rect.yMaximum () ) );
60
64
61
- if ( !P ->mSpatialIndex .isNull () )
65
+ if ( !mSource ->mSpatialIndex .isNull () )
62
66
{
63
- whereClause = QString ( " sdo_filter(%1,%2)='TRUE'" ).arg ( P-> quotedIdentifier ( P ->mGeometryColumn ) ).arg ( bbox );
67
+ whereClause = QString ( " sdo_filter(%1,%2)='TRUE'" ).arg ( QgsOracleProvider:: quotedIdentifier ( mSource ->mGeometryColumn ) ).arg ( bbox );
64
68
#if 0
65
69
if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect )
66
70
{
@@ -74,30 +78,30 @@ QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleProvider *p, const
74
78
break ;
75
79
76
80
case QgsFeatureRequest::FilterFid:
77
- whereClause = P-> whereClause ( request.filterFid () );
81
+ whereClause = QgsOracleUtils:: whereClause ( request.filterFid (), mSource -> mFields , mSource -> mPrimaryKeyType , mSource -> mPrimaryKeyAttrs , mSource -> mShared );
78
82
break ;
79
83
80
84
case QgsFeatureRequest::FilterFids:
81
- whereClause = P-> whereClause ( request.filterFids () );
85
+ whereClause = QgsOracleUtils:: whereClause ( request.filterFids (), mSource -> mFields , mSource -> mPrimaryKeyType , mSource -> mPrimaryKeyAttrs , mSource -> mShared );
82
86
break ;
83
87
84
88
case QgsFeatureRequest::FilterNone:
85
89
break ;
86
90
}
87
91
88
- if ( P ->mRequestedGeomType != QGis::WKBUnknown && P ->mRequestedGeomType != P ->mDetectedGeomType )
92
+ if ( mSource ->mRequestedGeomType != QGis::WKBUnknown && mSource ->mRequestedGeomType != mSource ->mDetectedGeomType )
89
93
{
90
94
if ( !whereClause.isEmpty () )
91
95
whereClause += " AND " ;
92
96
93
- whereClause += QgsOracleConn::databaseTypeFilter ( " featureRequest" , P ->mGeometryColumn , P ->mRequestedGeomType );
97
+ whereClause += QgsOracleConn::databaseTypeFilter ( " featureRequest" , mSource ->mGeometryColumn , mSource ->mRequestedGeomType );
94
98
}
95
99
96
- if ( !P ->mSqlWhereClause .isEmpty () )
100
+ if ( !mSource ->mSqlWhereClause .isEmpty () )
97
101
{
98
102
if ( !whereClause.isEmpty () )
99
103
whereClause += " AND " ;
100
- whereClause += " (" + P ->mSqlWhereClause + " )" ;
104
+ whereClause += " (" + mSource ->mSqlWhereClause + " )" ;
101
105
}
102
106
103
107
if ( !openQuery ( whereClause ) )
@@ -118,7 +122,7 @@ bool QgsOracleFeatureIterator::fetchFeature( QgsFeature& feature )
118
122
119
123
for ( ;; )
120
124
{
121
- feature.initAttributes ( P-> fields () .count () );
125
+ feature.initAttributes ( mSource -> mFields .count () );
122
126
feature.setGeometry ( 0 );
123
127
124
128
if ( mRewind )
@@ -135,15 +139,15 @@ bool QgsOracleFeatureIterator::fetchFeature( QgsFeature& feature )
135
139
int col = 0 ;
136
140
137
141
if (( mRequest .flags () & QgsFeatureRequest::NoGeometry ) == 0 ||
138
- (( mRequest .flags () & QgsFeatureRequest::ExactIntersect ) != 0 && !P-> mConnection ->hasSpatial () ) )
142
+ (( mRequest .flags () & QgsFeatureRequest::ExactIntersect ) != 0 && !mConnection ->hasSpatial () ) )
139
143
{
140
144
QByteArray *ba = static_cast <QByteArray*>( mQry .value ( col++ ).data () );
141
145
unsigned char *copy = new unsigned char [ba->size ()];
142
146
memcpy ( copy, ba->constData (), ba->size () );
143
147
144
148
feature.setGeometryAndOwnership ( copy, ba->size () );
145
149
146
- if ( !P-> mConnection ->hasSpatial () &&
150
+ if ( !mConnection ->hasSpatial () &&
147
151
mRequest .filterType () == QgsFeatureRequest::FilterRect &&
148
152
( mRequest .flags () & QgsFeatureRequest::ExactIntersect ) != 0 &&
149
153
( !feature.geometry () || !feature.geometry ()->intersects ( mRequest .filterRect () ) ) )
@@ -162,27 +166,27 @@ bool QgsOracleFeatureIterator::fetchFeature( QgsFeature& feature )
162
166
163
167
QgsFeatureId fid = 0 ;
164
168
165
- switch ( P ->mPrimaryKeyType )
169
+ switch ( mSource ->mPrimaryKeyType )
166
170
{
167
- case QgsOracleProvider:: pktInt:
171
+ case pktInt:
168
172
// get 64bit integer from result
169
173
fid = mQry .value ( col++ ).toLongLong ();
170
- if ( mAttributeList .contains ( P ->mPrimaryKeyAttrs [0 ] ) )
171
- feature.setAttribute ( P ->mPrimaryKeyAttrs [0 ], fid );
174
+ if ( mAttributeList .contains ( mSource ->mPrimaryKeyAttrs [0 ] ) )
175
+ feature.setAttribute ( mSource ->mPrimaryKeyAttrs [0 ], fid );
172
176
break ;
173
177
174
- case QgsOracleProvider:: pktRowId:
175
- case QgsOracleProvider:: pktFidMap:
178
+ case pktRowId:
179
+ case pktFidMap:
176
180
{
177
181
QList<QVariant> primaryKeyVals;
178
182
179
- if ( P ->mPrimaryKeyType == QgsOracleProvider:: pktFidMap )
183
+ if ( mSource ->mPrimaryKeyType == pktFidMap )
180
184
{
181
- foreach ( int idx, P ->mPrimaryKeyAttrs )
185
+ foreach ( int idx, mSource ->mPrimaryKeyAttrs )
182
186
{
183
- const QgsField &fld = P-> field ( idx ) ;
187
+ const QgsField &fld = mSource -> mFields [ idx] ;
184
188
185
- QVariant v = P-> convertValue ( fld.type (), mQry .value ( col ).toString () );
189
+ QVariant v = QgsVectorDataProvider:: convertValue ( fld.type (), mQry .value ( col ).toString () );
186
190
primaryKeyVals << v;
187
191
188
192
if ( mAttributeList .contains ( idx ) )
@@ -196,11 +200,11 @@ bool QgsOracleFeatureIterator::fetchFeature( QgsFeature& feature )
196
200
primaryKeyVals << mQry .value ( col++ );
197
201
}
198
202
199
- fid = P ->lookupFid ( QVariant ( primaryKeyVals ) );
203
+ fid = mSource -> mShared ->lookupFid ( QVariant ( primaryKeyVals ) );
200
204
}
201
205
break ;
202
206
203
- case QgsOracleProvider:: pktUnknown:
207
+ case pktUnknown:
204
208
Q_ASSERT ( !" FAILURE: cannot get feature with unknown primary key" );
205
209
return false ;
206
210
}
@@ -211,19 +215,19 @@ bool QgsOracleFeatureIterator::fetchFeature( QgsFeature& feature )
211
215
// iterate attributes
212
216
foreach ( int idx, mAttributeList )
213
217
{
214
- if ( P ->mPrimaryKeyAttrs .contains ( idx ) )
218
+ if ( mSource ->mPrimaryKeyAttrs .contains ( idx ) )
215
219
continue ;
216
220
217
- const QgsField &fld = P-> field ( idx ) ;
221
+ const QgsField &fld = mSource -> mFields [ idx] ;
218
222
219
- QVariant v = P-> convertValue ( fld.type (), mQry .value ( col ).toString () );
223
+ QVariant v = QgsVectorDataProvider:: convertValue ( fld.type (), mQry .value ( col ).toString () );
220
224
feature.setAttribute ( idx, v );
221
225
222
226
col++;
223
227
}
224
228
225
229
feature.setValid ( true );
226
- feature.setFields ( &P-> mAttributeFields ); // allow name-based attribute lookups
230
+ feature.setFields ( &mSource -> mFields ); // allow name-based attribute lookups
227
231
228
232
return true ;
229
233
}
@@ -246,14 +250,18 @@ bool QgsOracleFeatureIterator::close()
246
250
247
251
mQry .finish ();
248
252
249
- P->mActiveIterators .remove ( this );
253
+ if ( mConnection )
254
+ mConnection ->disconnect ();
255
+ mConnection = 0 ;
256
+
257
+ iteratorClosed ();
250
258
251
259
return true ;
252
260
}
253
261
254
262
bool QgsOracleFeatureIterator::openQuery ( QString whereClause )
255
263
{
256
- if (( mRequest .flags () & QgsFeatureRequest::NoGeometry ) == 0 && P ->mGeometryColumn .isNull () )
264
+ if (( mRequest .flags () & QgsFeatureRequest::NoGeometry ) == 0 && mSource ->mGeometryColumn .isNull () )
257
265
{
258
266
return false ;
259
267
}
@@ -264,51 +272,51 @@ bool QgsOracleFeatureIterator::openQuery( QString whereClause )
264
272
265
273
if (( mRequest .flags () & QgsFeatureRequest::NoGeometry ) == 0 )
266
274
{
267
- query += P-> quotedIdentifier ( P ->mGeometryColumn );
275
+ query += QgsOracleProvider:: quotedIdentifier ( mSource ->mGeometryColumn );
268
276
delim = " ," ;
269
277
}
270
278
271
- switch ( P ->mPrimaryKeyType )
279
+ switch ( mSource ->mPrimaryKeyType )
272
280
{
273
- case QgsOracleProvider:: pktRowId:
274
- query += delim + P-> quotedIdentifier ( " ROWID" );
281
+ case pktRowId:
282
+ query += delim + QgsOracleProvider:: quotedIdentifier ( " ROWID" );
275
283
delim = " ," ;
276
284
break ;
277
285
278
- case QgsOracleProvider:: pktInt:
279
- query += delim + P-> quotedIdentifier ( P-> field ( P ->mPrimaryKeyAttrs [0 ] ) .name () );
286
+ case pktInt:
287
+ query += delim + QgsOracleProvider:: quotedIdentifier ( mSource -> mFields [ mSource ->mPrimaryKeyAttrs [0 ] ] .name () );
280
288
delim = " ," ;
281
289
break ;
282
290
283
- case QgsOracleProvider:: pktFidMap:
284
- foreach ( int idx, P ->mPrimaryKeyAttrs )
291
+ case pktFidMap:
292
+ foreach ( int idx, mSource ->mPrimaryKeyAttrs )
285
293
{
286
- query += delim + P-> mConnection ->fieldExpression ( P-> field ( idx ) );
294
+ query += delim + mConnection ->fieldExpression ( mSource -> mFields [ idx] );
287
295
delim = " ," ;
288
296
}
289
297
break ;
290
298
291
- case QgsOracleProvider:: pktUnknown:
299
+ case pktUnknown:
292
300
QgsDebugMsg ( " Cannot query without primary key." );
293
301
return false ;
294
302
break ;
295
303
}
296
304
297
305
foreach ( int idx, mAttributeList )
298
306
{
299
- if ( P ->mPrimaryKeyAttrs .contains ( idx ) )
307
+ if ( mSource ->mPrimaryKeyAttrs .contains ( idx ) )
300
308
continue ;
301
309
302
- query += delim + P-> mConnection ->fieldExpression ( P-> field ( idx ) );
310
+ query += delim + mConnection ->fieldExpression ( mSource -> mFields [ idx] );
303
311
}
304
312
305
- query += QString ( " FROM %1 \" featureRequest\" " ).arg ( P ->mQuery );
313
+ query += QString ( " FROM %1 \" featureRequest\" " ).arg ( mSource ->mQuery );
306
314
307
315
if ( !whereClause.isEmpty () )
308
316
query += QString ( " WHERE %1" ).arg ( whereClause );
309
317
310
318
QgsDebugMsg ( QString ( " Fetch features: %1" ).arg ( query ) );
311
- if ( !P-> exec ( mQry , query ) )
319
+ if ( !QgsOracleProvider:: exec ( mQry , query ) )
312
320
{
313
321
QgsMessageLog::logMessage ( QObject::tr ( " Fetching features failed.\n SQL:%1\n Error: %2" )
314
322
.arg ( mQry .lastQuery () )
@@ -324,3 +332,26 @@ bool QgsOracleFeatureIterator::openQuery( QString whereClause )
324
332
325
333
return true ;
326
334
}
335
+
336
+ // -----------
337
+
338
+ QgsOracleFeatureSource::QgsOracleFeatureSource ( const QgsOracleProvider* p )
339
+ : mUri( p->mUri )
340
+ , mFields( p->mAttributeFields )
341
+ , mGeometryColumn( p->mGeometryColumn )
342
+ , mSrid( p->mSrid )
343
+ , mSpatialIndex( p->mSpatialIndex )
344
+ , mDetectedGeomType( p->mDetectedGeomType )
345
+ , mRequestedGeomType( p->mRequestedGeomType )
346
+ , mSqlWhereClause( p->mSqlWhereClause )
347
+ , mPrimaryKeyType( p->mPrimaryKeyType )
348
+ , mPrimaryKeyAttrs( p->mPrimaryKeyAttrs )
349
+ , mQuery( p->mQuery )
350
+ , mShared( p->mShared )
351
+ {
352
+ }
353
+
354
+ QgsFeatureIterator QgsOracleFeatureSource::getFeatures ( const QgsFeatureRequest& request )
355
+ {
356
+ return QgsFeatureIterator ( new QgsOracleFeatureIterator ( this , false , request ) );
357
+ }
0 commit comments