package divconq.db.proc; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import divconq.db.TablesAdapter; import divconq.db.DatabaseInterface; import divconq.db.DatabaseTask; import divconq.db.IStoredProc; import divconq.lang.BigDateTime; import divconq.lang.op.OperationResult; import divconq.struct.ListStruct; import divconq.struct.RecordStruct; import divconq.struct.Struct; public class UpdateSet implements IStoredProc { @Override public void execute(DatabaseInterface conn, DatabaseTask task, OperationResult log) { RecordStruct params = task.getParamsAsRecord(); String table = params.getFieldAsString("Table"); String field = params.getFieldAsString("Field"); String op = params.getFieldAsString("Operation"); ListStruct records = params.getFieldAsList("Records"); ListStruct subids = params.getFieldAsList("Values"); TablesAdapter db = new TablesAdapter(conn, task); BigDateTime when = BigDateTime.nowDateTime(); // TODO store in params for replication - use same when for (Struct ssid : records.getItems()) { String id = ssid.toString(); // make a copy List<String> lsubids = subids.toStringList(); List<String> othersubids = new ArrayList<>(); db.traverseSubIds(table, id, field, when, false, new Consumer<Object>() { @Override public void accept(Object msub) { String suid = msub.toString(); boolean fnd = lsubids.remove(suid); if (!fnd) othersubids.add(suid); if ("RemoveFromSet".equals(op) && fnd) { // if present in our list then retire it db.setFields(table, id, new RecordStruct() .withField(field, new RecordStruct() .withField(suid, new RecordStruct() .withField("Retired", true) ) ) ); } } }); // Make negates non matches, so retire those if ("MakeSet".equals(op)) { for (String suid : othersubids) { // if present in our list then retire it db.setFields(table, id, new RecordStruct() .withField(field, new RecordStruct() .withField(suid, new RecordStruct() .withField("Retired", true) ) ) ); } } // Make and Add will add any remaining - unmatched - suids if ("MakeSet".equals(op) || "AddToSet".equals(op)) { for (String suid : lsubids) { // if present in our list then retire it db.setFields(table, id, new RecordStruct() .withField(field, new RecordStruct() .withField(suid, new RecordStruct() .withField("Data", suid) ) ) ); } } // TODO make a record of everything for replication? or just let it figure it out? } task.complete(); } }