New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add support for Partition API #1320
Conversation
4f8d7b4
to
5438615
Compare
Codecov Report
@@ Coverage Diff @@
## master #1320 +/- ##
==========================================
- Coverage 98.51% 98.49% -0.02%
==========================================
Files 30 32 +2
Lines 18760 19111 +351
Branches 1451 1464 +13
==========================================
+ Hits 18481 18823 +342
- Misses 276 285 +9
Partials 3 3
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly left some commenting nits along with some questions
dev/src/query-partition.ts
Outdated
constructor( | ||
private readonly _firestore: Firestore, | ||
private readonly _collectionId: string, | ||
private readonly _converter: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this converter have to be undefined
here? QueryPartition
's converter comes from QueryOptions
, which always has FirestoreDataConverter
defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Simplified.
private _memoizedStartAt: unknown[] | undefined; | ||
private _memoizedEndBefore: unknown[] | undefined; | ||
|
||
constructor( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add hideconstructor
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
dev/src/collection-group.ts
Outdated
* @return {AsyncIterable<QueryPartition>} An AsyncIterable of | ||
* `QueryPartition`s. | ||
*/ | ||
async *getPartitionsAsync( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getPartitionsAsync()
's name was initially confusing to me, since I thought once the non-async one would be a function that had a : void
return signature. Both getPartitionsAsync()
and getPartitions()
are essentially async methods, which added to my confusion.
How about getPartititionsIterator
and getPartitionsPromise
, or something more along those lines (granted, those 2 names are the best)? Is there any other established pattern for methods that return an iterator vs. a promise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This follows the precedent in the generated Gapic library. I am kind of leaning towards removing the "non-async" method (which is also async) altogether. Streaming iterators are very easy to use, so maybe there is no benefit of exposing both methods. I will ask for opinions before merging.
dev/src/query-partition.ts
Outdated
* The cursor that defines the first result for this partition or `undefined` | ||
* if this is the first partition. | ||
* | ||
* @return a cursor value that can be used with {@link Query#startAt} or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding other annotations (@return, @type, etc.) like in other getters. As it stands, the docs file looks pretty bare: https://screenshot.googleplex.com/mNvFsQh4X2E2msJ.png.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. We should always do this for JSDoc.
dev/src/query-partition.ts
Outdated
/** | ||
* Returns a query that only returns the documents for this partition. | ||
* | ||
* @return a query partitioned by a {@link Query#startAt} and {@link |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding return type: {Query<T>}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
dev/src/query-partition.ts
Outdated
* The cursor that defines the first result for this partition or `undefined` | ||
* if this is the first partition. | ||
* | ||
* @return a cursor value that can be used with {@link Query#startAt} or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uber-nit: s/a cursor/A cursor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
dev/src/query-partition.ts
Outdated
} | ||
|
||
/** | ||
* Returns a query that only returns the documents for this partition. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider: Returns a query that only contains documents for/inside this partition.
Technically, a query doesn't "return" the documents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used encapsulates
. Let me know what you think.
dev/test/partition-query.ts
Outdated
expect(actual).to.deep.eq(query); | ||
} | ||
|
||
export function result(documentId: string): api.IRunQueryResponse { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete unused function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops
queryOptions = queryOptions.with({ | ||
startAt: {before: true, values: this._startAt}, | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how important it is to test L105-108, but codecov is complaining about missing tests here. Flagging this in-case you missed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a test that should cover this.
types/firestore.d.ts
Outdated
* The cursor that defines the first result for this partition or | ||
* `undefined` if this is the first partition. | ||
* | ||
* @return cursor values that can be used with {@link Query#startAt} or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "destructure" comment was hard for me to follow, consider adding an example of how to do so properly?
Also, consider adding test for query.startAt(..queryPartition.start)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added examples for all methods and expanded on the description of the return type. Also added test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, those were some pretty sleek tests
/** | ||
* A `CollectionGroup` refers to all documents that are contained in a | ||
* collection or subcollection with a specific collection ID. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need add the CollectionGroup
after @class
, or else the constructor will still appear. Not sure why, but I regenerated the docs and still see the constructor with your current PR.
* A split point that can be used in a query as a starting and/or end point for | ||
* the query results. The cursors returned by {@link #startAt} and {@link | ||
* #endBefore} can only be used in a query that matches the constraint of query | ||
* that produced this partition. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above.
@@ -194,6 +196,126 @@ describe('Firestore class', () => { | |||
}); | |||
}); | |||
|
|||
describe('CollectionGroup class', () => { | |||
const desiredPartitionCount = 3; | |||
const documentCount = 2 * 128 + 127; // Minimum partition size is 128. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, just caught this, but why is the minimum partition size 128? I didn't see this requirement elsewhere in the code. Also, is this something the developer needs to know?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the partition size, but rather the minimum result set size in order for partitions to work. If a collection group has fewer than 128 documents, then it will not be partitioned. This is deemed acceptable with the current API as the provided partition count value is documented to be best effort.
@BenWhitehead Can you take a look at this as well? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Superficial LGTM.
The signatures look in line with the design set forward in the Java PR. But I don't know the knitty gritty of typescript so can't comment on that.
Discussed offline with @bcoe. We may add a |
This adds support for the Partition API.
Port of googleapis/java-firestore#202