Factor out the canonical order generation as we'll still need this for the
static newKey() methods even if we revamp this whole business.
This commit is contained in:
@@ -128,50 +128,7 @@ public class Key<T extends PersistentRecord> extends WhereClause
|
|||||||
*/
|
*/
|
||||||
public Key (Class<T> pClass, ColumnExp[] fields, Comparable<?>[] values)
|
public Key (Class<T> pClass, ColumnExp[] fields, Comparable<?>[] values)
|
||||||
{
|
{
|
||||||
if (fields.length != values.length) {
|
this(pClass, toCanonicalOrder(pClass, fields, values));
|
||||||
throw new IllegalArgumentException("Field and Value arrays must be of equal length.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// keep this for posterity
|
|
||||||
_pClass = pClass;
|
|
||||||
|
|
||||||
// look up the cached primary key fields for this object
|
|
||||||
ColumnExp[] keyFields = DepotUtil.getKeyFields(pClass);
|
|
||||||
|
|
||||||
// fast path!
|
|
||||||
if (fields.length == 1 && keyFields.length == 1 && keyFields[0].equals(fields[0])) {
|
|
||||||
_values = new Comparable<?>[] { values[0] };
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// build a local map of field name -> field value
|
|
||||||
Map<ColumnExp, Comparable<?>> map = Maps.newHashMap();
|
|
||||||
for (int ii = 0; ii < fields.length; ii++) {
|
|
||||||
map.put(fields[ii], values[ii]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now extract the values in field order and ensure none are extra or missing
|
|
||||||
_values = new Comparable<?>[values.length];
|
|
||||||
for (int ii = 0; ii < keyFields.length; ii++) {
|
|
||||||
Comparable<?> value = map.remove(keyFields[ii]);
|
|
||||||
if (value == null) {
|
|
||||||
// make sure we were provided with a value for this primary key field
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Missing value for key field: " + keyFields[ii]);
|
|
||||||
}
|
|
||||||
if (!(value instanceof Serializable)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Non-serializable argument [key=" + keyFields[ii] +
|
|
||||||
", value=" + value + "]");
|
|
||||||
}
|
|
||||||
_values[ii] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally make sure we were not given any fields that are not primary key fields
|
|
||||||
if (map.size() > 0) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Non-key columns given: " + StringUtil.join(map.keySet().toArray(), ", "));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -284,6 +241,53 @@ public class Key<T extends PersistentRecord> extends WhereClause
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static Comparable<?>[] toCanonicalOrder (
|
||||||
|
Class<? extends PersistentRecord> pClass, ColumnExp[] fields, Comparable<?>[] values)
|
||||||
|
{
|
||||||
|
if (fields.length != values.length) {
|
||||||
|
throw new IllegalArgumentException("Field and Value arrays must be of equal length.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// look up the cached primary key fields for this object
|
||||||
|
ColumnExp[] keyFields = DepotUtil.getKeyFields(pClass);
|
||||||
|
|
||||||
|
// fast path!
|
||||||
|
if (fields.length == 1 && keyFields.length == 1 && keyFields[0].equals(fields[0])) {
|
||||||
|
return new Comparable<?>[] { values[0] };
|
||||||
|
}
|
||||||
|
|
||||||
|
// build a local map of field name -> field value
|
||||||
|
Map<ColumnExp, Comparable<?>> map = Maps.newHashMap();
|
||||||
|
for (int ii = 0; ii < fields.length; ii++) {
|
||||||
|
map.put(fields[ii], values[ii]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now extract the values in field order and ensure none are extra or missing
|
||||||
|
Comparable<?>[] cvalues = new Comparable<?>[values.length];
|
||||||
|
for (int ii = 0; ii < keyFields.length; ii++) {
|
||||||
|
Comparable<?> value = map.remove(keyFields[ii]);
|
||||||
|
if (value == null) {
|
||||||
|
// make sure we were provided with a value for this primary key field
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Missing value for key field: " + keyFields[ii]);
|
||||||
|
}
|
||||||
|
if (!(value instanceof Serializable)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Non-serializable argument [key=" + keyFields[ii] +
|
||||||
|
", value=" + value + "]");
|
||||||
|
}
|
||||||
|
cvalues[ii] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally make sure we were not given any fields that are not primary key fields
|
||||||
|
if (map.size() > 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Non-key columns given: " + StringUtil.join(map.keySet().toArray(), ", "));
|
||||||
|
}
|
||||||
|
|
||||||
|
return cvalues;
|
||||||
|
}
|
||||||
|
|
||||||
/** The persistent record type for which we are a key. */
|
/** The persistent record type for which we are a key. */
|
||||||
protected final Class<T> _pClass;
|
protected final Class<T> _pClass;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user