Skip to content

Commit

Permalink
Adding FieldValue.increment() (#4018)
Browse files Browse the repository at this point in the history
* DO NOT MERGE: Adding FieldValue.increment()

* Use "increment" Proto naming
  • Loading branch information
schmidt-sebastian authored and sduskis committed Mar 8, 2019
1 parent abf4f93 commit e4c11c0
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,55 @@ FieldTransform toProto(FieldPath path) {
}
};

static class NumericIncrementFieldValue extends FieldValue {
final Number operand;

NumericIncrementFieldValue(Number operand) {
this.operand = operand;
}

@Override
boolean includeInDocumentMask() {
return false;
}

@Override
boolean includeInDocumentTransform() {
return true;
}

@Override
String getMethodName() {
return "FieldValue.increment()";
}

@Override
FieldTransform toProto(FieldPath path) {
FieldTransform.Builder fieldTransform = FieldTransform.newBuilder();
fieldTransform.setFieldPath(path.getEncodedPath());
fieldTransform.setIncrement(
UserDataConverter.encodeValue(path, operand, UserDataConverter.ARGUMENT));
return fieldTransform.build();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
NumericIncrementFieldValue that = (NumericIncrementFieldValue) o;
return Objects.equals(operand, that.operand);
}

@Override
public int hashCode() {
return Objects.hash(operand);
}
}

