Пример #1
0
OGRErr OGRIDBTableLayer::ISetFeature( OGRFeature *poFeature )
{
    OGRErr eErr(OGRERR_FAILURE);

    if ( ! bUpdateAccess )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Error update feature. Layer is read only." );
        return eErr;
    }

    if( NULL == poFeature )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "NULL pointer to OGRFeature passed to SetFeature()." );
        return eErr;
    }

    if( poFeature->GetFID() == OGRNullFID )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "FID required on features given to SetFeature()." );
        return eErr;
    }

    ITStatement oQuery( *poDS->GetConnection() );

    int bUpdateGeom = TRUE;
    OGRwkbGeometryType nGeomType = poFeature->GetGeometryRef()->getGeometryType();
    CPLString osGeomFunc;
    int nSrid = 0; // FIXME Obtain geometry SRID

    switch (nGeomType)
    {
        case wkbPoint:
            osGeomFunc = "ST_PointFromText";
            break;
        case wkbLineString:
            osGeomFunc = "ST_LineFromText";
            break;
        case wkbPolygon:
            osGeomFunc = "ST_PolyFromText";
            break;
        case wkbMultiPoint:
            osGeomFunc = "ST_MPointFromText";
            break;
        case wkbMultiLineString:
            osGeomFunc = "ST_MLineFromText";
            break;
        case wkbMultiPolygon:
            osGeomFunc = "ST_MPolyFromText";
            break;
        default:
            bUpdateGeom = FALSE;
            CPLDebug("OGR_IDB", "SetFeature(): Unknown geometry type. Geometry will not be updated.");
    }


    // Create query
    CPLString osSql;
    CPLString osFields;

    if ( pszGeomColumn && bUpdateGeom )
    {
        osFields.Printf( "%s = %s( ?, %d )", pszGeomColumn, osGeomFunc.c_str(), nSrid );
    }

    for( int i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        const char * pszFieldName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();

        // skip fid column from update
        if ( EQUAL( pszFIDColumn, pszFieldName ) )
            continue;

        if ( ! osFields.empty() )
        {
            osFields += ",";
        }

        osFields += pszFieldName;
        osFields += "=?";
    }

    osSql.Printf( "UPDATE %s SET %s WHERE %s = %d",
                  poFeatureDefn->GetName(),
                  osFields.c_str(),
                  pszFIDColumn,
                  poFeature->GetFID() );

    if ( ! oQuery.Prepare( osSql.c_str() ) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Error prepare SQL.\n%s",osSql.c_str() );
        return eErr;
    }

    int iParam = 0;

    if ( pszGeomColumn && bUpdateGeom )
    {
        ITValue * par = oQuery.Param( iParam ); // it should be a geom value
        if ( ! par )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Error prepare geom param");
            return eErr;
        }

        OGRGeometry * poGeom = poFeature->GetGeometryRef();
        char * wkt;
        poGeom->exportToWkt( &wkt );

        if( ! par->FromPrintable( wkt ) )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Error prepare geom param");
            par->Release();
            return eErr;
        }

        CPLFree( wkt );
        par->Release();

        iParam++;
    }

    for ( int i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        ITValue * par = oQuery.Param( iParam );
        if ( ! par )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Error prepare param %d", iParam);
            return eErr;
        }

        if ( ! poFeature->IsFieldSet( i ) )
        {
            if ( ! par->SetNull() )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                        "Error set param %d to NULL", iParam);
                par->Release();
                return eErr;
            }
            par->Release();
            continue;
        }

        ITConversions * cv = 0;
        bool res = FALSE;

        if ( par->QueryInterface( ITConversionsIID, (void **) &cv) !=
             IT_QUERYINTERFACE_SUCCESS )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "Error prepare param %d", iParam);
            par->Release();
            return eErr;
        }

        switch ( poFeatureDefn->GetFieldDefn( i )->GetType() )
        {
            case OFTInteger:
                res = cv->ConvertFrom( poFeature->GetFieldAsInteger( i ) );
                break;

            case OFTReal:
                res = cv->ConvertFrom( poFeature->GetFieldAsDouble( i ) );
                break;

            case OFTIntegerList:
            case OFTRealList:
            case OFTStringList:
                // FIXME Prepare array of values field
                //cv->ConvertFrom( poFeature->GetFieldAsStringList( i ) );
                //break;

            case OFTBinary:
                // FIXME Prepare binary field

            case OFTString:
            case OFTDate:
            case OFTTime:
            case OFTDateTime:
                res = cv->ConvertFrom( poFeature->GetFieldAsString( i ) );
                break;
            default:
                CPLError( CE_Failure, CPLE_AppDefined,
                        "Error prepare param %d. Unknown data type.", iParam);
                cv->Release();
                par->Release();
                return eErr;
        }
        if ( res != TRUE )
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Error prepare param.");
        cv->Release();
        par->Release();
    }

    CPLDebug( "OGR_IDB", "ExecuteSQL(%s)", oQuery.QueryText().Data() );
    if( !oQuery.Exec() )
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Error update Feature.");
        return eErr;
    }

    return OGRERR_NONE;
}
Пример #2
0
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;
}
Пример #3
0
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;
}