private List<String> performUpdateRelational(
      QName ftName, List<ParsedPropertyReplacement> replacementProps, IdFilter filter)
      throws FeatureStoreException, FilterEvaluationException {

    FeatureTypeMapping ftMapping = schema.getFtMapping(ftName);
    FIDMapping fidMapping = ftMapping.getFidMapping();

    int updated = 0;
    PreparedStatement stmt = null;
    try {
      String sql =
          createRelationalUpdateStatement(
              ftMapping, fidMapping, replacementProps, filter.getSelectedIds());

      if (sql != null) {
        LOG.debug("Update: " + sql);
        stmt = conn.prepareStatement(sql.toString());
        setRelationalUpdateValues(replacementProps, ftMapping, stmt, filter, fidMapping);
        int[] updates = stmt.executeBatch();
        for (int noUpdated : updates) {
          updated += noUpdated;
        }
      }
    } catch (SQLException e) {
      JDBCUtils.log(e, LOG);
      throw new FeatureStoreException(JDBCUtils.getMessage(e), e);
    } finally {
      JDBCUtils.close(stmt);
    }
    LOG.debug("Updated {} features.", updated);
    return new ArrayList<String>(filter.getMatchingIds());
  }
 private List<String> performUpdateRelational(
     QName ftName, List<ParsedPropertyReplacement> replacementProps, Filter filter)
     throws FeatureStoreException {
   IdFilter idFilter = null;
   try {
     if (filter instanceof IdFilter) {
       idFilter = (IdFilter) filter;
     } else {
       idFilter = getIdFilter(ftName, (OperatorFilter) filter);
     }
   } catch (Exception e) {
     LOG.debug(e.getMessage(), e);
   }
   List<String> updated = null;
   if (blobMapping != null) {
     throw new FeatureStoreException(
         "Updates in SQLFeatureStore (BLOB mode) are currently not implemented.");
   } else {
     try {
       updated = performUpdateRelational(ftName, replacementProps, idFilter);
       if (fs.getCache() != null) {
         for (ResourceId id : idFilter.getSelectedIds()) {
           fs.getCache().remove(id.getRid());
         }
       }
     } catch (Exception e) {
       LOG.debug(e.getMessage(), e);
       throw new FeatureStoreException(e.getMessage(), e);
     }
   }
   return updated;
 }
 private int performDeleteBlob(IdFilter filter, Lock lock) throws FeatureStoreException {
   int deleted = 0;
   PreparedStatement stmt = null;
   try {
     stmt =
         conn.prepareStatement(
             "DELETE FROM "
                 + blobMapping.getTable()
                 + " WHERE "
                 + blobMapping.getGMLIdColumn()
                 + "=?");
     for (ResourceId id : filter.getSelectedIds()) {
       stmt.setString(1, id.getRid());
       stmt.addBatch();
       if (fs.getCache() != null) {
         fs.getCache().remove(id.getRid());
       }
     }
     int[] deletes = stmt.executeBatch();
     for (int noDeleted : deletes) {
       deleted += noDeleted;
     }
   } catch (SQLException e) {
     LOG.debug(e.getMessage(), e);
     throw new FeatureStoreException(e.getMessage(), e);
   } finally {
     JDBCUtils.close(stmt);
   }
   LOG.debug("Deleted " + deleted + " features.");
   return deleted;
 }
  private void setRelationalUpdateValues(
      List<ParsedPropertyReplacement> replacementProps,
      FeatureTypeMapping ftMapping,
      PreparedStatement stmt,
      IdFilter filter,
      FIDMapping fidMapping)
      throws SQLException {
    int i = 1;

    for (ParsedPropertyReplacement replacement : replacementProps) {
      Property replacementProp = replacement.getNewValue();
      QName propName = replacementProp.getType().getName();
      Mapping mapping = ftMapping.getMapping(propName);
      if (mapping != null) {
        if (mapping.getJoinedTable() != null && !mapping.getJoinedTable().isEmpty()) {
          continue;
        }

        Object value = replacementProp.getValue();
        if (value != null) {
          ParticleConverter<TypedObjectNode> converter =
              (ParticleConverter<TypedObjectNode>) fs.getConverter(mapping);
          if (mapping instanceof PrimitiveMapping) {
            MappingExpression me = ((PrimitiveMapping) mapping).getMapping();
            if (!(me instanceof DBField)) {
              continue;
            }
            converter.setParticle(stmt, (PrimitiveValue) value, i++);
          } else if (mapping instanceof GeometryMapping) {
            MappingExpression me = ((GeometryMapping) mapping).getMapping();
            if (!(me instanceof DBField)) {
              continue;
            }
            converter.setParticle(stmt, (Geometry) value, i++);
          }
        } else {
          stmt.setObject(i++, null);
        }
      }
    }

    for (String id : filter.getMatchingIds()) {
      IdAnalysis analysis = schema.analyzeId(id);
      int j = i;
      for (String fidKernel : analysis.getIdKernels()) {
        PrimitiveValue value =
            new PrimitiveValue(fidKernel, new PrimitiveType(fidMapping.getColumnType()));
        Object sqlValue = SQLValueMangler.internalToSQL(value);
        stmt.setObject(j++, sqlValue);
      }
      stmt.addBatch();
    }
  }
  private int performDeleteRelational(IdFilter filter, Lock lock) throws FeatureStoreException {

    int deleted = 0;
    for (ResourceId id : filter.getSelectedIds()) {
      LOG.debug("Analyzing id: " + id.getRid());
      IdAnalysis analysis = null;
      try {
        analysis = schema.analyzeId(id.getRid());
        LOG.debug("Analysis: " + analysis);
        if (!schema.getKeyDependencies().getDeleteCascadingByDB()) {
          LOG.debug("Deleting joined rows manually.");
          deleteJoinedRows(analysis);
        } else {
          LOG.debug("Depending on database to delete joined rows automatically.");
        }
        deleted += deleteFeatureRow(analysis);
      } catch (IllegalArgumentException e) {
        throw new FeatureStoreException("Unable to determine feature type for id '" + id + "'.");
      }
    }
    return deleted;
  }