Skip to content

Commit 36672c4

Browse files
committed
oracle provider: add/fix support for multiple geometry columns (fixes #13158)
1 parent 9b192d4 commit 36672c4

8 files changed

+124
-83
lines changed

src/providers/oracle/ocispatial/qsql_ocispatial.cpp

+42-33
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ struct QOCISpatialResultPrivate
347347
OCIError *err;
348348
OCISvcCtx *&svc;
349349
OCIStmt *sql;
350-
QOCISDOGeometryObj *sdoobj;
351-
QOCISDOGeometryInd *sdoind;
350+
QList<QOCISDOGeometryObj*> sdoobj;
351+
QList<QOCISDOGeometryInd*> sdoind;
352352
bool transaction;
353353
int serverVersion;
354354
int prefetchRows, prefetchMem;
@@ -1151,7 +1151,7 @@ class QOCISpatialCols
11511151
QString oraTypeName;
11521152
};
11531153

1154-
bool convertToWkb( QVariant &v );
1154+
bool convertToWkb( QVariant &v, int index );
11551155
bool getValue( OCINumber *num, unsigned int &value );
11561156
bool getValue( OCINumber *num, int &value );
11571157
bool getValue( OCINumber *num, double &value );
@@ -1336,12 +1336,15 @@ QOCISpatialCols::QOCISpatialCols( int size, QOCISpatialResultPrivate* dp )
13361336