static class ArrayUnionFieldValue extends FieldValue {
final List<Object> elements;

Expand Down Expand Up @@ -205,11 +254,44 @@ public static FieldValue delete() {
}

/**
* Returns a special value that can be used with set() or update() that tells the server to union
* the given elements with any array value that already exists on the server. Each specified
* element that doesn't already exist in the array will be added to the end. If the field being
* modified is not already an array it will be overwritten with an array containing exactly the
* specified elements.
* Returns a special value that can be used with set(), create() or update() that tells the server
* to increment the field's current value by the given value.
*
* <p>If the current field value is an integer, possible integer overflows are resolved to
* Long.MAX_VALUE or Long.MIN_VALUE. If the current field value is a double, both values will be
* interpreted as doubles and the arithmetic will follow IEEE 754 semantics.
*
* <p>If the current field is not an integer or double, or if the field does not yet exist, the
* transformation will set the field to the given value.
*
* @return The FieldValue sentinel for use in a call to set(), create() or update().
*/
@Nonnull
public static FieldValue increment(long l) {
return new NumericIncrementFieldValue(l);
}

/**
* Returns a special value that can be used with set(), create() or update() that tells the server
* to increment the field's current value by the given value.
*
* <p>If the current value is an integer or a double, both the current and the given value will be
* interpreted as doubles and all arithmetic will follow IEEE 754 semantics. Otherwise, the
* transformation will set the field to the given value.
*
* @return The FieldValue sentinel for use in a call to set(), create() or update().
*/
@Nonnull
public static FieldValue increment(double d) {
return new NumericIncrementFieldValue(d);
}

/**
* Returns a special value that can be used with set(), create() or update() that tells the server
* to union the given elements with any array value that already exists on the server. Each
* specified element that doesn't already exist in the array will be added to the end. If the
* field being modified is not already an array it will be overwritten with an array containing
* exactly the specified elements.
*
* @param elements The elements to union into the array.
* @return The FieldValue sentinel for use in a call to set() or update().
Expand All @@ -221,10 +303,10 @@ public static FieldValue arrayUnion(@Nonnull Object... elements) {
}

/**
* Returns a special value that can be used with set() or update() that tells the server to remove
* the given elements from any array value that already exists on the server. All instances of
* each element specified will be removed from the array. If the field being modified is not
* already an array it will be overwritten with an empty array.
* Returns a special value that can be used with set(), create() or update() that tells the server
* to remove the given elements from any array value that already exists on the server. All
* instances of each element specified will be removed from the array. If the field being modified
* is not already an array it will be overwritten with an empty array.
*
* @param elements The elements to remove from the array.
* @return The FieldValue sentinel for use in a call to set() or update().
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private UserDataConverter() {}
* @param path path THe field path of the object to encode.
* @param sanitizedObject An Object that has been sanitized by CustomClassMapper and only contains
* valid types.
* @param options Encoding opions to use for this value.
* @param options Encoding options to use for this value.
* @return The Value proto.
*/
@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import static com.google.cloud.firestore.LocalFirestoreHelper.delete;
import static com.google.cloud.firestore.LocalFirestoreHelper.get;
import static com.google.cloud.firestore.LocalFirestoreHelper.getAllResponse;
import static com.google.cloud.firestore.LocalFirestoreHelper.increment;
import static com.google.cloud.firestore.LocalFirestoreHelper.map;
import static com.google.cloud.firestore.LocalFirestoreHelper.object;
import static com.google.cloud.firestore.LocalFirestoreHelper.serverTimestamp;
Expand Down Expand Up @@ -408,6 +409,30 @@ public void mergeWithServerTimestamps() throws Exception {
assertCommitEquals(set, commitRequests.get(1));
}

@Test
public void setWithIncrement() throws Exception {
doReturn(FIELD_TRANSFORM_COMMIT_RESPONSE)
.when(firestoreMock)
.sendRequest(
commitCapture.capture(), Matchers.<UnaryCallable<CommitRequest, CommitResponse>>any());

documentReference
.set(map("integer", FieldValue.increment(1), "double", FieldValue.increment(1.1)))
.get();

CommitRequest set =
commit(
set(Collections.<String, Value>emptyMap()),
transform(
"integer",
increment(Value.newBuilder().setIntegerValue(1).build()),
"double",
increment(Value.newBuilder().setDoubleValue(1.1).build())));

CommitRequest commitRequest = commitCapture.getValue();
assertCommitEquals(set, commitRequest);
}

@Test
public void setWithArrayUnion() throws Exception {
doReturn(FIELD_TRANSFORM_COMMIT_RESPONSE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,16 @@ public void arrayRemoveEquals() {
assertNotEquals(arrayRemove1, arrayRemove3);
assertNotEquals(arrayRemove1, arrayUnion);
}

@Test
public void incrementEquals() {
FieldValue increment1 = FieldValue.increment(42);
FieldValue increment2 = FieldValue.increment(42);
FieldValue increment3 = FieldValue.increment(42.0);
FieldValue increment4 = FieldValue.increment(42.0);
assertEquals(increment1, increment2);
assertEquals(increment3, increment4);
assertNotEquals(increment1, increment3);
assertNotEquals(increment2, increment4);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ public static FieldTransform serverTimestamp() {
.build();
}

public static FieldTransform increment(Value value) {
return FieldTransform.newBuilder().setIncrement(value).build();
}

public static FieldTransform arrayUnion(Value... values) {
return FieldTransform.newBuilder()
.setAppendMissingElements(ArrayValue.newBuilder().addAllValues(Arrays.asList(values)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@

public class ITSystemTest {

private static final double DOUBLE_EPSILON = 0.000001;

private final Map<String, Object> SINGLE_FIELD_MAP = LocalFirestoreHelper.SINGLE_FIELD_MAP;
private final Map<String, Object> ALL_SUPPORTED_TYPES_MAP =
LocalFirestoreHelper.ALL_SUPPORTED_TYPES_MAP;
Expand Down Expand Up @@ -977,4 +979,22 @@ public void arrayOperators() throws ExecutionException, InterruptedException {

assertTrue(containsQuery.get().get().isEmpty());
}

@Test
public void integerIncrement() throws ExecutionException, InterruptedException {
DocumentReference docRef = randomColl.document();
docRef.set(Collections.singletonMap("sum", (Object) 1L)).get();
docRef.update("sum", FieldValue.increment(2)).get();
DocumentSnapshot docSnap = docRef.get().get();
assertEquals(3L, docSnap.get("sum"));
}

@Test
public void floatIncrement() throws ExecutionException, InterruptedException {
DocumentReference docRef = randomColl.document();
docRef.set(Collections.singletonMap("sum", (Object) 1.1)).get();
docRef.update("sum", FieldValue.increment(2.2)).get();
DocumentSnapshot docSnap = docRef.get().get();
assertEquals(3.3, (Double) docSnap.get("sum"), DOUBLE_EPSILON);
}
}

0 comments on commit e4c11c0

Please sign in to comment.