~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to ogr/ogrsf_frmts/oci/ogrocitablelayer.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: ogrocitablelayer.cpp 14864 2008-07-08 21:03:31Z mloskot $
 
2
 * $Id: ogrocitablelayer.cpp 23102 2011-09-22 16:12:14Z ilucena $
3
3
 *
4
4
 * Project:  Oracle Spatial Driver
5
5
 * Purpose:  Implementation of the OGROCITableLayer class.  This class provides
33
33
#include "cpl_conv.h"
34
34
#include "cpl_string.h"
35
35
 
36
 
CPL_CVSID("$Id: ogrocitablelayer.cpp 14864 2008-07-08 21:03:31Z mloskot $");
 
36
CPL_CVSID("$Id: ogrocitablelayer.cpp 23102 2011-09-22 16:12:14Z ilucena $");
37
37
 
38
38
static int nDiscarded = 0;
39
39
static int nHits = 0;
106
106
{
107
107
    int   i;
108
108
 
109
 
    if( bNewLayer )
110
 
        FinalizeNewLayer();
 
109
    SyncToDisk();
111
110
 
112
111
    CPLFree( panWriteFIDs );
113
112
    if( papWriteFields != NULL )
156
155
    poDefn->Reference();
157
156
 
158
157
/* -------------------------------------------------------------------- */
 
158
/*      Split out the owner if available.                               */
 
159
/* -------------------------------------------------------------------- */
 
160
    if( strstr(pszTable,".") != NULL )
 
161
    {
 
162
        osTableName = strstr(pszTable,".") + 1;
 
163
        osOwner.assign( pszTable, strlen(pszTable)-osTableName.size() - 1 );
 
164
    }
 
165
    else
 
166
    {
 
167
        osTableName = pszTable;
 
168
        osOwner = "";
 
169
    }
 
170
 
 
171
/* -------------------------------------------------------------------- */
159
172
/*      Do a DescribeAll on the table.                                  */
160
173
/* -------------------------------------------------------------------- */
161
174
    OCIParam *hAttrParam = NULL;
240
253
        poDefn->AddFieldDefn( &oField );
241
254
    }
242
255
 
 
256
    /* -------------------------------------------------------------------- */
 
257
    /*      Identify Geometry dimension                                     */
 
258
    /* -------------------------------------------------------------------- */
 
259
 
 
260
    if( pszGeomName != NULL && strlen(pszGeomName) > 0 )
 
261
    {
 
262
        OGROCIStringBuf oDimCmd;
 
263
        OGROCIStatement oDimStatement( poSession );
 
264
        char **papszResult;
 
265
        int iDim = -1;
 
266
 
 
267
                oDimCmd.Append( "SELECT COUNT(*) FROM ALL_SDO_GEOM_METADATA u," );
 
268
                oDimCmd.Append( "  TABLE(u.diminfo) t" );
 
269
                oDimCmd.Append( "  WHERE u.table_name = '" );
 
270
                oDimCmd.Append( osTableName );
 
271
                oDimCmd.Append( "' AND u.column_name = '" );
 
272
                oDimCmd.Append( pszGeomName  );
 
273
                oDimCmd.Append( "'" );
 
274
 
 
275
        oDimStatement.Execute( oDimCmd.GetString() );
 
276
 
 
277
        papszResult = oDimStatement.SimpleFetchRow();
 
278
 
 
279
        if( CSLCount(papszResult) < 1 )
 
280
        {
 
281
            OGROCIStringBuf oDimCmd2;
 
282
            OGROCIStatement oDimStatement2( poSession );
 
283
            char **papszResult2;
 
284
 
 
285
            CPLErrorReset();
 
286
                        
 
287
            oDimCmd2.Appendf( 1024,
 
288
                "select m.sdo_index_dims\n"
 
289
                "from   all_sdo_index_metadata m, all_sdo_index_info i\n"
 
290
                "where  i.index_name = m.sdo_index_name\n"
 
291
                "   and i.sdo_index_owner = m.sdo_index_owner\n"
 
292
                "   and i.table_name = upper('%s')",
 
293
                osTableName.c_str() );
 
294
 
 
295
            oDimStatement2.Execute( oDimCmd2.GetString() );
 
296
 
 
297
            papszResult2 = oDimStatement2.SimpleFetchRow();
 
298
 
 
299
            if( CSLCount( papszResult2 ) > 0 )
 
300
            {
 
301
                iDim = atoi( papszResult2[0] );
 
302
            }
 
303
            else
 
304
            {
 
305
                // we want to clear any errors to avoid confusing the application.
 
306
                CPLErrorReset();
 
307
            }
 
308
        }
 
309
        else
 
310
        {
 
311
            iDim = atoi( papszResult[0] );
 
312
        }
 
313
 
 
314
        if( iDim > 0 )
 
315
        {
 
316
            SetDimension( iDim );
 
317
        }
 
318
        else
 
319
        {
 
320
            CPLDebug( "OCI", "get dim based of existing data or index failed." );
 
321
        }
 
322
    }
 