13371337
if ( r == OCI_SUCCESS )
13381338
{
1339+
dp->sdoobj.push_back( 0 );
1340+
dp->sdoind.push_back( 0 );
1341+
13391342
qDebug( "define object" );
13401343
r = OCIDefineObject( dfn,
13411344
d->err,
13421345
ofi.oraOCIType,
1343-
( void** ) & dp->sdoobj, 0,
1344-
( void** ) & dp->sdoind, 0 );
1346+
( void** ) & dp->sdoobj.last(), 0,
1347+
( void** ) & dp->sdoind.last(), 0 );
13451348
}
13461349
else
13471350
{
@@ -2315,31 +2318,37 @@ bool QOCISpatialCols::getElemInfoElem( int iElem, const QVector<int> &vElems, in
23152318
return true;
23162319
}
23172320

2318-
bool QOCISpatialCols::convertToWkb( QVariant &v )
2321+
bool QOCISpatialCols::convertToWkb( QVariant &v, int index )
23192322
{
23202323
ENTER
23212324

2322-
qDebug() << "sdoobj =" << d->sdoobj;
2323-
qDebug() << "sdoinf =" << d->sdoind;
2324-
if ( d->sdoind )
2325-
qDebug() << "sdoind->_atomic =" << d->sdoind->_atomic;
2325+
Q_ASSERT( index < d->sdoobj.size() );
2326+
Q_ASSERT( index < d->sdoind.size() );
2327+
2328+
QOCISDOGeometryObj *sdoobj = d->sdoobj[index];
2329+
QOCISDOGeometryInd *sdoind = d->sdoind[index];
2330+
2331+
qDebug() << "sdoobj =" << sdoobj;
2332+
qDebug() << "sdoinf =" << sdoind;
2333+
if ( sdoind )
2334+
qDebug() << "sdoind->_atomic =" << sdoind->_atomic;
23262335

23272336
v = QVariant( QVariant::ByteArray );
23282337

2329-
if ( !d->sdoobj || !d->sdoind )
2338+
if ( !sdoobj || !sdoind )
23302339
{
23312340
qDebug() << "sdoobj or sdoind not set";
23322341
return false;
23332342
}
23342343

2335-
if ( d->sdoind->_atomic == OCI_IND_NULL )
2344+
if ( sdoind->_atomic == OCI_IND_NULL )
23362345
{
23372346
qDebug() << "geometry is NULL";
23382347
return true;
23392348
}
23402349

23412350
unsigned int iGType;
2342-
if ( !getValue( &d->sdoobj->gtype, iGType ) )
2351+
if ( !getValue( &sdoobj->gtype, iGType ) )
23432352
return false;
23442353

23452354
int nDims = SDO_GTYPE_D( iGType );
@@ -2353,9 +2362,9 @@ bool QOCISpatialCols::convertToWkb( QVariant &v )
23532362
}
23542363

23552364
int iSrid = 0;
2356-
if ( d->sdoind->srid == OCI_IND_NOTNULL )
2365+
if ( sdoind->srid == OCI_IND_NOTNULL )
23572366
{
2358-
if ( !getValue( &d->sdoobj->srid, iSrid ) )
2367+
if ( !getValue( &sdoobj->srid, iSrid ) )
23592368
return false;
23602369
}
23612370

@@ -2366,14 +2375,14 @@ bool QOCISpatialCols::convertToWkb( QVariant &v )
23662375
union wkbPtr ptr;
23672376

23682377
int nElems;
2369-
if ( !getArraySize( d->sdoobj->elem_info, nElems ) )
2378+
if ( !getArraySize( sdoobj->elem_info, nElems ) )
23702379
{
23712380
qWarning() << "could not determine element info array size";
23722381
return false;
23732382
}
23742383

23752384
int nOrds;
2376-
if ( !getArraySize( d->sdoobj->ordinates, nOrds ) )
2385+
if ( !getArraySize( sdoobj->ordinates, nOrds ) )
23772386
{
23782387
qWarning() << "could not determine ordinate array size";
23792388
return false;
@@ -2392,37 +2401,37 @@ bool QOCISpatialCols::convertToWkb( QVariant &v )
23922401
{
23932402
Q_ASSERT( nOrds == 0 );
23942403

2395-
if ( d->sdoind->_atomic != OCI_IND_NOTNULL ||
2396-
d->sdoind->point.x != OCI_IND_NOTNULL ||
2397-
d->sdoind->point.y != OCI_IND_NOTNULL )
2404+
if ( sdoind->_atomic != OCI_IND_NOTNULL ||
2405+
sdoind->point.x != OCI_IND_NOTNULL ||
2406+
sdoind->point.y != OCI_IND_NOTNULL )
23982407
{
23992408
qDebug() << "null point";
24002409
v = QVariant();
24012410
return true;
24022411
}
24032412

24042413
double x, y, z = 0.0;
2405-
if ( !getValue( &d->sdoobj->point.x, x ) )
2414+
if ( !getValue( &sdoobj->point.x, x ) )
24062415
{
24072416
qWarning() << "could not convert x ordinate to real";
24082417
return false;
24092418
}
24102419

2411-
if ( !getValue( &d->sdoobj->point.y, y ) )
2420+
if ( !getValue( &sdoobj->point.y, y ) )
24122421
{
24132422
qWarning() << "could not convert y ordinate to real";
24142423
return false;
24152424
}
24162425

24172426
if ( nDims > 2 )
24182427
{
2419-
if ( d->sdoind->point.z != OCI_IND_NOTNULL )
2428+
if ( sdoind->point.z != OCI_IND_NOTNULL )
24202429
{
24212430
qWarning() << "null value in z ordinate";
24222431
return false;
24232432
}
24242433

2425-
if ( !getValue( &d->sdoobj->point.z, z ) )
2434+
if ( !getValue( &sdoobj->point.z, z ) )
24262435
{
24272436
qDebug() << "could not convert z ordinate to real";
24282437
return false;
@@ -2442,7 +2451,7 @@ bool QOCISpatialCols::convertToWkb( QVariant &v )
24422451
return true;
24432452
}
24442453

2445-
if ( d->sdoind->_atomic != OCI_IND_NOTNULL )
2454+
if ( sdoind->_atomic != OCI_IND_NOTNULL )
24462455
{
24472456
qWarning() << "geometry with sdo_elem_info and non-null sdo_point found.";
24482457
return false;
@@ -2455,7 +2464,7 @@ bool QOCISpatialCols::convertToWkb( QVariant &v )
24552464
QVector<boolean> exists( nElems );
24562465
QVector<OCINumber*> numbers( nElems );
24572466
uword nelems = nElems;
2458-
OCI_VERIFY_E( d->err, OCICollGetElemArray( d->env, d->err, d->sdoobj->elem_info, 0, exists.data(), ( void** ) numbers.data(), 0, &nelems ) );
2467+
OCI_VERIFY_E( d->err, OCICollGetElemArray( d->env, d->err, sdoobj->elem_info, 0, exists.data(), ( void** ) numbers.data(), 0, &nelems ) );
24592468
if ( !exists[0] )
24602469
{
24612470
qWarning() << "element info array does not exists";
@@ -2484,7 +2493,7 @@ bool QOCISpatialCols::convertToWkb( QVariant &v )
24842493
QVector<boolean> exists( nOrds );
24852494
QVector<OCINumber*> numbers( nOrds );
24862495
uword nords = nOrds;
2487-
OCI_VERIFY_E( d->err, OCICollGetElemArray( d->env, d->err, d->sdoobj->ordinates, 0, exists.data(), ( void** ) numbers.data(), 0, &nords ) );
2496+
OCI_VERIFY_E( d->err, OCICollGetElemArray( d->env, d->err, sdoobj->ordinates, 0, exists.data(), ( void** ) numbers.data(), 0, &nords ) );
24882497
if ( !exists[0] )
24892498
{
24902499
qWarning() << "ordinate array does not exists";
@@ -2797,7 +2806,7 @@ bool QOCISpatialCols::convertToWkb( QVariant &v )
27972806
void QOCISpatialCols::getValues( QVector<QVariant> &v, int index )
27982807
{
27992808
ENTER
2800-
for ( int i = 0; i < fieldInf.size(); ++i )
2809+
for ( int i = 0, gcindex = 0; i < fieldInf.size(); ++i )
28012810
{
28022811
qDebug() << "getValues( index =" << index << "i =" << i << " )";
28032812
const OraFieldInf &fld = fieldInf.at( i );
@@ -2871,7 +2880,7 @@ void QOCISpatialCols::getValues( QVector<QVariant> &v, int index )
28712880
if ( fld.oraType == SQLT_NTY && fld.oraTypeName == "SDO_GEOMETRY" )
28722881
{
28732882
qDebug() << "SQLT_NTY SDO_GEOMETRY";
2874-
convertToWkb( v[ index+i ] );
2883+
convertToWkb( v[ index+i ], gcindex++ );
28752884
}
28762885
else
28772886
{
@@ -2896,8 +2905,8 @@ QOCISpatialResultPrivate::QOCISpatialResultPrivate( QOCISpatialResult *result, c
28962905
, err( 0 )
28972906
, svc( const_cast<OCISvcCtx*&>( driver->svc ) )
28982907
, sql( 0 )
2899-
, sdoobj( 0 )
2900-
, sdoind( 0 )
2908+
, sdoobj()
2909+
, sdoind()
29012910
, transaction( driver->transaction )
29022911
, serverVersion( driver->serverVersion )
29032912
, prefetchRows( driver->prefetchRows )
@@ -3190,8 +3199,8 @@ bool QOCISpatialResult::exec()
31903199
0, OCI_ATTR_PARAM_COUNT, d->err );
31913200
if ( r == OCI_SUCCESS && !d->cols )
31923201
{
3193-
d->sdoobj = 0;
3194-
d->sdoind = 0;
3202+
d->sdoobj.clear();
3203+
d->sdoind.clear();
31953204
d->cols = new QOCISpatialCols( parmCount, d );
31963205
}
31973206
else

src/providers/oracle/qgsoracleconn.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,14 @@ struct QgsOracleLayerProperty
7676
QString toString() const
7777
{
7878
QString typeString;
79-
foreach ( QGis::WkbType type, types )
79+
Q_FOREACH ( QGis::WkbType type, types )
8080
{
8181
if ( !typeString.isEmpty() )
8282
typeString += "|";
8383
typeString += QString::number( type );
8484
}
8585
QString sridString;
86-
foreach ( int srid, srids )
86+
Q_FOREACH ( int srid, srids )
8787
{
8888
if ( !sridString.isEmpty() )
8989
sridString += "|";

src/providers/oracle/qgsoracledataitems.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ void QgsOracleConnectionItem::refresh()
5757

5858
stop();
5959

60-
foreach ( QgsDataItem *child, mChildren )
60+
Q_FOREACH ( QgsDataItem *child, mChildren )
6161
{
6262
deleteChildItem( child );
6363
}
6464

65-
foreach ( QgsDataItem *item, createChildren() )
65+
Q_FOREACH ( QgsDataItem *item, createChildren() )
6666
{
6767
addChildItem( item, true );
6868
}
@@ -215,7 +215,7 @@ bool QgsOracleConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction
215215
QStringList importResults;
216216
bool hasError = false;
217217
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
218-
foreach ( const QgsMimeDataUtils::Uri& u, lst )
218+
Q_FOREACH ( const QgsMimeDataUtils::Uri& u, lst )
219219
{
220220
if ( u.layerType != "vector" )
221221
{
@@ -415,7 +415,7 @@ QgsOracleRootItem::~QgsOracleRootItem()
415415
QVector<QgsDataItem*> QgsOracleRootItem::createChildren()
416416
{
417417
QVector<QgsDataItem*> connections;
418-
foreach ( QString connName, QgsOracleConn::connectionList() )
418+
Q_FOREACH ( QString connName, QgsOracleConn::connectionList() )
419419
{
420420
connections << new QgsOracleConnectionItem( this, connName, mPath + "/" + connName );
421421
}

src/providers/oracle/qgsoraclefeatureiterator.cpp

+16-5
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ bool QgsOracleFeatureIterator::fetchFeature( QgsFeature& feature )
187187

188188
if ( mSource->mPrimaryKeyType == pktFidMap )
189189
{
190-
foreach ( int idx, mSource->mPrimaryKeyAttrs )
190+
Q_FOREACH ( int idx, mSource->mPrimaryKeyAttrs )
191191
{
192192
const QgsField &fld = mSource->mFields[idx];
193193

@@ -220,15 +220,26 @@ bool QgsOracleFeatureIterator::fetchFeature( QgsFeature& feature )
220220
QgsDebugMsgLevel( QString( "fid=%1" ).arg( fid ), 5 );
221221

222222
// iterate attributes
223-
foreach ( int idx, mAttributeList )
223+
Q_FOREACH ( int idx, mAttributeList )
224224
{
225225
if ( mSource->mPrimaryKeyAttrs.contains( idx ) )
226226
continue;
227227

228228
const QgsField &fld = mSource->mFields[idx];
229229

230230
QVariant v = mQry.value( col );
231-
if ( v.type() != fld.type() )
231+
if ( fld.type() == QVariant::ByteArray && fld.typeName().endsWith( ".SDO_GEOMETRY" ) )
232+
{
233+
QByteArray *ba = static_cast<QByteArray*>( v.data() );
234+
unsigned char *copy = new unsigned char[ba->size()];
235+
memcpy( copy, ba->constData(), ba->size() );
236+
237+
QgsGeometry *g = new QgsGeometry();
238+
g->fromWkb( copy, ba->size() );
239+
v = g->exportToWkt();
240+
delete g;
241+
}
242+
else if ( v.type() != fld.type() )
232243
v = QgsVectorDataProvider::convertValue( fld.type(), v.toString() );
233244
feature.setAttribute( idx, v );
234245

@@ -291,7 +302,7 @@ bool QgsOracleFeatureIterator::openQuery( QString whereClause )
291302
break;
292303

293304
case pktFidMap:
294-
foreach ( int idx, mSource->mPrimaryKeyAttrs )
305+
Q_FOREACH ( int idx, mSource->mPrimaryKeyAttrs )
295306
{
296307
query += delim + mConnection->fieldExpression( mSource->mFields[idx] );
297308
delim = ",";
@@ -304,7 +315,7 @@ bool QgsOracleFeatureIterator::openQuery( QString whereClause )
304315
break;
305316
}
306317

307-
foreach ( int idx, mAttributeList )
318+
Q_FOREACH ( int idx, mAttributeList )
308319
{
309320
if ( mSource->mPrimaryKeyAttrs.contains( idx ) )
310321
continue;

0 commit comments

Comments
 (0)