use of edu.umass.cs.gnsserver.database.ColumnField in project GNS by MobilityFirst.
the class NameRecord method updateNameRecord.
/**
* Updates the value of the field associated with the key.
*
* @param recordKey
* @param newValues
* @param oldValues
* @param argument
* @param operation
* @param userJSON
* @return True if the updateEntireValuesMap does anything, false otherwise.
* @throws edu.umass.cs.gnscommon.exceptions.server.FieldNotFoundException
* @throws edu.umass.cs.gnscommon.exceptions.server.FailedDBOperationException
*/
public boolean updateNameRecord(String recordKey, ResultValue newValues, ResultValue oldValues, int argument, ValuesMap userJSON, UpdateOperation operation) throws FieldNotFoundException, FailedDBOperationException {
// whose purpose is to remove the field with name = key from values map.
if (operation.equals(UpdateOperation.SINGLE_FIELD_REMOVE_FIELD)) {
ArrayList<ColumnField> keys = new ArrayList<>();
keys.add(new ColumnField(recordKey, ColumnFieldType.LIST_STRING));
GNSConfig.getLogger().log(Level.FINE, "<============>REMOVE {0} from {1}<============>", new Object[] { recordKey, getName() });
recordMap.removeMapKeys(getName(), VALUES_MAP, keys);
return true;
}
/*
* Some updateEntireValuesMap operations require that record is first read from DB, modified, and then written.
* That is 1 DB read + 1 DB write. Others do not require record to be read, but we can directly do a write.
* This saves us a database read.
*
* To implement this, we changed both ClientRequestWorker.updateAdddressNS and NameRecord.updateNameRecord.
* There could be other operations like SINGLE_FIELD_REPLACE_ALL which could proceed without DB read,
* and should be handled similar to SINGLE_FIELD_REPLACE_ALL. In my experiments, I was using SINGLE_FIELD_REPLACE_ALL so I have
* included it as a special case for it.
*/
ValuesMap valuesMap;
if (operation.isAbleToSkipRead()) {
valuesMap = new ValuesMap();
hashMap.put(VALUES_MAP, valuesMap);
} else {
// this will throw an exception if field is not read.
valuesMap = getValuesMap();
}
// FIXME: might want to handle this without a special case at some point
boolean updated = UpdateOperation.USER_JSON_REPLACE.equals(operation) || UpdateOperation.USER_JSON_REPLACE_OR_CREATE.equals(operation) ? true : UpdateOperation.updateValuesMap(valuesMap, recordKey, newValues, oldValues, argument, userJSON, operation);
if (updated) {
// commit updateEntireValuesMap to database
ArrayList<ColumnField> updatedFields = new ArrayList<>();
ArrayList<Object> updatedValues = new ArrayList<>();
if (userJSON != null) {
// full userJSON (new style) updateEntireValuesMap
Iterator<?> keyIter = userJSON.keys();
while (keyIter.hasNext()) {
String key = (String) keyIter.next();
try {
updatedFields.add(new ColumnField(key, ColumnFieldType.USER_JSON));
updatedValues.add(userJSON.get(key));
} catch (JSONException e) {
GNSConfig.getLogger().log(Level.SEVERE, "Unable to get {0} from userJSON:{1}", new Object[] { key, e });
}
}
} else {
// single field updateEntireValuesMap
updatedFields.add(new ColumnField(recordKey, ColumnFieldType.LIST_STRING));
updatedValues.add(valuesMap.getAsArray(recordKey));
}
recordMap.updateIndividualFields(getName(), updatedFields, updatedValues);
}
return updated;
}
Aggregations