CPLErr OGRIDBTableLayer::Initialize( const char *pszTableName, const char *pszGeomCol, int bUpdate ) { bUpdateAccess = bUpdate; ITConnection *poConn = poDS->GetConnection(); if ( pszFIDColumn ) { CPLFree( pszFIDColumn ); pszFIDColumn = NULL; } /* -------------------------------------------------------------------- */ /* Do we have a simple primary key? */ /* -------------------------------------------------------------------- */ if ( pszFIDColumn == NULL ) { ITCursor oGetKey( *poConn ); CPLString osSql = " select sc.colname" " from syscolumns sc, sysindexes si, systables st" " where st.tabid = si.tabid" " and st.tabid = sc.tabid" " and si.idxtype = 'U'" " and sc.colno = si.part1" " and si.part2 = 0" // only one-column keys " and st.tabname='"; osSql += pszTableName; osSql += "'"; if( oGetKey.Prepare( osSql.c_str() ) && oGetKey.Open(ITCursor::ReadOnly) ) { ITValue * poVal = oGetKey.Fetch(); if ( poVal && poVal->IsNull() == false ) { pszFIDColumn = CPLStrdup(poVal->Printable()); poVal->Release(); } if( oGetKey.Fetch() ) // more than one field in key! { CPLFree( pszFIDColumn ); pszFIDColumn = NULL; CPLDebug("OGR_IDB", "Table %s has multiple primary key fields," " ignoring them all.", pszTableName ); } } } /* -------------------------------------------------------------------- */ /* Have we been provided a geometry column? */ /* -------------------------------------------------------------------- */ CPLFree( pszGeomColumn ); if( pszGeomCol == NULL ) pszGeomColumn = NULL; else pszGeomColumn = CPLStrdup( pszGeomCol ); /* -------------------------------------------------------------------- */ /* Get the column definitions for this table. */ /* -------------------------------------------------------------------- */ ITCursor oGetCol( *poConn ); CPLErr eErr; CPLString sql; sql.Printf( "select * from %s where 1=0", pszTableName ); if( ! oGetCol.Prepare( sql.c_str() ) || ! oGetCol.Open(ITCursor::ReadOnly) ) return CE_Failure; eErr = BuildFeatureDefn( pszTableName, &oGetCol ); if( eErr != CE_None ) return eErr; if( poFeatureDefn->GetFieldCount() == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "No column definitions found for table '%s', layer not usable.", pszTableName ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Do we have XMIN, YMIN, XMAX, YMAX extent fields? */ /* -------------------------------------------------------------------- */ if( poFeatureDefn->GetFieldIndex( "XMIN" ) != -1 && poFeatureDefn->GetFieldIndex( "XMAX" ) != -1 && poFeatureDefn->GetFieldIndex( "YMIN" ) != -1 && poFeatureDefn->GetFieldIndex( "YMAX" ) != -1 ) { bHaveSpatialExtents = TRUE; CPLDebug( "OGR_IDB", "Table %s has geometry extent fields.", pszTableName ); } /* -------------------------------------------------------------------- */ /* If we got a geometry column, does it exist? Is it binary? */ /* -------------------------------------------------------------------- */ if( pszGeomColumn != NULL ) { int iColumn = oGetCol.RowType()->ColumnId( pszGeomColumn ); if( iColumn < 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Column %s requested for geometry, but it does not exist.", pszGeomColumn ); CPLFree( pszGeomColumn ); pszGeomColumn = NULL; } bGeomColumnWKB = TRUE; /*else { if( ITCursor::GetTypeMapping( oGetCol.GetColType( iColumn )) == SQL_C_BINARY ) bGeomColumnWKB = TRUE; }*/ } return CE_None; }
OGRFeature *OGRIDBLayer::GetNextRawFeature() { if( GetQuery() == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* If we are marked to restart then do so, and fetch a record. */ /* -------------------------------------------------------------------- */ ITRow * row = poCurr->NextRow(); if ( ! row ) { delete poCurr; poCurr = NULL; return NULL; } iNextShapeId++; m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Create a feature from the current result. */ /* -------------------------------------------------------------------- */ int iField; OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); const ITTypeInfo * poRowType = poCurr->RowType(); int nFieldCount = poRowType->ColumnCount(); for ( iField = 0; iField < nFieldCount; iField++ ) { /* -------------------------------------------------------------------- */ /* Handle FID column */ /* -------------------------------------------------------------------- */ if ( pszFIDColumn != NULL && EQUAL( poRowType->ColumnName( iField ), pszFIDColumn ) ) poFeature->SetFID( atoi( row->Column( iField )->Printable() ) ); /* -------------------------------------------------------------------- */ /* Handle geometry */ /* -------------------------------------------------------------------- */ if( pszGeomColumn != NULL && EQUAL( poRowType->ColumnName( iField ), pszGeomColumn ) ) { OGRGeometry *poGeom = NULL; OGRErr eErr = OGRERR_NONE; ITValue * v = row->Column( iField ); if( ! v->IsNull() && ! bGeomColumnWKB ) { const char *pszGeomText = v->Printable(); if ( pszGeomText != NULL ) eErr = OGRGeometryFactory::createFromWkt((char **) &pszGeomText, poSRS, &poGeom); } else if( ! v->IsNull() && bGeomColumnWKB ) { ITDatum *rv = 0; if ( v->QueryInterface( ITDatumIID, (void **) &rv ) == IT_QUERYINTERFACE_SUCCESS ) { int nLength = rv->DataLength(); unsigned char * wkb = (unsigned char *)rv->Data(); eErr = OGRGeometryFactory::createFromWkb( wkb, poSRS, &poGeom, nLength); rv->Release(); } } v->Release(); if ( eErr != OGRERR_NONE ) { const char *pszMessage; switch ( eErr ) { case OGRERR_NOT_ENOUGH_DATA: pszMessage = "Not enough data to deserialize"; break; case OGRERR_UNSUPPORTED_GEOMETRY_TYPE: pszMessage = "Unsupported geometry type"; break; case OGRERR_CORRUPT_DATA: pszMessage = "Corrupt data"; default: pszMessage = "Unrecognized error"; } CPLError(CE_Failure, CPLE_AppDefined, "GetNextRawFeature(): %s", pszMessage); } if( poGeom != NULL ) { poFeature->SetGeometryDirectly( poGeom ); } continue; } /* -------------------------------------------------------------------- */ /* Transfer regular data fields. */ /* -------------------------------------------------------------------- */ int iOGRField = poFeatureDefn->GetFieldIndex( poRowType->ColumnName( iField ) ); if( iOGRField < 0 ) continue; const char * pszColData = row->Column( iField )->Printable(); if( ! pszColData ) continue; if( poFeatureDefn->GetFieldDefn(iOGRField)->GetType() == OFTBinary ) poFeature->SetField( iOGRField, poRowType->ColumnType( iField )->Size(), (GByte *) pszColData ); else poFeature->SetField( iOGRField, pszColData ); } row->Release(); return poFeature; }