@@ -18,8 +18,8 @@ import com.google.android.gms.tasks.Task
1818import com.google.android.gms.tasks.TaskCompletionSource
1919import com.google.common.collect.FluentIterable
2020import com.google.common.collect.ImmutableList
21+ import com.google.firebase.Timestamp
2122import com.google.firebase.firestore.model.DocumentKey
22- import com.google.firebase.firestore.model.SnapshotVersion
2323import com.google.firebase.firestore.model.Values
2424import com.google.firebase.firestore.pipeline.AddFieldsStage
2525import com.google.firebase.firestore.pipeline.AggregateStage
@@ -32,7 +32,6 @@ import com.google.firebase.firestore.pipeline.DistinctStage
3232import com.google.firebase.firestore.pipeline.DocumentsSource
3333import com.google.firebase.firestore.pipeline.Expr
3434import com.google.firebase.firestore.pipeline.Field
35- import com.google.firebase.firestore.pipeline.FindNearestOptions
3635import com.google.firebase.firestore.pipeline.FindNearestStage
3736import com.google.firebase.firestore.pipeline.GenericArg
3837import com.google.firebase.firestore.pipeline.GenericStage
@@ -47,7 +46,6 @@ import com.google.firebase.firestore.pipeline.Selectable
4746import com.google.firebase.firestore.pipeline.SortStage
4847import com.google.firebase.firestore.pipeline.Stage
4948import com.google.firebase.firestore.pipeline.UnionStage
50- import com.google.firebase.firestore.pipeline.UnnestOptions
5149import com.google.firebase.firestore.pipeline.UnnestStage
5250import com.google.firebase.firestore.pipeline.WhereStage
5351import com.google.firebase.firestore.util.Preconditions
@@ -59,15 +57,15 @@ class Pipeline
5957internal constructor (
6058 internal val firestore: FirebaseFirestore ,
6159 internal val userDataReader: UserDataReader ,
62- private val stages: FluentIterable <Stage >
60+ private val stages: FluentIterable <Stage < * > >
6361) {
6462 internal constructor (
6563 firestore: FirebaseFirestore ,
6664 userDataReader: UserDataReader ,
67- stage: Stage
65+ stage: Stage < * >
6866 ) : this (firestore, userDataReader, FluentIterable .of(stage))
6967
70- private fun append (stage : Stage ): Pipeline {
68+ private fun append (stage : Stage < * > ): Pipeline {
7169 return Pipeline (firestore, userDataReader, stages.append(stage))
7270 }
7371
@@ -144,15 +142,28 @@ internal constructor(
144142 fun findNearest (
145143 property : Expr ,
146144 vector : DoubleArray ,
147- distanceMeasure : FindNearestStage .DistanceMeasure
148- ) = append(FindNearestStage (property, vector, distanceMeasure, FindNearestOptions . DEFAULT ))
145+ distanceMeasure : FindNearestStage .DistanceMeasure ,
146+ ) = append(FindNearestStage .of (property, vector, distanceMeasure))
149147
150148 fun findNearest (
151- property : Expr ,
149+ propertyField : String ,
152150 vector : DoubleArray ,
153151 distanceMeasure : FindNearestStage .DistanceMeasure ,
154- options : FindNearestOptions
155- ) = append(FindNearestStage (property, vector, distanceMeasure, options))
152+ ) = append(FindNearestStage .of(propertyField, vector, distanceMeasure))
153+
154+ fun findNearest (
155+ property : Expr ,
156+ vector : Expr ,
157+ distanceMeasure : FindNearestStage .DistanceMeasure ,
158+ ) = append(FindNearestStage .of(property, vector, distanceMeasure))
159+
160+ fun findNearest (
161+ propertyField : String ,
162+ vector : Expr ,
163+ distanceMeasure : FindNearestStage .DistanceMeasure ,
164+ ) = append(FindNearestStage .of(propertyField, vector, distanceMeasure))
165+
166+ fun findNearest (stage : FindNearestStage ) = append(stage)
156167
157168 fun replace (field : String ): Pipeline = replace(Field .of(field))
158169
@@ -165,34 +176,36 @@ internal constructor(
165176
166177 fun union (other : Pipeline ): Pipeline = append(UnionStage (other))
167178
168- fun unnest (field : String , alias : String ): Pipeline = unnest(Field .of(field).alias(alias))
169-
170- fun unnest (field : String , alias : String , options : UnnestOptions ): Pipeline =
171- unnest(Field .of(field).alias(alias), options)
179+ fun unnest (field : String , alias : String ): Pipeline = unnest(UnnestStage .withField(field, alias))
172180
173181 fun unnest (selectable : Selectable ): Pipeline = append(UnnestStage (selectable))
174182
175- fun unnest (selectable : Selectable , options : UnnestOptions ): Pipeline =
176- append(UnnestStage (selectable))
183+ fun unnest (stage : UnnestStage ): Pipeline = append(stage)
177184
178185 private inner class ObserverSnapshotTask : PipelineResultObserver {
179186 private val userDataWriter =
180187 UserDataWriter (firestore, DocumentSnapshot .ServerTimestampBehavior .DEFAULT )
181188 private val taskCompletionSource = TaskCompletionSource <PipelineSnapshot >()
182189 private val results: ImmutableList .Builder <PipelineResult > = ImmutableList .builder()
183- override fun onDocument (key : DocumentKey ? , data : Map <String , Value >, version : SnapshotVersion ) {
190+ override fun onDocument (
191+ key : DocumentKey ? ,
192+ data : Map <String , Value >,
193+ createTime : Timestamp ? ,
194+ updateTime : Timestamp ?
195+ ) {
184196 results.add(
185197 PipelineResult (
186198 firestore,
187199 userDataWriter,
188200 if (key == null ) null else DocumentReference (key, firestore),
189201 data,
190- version
202+ createTime,
203+ updateTime
191204 )
192205 )
193206 }
194207
195- override fun onComplete (executionTime : SnapshotVersion ) {
208+ override fun onComplete (executionTime : Timestamp ) {
196209 taskCompletionSource.setResult(PipelineSnapshot (executionTime, results.build()))
197210 }
198211
@@ -205,24 +218,58 @@ internal constructor(
205218 }
206219}
207220
221+ /* * Start of a Firestore Pipeline */
208222class PipelineSource internal constructor(private val firestore : FirebaseFirestore ) {
223+
224+ /* *
225+ * Convert the given Query into an equivalent Pipeline.
226+ *
227+ * @param query A Query to be converted into a Pipeline.
228+ * @return Pipeline that is equivalent to [query]
229+ * @throws [IllegalArgumentException] Thrown if the [query] provided targets a different project
230+ * or database than the pipeline.
231+ */
209232 fun createFrom (query : Query ): Pipeline {
210233 if (query.firestore.databaseId != firestore.databaseId) {
211234 throw IllegalArgumentException (" Provided query is from a different Firestore instance." )
212235 }
213236 return query.query.toPipeline(firestore, firestore.userDataReader)
214237 }
215238
216- fun createFrom (query : AggregateQuery ): Pipeline =
217- createFrom(query.query)
239+ /* *
240+ * Convert the given Aggregate Query into an equivalent Pipeline.
241+ *
242+ * @param aggregateQuery An Aggregate Query to be converted into a Pipeline.
243+ * @return Pipeline that is equivalent to [aggregateQuery]
244+ * @throws [IllegalArgumentException] Thrown if the [aggregateQuery] provided targets a different
245+ * project or database than the pipeline.
246+ */
247+ fun createFrom (aggregateQuery : AggregateQuery ): Pipeline =
248+ createFrom(aggregateQuery.query)
218249 .aggregate(
219- * query.aggregateFields.map(AggregateField ::toPipeline).toTypedArray<AggregateWithAlias >()
250+ * aggregateQuery.aggregateFields
251+ .map(AggregateField ::toPipeline)
252+ .toTypedArray<AggregateWithAlias >()
220253 )
221254
255+ /* *
256+ * Set the pipeline's source to the collection specified by the given path.
257+ *
258+ * @param path A path to a collection that will be the source of this pipeline.
259+ * @return Pipeline with documents from target collection.
260+ */
222261 fun collection (path : String ): Pipeline =
223262 // Validate path by converting to CollectionReference
224263 collection(firestore.collection(path))
225264
265+ /* *
266+ * Set the pipeline's source to the collection specified by the given CollectionReference.
267+ *
268+ * @param ref A CollectionReference for a collection that will be the source of this pipeline.
269+ * @return Pipeline with documents from target collection.
270+ * @throws [IllegalArgumentException] Thrown if the [ref] provided targets a different project or
271+ * database than the pipeline.
272+ */
226273 fun collection (ref : CollectionReference ): Pipeline {
227274 if (ref.firestore.databaseId != firestore.databaseId) {
228275 throw IllegalArgumentException (
@@ -232,6 +279,11 @@ class PipelineSource internal constructor(private val firestore: FirebaseFiresto
232279 return Pipeline (firestore, firestore.userDataReader, CollectionSource (ref.path))
233280 }
234281
282+ /* *
283+ * Set the pipeline's source to the collection group with the given id.
284+ *
285+ * @param collectionid The id of a collection group that will be the source of this pipeline.
286+ */
235287 fun collectionGroup (collectionId : String ): Pipeline {
236288 Preconditions .checkNotNull(collectionId, " Provided collection ID must not be null." )
237289 require(! collectionId.contains(" /" )) {
@@ -240,12 +292,33 @@ class PipelineSource internal constructor(private val firestore: FirebaseFiresto
240292 return Pipeline (firestore, firestore.userDataReader, CollectionGroupSource (collectionId))
241293 }
242294
295+ /* *
296+ * Set the pipeline's source to be all documents in this database.
297+ *
298+ * @return Pipeline with all documents in this database.
299+ */
243300 fun database (): Pipeline = Pipeline (firestore, firestore.userDataReader, DatabaseSource ())
244301
302+ /* *
303+ * Set the pipeline's source to the documents specified by the given paths.
304+ *
305+ * @param documents Paths specifying the individual documents that will be the source of this
306+ * pipeline.
307+ * @return Pipeline with [documents].
308+ */
245309 fun documents (vararg documents : String ): Pipeline =
246310 // Validate document path by converting to DocumentReference
247311 documents(* documents.map(firestore::document).toTypedArray())
248312
313+ /* *
314+ * Set the pipeline's source to the documents specified by the given DocumentReferences.
315+ *
316+ * @param documents DocumentReferences specifying the individual documents that will be the source
317+ * of this pipeline.
318+ * @return Pipeline with [documents].
319+ * @throws [IllegalArgumentException] Thrown if the [documents] provided targets a different
320+ * project or database than the pipeline.
321+ */
249322 fun documents (vararg documents : DocumentReference ): Pipeline {
250323 val databaseId = firestore.databaseId
251324 for (document in documents) {
@@ -263,29 +336,70 @@ class PipelineSource internal constructor(private val firestore: FirebaseFiresto
263336 }
264337}
265338
339+ /* *
340+ */
266341class PipelineSnapshot
267- internal constructor (
268- private val executionTime: SnapshotVersion ,
269- val results: List <PipelineResult >
270- ) : Iterable <PipelineResult > {
342+ internal constructor (executionTime: Timestamp , results: List <PipelineResult >) :
343+ Iterable <PipelineResult > {
344+
345+ /* * The time at which the pipeline producing this result is executed. */
346+ val executionTime: Timestamp = executionTime
347+
348+ /* * List of all the results */
349+ val results: List <PipelineResult > = results
350+
271351 override fun iterator () = results.iterator()
272352}
273353
274354class PipelineResult
275355internal constructor (
276356 private val firestore: FirebaseFirestore ,
277357 private val userDataWriter: UserDataWriter ,
278- val ref: DocumentReference ? ,
358+ ref: DocumentReference ? ,
279359 private val fields: Map <String , Value >,
280- private val version: SnapshotVersion ,
360+ createTime: Timestamp ? ,
361+ updateTime: Timestamp ? ,
281362) {
282363
364+ /* * The time the document was created. Null if this result is not a document. */
365+ val createTime: Timestamp ? = createTime
366+
367+ /* *
368+ * The time the document was last updated (at the time the snapshot was generated). Null if this
369+ * result is not a document.
370+ */
371+ val updateTime: Timestamp ? = updateTime
372+
373+ /* *
374+ * The reference to the document, if the query returns the `__name__` field for a document. The
375+ * name field will be returned by default if querying a document.
376+ *
377+ * The `__name__` field will not be returned if the query projects away this field. For example:
378+ * ```
379+ * // this query does not select the `__name__` field as part of the select stage,
380+ * // so the __name__ field will not be in the output docs from this stage
381+ * db.pipeline().collection("books").select("title", "desc")
382+ * ```
383+ *
384+ * The `__name__` field will not be returned from queries with aggregate or distinct stages.
385+ *
386+ * @return [DocumentReference] Reference to the document, if applicable.
387+ */
388+ val ref: DocumentReference ? = ref
389+
283390 /* *
284391 * Returns the ID of the document represented by this result. Returns null if this result is not
285392 * corresponding to a Firestore document.
393+ *
394+ * @return ID of document, if applicable.
286395 */
287396 fun getId (): String? = ref?.id
288397
398+ /* *
399+ * Retrieves all fields in the result as an object map.
400+ *
401+ * @return Map of field names to objects.
402+ */
289403 fun getData (): Map <String , Any ?> = userDataWriter.convertObject(fields)
290404
291405 private fun extractNestedValue (fieldPath : FieldPath ): Value ? {
@@ -307,15 +421,32 @@ internal constructor(
307421 return value
308422 }
309423
424+ /* *
425+ * Retrieves the field specified by [field].
426+ *
427+ * @param field The field path (e.g. "foo" or "foo.bar") to a specific field.
428+ * @return The data at the specified field location or null if no such field exists.
429+ */
310430 fun get (field : String ): Any? = get(FieldPath .fromDotSeparatedPath(field))
311431
432+ /* *
433+ * Retrieves the field specified by [fieldPath].
434+ *
435+ * @param fieldPath The field path to a specific field.
436+ * @return The data at the specified field location or null if no such field exists.
437+ */
312438 fun get (fieldPath : FieldPath ): Any? = userDataWriter.convertValue(extractNestedValue(fieldPath))
313439
314- override fun toString () = " PipelineResult{ref=$ref , version= $version }, data=${getData()} "
440+ override fun toString () = " PipelineResult{ref=$ref , updateTime= $updateTime }, data=${getData()} "
315441}
316442
317443internal interface PipelineResultObserver {
318- fun onDocument (key : DocumentKey ? , data : Map <String , Value >, version : SnapshotVersion )
319- fun onComplete (executionTime : SnapshotVersion )
444+ fun onDocument (
445+ key : DocumentKey ? ,
446+ data : Map <String , Value >,
447+ createTime : Timestamp ? ,
448+ updateTime : Timestamp ?
449+ )
450+ fun onComplete (executionTime : Timestamp )
320451 fun onError (exception : FirebaseFirestoreException )
321452}
0 commit comments