323
 
243
324
    bValidTable = TRUE;
244
325
 
245
326
    return poDefn;
688
769
        OGREnvelope  sThisExtent;
689
770
        
690
771
        poFeature->GetGeometryRef()->getEnvelope( &sThisExtent );
691
 
        sExtent.Merge( sThisExtent );
 
772
 
 
773
        if( !sExtent.Contains( sThisExtent ) )                          
 
774
        {
 
775
            sExtent.Merge( sThisExtent );
 
776
            bExtentUpdated = true;
 
777
        }
692
778
    }
693
779
 
694
780
/* -------------------------------------------------------------------- */
695
781
/*      Do the actual creation.                                         */
696
782
/* -------------------------------------------------------------------- */
697
 
    if( CSLFetchBoolean( papszOptions, "MULTI_LOAD", bNewLayer ) )
 
783
    if( CSLFetchBoolean( papszOptions, "MULTI_LOAD", true ) )
698
784
        return BoundCreateFeature( poFeature );
699
785
    else
700
786
        return UnboundCreateFeature( poFeature );
1079
1165
    CPLAssert( NULL != psExtent );
1080
1166
 
1081
1167
    OGRErr err = OGRERR_FAILURE;
1082
 
    
1083
 
/* -------------------------------------------------------------------- */
1084
 
/*      Split out the owner if available.                               */
1085
 
/* -------------------------------------------------------------------- */
1086
 
    const char *pszTableName = GetLayerDefn()->GetName();
1087
 
    char *pszOwner = NULL;
1088
1168
 
1089
 
    if( strstr(pszTableName,".") != NULL )
 
1169
    if( EQUAL(GetGeometryColumn(),"") )
1090
1170
    {
1091
 
        pszOwner = CPLStrdup(pszTableName);
1092
 
        pszTableName = strstr(pszTableName,".") + 1;
1093
 
 
1094
 
        *(strstr(pszOwner,".")) = '\0';
 
1171
        return OGRERR_NONE;
1095
1172
    }
1096
1173
 
1097
1174
/* -------------------------------------------------------------------- */
1108
1185
                      "FROM ALL_SDO_GEOM_METADATA m, ",
1109
1186
                      pszGeomName, pszGeomName, pszGeomName, pszGeomName );
1110
1187
 
1111
 
    if( pszOwner != NULL )
 
1188
    if( osOwner != "" )
1112
1189
    {
1113
1190
        oCommand.Appendf( 500, " %s.%s t ",
1114
 
                          pszOwner, pszTableName );
 
1191
                          osOwner.c_str(), osTableName.c_str() );
1115
1192
    }
1116
1193
    else
1117
1194
    {
1118
1195
        oCommand.Appendf( 500, " %s t ",
1119
 
                          pszTableName );
 
1196
                          osTableName.c_str() );
1120
1197
    }
1121
1198
 
1122
 
    oCommand.Appendf( 500, "WHERE m.TABLE_NAME = '%s' AND m.COLUMN_NAME='%s'",
1123
 
                      pszTableName, pszGeomName );
 
1199
    oCommand.Appendf( 500, "WHERE m.TABLE_NAME = UPPER('%s') AND m.COLUMN_NAME = UPPER('%s')",
 
1200
                      osTableName.c_str(), pszGeomName );
1124
1201
 
1125
 
    if( pszOwner != NULL )
 
1202
    if( osOwner != "" )
1126
1203
    {
1127
 
        oCommand.Appendf( 500, " AND OWNER = '%s'", pszOwner );
1128
 
        CPLFree( pszOwner );
 
1204
        oCommand.Appendf( 500, " AND OWNER = UPPER('%s')", osOwner.c_str() );
1129
1205
    }
1130
1206
 
1131
1207
/* -------------------------------------------------------------------- */
1162
1238
        err = OGRLayer::GetExtent( psExtent, bForce );
1163
1239
        CPLDebug( "OCI", 
1164
1240
                  "Failing to query extent of %s using default GetExtent",
1165
 
                  pszTableName );
 
1241
                  osTableName.c_str() );
