OGRErr OGRMSSQLSpatialTableLayer::SetFeature( OGRFeature *poFeature )

{
    OGRErr              eErr = OGRERR_FAILURE;

    GetLayerDefn();

    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;
    }

    if( !pszFIDColumn )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unable to update features in tables without\n"
                  "a recognised FID column.");
        return eErr;

    }
    
    ClearStatement();

/* -------------------------------------------------------------------- */
/*      Form the UPDATE command.                                        */
/* -------------------------------------------------------------------- */
    CPLODBCStatement oStmt( poDS->GetSession() );
            
    oStmt.Appendf( "UPDATE [%s].[%s] SET ", pszSchemaName, pszTableName);

    OGRMSSQLGeometryValidator oValidator(poFeature->GetGeometryRef());
    OGRGeometry *poGeom = oValidator.GetValidGeometryRef();

    if (poFeature->GetGeometryRef() != poGeom)
    {
        CPLError( CE_Warning, CPLE_NotSupported,
                  "Geometry with FID = %ld has been modified.", poFeature->GetFID() );
    }

    int bNeedComma = FALSE;
    if(pszGeomColumn != NULL)
    {
        char    *pszWKT = NULL;

        if (poGeom != NULL)
            poGeom->exportToWkt( &pszWKT );

        oStmt.Appendf( "[%s] = ", pszGeomColumn );

        if( pszWKT != NULL && (nGeomColumnType == MSSQLCOLTYPE_GEOMETRY 
            || nGeomColumnType == MSSQLCOLTYPE_GEOGRAPHY))
        {
            if (nGeomColumnType == MSSQLCOLTYPE_GEOGRAPHY)
            {
                oStmt.Append( "geography::STGeomFromText(" );
                OGRMSSQLAppendEscaped(&oStmt, pszWKT);
                oStmt.Appendf(",%d)", nSRSId );
            }
            else
            {
                oStmt.Append( "geometry::STGeomFromText(" );
                OGRMSSQLAppendEscaped(&oStmt, pszWKT);
                oStmt.Appendf(",%d).MakeValid()", nSRSId );
            }
        }
        else
            oStmt.Append( "null" );

        bNeedComma = TRUE;
        CPLFree(pszWKT);
    }

    int nFieldCount = poFeatureDefn->GetFieldCount();
    int i;
    for( i = 0; i < nFieldCount; i++ )
    {
        if (bNeedComma)
            oStmt.Appendf( ", [%s] = ", poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
        else
        {
            oStmt.Appendf( "[%s] = ", poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
            bNeedComma = TRUE;
        }

        if( !poFeature->IsFieldSet( i ) )
            oStmt.Append( "null" );
        else
            AppendFieldValue(&oStmt, poFeature, i);
    }

    /* Add the WHERE clause */
    oStmt.Appendf( " WHERE [%s] = %ld" , pszFIDColumn, poFeature->GetFID());

/* -------------------------------------------------------------------- */
/*      Execute the update.                                             */
/* -------------------------------------------------------------------- */

    if( !oStmt.ExecuteSQL() )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
            "Error updating feature with FID:%ld, %s", poFeature->GetFID(), 
                    poDS->GetSession()->GetLastError() );

        return OGRERR_FAILURE;
    }
    
    return OGRERR_NONE;
}
OGRErr OGRMSSQLSpatialTableLayer::CreateFeature( OGRFeature *poFeature )

{
    GetLayerDefn();

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

    CPLODBCStatement oStatement( poDS->GetSession() );

    /* the fid values are retieved from the source layer */
    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
        oStatement.Appendf("SET IDENTITY_INSERT [%s].[%s] ON;", pszSchemaName, pszTableName );

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */

    oStatement.Appendf( "INSERT INTO [%s].[%s] (", pszSchemaName, pszTableName );

    OGRMSSQLGeometryValidator oValidator(poFeature->GetGeometryRef());
    OGRGeometry *poGeom = oValidator.GetValidGeometryRef();

    if (poFeature->GetGeometryRef() != poGeom)
    {
        CPLError( CE_Warning, CPLE_NotSupported,
                  "Geometry with FID = %ld has been modified.", poFeature->GetFID() );
    }

    int bNeedComma = FALSE;

    if (poGeom != NULL && pszGeomColumn != NULL)
    {
        oStatement.Append( pszGeomColumn );
        bNeedComma = TRUE;
    }

    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
    {
        if (bNeedComma)
            oStatement.Appendf( ", [%s]", pszFIDColumn );
        else
        {
            oStatement.Appendf( "[%s]", pszFIDColumn );
            bNeedComma = TRUE;
        }
    }

    int nFieldCount = poFeatureDefn->GetFieldCount();
    int i;
    for( i = 0; i < nFieldCount; i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if (bNeedComma)
            oStatement.Appendf( ", [%s]", poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
        else
        {
            oStatement.Appendf( "[%s]", poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
            bNeedComma = TRUE;
        }
    }

    oStatement.Appendf( ") VALUES (" );

    /* Set the geometry */
    bNeedComma = FALSE;
    if(poGeom != NULL && pszGeomColumn != NULL)
    {
        char    *pszWKT = NULL;
    
        //poGeom->setCoordinateDimension( nCoordDimension );

        poGeom->exportToWkt( &pszWKT );

        if( pszWKT != NULL && (nGeomColumnType == MSSQLCOLTYPE_GEOMETRY 
            || nGeomColumnType == MSSQLCOLTYPE_GEOGRAPHY))
        {
            if (nGeomColumnType == MSSQLCOLTYPE_GEOGRAPHY)
            {
                oStatement.Append( "geography::STGeomFromText(" );
                OGRMSSQLAppendEscaped(&oStatement, pszWKT);
                oStatement.Appendf(",%d)", nSRSId );
            }
            else
            {
                oStatement.Append( "geometry::STGeomFromText(" );
                OGRMSSQLAppendEscaped(&oStatement, pszWKT);
                oStatement.Appendf(",%d).MakeValid()", nSRSId );
            }     
        }
        else
            oStatement.Append( "null" );

        bNeedComma = TRUE;
        CPLFree(pszWKT);
    }

    /* Set the FID */
    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
    {
        if (bNeedComma)
            oStatement.Appendf( ", %ld", poFeature->GetFID() );
        else
        {
            oStatement.Appendf( "%ld", poFeature->GetFID() );
            bNeedComma = TRUE;
        }
    }

    for( i = 0; i < nFieldCount; i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if (bNeedComma)
            oStatement.Append( ", " );
        else
            bNeedComma = TRUE;

        AppendFieldValue(&oStatement, poFeature, i);
    }

    oStatement.Append( ");" );

    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
        oStatement.Appendf("SET IDENTITY_INSERT [%s].[%s] OFF;", pszSchemaName, pszTableName );

/* -------------------------------------------------------------------- */
/*      Execute the insert.                                             */
/* -------------------------------------------------------------------- */
    
    if( !oStatement.ExecuteSQL() )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "INSERT command for new feature failed. %s", 
                   poDS->GetSession()->GetLastError() );

        return OGRERR_FAILURE;
    }

    return OGRERR_NONE;
}
OGRErr OGRPGDumpLayer::CreateFeatureViaInsert( OGRFeature *poFeature )

