コード例 #1
0
ファイル: ogridbtablelayer.cpp プロジェクト: Wedjaa/node-gdal
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;
}