| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Codecov Report
@@ Coverage Diff @@
## master #4652 +/- ##
============================================
+ Coverage 49.67% 49.68% +<.01%
- Complexity 22300 22308 +8
============================================
Files 2238 2238
Lines 221344 221337 -7
Branches 24079 24069 -10
============================================
+ Hits 109949 109967 +18
+ Misses 102937 102924 -13
+ Partials 8458 8446 -12
Continue to review full report at Codecov.
|
Sorry, something went wrong.
There was a problem hiding this comment.
lgtm with a bunch of nits.
Sorry, something went wrong.
|
|
||
| QueryOptions that = (QueryOptions) o; | ||
|
|
||
| if (allDescendants != that.allDescendants) { |
There was a problem hiding this comment.
nit: Is there reasoning for this order? If not, then consider reordering to match the declaration order. (If certain variables are more likely to differ, that might be a legit reason to prioritize checking those ones in the presence of a tight loop.)
Sorry, something went wrong.
There was a problem hiding this comment.
This is auto-generated code by IntelliJ (and not by AutoValue).
Sorry, something went wrong.
| fieldFilters = new ArrayList<>(); | ||
| fieldOrders = new ArrayList<>(); | ||
| fieldProjections = new ArrayList<>(); | ||
| protected static class QueryOptions { |
There was a problem hiding this comment.
Unless there's a reason not to, you should probably make this class final.
Sorry, something went wrong.
There was a problem hiding this comment.
I updated this class to use AutoValue.
Sorry, something went wrong.
|
|
||
| if (allDescendants != that.allDescendants) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Consider refactoring to look like this: http://go/java-practices/equals#impl
Specifically:
a) optionally drop the this==o check unless you think it's useful.
b) use instanceof instead of getClass. (Less relevant if you mark this class final.)
c) Instead of using 3 lines per variable, just use ~1 per variable, i.e.:
return (foo == that.foo && bar == that.bar && ...);
Entirely optional.
Sorry, something went wrong.
There was a problem hiding this comment.
As above, this is auto-generated and now replaced by AutoValue.
Sorry, something went wrong.
| fieldFilters = new ArrayList<>(); | ||
| fieldOrders = new ArrayList<>(); | ||
| fieldProjections = new ArrayList<>(); | ||
| protected static class QueryOptions { |
There was a problem hiding this comment.
Can we just use go/autovalue here? (public link: https://github.com/google/auto/blob/master/value/userguide/index.md)
If we can, it'd cut this down by quite a lot.
Sorry, something went wrong.
There was a problem hiding this comment.
I changed this to use AutoValue as suggested. I personally don't consider this an improvement, as it adds a lot of indirection. QueryOptions was treated by me like a value struct, but its immutability was merely by design. With AutoValue and with the migration to ImmutableList, this is now enforced in code.
Sorry, something went wrong.
| fieldProjections = new ArrayList<>(); | ||
| protected static class QueryOptions { | ||
|
|
||
| ResourcePath parentPath; |
There was a problem hiding this comment.
These instance variables should all be final too. http://go/java-practices/final#fields.
(Or at least final where possible. I'm haven't checked to see if these are reassigned or not. Hopefully mostly not.)
Sorry, something went wrong.
There was a problem hiding this comment.
They were reassigned as part of my "builder-light" pattern:
Options newOptions = new Options(oldOptions); newOptions.foo = bar;
This is no longer applicable.
Sorry, something went wrong.
| Query(FirestoreImpl firestore, ResourcePath path) { | ||
| this(firestore, path, new QueryOptions()); | ||
| this.firestore = firestore; | ||
| this.options = new QueryOptions(path.getParent(), path.getId()); |
There was a problem hiding this comment.
Seems reasonable, but consider delegating to the private ctor anyway, i.e.:
Query(firestore, path) {
this(firestore, new QueryOptoins(path.getParent(), path.getId());
}
Sorry, something went wrong.
There was a problem hiding this comment.
Done.
Sorry, something went wrong.
|
|
||
| this.firestore = firestore; | ||
| this.path = path; | ||
| this.options = queryOptions; |
There was a problem hiding this comment.
Similarly, consider delegating to the primary ctor. Optional.
Also note that this ctor (and the other one above) could also be rephrased as static factory methods. (Which would allow you to rename them to something other than 'Query'. Whether that's useful or not is up to you.)
Sorry, something went wrong.
There was a problem hiding this comment.
I made this change, which is now possible thanks to the QueryOptions.Builder. Without it, I had no way to initialize allDescendants.
I opted not to make these factory methods since CollectionReference inherits from Query and I like the consistency of having two constructors rather than one constructor and one factory method.
Sorry, something went wrong.
| Query query = firestoreMock.collectionGroup("foo/bar"); | ||
| fail(); | ||
| } catch (IllegalArgumentException e) { | ||
| assertEquals( |
There was a problem hiding this comment.
This is fine. Personally, I find it slightly over-specified. (I'd just remove the assertEquals entirely.) Feel free to leave as is.
Sorry, something went wrong.
There was a problem hiding this comment.
Acknowledged.
Sorry, something went wrong.
|
|
||
| assertEquals(begin(), requests.get(0)); | ||
| assertEquals(query(TRANSACTION_ID), requests.get(1)); | ||
| assertEquals(query(TRANSACTION_ID, false), requests.get(1)); |
There was a problem hiding this comment.
I've forgotten what the second parameter is (and am too lazy to look it up.) Consider one of the options here:
http://go/java-practices/boolean-parameters
Sorry, something went wrong.
There was a problem hiding this comment.
Added /* allDescendants= */ as a comment. Thanks
Sorry, something went wrong.
There was a problem hiding this comment.
I addressed your feedback and bit the bullet by moving to AutoValue.
Sorry, something went wrong.
| fieldFilters = new ArrayList<>(); | ||
| fieldOrders = new ArrayList<>(); | ||
| fieldProjections = new ArrayList<>(); | ||
| protected static class QueryOptions { |
There was a problem hiding this comment.
I updated this class to use AutoValue.
Sorry, something went wrong.
| fieldFilters = new ArrayList<>(); | ||
| fieldOrders = new ArrayList<>(); | ||
| fieldProjections = new ArrayList<>(); | ||
| protected static class QueryOptions { |
There was a problem hiding this comment.
I changed this to use AutoValue as suggested. I personally don't consider this an improvement, as it adds a lot of indirection. QueryOptions was treated by me like a value struct, but its immutability was merely by design. With AutoValue and with the migration to ImmutableList, this is now enforced in code.
Sorry, something went wrong.
| fieldProjections = new ArrayList<>(); | ||
| protected static class QueryOptions { | ||
|
|
||
| ResourcePath parentPath; |
There was a problem hiding this comment.
They were reassigned as part of my "builder-light" pattern:
Options newOptions = new Options(oldOptions); newOptions.foo = bar;
This is no longer applicable.
Sorry, something went wrong.
|
|
||
| QueryOptions that = (QueryOptions) o; | ||
|
|
||
| if (allDescendants != that.allDescendants) { |
There was a problem hiding this comment.
This is auto-generated code by IntelliJ (and not by AutoValue).
Sorry, something went wrong.
|
|
||
| if (allDescendants != that.allDescendants) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
As above, this is auto-generated and now replaced by AutoValue.
Sorry, something went wrong.
| Query(FirestoreImpl firestore, ResourcePath path) { | ||
| this(firestore, path, new QueryOptions()); | ||
| this.firestore = firestore; | ||
| this.options = new QueryOptions(path.getParent(), path.getId()); |
There was a problem hiding this comment.
Done.
Sorry, something went wrong.
|
|
||
| this.firestore = firestore; | ||
| this.path = path; | ||
| this.options = queryOptions; |
There was a problem hiding this comment.
I made this change, which is now possible thanks to the QueryOptions.Builder. Without it, I had no way to initialize allDescendants.
I opted not to make these factory methods since CollectionReference inherits from Query and I like the consistency of having two constructors rather than one constructor and one factory method.
Sorry, something went wrong.
| Query query = firestoreMock.collectionGroup("foo/bar"); | ||
| fail(); | ||
| } catch (IllegalArgumentException e) { | ||
| assertEquals( |
There was a problem hiding this comment.
Acknowledged.
Sorry, something went wrong.
|
|
||
| assertEquals(begin(), requests.get(0)); | ||
| assertEquals(query(TRANSACTION_ID), requests.get(1)); | ||
| assertEquals(query(TRANSACTION_ID, false), requests.get(1)); |
There was a problem hiding this comment.
Added /* allDescendants= */ as a comment. Thanks
Sorry, something went wrong.
|
This is no longer blocked and needs sign off from the Yoshi team. |
Sorry, something went wrong.
There was a problem hiding this comment.
Just a question on whether or not to add a getter method. Otherwise, LGTM.
Sorry, something went wrong.
| QueryTarget.newBuilder() | ||
| .setStructuredQuery(query.buildQuery()) | ||
| .setParent(query.getResourcePath().getParent().getName()) | ||
| .setParent(query.options.getParentPath().getName()) |
There was a problem hiding this comment.
Any particular reason for direct field access vs. a getter? We provide getFirestore() on query, but not getOptions().
Sorry, something went wrong.
There was a problem hiding this comment.
options is purely an internal field that is only used inside the client. We could still use a getOptions() here, but I felt that making it package-private was safe enough.
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
CollectionGroup queries add support for queries to Firestore that query documents by collection ID rather than by collection path. With this feature, users can now query for documents in collections that share a name, no matter where these collection are located.
This the server port of firebase/firebase-android-sdk#233, meaning there is less input validation (since the backend does most of it for us) and there is no local logic to execute these queries.
Note: This PR is blocked on a backend release.