diff --git a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java index f81ee0e..5cffea2 100644 --- a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java +++ b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java @@ -51,8 +51,8 @@ public class DepotMarshaller _tableName = _pclass.getName(); _tableName = _tableName.substring(_tableName.lastIndexOf(".")+1); - // introspect on the class and create field marshallers for all of its - // fields + // introspect on the class and create marshallers for persistent fields + ArrayList fields = new ArrayList(); for (Field field : _pclass.getFields()) { // the field must be public, non-static and non-transient int mods = field.getModifiers(); @@ -64,6 +64,7 @@ public class DepotMarshaller FieldMarshaller fm = FieldMarshaller.createMarshaller(field); _fields.put(fm.getColumnName(), fm); + fields.add(fm.getColumnName()); // check to see if this is our primary key if (field.getAnnotation(Id.class) != null) { @@ -72,12 +73,8 @@ public class DepotMarshaller } } - // generate our full list of columns for use in queries - _allFields = new String[_fields.size()]; - int idx = 0; - for (FieldMarshaller fm : _fields.values()) { - _allFields[idx++] = fm.getColumnName(); - } + // generate our full list of fields/columns for use in queries + _allFields = fields.toArray(new String[fields.size()]); _fullColumnList = StringUtil.join(_allFields, ","); } @@ -257,6 +254,46 @@ public class DepotMarshaller } } + /** + * Creates a statement that will update the specified set of fields for all + * persistent objects that match the supplied key. + */ + public PreparedStatement createPartialUpdate ( + Connection conn, DepotRepository.Key key, + String[] modifiedFields, Object[] modifiedValues) + throws SQLException + { + StringBuilder update = new StringBuilder(); + update.append("update ").append(getTableName()).append(" set "); + int idx = 0; + for (String field : modifiedFields) { + if (idx++ > 0) { + update.append(", "); + } + update.append(field).append(" = ?"); + } + update.append(" where ").append(key.toWhereClause()); + + try { + PreparedStatement pstmt = conn.prepareStatement(update.toString()); + idx = 0; + for (Object value : modifiedValues) { + // TODO: use the field marshaller? + pstmt.setObject(++idx, value); + } + return pstmt; + + } catch (SQLException sqe) { + // pass this on through + throw sqe; + + } catch (Exception e) { + String errmsg = "Failed to marshall persistent object " + + "[pclass=" + _pclass.getName() + "]"; + throw (SQLException)new SQLException(errmsg).initCause(e); + } + } + protected Class _pclass; protected HashMap _fields = new HashMap(); diff --git a/src/java/com/samskivert/jdbc/depot/DepotRepository.java b/src/java/com/samskivert/jdbc/depot/DepotRepository.java index 2abfa54..8e849e8 100644 --- a/src/java/com/samskivert/jdbc/depot/DepotRepository.java +++ b/src/java/com/samskivert/jdbc/depot/DepotRepository.java @@ -145,9 +145,23 @@ public class DepotRepository return 0; } - protected int update (Object record, String ... modifiedFields) + protected int update (final Object record, final String ... modifiedFields) throws PersistenceException { + final DepotMarshaller marsh = getMarshaller(record.getClass()); + invoke(new Modifier(marsh.getPrimaryKey(record)) { + public int invoke (Connection conn) + throws SQLException + { + PreparedStatement stmt = marsh.createUpdate( + conn, record, marsh.getPrimaryKey(record), modifiedFields); + try { + return stmt.executeUpdate(); + } finally { + stmt.close(); + } + } + }); return 0; }