Skip to content

Commit 8b5c050

Browse files
committed
Merge remote-tracking branch 'origin/wuandy/TestNamedDb' into wuandy/TestNamedDb
2 parents 6dee28b + 225c590 commit 8b5c050

File tree

22 files changed

+378
-23
lines changed

22 files changed

+378
-23
lines changed

firebase-firestore/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* [feature] Expose MultiDb support in API. [#4015](//github.com/firebase/firebase-android-sdk/issues/4015)
33
* [fixed] Fixed a thread interference issue that may lead to a ConcurrentModificationException.
44
(GitHub [#5091](//github.com/firebase/firebase-android-sdk/issues/5091){: .external})
5+
* [fixed] Implement equals method on Filter class. [#5210](//github.com/firebase/firebase-android-sdk/issues/5210)
56

67
# 24.6.1
78
* [feature] Implemented an optimization in the local cache synchronization logic that reduces the number of billed document reads when documents were deleted on the server while the client was not actively listening to the query (e.g. while the client was offline). (GitHub [#4982](//github.com/firebase/firebase-android-sdk/pull/4982){: .external})

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ public void testAutoIndexCreationSetSuccessfully() {
136136

137137
results = waitFor(collection.whereEqualTo("match", true).get());
138138
assertEquals(1, results.size());
139+
140+
assertDoesNotThrow(() -> db.getPersistentCacheIndexManager().deleteAllIndexes());
141+
assertEquals(1, results.size());
139142
}
140143

141144
@Test
@@ -161,6 +164,9 @@ public void testAutoIndexCreationSetSuccessfullyUsingDefault() {
161164

162165
results = waitFor(collection.whereEqualTo("match", true).get());
163166
assertEquals(1, results.size());
167+
168+
assertDoesNotThrow(() -> db.getPersistentCacheIndexManager().deleteAllIndexes());
169+
assertEquals(1, results.size());
164170
}
165171

166172
@Test
@@ -175,5 +181,9 @@ public void testAutoIndexCreationAfterFailsTermination() {
175181
expectError(
176182
() -> db.getPersistentCacheIndexManager().disableIndexAutoCreation(),
177183
"The client has already been terminated");
184+
185+
expectError(
186+
() -> db.getPersistentCacheIndexManager().deleteAllIndexes(),
187+
"The client has already been terminated");
178188
}
179189
}

firebase-firestore/src/main/java/com/google/firebase/firestore/Filter.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.firebase.firestore.core.FieldFilter.Operator;
2020
import java.util.Arrays;
2121
import java.util.List;
22+
import java.util.Objects;
2223

2324
/**
2425
* A {@code Filter} represents a restriction on one or more field values and can be used to refine
@@ -48,6 +49,26 @@ public Operator getOperator() {
4849
public Object getValue() {
4950
return value;
5051
}
52+
53+
@Override
54+
public boolean equals(Object o) {
55+
if (this == o) return true;
56+
if (o == null || getClass() != o.getClass()) return false;
57+
58+
UnaryFilter that = (UnaryFilter) o;
59+
60+
return this.operator == that.operator
61+
&& Objects.equals(this.field, that.field)
62+
&& Objects.equals(this.value, that.value);
63+
}
64+
65+
@Override
66+
public int hashCode() {
67+
int result = field != null ? field.hashCode() : 0;
68+
result = 31 * result + (operator != null ? operator.hashCode() : 0);
69+
result = 31 * result + (value != null ? value.hashCode() : 0);
70+
return result;
71+
}
5172
}
5273

5374
static class CompositeFilter extends Filter {
@@ -68,6 +89,23 @@ public List<Filter> getFilters() {
6889
public com.google.firebase.firestore.core.CompositeFilter.Operator getOperator() {
6990
return operator;
7091
}
92+
93+
@Override
94+
public boolean equals(Object o) {
95+
if (this == o) return true;
96+
if (o == null || getClass() != o.getClass()) return false;
97+
98+
CompositeFilter that = (CompositeFilter) o;
99+
100+
return this.operator == that.operator && Objects.equals(this.filters, that.filters);
101+
}
102+
103+
@Override
104+
public int hashCode() {
105+
int result = filters != null ? filters.hashCode() : 0;
106+
result = 31 * result + (operator != null ? operator.hashCode() : 0);
107+
return result;
108+
}
71109
}
72110

73111
/**

firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,12 @@ public void enableIndexAutoCreation() {
5151
public void disableIndexAutoCreation() {
5252
client.setIndexAutoCreationEnabled(false);
5353
}
54+
55+
/**
56+
* Removes all persistent cache indexes. Please note this function will also deletes indexes
57+
* generated by {@link FirebaseFirestore#setIndexConfiguration(String)}, which is deprecated.
58+
*/
59+
public void deleteAllIndexes() {
60+
client.deleteAllFieldIndexes();
61+
}
5462
}

firebase-firestore/src/main/java/com/google/firebase/firestore/core/FirestoreClient.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,14 @@ public Task<Void> configureFieldIndexes(List<FieldIndex> fieldIndices) {
353353
return asyncQueue.enqueue(() -> localStore.configureFieldIndexes(fieldIndices));
354354
}
355355

356-
public void setIndexAutoCreationEnabled(boolean enabled) {
356+
public void setIndexAutoCreationEnabled(boolean isEnabled) {
357357
verifyNotTerminated();
358-
asyncQueue.enqueueAndForget(() -> localStore.setIndexAutoCreationEnabled(enabled));
358+
asyncQueue.enqueueAndForget(() -> localStore.setIndexAutoCreationEnabled(isEnabled));
359+
}
360+
361+
public void deleteAllFieldIndexes() {
362+
verifyNotTerminated();
363+
asyncQueue.enqueueAndForget(() -> localStore.deleteAllFieldIndexes());
359364
}
360365

361366
public void removeSnapshotsInSyncListener(EventListener<Void> listener) {

firebase-firestore/src/main/java/com/google/firebase/firestore/local/IndexManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ enum IndexType {
7878
/** Removes the given field index and deletes all index values. */
7979
void deleteFieldIndex(FieldIndex index);
8080

81+
/** Removes all field indexes and deletes all index values. */
82+
void deleteAllFieldIndexes();
83+
8184
/** Creates a full matched field index which serves the given target. */
8285
void createTargetIndexes(Target target);
8386

firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,8 +802,12 @@ public void configureFieldIndexes(List<FieldIndex> newFieldIndexes) {
802802
});
803803
}
804804

805-
public void setIndexAutoCreationEnabled(boolean enabled) {
806-
queryEngine.setIndexAutoCreationEnabled(enabled);
805+
public void deleteAllFieldIndexes() {
806+
persistence.runTransaction("Delete All Indexes", () -> indexManager.deleteAllFieldIndexes());
807+
}
808+
809+
public void setIndexAutoCreationEnabled(boolean isEnabled) {
810+
queryEngine.setIndexAutoCreationEnabled(isEnabled);
807811
}
808812

809813
/** Mutable state for the transaction in allocateQuery. */

firebase-firestore/src/main/java/com/google/firebase/firestore/local/MemoryIndexManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ public void deleteFieldIndex(FieldIndex index) {
6060
// Field indices are not supported with memory persistence.
6161
}
6262

63+
@Override
64+
public void deleteAllFieldIndexes() {
65+
// Field indices are not supported with memory persistence.
66+
}
67+
6368
@Override
6469
public void createTargetIndexes(Target target) {}
6570

firebase-firestore/src/main/java/com/google/firebase/firestore/local/QueryEngine.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ public void initialize(LocalDocumentsView localDocumentsView, IndexManager index
8888
this.initialized = true;
8989
}
9090

91-
public void setIndexAutoCreationEnabled(boolean enabled) {
92-
this.indexAutoCreationEnabled = enabled;
91+
public void setIndexAutoCreationEnabled(boolean isEnabled) {
92+
this.indexAutoCreationEnabled = isEnabled;
9393
}
9494

9595
public ImmutableSortedMap<DocumentKey, Document> getDocumentsMatchingQuery(

firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteIndexManager.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,16 @@ public void deleteFieldIndex(FieldIndex index) {
233233
}
234234
}
235235

236+
@Override
237+
public void deleteAllFieldIndexes() {
238+
db.execute("DELETE FROM index_configuration");
239+
db.execute("DELETE FROM index_entries");
240+
db.execute("DELETE FROM index_state");
241+
242+
nextIndexToUpdate.clear();
243+
memoizedIndexes.clear();
244+
}
245+
236246
@Override
237247
public void createTargetIndexes(Target target) {
238248
hardAssert(started, "IndexManager not started");

firebase-firestore/src/main/java/com/google/firebase/firestore/model/TargetIndexMatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public boolean servedByIndex(FieldIndex index) {
195195
/** Returns a full matched field index for this target. */
196196
public FieldIndex buildTargetIndex() {
197197
// We want to make sure only one segment created for one field. For example, in case like
198-
// a == 3 and a > 2, index, a ASCENDING, will only be created once.
198+
// a == 3 and a > 2, Index: {a ASCENDING} will only be created once.
199199
Set<FieldPath> uniqueFields = new HashSet<>();
200200
List<FieldIndex.Segment> segments = new ArrayList<>();
201201

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.firestore;
16+
17+
import static org.junit.Assert.assertEquals;
18+
import static org.junit.Assert.assertNotEquals;
19+
20+
import com.google.common.collect.ImmutableList;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.robolectric.RobolectricTestRunner;
24+
import org.robolectric.annotation.Config;
25+
26+
@RunWith(RobolectricTestRunner.class)
27+
@Config(manifest = Config.NONE)
28+
public class FilterTest {
29+
30+
@Test
31+
public void equalTo() {
32+
Filter filter = Filter.equalTo("x", "v");
33+
assertEquals(filter, filter);
34+
assertEquals(filter, Filter.equalTo(FieldPath.of("x"), "v"));
35+
assertNotEquals(filter, Filter.equalTo("x", "z"));
36+
assertNotEquals(filter, Filter.equalTo("y", "v"));
37+
assertNotEquals(filter, Filter.notEqualTo("x", "v"));
38+
}
39+
40+
@Test
41+
public void notEqualTo() {
42+
Filter filter = Filter.notEqualTo("x", "v");
43+
assertEquals(filter, filter);
44+
assertEquals(filter, Filter.notEqualTo(FieldPath.of("x"), "v"));
45+
assertNotEquals(filter, Filter.notEqualTo("x", "z"));
46+
assertNotEquals(filter, Filter.notEqualTo("y", "v"));
47+
assertNotEquals(filter, Filter.equalTo("x", "v"));
48+
}
49+
50+
@Test
51+
public void greaterThan() {
52+
Filter filter = Filter.greaterThan("x", "v");
53+
assertEquals(filter, filter);
54+
assertEquals(filter, Filter.greaterThan(FieldPath.of("x"), "v"));
55+
assertNotEquals(filter, Filter.greaterThan("x", "z"));
56+
assertNotEquals(filter, Filter.greaterThan("y", "v"));
57+
assertNotEquals(filter, Filter.lessThan("x", "v"));
58+
}
59+
60+
@Test
61+
public void greaterThanOrEqualTo() {
62+
Filter filter = Filter.greaterThanOrEqualTo("x", "v");
63+
assertEquals(filter, filter);
64+
assertEquals(filter, Filter.greaterThanOrEqualTo(FieldPath.of("x"), "v"));
65+
assertNotEquals(filter, Filter.greaterThanOrEqualTo("x", "z"));
66+
assertNotEquals(filter, Filter.greaterThanOrEqualTo("y", "v"));
67+
assertNotEquals(filter, Filter.lessThanOrEqualTo("x", "v"));
68+
}
69+
70+
@Test
71+
public void lessThan() {
72+
Filter filter = Filter.lessThan("x", "v");
73+
assertEquals(filter, filter);
74+
assertEquals(filter, Filter.lessThan(FieldPath.of("x"), "v"));
75+
assertNotEquals(filter, Filter.lessThan("x", "z"));
76+
assertNotEquals(filter, Filter.lessThan("y", "v"));
77+
assertNotEquals(filter, Filter.greaterThan("x", "v"));
78+
}
79+
80+
@Test
81+
public void lessThanOrEqualTo() {
82+
Filter filter = Filter.lessThanOrEqualTo("x", "v");
83+
assertEquals(filter, filter);
84+
assertEquals(filter, Filter.lessThanOrEqualTo(FieldPath.of("x"), "v"));
85+
assertNotEquals(filter, Filter.lessThanOrEqualTo("x", "z"));
86+
assertNotEquals(filter, Filter.lessThanOrEqualTo("y", "v"));
87+
assertNotEquals(filter, Filter.greaterThanOrEqualTo("x", "v"));
88+
}
89+
90+
@Test
91+
public void arrayContains() {
92+
Filter filter = Filter.arrayContains("x", "v");
93+
assertEquals(filter, filter);
94+
assertEquals(filter, Filter.arrayContains(FieldPath.of("x"), "v"));
95+
assertNotEquals(filter, Filter.arrayContains("x", "z"));
96+
assertNotEquals(filter, Filter.arrayContains("y", "v"));
97+
assertNotEquals(filter, Filter.equalTo("x", "v"));
98+
}
99+
100+
@Test
101+
public void arrayContainsAny() {
102+
Filter filter = Filter.arrayContainsAny("x", ImmutableList.of("v1", "v2"));
103+
assertEquals(filter, filter);
104+
assertEquals(filter, Filter.arrayContainsAny(FieldPath.of("x"), ImmutableList.of("v1", "v2")));
105+
assertNotEquals(filter, Filter.arrayContainsAny("x", ImmutableList.of("v2", "v1")));
106+
assertNotEquals(filter, Filter.arrayContainsAny("x", ImmutableList.of("v2", "v3")));
107+
assertNotEquals(filter, Filter.arrayContainsAny("y", ImmutableList.of("v1", "v2")));
108+
assertNotEquals(filter, Filter.equalTo("x", "v"));
109+
}
110+
111+
@Test
112+
public void inArray() {
113+
Filter filter = Filter.inArray("x", ImmutableList.of("v1", "v2"));
114+
assertEquals(filter, filter);
115+
assertEquals(filter, Filter.inArray(FieldPath.of("x"), ImmutableList.of("v1", "v2")));
116+
assertNotEquals(filter, Filter.inArray("x", ImmutableList.of("v2", "v1")));
117+
assertNotEquals(filter, Filter.inArray("x", ImmutableList.of("v2", "v3")));
118+
assertNotEquals(filter, Filter.inArray("y", ImmutableList.of("v1", "v2")));
119+
assertNotEquals(filter, Filter.notInArray("x", ImmutableList.of("v1", "v2")));
120+
}
121+
122+
@Test
123+
public void notInArray() {
124+
Filter filter = Filter.notInArray("x", ImmutableList.of("v1", "v2"));
125+
assertEquals(filter, filter);
126+
assertEquals(filter, Filter.notInArray(FieldPath.of("x"), ImmutableList.of("v1", "v2")));
127+
assertNotEquals(filter, Filter.notInArray("x", ImmutableList.of("v2", "v1")));
128+
assertNotEquals(filter, Filter.notInArray("x", ImmutableList.of("v2", "v3")));
129+
assertNotEquals(filter, Filter.notInArray("y", ImmutableList.of("v1", "v2")));
130+
assertNotEquals(filter, Filter.inArray("x", ImmutableList.of("v1", "v2")));
131+
}
132+
133+
@Test
134+
public void or() {
135+
Filter filter =
136+
Filter.or(
137+
Filter.inArray("x", ImmutableList.of("v1", "v2")),
138+
Filter.inArray("y", ImmutableList.of("v3", "v4")));
139+
assertEquals(
140+
filter,
141+
Filter.or(
142+
Filter.inArray(FieldPath.of("x"), ImmutableList.of("v1", "v2")),
143+
Filter.inArray(FieldPath.of("y"), ImmutableList.of("v3", "v4"))));
144+
assertNotEquals(
145+
filter,
146+
Filter.and(
147+
Filter.inArray("x", ImmutableList.of("v1", "v2")),
148+
Filter.inArray("y", ImmutableList.of("v3", "v4"))));
149+
assertNotEquals(
150+
filter,
151+
Filter.or(
152+
Filter.inArray("y", ImmutableList.of("v3", "v4")),
153+
Filter.inArray("x", ImmutableList.of("v1", "v2"))));
154+
}
155+
156+
@Test
157+
public void and() {
158+
Filter filter =
159+
Filter.and(
160+
Filter.inArray("x", ImmutableList.of("v1", "v2")),
161+
Filter.inArray("y", ImmutableList.of("v3", "v4")));
162+
assertEquals(
163+
filter,
164+
Filter.and(
165+
Filter.inArray(FieldPath.of("x"), ImmutableList.of("v1", "v2")),
166+
Filter.inArray(FieldPath.of("y"), ImmutableList.of("v3", "v4"))));
167+
assertNotEquals(
168+
filter,
169+
Filter.or(
170+
Filter.inArray("x", ImmutableList.of("v1", "v2")),
171+
Filter.inArray("y", ImmutableList.of("v3", "v4"))));
172+
assertNotEquals(
173+
filter,
174+
Filter.and(
175+
Filter.inArray("y", ImmutableList.of("v3", "v4")),
176+
Filter.inArray("x", ImmutableList.of("v1", "v2"))));
177+
}
178+
}

firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ public ImmutableSortedMap<DocumentKey, Document> getDocumentsMatchingQuery(
8888
}
8989

9090
@Override
91-
public void setIndexAutoCreationEnabled(boolean enabled) {
92-
queryEngine.setIndexAutoCreationEnabled(enabled);
91+
public void setIndexAutoCreationEnabled(boolean isEnabled) {
92+
queryEngine.setIndexAutoCreationEnabled(isEnabled);
9393
}
9494

9595
@Override

0 commit comments

Comments
 (0)