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

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

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

    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "FID ignored on feature given to CreateFeature(). Unknown FID column." );
        return eErr;
    }

    int bUpdateGeom = TRUE;
    CPLString osGeomFunc;

    if ( poFeature->GetGeometryRef() )
    {
        OGRwkbGeometryType nGeomType = poFeature->GetGeometryRef()->getGeometryType();

        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.");
        }
    }
    else
        bUpdateGeom = FALSE;

    // Create query
    CPLString osSql;
    CPLString osFields;
    CPLString osValues;

    if ( pszGeomColumn && bUpdateGeom )
    {
        OGRGeometry * poGeom = poFeature->GetGeometryRef();
        char * wkt;
        poGeom->exportToWkt( &wkt );

        osFields += pszGeomColumn;
        osValues.Printf( "%s( '%s', %d )", osGeomFunc.c_str(), wkt, nSRSId );

        CPLFree( wkt );
    }

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

        // Skip NULL fields
        if ( ! poFeature->IsFieldSet( i ) )
        {
            continue;
        }

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

        osFields += pszFieldName;

        CPLString osVal;

        switch ( poFeatureDefn->GetFieldDefn( i )->GetType() )
        {
            case OFTInteger:
                osVal.Printf( "%d", poFeature->GetFieldAsInteger( i ) );
                break;

            case OFTReal:
                if ( poFeatureDefn->GetFieldDefn( i )->GetPrecision() )
                {
                    // have a decimal format width.precision
                    CPLString osFormatString;
                    osFormatString.Printf( "%%%d.%df",
                                           poFeatureDefn->GetFieldDefn( i )->GetWidth(),
                                           poFeatureDefn->GetFieldDefn( i )->GetPrecision() );
                    osVal.Printf( osFormatString.c_str(), poFeature->GetFieldAsDouble( i ) );
                }
                else
                    osVal.Printf( "%f", 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:
            default:
                osVal.Printf( "'%s'", poFeature->GetFieldAsString( i ) );
                break;
        }
        osValues += osVal;
    }

    osSql.Printf( "INSERT INTO %s (%s) VALUES (%s)",
                  poFeatureDefn->GetName(),
                  osFields.c_str(),
                  osValues.c_str() );

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

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

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

    ITQuery oFidQuery( *poDS->GetConnection() );
    osSql.Printf( "SELECT MAX(%s) from %s", pszFIDColumn, poFeatureDefn->GetName() );

    CPLDebug( "OGR_IDB", "Exec(%s)", osSql.c_str() );

    ITRow * row = oFidQuery.ExecOneRow( osSql.c_str() );
    if( ! row || row->NumColumns() < 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Error create Feature.");
        return eErr;
    }

    int fid = atoi( row->Column(0)->Printable() );

    if ( fid > 0 )
        poFeature->SetFID( fid );
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Error create Feature. Unable to get new fid" );
        return eErr;
    }

    return OGRERR_NONE;
}