[jOOQ/jOOQ#12494] Add additional Record.modified() methods
This commit is contained in:
parent
dce730d397
commit
34b560bf82
@ -592,6 +592,9 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
/**
|
||||
* Check if this record has been touched since it was created or fetched
|
||||
* from the database.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @see #original()
|
||||
* @see #touched(Field)
|
||||
@ -603,6 +606,9 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
/**
|
||||
* Check if a field's value has been touched since the record was created or
|
||||
* fetched from the database, using {@link #field(Field)} for lookup.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @see #touched()
|
||||
* @see #original(Field)
|
||||
@ -612,6 +618,9 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
/**
|
||||
* Check if a field's value has been touched since the record was created or
|
||||
* fetched from the database, using {@link #field(int)} for lookup.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @param fieldIndex The 0-based field index in this record.
|
||||
* @see #touched()
|
||||
@ -622,6 +631,9 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
/**
|
||||
* Check if a field's value has been touched since the record was created or
|
||||
* fetched from the database, using {@link #field(String)} for lookup.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @see #touched()
|
||||
* @see #original(String)
|
||||
@ -631,6 +643,9 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
/**
|
||||
* Check if a field's value has been touched since the record was created or
|
||||
* fetched from the database, using {@link #field(Name)} for lookup.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @see #touched()
|
||||
* @see #original(Name)
|
||||
@ -642,7 +657,10 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
* <p>
|
||||
* If the <code>touched</code> argument is <code>false</code>, the
|
||||
* {@link #original()} values will be reset to the corresponding "current"
|
||||
* values as well
|
||||
* values as well.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @see #touched()
|
||||
* @see #touched(Field, boolean)
|
||||
@ -657,7 +675,10 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
* <p>
|
||||
* If the <code>touched</code> argument is <code>false</code>, the
|
||||
* {@link #original(Field)} value will be reset to the corresponding
|
||||
* "current" value as well
|
||||
* "current" value as well.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @see #touched()
|
||||
* @see #touched(Field)
|
||||
@ -670,7 +691,10 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
* <p>
|
||||
* If the <code>touched</code> argument is <code>false</code>, the
|
||||
* {@link #original(int)} value will be reset to the corresponding "current"
|
||||
* value as well
|
||||
* value as well.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @param fieldIndex The 0-based field index in this record.
|
||||
* @see #touched()
|
||||
@ -684,7 +708,10 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
* <p>
|
||||
* If the <code>touched</code> argument is <code>false</code>, the
|
||||
* {@link #touched(String)} value will be reset to the corresponding
|
||||
* "current" value as well
|
||||
* "current" value as well.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @see #touched()
|
||||
* @see #touched(String)
|
||||
@ -697,13 +724,79 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
* <p>
|
||||
* If the <code>touched</code> argument is <code>false</code>, the
|
||||
* {@link #original(Name)} value will be reset to the corresponding
|
||||
* "current" value as well
|
||||
* "current" value as well.
|
||||
* <p>
|
||||
* A record may have been {@link #touched()} (a setter was called) without
|
||||
* having been {@link #modified()} (a value was changed).
|
||||
*
|
||||
* @see #touched()
|
||||
* @see #touched(Name)
|
||||
*/
|
||||
void touched(Name fieldName, boolean touched);
|
||||
|
||||
/**
|
||||
* Check if this record has been modified since it was created or fetched
|
||||
* from the database.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
*
|
||||
* @see #original()
|
||||
* @see #modified(Field)
|
||||
* @see #modified(int)
|
||||
* @see #modified(String)
|
||||
*/
|
||||
boolean modified();
|
||||
|
||||
/**
|
||||
* Check if a field's value has been modified since the record was created or
|
||||
* fetched from the database, using {@link #field(Field)} for lookup.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
*
|
||||
* @see #modified()
|
||||
* @see #original(Field)
|
||||
*/
|
||||
boolean modified(Field<?> field);
|
||||
|
||||
/**
|
||||
* Check if a field's value has been modified since the record was created or
|
||||
* fetched from the database, using {@link #field(int)} for lookup.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
*
|
||||
* @param fieldIndex The 0-based field index in this record.
|
||||
* @see #modified()
|
||||
* @see #original(int)
|
||||
*/
|
||||
boolean modified(int fieldIndex);
|
||||
|
||||
/**
|
||||
* Check if a field's value has been modified since the record was created or
|
||||
* fetched from the database, using {@link #field(String)} for lookup.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
*
|
||||
* @see #modified()
|
||||
* @see #original(String)
|
||||
*/
|
||||
boolean modified(String fieldName);
|
||||
|
||||
/**
|
||||
* Check if a field's value has been modified since the record was created or
|
||||
* fetched from the database, using {@link #field(Name)} for lookup.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
*
|
||||
* @see #modified()
|
||||
* @see #original(Name)
|
||||
*/
|
||||
boolean modified(Name fieldName);
|
||||
|
||||
/**
|
||||
* Reset all values to their {@link #original()} values and all
|
||||
* {@link #touched()} flags to <code>false</code>.
|
||||
|
||||
@ -552,6 +552,37 @@ implements
|
||||
touched(indexOrFail(fields, fieldName), c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean modified() {
|
||||
for (int i = 0; i < size(); i++)
|
||||
if (modified(i))
|
||||
return true;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean modified(Field<?> field) {
|
||||
return modified(indexOrFail(fields, field));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean modified(int fieldIndex) {
|
||||
int i = safeIndex(fieldIndex);
|
||||
return touched.get(i) && !deepEqual(values[i], originals[i]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean modified(String fieldName) {
|
||||
return modified(indexOrFail(fields, fieldName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean modified(Name fieldName) {
|
||||
return modified(indexOrFail(fields, fieldName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void reset() {
|
||||
touched.clear();
|
||||
|
||||
@ -139,41 +139,10 @@ abstract class AbstractStore extends AbstractFormattable {
|
||||
// Note: keep this implementation in-sync with AbstractRecord.compareTo()!
|
||||
if (obj instanceof AbstractStore that) {
|
||||
if (size() == that.size()) {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
final Object thisValue = get(i);
|
||||
final Object thatValue = that.get(i);
|
||||
|
||||
// [#1850] Only return false early. In all other cases,
|
||||
// continue checking the remaining fields
|
||||
if (thisValue == null && thatValue == null)
|
||||
continue;
|
||||
|
||||
else if (thisValue == null || thatValue == null)
|
||||
for (int i = 0; i < size(); i++)
|
||||
if (!deepEqual(get(i), that.get(i)))
|
||||
return false;
|
||||
|
||||
// [#985] Compare arrays too.
|
||||
else if (thisValue.getClass().isArray() && thatValue.getClass().isArray()) {
|
||||
|
||||
// Might be byte[]
|
||||
if (thisValue.getClass() == byte[].class && thatValue.getClass() == byte[].class) {
|
||||
if (!Arrays.equals((byte[]) thisValue, (byte[]) thatValue))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Other primitive types are not expected
|
||||
else if (!thisValue.getClass().getComponentType().isPrimitive() &&
|
||||
!thatValue.getClass().getComponentType().isPrimitive()) {
|
||||
if (!Arrays.deepEquals((Object[]) thisValue, (Object[]) thatValue))
|
||||
return false;
|
||||
}
|
||||
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (!thisValue.equals(thatValue))
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we got through the above loop, the two records are equal
|
||||
return true;
|
||||
}
|
||||
@ -181,4 +150,35 @@ abstract class AbstractStore extends AbstractFormattable {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static final boolean deepEqual(Object thisValue, Object thatValue) {
|
||||
|
||||
// [#1850] Only return false early. In all other cases,
|
||||
// continue checking the remaining fields
|
||||
if (thisValue == null && thatValue == null)
|
||||
return true;
|
||||
|
||||
else if (thisValue == null || thatValue == null)
|
||||
return false;
|
||||
|
||||
// [#985] Compare arrays too.
|
||||
else if (thisValue.getClass().isArray() && thatValue.getClass().isArray()) {
|
||||
|
||||
// Might be byte[]
|
||||
if (thisValue.getClass() == byte[].class && thatValue.getClass() == byte[].class) {
|
||||
return Arrays.equals((byte[]) thisValue, (byte[]) thatValue);
|
||||
}
|
||||
|
||||
// Other primitive types are not expected
|
||||
else if (!thisValue.getClass().getComponentType().isPrimitive() &&
|
||||
!thatValue.getClass().getComponentType().isPrimitive()) {
|
||||
return Arrays.deepEquals((Object[]) thisValue, (Object[]) thatValue);
|
||||
}
|
||||
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return thisValue.equals(thatValue);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user