{
    CPLString           osCommand;
    int                 i = 0;
    int                 bNeedComma = FALSE;
    OGRErr              eErr = OGRERR_FAILURE;
    int bEmptyInsert = FALSE;

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

    /* -------------------------------------------------------------------- */
    /*      Form the INSERT command.                                        */
    /* -------------------------------------------------------------------- */
    osCommand.Printf( "INSERT INTO %s (", pszSqlTableName );

    for(i = 0; i < poFeatureDefn->GetGeomFieldCount(); i++ )
    {
        OGRGeometry *poGeom = poFeature->GetGeomFieldRef(i);
        if( poGeom != NULL )
        {
            if( bNeedComma )
                osCommand += ", ";

            OGRGeomFieldDefn* poGFldDefn = poFeature->GetGeomFieldDefnRef(i);
            osCommand = osCommand + OGRPGDumpEscapeColumnName(poGFldDefn->GetNameRef()) + " ";
            bNeedComma = TRUE;
        }
    }

    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
    {
        if( bNeedComma )
            osCommand += ", ";

        osCommand = osCommand + OGRPGDumpEscapeColumnName(pszFIDColumn) + " ";
        bNeedComma = TRUE;
    }

    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( !bNeedComma )
            bNeedComma = TRUE;
        else
            osCommand += ", ";

        osCommand = osCommand
                    + OGRPGDumpEscapeColumnName(poFeatureDefn->GetFieldDefn(i)->GetNameRef());
    }

    if (!bNeedComma)
        bEmptyInsert = TRUE;

    osCommand += ") VALUES (";

    /* Set the geometry */
    bNeedComma = FALSE;
    for(i = 0; i < poFeatureDefn->GetGeomFieldCount(); i++ )
    {
        OGRGeometry *poGeom = poFeature->GetGeomFieldRef(i);
        if( poGeom != NULL )
        {
            char    *pszWKT = NULL;

            OGRPGDumpGeomFieldDefn* poGFldDefn =
                (OGRPGDumpGeomFieldDefn*) poFeature->GetGeomFieldDefnRef(i);

            poGeom->closeRings();
            poGeom->setCoordinateDimension( poGFldDefn->nCoordDimension );

            if( bNeedComma )
                osCommand += ", ";

            if( bWriteAsHex )
            {
                char* pszHex = OGRGeometryToHexEWKB( poGeom, poGFldDefn->nSRSId );
                osCommand += "'";
                if (pszHex)
                    osCommand += pszHex;
                osCommand += "'";
                CPLFree(pszHex);
            }
            else
            {
                poGeom->exportToWkt( &pszWKT );

                if( pszWKT != NULL )
                {
                    osCommand +=
                        CPLString().Printf(
                            "GeomFromEWKT('SRID=%d;%s'::TEXT) ", poGFldDefn->nSRSId, pszWKT );
                    OGRFree( pszWKT );
                }
                else
                    osCommand += "''";
            }

            bNeedComma = TRUE;
        }
    }

    /* Set the FID */
    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
    {
        if( bNeedComma )
            osCommand += ", ";
        osCommand += CPLString().Printf( "%ld ", poFeature->GetFID() );
        bNeedComma = TRUE;
    }


    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( bNeedComma )
            osCommand += ", ";
        else
            bNeedComma = TRUE;

        AppendFieldValue(osCommand, poFeature, i);
    }

    osCommand += ")";

    if (bEmptyInsert)
        osCommand.Printf( "INSERT INTO %s DEFAULT VALUES", pszSqlTableName );

    /* -------------------------------------------------------------------- */
    /*      Execute the insert.                                             */
    /* -------------------------------------------------------------------- */
    poDS->Log(osCommand);

    return OGRERR_NONE;
}