18
18
import static com .google .firebase .firestore .model .Values .min ;
19
19
20
20
import androidx .annotation .Nullable ;
21
- import com .google .firebase .firestore .core .OrderBy .Direction ;
22
21
import com .google .firebase .firestore .model .DocumentKey ;
23
22
import com .google .firebase .firestore .model .FieldIndex ;
24
23
import com .google .firebase .firestore .model .ResourcePath ;
25
24
import com .google .firebase .firestore .model .Values ;
26
- import com .google .firestore .v1 .ArrayValue ;
27
25
import com .google .firestore .v1 .Value ;
28
26
import java .util .ArrayList ;
27
+ import java .util .Collections ;
29
28
import java .util .List ;
30
29
31
30
/**
@@ -115,6 +114,27 @@ public boolean hasLimit() {
115
114
return endAt ;
116
115
}
117
116
117
+ /** Returns the list of values that are used in ARRAY_CONTAINS and ARRAY_CONTAINS_ANY filter. */
118
+ public List <Value > getArrayValues (FieldIndex fieldIndex ) {
119
+ for (FieldIndex .Segment segment : fieldIndex .getArraySegments ()) {
120
+ for (Filter filter : filters ) {
121
+ if (filter .getField ().equals (segment .getFieldPath ())) {
122
+ FieldFilter fieldFilter = (FieldFilter ) filter ;
123
+ switch (fieldFilter .getOperator ()) {
124
+ case ARRAY_CONTAINS_ANY :
125
+ return fieldFilter .getValue ().getArrayValue ().getValuesList ();
126
+ case ARRAY_CONTAINS :
127
+ return Collections .singletonList (fieldFilter .getValue ());
128
+ default :
129
+ // Remaining filters cannot be used as array filters.
130
+ }
131
+ }
132
+ }
133
+ }
134
+
135
+ return Collections .emptyList ();
136
+ }
137
+
118
138
/**
119
139
* Returns a lower bound of field values that can be used as a starting point to scan the index
120
140
* defined by {@code fieldIndex}.
@@ -127,7 +147,7 @@ public Bound getLowerBound(FieldIndex fieldIndex) {
127
147
boolean inclusive = true ;
128
148
129
149
// Go through all filters to find a value for the current field segment
130
- for (FieldIndex .Segment segment : fieldIndex ) {
150
+ for (FieldIndex .Segment segment : fieldIndex . getDirectionalSegments () ) {
131
151
Value segmentValue = Values .NULL_VALUE ;
132
152
boolean segmentInclusive = true ;
133
153
@@ -142,26 +162,17 @@ public Bound getLowerBound(FieldIndex fieldIndex) {
142
162
case LESS_THAN_OR_EQUAL :
143
163
filterValue = Values .getLowerBound (fieldFilter .getValue ().getValueTypeCase ());
144
164
break ;
145
- case NOT_EQUAL :
146
- filterValue = Values .NULL_VALUE ;
147
- break ;
148
- case NOT_IN :
149
- filterValue =
150
- Value .newBuilder ()
151
- .setArrayValue (ArrayValue .newBuilder ().addValues (Values .NULL_VALUE ))
152
- .build ();
153
- break ;
154
165
case EQUAL :
155
166
case IN :
156
- case ARRAY_CONTAINS_ANY :
157
- case ARRAY_CONTAINS :
158
167
case GREATER_THAN_OR_EQUAL :
159
168
filterValue = fieldFilter .getValue ();
160
169
break ;
161
170
case GREATER_THAN :
162
171
filterValue = fieldFilter .getValue ();
163
172
filterInclusive = false ;
164
173
break ;
174
+ default :
175
+ // Remaining filters cannot be used as upper bounds.
165
176
}
166
177
167
178
if (max (segmentValue , filterValue ) == filterValue ) {
@@ -206,7 +217,7 @@ public Bound getLowerBound(FieldIndex fieldIndex) {
206
217
List <Value > values = new ArrayList <>();
207
218
boolean inclusive = true ;
208
219
209
- for (FieldIndex .Segment segment : fieldIndex ) {
220
+ for (FieldIndex .Segment segment : fieldIndex . getDirectionalSegments () ) {
210
221
@ Nullable Value segmentValue = null ;
211
222
boolean segmentInclusive = true ;
212
223
@@ -218,26 +229,22 @@ public Bound getLowerBound(FieldIndex fieldIndex) {
218
229
boolean filterInclusive = true ;
219
230
220
231
switch (fieldFilter .getOperator ()) {
221
- case NOT_IN :
222
- case NOT_EQUAL :
223
- // These filters cannot be used as an upper bound. Skip.
224
- break ;
225
232
case GREATER_THAN_OR_EQUAL :
226
233
case GREATER_THAN :
227
234
filterValue = Values .getUpperBound (fieldFilter .getValue ().getValueTypeCase ());
228
235
filterInclusive = false ;
229
236
break ;
230
237
case EQUAL :
231
238
case IN :
232
- case ARRAY_CONTAINS_ANY :
233
- case ARRAY_CONTAINS :
234
239
case LESS_THAN_OR_EQUAL :
235
240
filterValue = fieldFilter .getValue ();
236
241
break ;
237
242
case LESS_THAN :
238
243
filterValue = fieldFilter .getValue ();
239
244
filterInclusive = false ;
240
245
break ;
246
+ default :
247
+ // Remaining filters cannot be used as upper bounds.
241
248
}
242
249
243
250
if (min (segmentValue , filterValue ) == filterValue ) {
@@ -283,6 +290,11 @@ public List<OrderBy> getOrderBy() {
283
290
return this .orderBys ;
284
291
}
285
292
293
+ /** Returns the first order by (which always exists). */
294
+ public OrderBy getFirstOrderBy () {
295
+ return this .orderBys .get (0 );
296
+ }
297
+
286
298
/** Returns a canonical string representing this target. */
287
299
public String getCanonicalId () {
288
300
if (memoizedCannonicalId != null ) {
@@ -307,7 +319,7 @@ public String getCanonicalId() {
307
319
builder .append ("|ob:" );
308
320
for (OrderBy orderBy : getOrderBy ()) {
309
321
builder .append (orderBy .getField ().canonicalString ());
310
- builder .append (orderBy .getDirection ().equals ( Direction . ASCENDING ) ? "asc" : "desc" );
322
+ builder .append (orderBy .getDirection ().canonicalString () );
311
323
}
312
324
313
325
// Add limit.
0 commit comments