1166
1242
    }
1167
1243
 
1168
1244
    return err;
1233
1309
}
1234
1310
 
1235
1311
/************************************************************************/
1236
 
/*                          FinalizeNewLayer()                          */
1237
 
/*                                                                      */
1238
 
/*      Our main job here is to update the USER_SDO_GEOM_METADATA       */
1239
 
/*      table to include the correct array of dimension object with     */
1240
 
/*      the appropriate extents for this layer.  We may also do         */
1241
 
/*      spatial indexing at this point.                                 */
 
1312
/*                         UpdateLayerExtents()                         */
1242
1313
/************************************************************************/
1243
1314
 
1244
 
void OGROCITableLayer::FinalizeNewLayer()
 
1315
void OGROCITableLayer::UpdateLayerExtents()
1245
1316
 
1246
1317
{
1247
 
    OGROCIStringBuf  sDimUpdate;
1248
 
 
1249
 
    FlushPendingFeatures();
1250
 
 
1251
 
/* -------------------------------------------------------------------- */
1252
 
/*      If the dimensions are degenerate (all zeros) then we assume     */
1253
 
/*      there were no geometries, and we don't bother setting the       */
1254
 
/*      dimensions.                                                     */
1255
 
/* -------------------------------------------------------------------- */
1256
 
    if( sExtent.MaxX == 0 && sExtent.MinX == 0
1257
 
        && sExtent.MaxY == 0 && sExtent.MinY == 0 )
 
1318
    if( !bExtentUpdated )
 
1319
        return;
 
1320
 
 
1321
    bExtentUpdated = false;
 
1322
 
 
1323
/* -------------------------------------------------------------------- */
 
1324
/*      Do we have existing layer extents we need to merge in to the    */
 
1325
/*      ones we collected as we created features?                       */
 
1326
/* -------------------------------------------------------------------- */
 
1327
    bool bHaveOldExtent = false;
 
1328
 
 
1329
    if( !bNewLayer && pszGeomName )
1258
1330
    {
1259
 
        CPLError( CE_Warning, CPLE_AppDefined, 
1260
 
                  "Layer %s appears to have no geometry ... not setting SDO DIMINFO metadata.", 
1261
 
                  poFeatureDefn->GetName() );
1262
 
        return;
1263
 
                  
 
1331
        OGROCIStringBuf oCommand;
 
1332
 
 
1333
        oCommand.Appendf(1000, 
 
1334
                          "select min(case when r=1 then sdo_lb else null end) minx, min(case when r=2 then sdo_lb else null end) miny, " 
 
1335
                          "min(case when r=1 then sdo_ub else null end) maxx, min(case when r=2 then sdo_ub else null end) maxy" 
 
1336
                          " from (SELECT d.sdo_dimname, d.sdo_lb, sdo_ub, sdo_tolerance, rownum r" 
 
1337
                          " FROM ALL_SDO_GEOM_METADATA m, table(m.diminfo) d"  
 
1338
                          " where m.table_name = UPPER('%s') and m.COLUMN_NAME = UPPER('%s')", 
 
1339
                          osTableName.c_str(), pszGeomName ); 
 
1340
                 
 
1341
        if( osOwner != "" ) 
 
1342
        { 
 
1343
            oCommand.Appendf(500, " AND OWNER = UPPER('%s')", osOwner.c_str() ); 
 
1344
        } 
 
1345
                 
 
1346
        oCommand.Append(" ) ");
 
1347
 
 
1348
        OGROCISession *poSession = poDS->GetSession();
 
1349
        CPLAssert( NULL != poSession );
 
1350
        
 
1351
        OGROCIStatement oGetExtent( poSession );
 
1352
        
 
1353
        if( oGetExtent.Execute( oCommand.GetString() ) == CE_None )
 
1354
        {
 
1355
            char **papszRow = oGetExtent.SimpleFetchRow();
 
1356
            
 
1357
            if( papszRow != NULL
 
1358
                && papszRow[0] != NULL && papszRow[1] != NULL
 
1359
                && papszRow[2] != NULL && papszRow[3] != NULL )
 
1360
            {
 
1361
                OGREnvelope sOldExtent;
 
1362
 
 
1363
                bHaveOldExtent = true;
 
1364
 
 
1365
                sOldExtent.MinX = CPLAtof(papszRow[0]);
 
1366
                sOldExtent.MinY = CPLAtof(papszRow[1]);
 
1367
                sOldExtent.MaxX = CPLAtof(papszRow[2]);
 
1368
                sOldExtent.MaxY = CPLAtof(papszRow[3]);
 
1369
 
 
1370
                if( sOldExtent.Contains( sExtent ) )
 
1371
                {
 
1372
                    // nothing to do!
 
1373
                    sExtent = sOldExtent;
 
1374
                    bExtentUpdated = false;
 
1375
                    return;
 
1376
                }
 
1377
                else
 
1378
                {
 
1379
                    sExtent.Merge( sOldExtent );
 
1380
                }
 
1381
            }
 
1382
        }
1264
1383
    }
1265
1384
 
1266
1385
/* -------------------------------------------------------------------- */
1290
1409
    dfZMax = 100000.0;
1291
1410
    dfZRes = 0.002;
1292
1411
    ParseDIMINFO( "DIMINFO_Z", &dfZMin, &dfZMax, &dfZRes );
 
1412
 
 
1413
/* -------------------------------------------------------------------- */
 
1414
/*      If we already have an extent in the table, we will need to      */
 
1415
/*      update it in place.                                             */
 
1416
/* -------------------------------------------------------------------- */
 
1417
    OGROCIStringBuf  sDimUpdate;
 
1418
 
 
1419
    if( bHaveOldExtent )
 
1420
    {
 
1421
        sDimUpdate.Append( "UPDATE USER_SDO_GEOM_METADATA " );
 
1422
        sDimUpdate.Append( "SET DIMINFO =" );
 
1423
        sDimUpdate.Append( "MDSYS.SDO_DIM_ARRAY(" );
 
1424
        sDimUpdate.Appendf(200,
 
1425
                           "MDSYS.SDO_DIM_ELEMENT('X',%.16g,%.16g,%.12g)",
 
1426
                           dfXMin, dfXMax, dfXRes );
 
1427
        sDimUpdate.Appendf(200,
 
1428
                           ",MDSYS.SDO_DIM_ELEMENT('Y',%.16g,%.16g,%.12g)",
 
1429
                           dfYMin, dfYMax, dfYRes );
 
1430
 
 
1431
        if( nDimension == 3 )
 
1432
        {
 
1433
            sDimUpdate.Appendf(200,
 
1434
                               ",MDSYS.SDO_DIM_ELEMENT('Z',%.16g,%.16g,%.12g)",
 
1435
                               dfZMin, dfZMax, dfZRes );
 
1436
        }      
1293
1437
    
 
1438
        sDimUpdate.Appendf(strlen(poFeatureDefn->GetName()) + 100,") WHERE TABLE_NAME = '%s'", poFeatureDefn->GetName());    
 
1439
        
 
1440
    } 
 
1441
    else
 
1442
    {     
1294
1443
/* -------------------------------------------------------------------- */
1295
1444
/*      Prepare dimension update statement.                             */
1296
1445
/* -------------------------------------------------------------------- */
1297
 
    sDimUpdate.Append( "INSERT INTO USER_SDO_GEOM_METADATA VALUES " );
1298
 
    sDimUpdate.Appendf( strlen(poFeatureDefn->GetName()) + 100,
1299
 
                        "('%s', '%s', ",
1300
 
                        poFeatureDefn->GetName(),
1301
 
                        pszGeomName );
1302
 
 
1303
 
    sDimUpdate.Append( "MDSYS.SDO_DIM_ARRAY(" );
1304
 
    sDimUpdate.Appendf(200,
1305
 
                       "MDSYS.SDO_DIM_ELEMENT('X',%.16g,%.16g,%.12g)",
1306
 
                       dfXMin, dfXMax, dfXRes );
1307
 
    sDimUpdate.Appendf(200,
1308
 
                       ",MDSYS.SDO_DIM_ELEMENT('Y',%.16g,%.16g,%.12g)",
1309
 
                       dfYMin, dfYMax, dfYRes );
1310
 
 
1311
 
    if( nDimension == 3 )
1312
 
    {
1313
 
        sDimUpdate.Appendf(200,
1314
 
                           ",MDSYS.SDO_DIM_ELEMENT('Z',%.16g,%.16g,%.12g)",
1315
 
                           dfZMin, dfZMax, dfZRes );
 
1446
        sDimUpdate.Append( "INSERT INTO USER_SDO_GEOM_METADATA VALUES " );
 
1447
        sDimUpdate.Appendf( strlen(poFeatureDefn->GetName()) + 100,
 
1448
                            "('%s', '%s', ",
 
1449
                            poFeatureDefn->GetName(),
 
1450
                            pszGeomName );
 
1451
 
 
1452
        sDimUpdate.Append( "MDSYS.SDO_DIM_ARRAY(" );
 
1453
        sDimUpdate.Appendf(200,
 
1454
                           "MDSYS.SDO_DIM_ELEMENT('X',%.16g,%.16g,%.12g)",
 
1455
                           dfXMin, dfXMax, dfXRes );
 
1456
        sDimUpdate.Appendf(200,
 
1457
                           ",MDSYS.SDO_DIM_ELEMENT('Y',%.16g,%.16g,%.12g)",
 
1458
                           dfYMin, dfYMax, dfYRes );
 
1459
 
 
1460
        if( nDimension == 3 )
 
1461
        {
 
1462
            sDimUpdate.Appendf(200,
 
1463
                               ",MDSYS.SDO_DIM_ELEMENT('Z',%.16g,%.16g,%.12g)",
 
1464
                               dfZMin, dfZMax, dfZRes );
 
1465
        }
 
1466
 
 
1467
        if( nSRID == -1 )
 
1468
            sDimUpdate.Append( "), NULL)" );
 
1469
        else
 
1470
            sDimUpdate.Appendf( 100, "), %d)", nSRID );
1316
1471
    }
1317
1472
 
1318
 
    if( nSRID == -1 )
1319
 
        sDimUpdate.Append( "), NULL)" );
1320
 
    else
1321
 
        sDimUpdate.Appendf( 100, "), %d)", nSRID );
1322
 
 
1323
1473
/* -------------------------------------------------------------------- */
1324
 
/*      Execute the metadata update.                                    */
 
1474
/*      Run the update/insert command.                                  */
1325
1475
/* -------------------------------------------------------------------- */
1326
1476
    OGROCIStatement oExecStatement( poDS->GetSession() );
1327
 
 
1328
 
    if( oExecStatement.Execute( sDimUpdate.GetString() ) != CE_None )
1329
 
        return;
1330
 
 
 
1477
    
 
1478
    oExecStatement.Execute( sDimUpdate.GetString() );
 
1479
}
 
1480
 
 
1481
/************************************************************************/
 
1482
/*                          FinalizeNewLayer()                          */
 
1483
/*                                                                      */
 
1484
/*      Our main job here is to update the USER_SDO_GEOM_METADATA       */
 
1485
/*      table to include the correct array of dimension object with     */
 
1486
/*      the appropriate extents for this layer.  We may also do         */
 
1487
/*      spatial indexing at this point.                                 */
 
1488
/************************************************************************/
 
1489
 
 
1490
void OGROCITableLayer::FinalizeNewLayer()
 
1491
 
 
1492
{
 
1493
    UpdateLayerExtents();
 
1494
 
 
1495
/* -------------------------------------------------------------------- */
 
1496
/*      For new layers we try to create a spatial index.                */
 
1497
/* -------------------------------------------------------------------- */
 
1498
    if( bNewLayer && sExtent.IsInit() )
 
1499
    {
1331
1500
/* -------------------------------------------------------------------- */
1332
1501
/*      If the user has disabled INDEX support then don't create the    */
1333
1502
/*      index.                                                          */
1334
1503
/* -------------------------------------------------------------------- */
1335
 
    if( !CSLFetchBoolean( papszOptions, "INDEX", TRUE ) )
1336
 
        return;
 
1504
        if( !CSLFetchBoolean( papszOptions, "INDEX", TRUE ) )
 
1505
            return;
1337
1506
 
1338
1507
/* -------------------------------------------------------------------- */
1339
1508
/*      Establish an index name.  For some reason Oracle 8.1.7 does     */
1340
1509
/*      not support spatial index names longer than 18 characters so    */
1341
1510
/*      we magic up an index name if it would be too long.              */
1342
1511
/* -------------------------------------------------------------------- */
1343
 
    char  szIndexName[20];
1344
 
 
1345
 
    if( strlen(poFeatureDefn->GetName()) < 15 )
1346
 
        sprintf( szIndexName, "%s_idx", poFeatureDefn->GetName() );
1347
 
    else if( strlen(poFeatureDefn->GetName()) < 17 )
1348
 
        sprintf( szIndexName, "%si", poFeatureDefn->GetName() );
1349
 
    else
1350
 
    {
1351
 
        int i, nHash = 0;
1352
 
        const char *pszSrcName = poFeatureDefn->GetName();
1353
 
 
1354
 
        for( i = 0; pszSrcName[i] != '\0'; i++ )
1355
 
            nHash = (nHash + i * pszSrcName[i]) % 987651;
 
1512
        char  szIndexName[20];
 
1513
 
 
1514
        if( strlen(poFeatureDefn->GetName()) < 15 )
 
1515
            sprintf( szIndexName, "%s_idx", poFeatureDefn->GetName() );
 
1516
        else if( strlen(poFeatureDefn->GetName()) < 17 )
 
1517
            sprintf( szIndexName, "%si", poFeatureDefn->GetName() );
 
1518
        else
 
1519
        {
 
1520
            int i, nHash = 0;
 
1521
            const char *pszSrcName = poFeatureDefn->GetName();
 
1522
 
 
1523
            for( i = 0; pszSrcName[i] != '\0'; i++ )
 
1524
                nHash = (nHash + i * pszSrcName[i]) % 987651;
1356
1525
        
1357
 
        sprintf( szIndexName, "OSI_%d", nHash );
1358
 
    }
 
1526
            sprintf( szIndexName, "OSI_%d", nHash );
 
1527
        }
1359
1528
 
1360
 
    poDS->GetSession()->CleanName( szIndexName );
 
1529
        poDS->GetSession()->CleanName( szIndexName );
1361
1530
 
1362
1531
/* -------------------------------------------------------------------- */
1363
1532
/*      Try creating an index on the table now.  Use a simple 5         */
1364
1533
/*      level quadtree based index.  Would R-tree be a better default?  */
1365
1534
/* -------------------------------------------------------------------- */
1366
 
 
1367
 
// Disable for now, spatial index creation always seems to cause me to 
1368
 
// lose my connection to the database!
1369
 
    OGROCIStringBuf  sIndexCmd;
1370
 
 
1371
 
    sIndexCmd.Appendf( 10000, "CREATE INDEX \"%s\" ON %s(\"%s\") "
1372
 
                       "INDEXTYPE IS MDSYS.SPATIAL_INDEX ",
1373
 
                       szIndexName, 
1374
 
                       poFeatureDefn->GetName(), 
1375
 
                       pszGeomName );
1376
 
 
1377
 
    if( CSLFetchNameValue( papszOptions, "INDEX_PARAMETERS" ) != NULL )
1378
 
    {
1379
 
        sIndexCmd.Append( " PARAMETERS( '" );
1380
 
        sIndexCmd.Append( CSLFetchNameValue(papszOptions,"INDEX_PARAMETERS") );
1381
 
        sIndexCmd.Append( "' )" );
1382
 
    }
1383
 
 
1384
 
    if( oExecStatement.Execute( sIndexCmd.GetString() ) != CE_None )
1385
 
    {
1386
 
        char szDropCommand[2000];
1387
 
        sprintf( szDropCommand, "DROP INDEX \"%s\"", szIndexName );
1388
 
        oExecStatement.Execute( szDropCommand );
1389
 
    }
 
1535
        OGROCIStringBuf  sIndexCmd;
 
1536
        OGROCIStatement oExecStatement( poDS->GetSession() );
 
1537
    
 
1538
 
 
1539
        sIndexCmd.Appendf( 10000, "CREATE INDEX \"%s\" ON %s(\"%s\") "
 
1540
                           "INDEXTYPE IS MDSYS.SPATIAL_INDEX ",
 
1541
                           szIndexName, 
 
1542
                           poFeatureDefn->GetName(), 
 
1543
                           pszGeomName );
 
1544
 
 
1545
        if( CSLFetchNameValue( papszOptions, "INDEX_PARAMETERS" ) != NULL )
 
1546
        {
 
1547
            sIndexCmd.Append( " PARAMETERS( '" );
 
1548
            sIndexCmd.Append( CSLFetchNameValue(papszOptions,"INDEX_PARAMETERS") );
 
1549
            sIndexCmd.Append( "' )" );
 
1550
        }
 
1551
 
 
1552
        if( oExecStatement.Execute( sIndexCmd.GetString() ) != CE_None )
 
1553
        {
 
1554
            CPLString osDropCommand;
 
1555
            osDropCommand.Printf( "DROP INDEX \"%s\"", szIndexName );
 
1556
            oExecStatement.Execute( osDropCommand );
 
1557
        }
 
1558
    }  
1390
1559
}
1391
1560
 
1392
1561
/************************************************************************/
1393
 
/*                        AllocAndBindForWrite()                        */
 
1562
/*                   AllocAndBindForWrite(int eType)                    */
1394
1563
/************************************************************************/
1395
1564
 
1396
 
int OGROCITableLayer::AllocAndBindForWrite()
 
1565
/* -------------------------------------------------------------------- */
 
1566
/*      PJH: modified with geometry type parameter so as not to         */
 
1567
/*      attempt to write geometry if there is none to write as          */
 
1568
/*      Oracle will default the value of the column to Null.            */
 
1569
/* -------------------------------------------------------------------- */
 
1570
int OGROCITableLayer::AllocAndBindForWrite(int eType)
1397
1571
 
1398
1572
{
1399
1573
    OGROCISession      *poSession = poDS->GetSession();
1415
1589
    oCmdBuf.Append( "INSERT INTO " );
1416
1590
    oCmdBuf.Append( poFeatureDefn->GetName() );
1417
1591
 
 
1592
    if (eType == wkbNone)
 
1593
        oCmdBuf.Append( " VALUES ( :fid" );
 
1594
    else
 
1595
        oCmdBuf.Append( " VALUES ( :fid, :geometry" );
 
1596
 
1418
1597
    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
1419
1598
    {
1420
 
        if( i == 0 )
1421
 
            oCmdBuf.Append( " VALUES ( :fid, :geometry, " );
1422
 
        else
1423
 
            oCmdBuf.Append( ", " );
 
1599
        oCmdBuf.Append( ", " );
1424
1600
 
1425
1601
        oCmdBuf.Appendf( 20, " :field_%d", i );
1426
1602
    }
1436
1612
/* -------------------------------------------------------------------- */
1437
1613
/*      Setup geometry indicator information.                           */
1438
1614
/* -------------------------------------------------------------------- */
1439
 
    pasWriteGeomInd = (SDO_GEOMETRY_ind *) 
1440
 
        CPLCalloc(sizeof(SDO_GEOMETRY_ind),nWriteCacheMax);
 
1615
    if (eType != wkbNone)
 
1616
    {
 
1617
        pasWriteGeomInd = (SDO_GEOMETRY_ind *)
 
1618
            CPLCalloc(sizeof(SDO_GEOMETRY_ind),nWriteCacheMax);
1441
1619
    
1442
 
    papsWriteGeomIndMap = (SDO_GEOMETRY_ind **)
1443
 
        CPLCalloc(sizeof(SDO_GEOMETRY_ind *),nWriteCacheMax);
 
1620
        papsWriteGeomIndMap = (SDO_GEOMETRY_ind **)
 
1621
            CPLCalloc(sizeof(SDO_GEOMETRY_ind *),nWriteCacheMax);
1444
1622
 
1445
 
    for( i = 0; i < nWriteCacheMax; i++ )
1446
 
        papsWriteGeomIndMap[i] = pasWriteGeomInd + i;
 
1623
        for( i = 0; i < nWriteCacheMax; i++ )
 
1624
            papsWriteGeomIndMap[i] = pasWriteGeomInd + i;
1447
1625
 
1448
1626
/* -------------------------------------------------------------------- */
1449
1627
/*      Setup all the required geometry objects, and the                */
1450
1628
/*      corresponding indicator map.                                    */
1451
1629
/* -------------------------------------------------------------------- */
1452
 
    pasWriteGeoms = (SDO_GEOMETRY_TYPE *) 
1453
 
        CPLCalloc( sizeof(SDO_GEOMETRY_TYPE), nWriteCacheMax);
1454
 
    papsWriteGeomMap = (SDO_GEOMETRY_TYPE **)
1455
 
        CPLCalloc( sizeof(SDO_GEOMETRY_TYPE *), nWriteCacheMax );
 
1630
        pasWriteGeoms = (SDO_GEOMETRY_TYPE *)
 
1631
            CPLCalloc( sizeof(SDO_GEOMETRY_TYPE), nWriteCacheMax);
 
1632
        papsWriteGeomMap = (SDO_GEOMETRY_TYPE **)
 
1633
            CPLCalloc( sizeof(SDO_GEOMETRY_TYPE *), nWriteCacheMax );
1456
1634
 
1457
 
    for( i = 0; i < nWriteCacheMax; i++ )
1458
 
        papsWriteGeomMap[i] = pasWriteGeoms + i;
 
1635
        for( i = 0; i < nWriteCacheMax; i++ )
 
1636
            papsWriteGeomMap[i] = pasWriteGeoms + i;
1459
1637
 
1460
1638
/* -------------------------------------------------------------------- */
1461
1639
/*      Allocate VARRAYs for the elem_info and ordinates.               */
1462
1640
/* -------------------------------------------------------------------- */
1463
 
    for( i = 0; i < nWriteCacheMax; i++ )
1464
 
    {
1465
 
        if( poSession->Failed(
 
1641
        for( i = 0; i < nWriteCacheMax; i++ )
 
1642
        {
 
1643
            if( poSession->Failed(
1466
1644
                OCIObjectNew( poSession->hEnv, poSession->hError, 
1467
1645
                              poSession->hSvcCtx, OCI_TYPECODE_VARRAY,
1468
1646
                              poSession->hElemInfoTDO, (dvoid *)NULL, 
1470
1648
                              FALSE, 
1471
1649
                              (dvoid **) &(pasWriteGeoms[i].sdo_elem_info)),
1472
1650
                "OCIObjectNew(elem_info)") )
1473
 
            return FALSE;
 
1651
                return FALSE;
1474
1652
 
1475
 
        if( poSession->Failed(
 
1653
            if( poSession->Failed(
1476
1654
                OCIObjectNew( poSession->hEnv, poSession->hError, 
1477
1655
                              poSession->hSvcCtx, OCI_TYPECODE_VARRAY,
1478
1656
                              poSession->hOrdinatesTDO, (dvoid *)NULL, 
1480
1658
                              FALSE, 
1481
1659
                              (dvoid **) &(pasWriteGeoms[i].sdo_ordinates)),
1482
1660
                "OCIObjectNew(ordinates)") )
1483
 
            return FALSE;
1484
 
    }
 
1661
                return FALSE;
 
1662
        }
1485
1663
 
1486
1664
/* -------------------------------------------------------------------- */
1487
1665
/*      Bind the geometry column.                                       */
1488
1666
/* -------------------------------------------------------------------- */
1489
 
    if( poBoundStatement->BindObject( 
 
1667
        if( poBoundStatement->BindObject(
1490
1668
            ":geometry", papsWriteGeomMap, poSession->hGeometryTDO, 
1491
1669
            (void**) papsWriteGeomIndMap) != CE_None )
1492
 
        return FALSE;
 
1670
            return FALSE;
 
1671
    }
1493
1672
 
1494
1673
/* -------------------------------------------------------------------- */
1495
1674
/*      Bind the FID column.                                            */
1574
1753
 
1575
1754
    iCache = nWriteCacheUsed;
1576
1755
 
 
1756
/* -------------------------------------------------------------------- */
 
1757
/*  PJH: Initiate the Insert, passing the geometry type as there is no  */
 
1758
/*  need to give null geometry to Oracle                                */
 
1759
/* -------------------------------------------------------------------- */
1577
1760
    if( nWriteCacheMax == 0 )
1578
1761
    {
1579
 
        if( !AllocAndBindForWrite() )
 
1762
        int eType;
 
1763
        if( poFeature->GetGeometryRef() == NULL )
 
1764
        {
 
1765
            eType = wkbNone;
 
1766
        }
 
1767
        else
 
1768
        {
 
1769
            eType = 1; /* PJH: properly, this should be the gType from the geometry */
 
1770
                       /* but the actual value does not matter, so long as it is    */
 
1771
                       /* not wkbNone                                               */
 
1772
        }
 
1773
        if( !AllocAndBindForWrite(eType) )
1580
1774
            return OGRERR_FAILURE;
1581
1775
    }
1582
1776
 
1583
1777
/* -------------------------------------------------------------------- */
1584
1778
/*      Set the geometry                                                */
1585
1779
/* -------------------------------------------------------------------- */
1586
 
    if( poFeature->GetGeometryRef() == NULL )
1587
 
    {
1588
 
        pasWriteGeomInd[iCache]._atomic = OCI_IND_NULL;
1589
 
    }
1590
 
    else
 
1780
    if( poFeature->GetGeometryRef() != NULL )
1591
1781
    {
1592
1782
        SDO_GEOMETRY_TYPE *psGeom = pasWriteGeoms + iCache;
1593
1783
        SDO_GEOMETRY_ind  *psInd  = pasWriteGeomInd + iCache;
1709
1899
/*      Set the other fields.                                           */
1710
1900
/* -------------------------------------------------------------------- */
1711
1901
    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
1712
 
    {
 
1902
    { 
1713
1903
        if( !poFeature->IsFieldSet( i ) )
1714
1904
        {
1715
1905
            papaeWriteFieldInd[i][iCache] = OCI_IND_NULL;
1804
1994
OGRErr OGROCITableLayer::SyncToDisk()
1805
1995
 
1806
1996
{
1807
 
    return FlushPendingFeatures();
 
1997
    OGRErr eErr = FlushPendingFeatures();
 
1998
 
 
1999
    UpdateLayerExtents();
 
2000
 
 
2001
    return eErr;
1808
2002
}
1809
2003