-
Notifications
You must be signed in to change notification settings - Fork 1.1k
DATAMONGO-2138 - Type-safe Kotlin query extension #622
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
Conversation
@TjeuKayim Please sign the Contributor License Agreement! Click here to manually synchronize the status of this Pull Request. See the FAQ for frequently asked questions. |
@TjeuKayim Thank you for signing the Contributor License Agreement! |
I am very reluctant to introduce changes in the type signature to cater a Kotlin extension. We don't want to add complexity for our Java developers (still more than 90% of our user base) that doesn't provide any obvious benefit. So far, the extensions we added didn't require those kinds of changes and I'd love to see that stay this way. |
You’re right. We should change as less Java as possible, and just add Kotlin extensions. I’m just trying to fit the new class |
b009401
to
fc5e59b
Compare
I am finally convinced that is it better not to change the signature of |
How would an example look like when querying nested properties? ( |
I'm not sure how we should handle nested properties. |
We can also consider 'typed updates'. operations.updateFirst(Book::name isEqualTo "Moby-Dick", set(Book::price, 11)) |
At first, I wanted to restricts the KProperty to members of the Entity class, but it requires much coding to make that work. Every use of Query as parameter will need an Kotlin extension, and the type parameter should be passed through to Criteria. |
Let's focus on find operations right now and make sure that we can query properties across the document – basically let's support the same criteria features as we do with the regular |
09c3cca
to
c6a49cd
Compare
This version has typed criteria builder functions for |
Let's discuss the syntax for typed queries.
What do you think? |
API usage should impose as little constraints as possible on client code in terms of technical constraints. Importing functions bears the risk of clashing with existing application code/external code. Examples 2 and 3 read naturally and if option 2 could clash with other imported functions, then option 3 seems the way to go. Reading criteria within a closure easily associates the We should also consider criteria {
Book::name isEqualTo "Moby-Dick"
or {
Book::price lt 1200
Book::price gt 240
}
} |
Looks nice! I was also imagining such "or" queries. |
All |
Pretty decent work, I did a more in-depth review pass and found only minor issues such as formatting and we typically use AssertJ for assertions. Maybe @sdeleuze can have also a look once you're done with changes. We'd like to include the change in the upcoming milestone release 2.2 M1 in early December. Once this PR is merged, we could have a look on typed updates. |
Thank you for the positive feedback! 😃 |
I will have look Monday asap back for vacation if that timing is ok from a Spring Data release perspective. |
What specific formatting rules do you mean @mp911de? Also, should I start test methods with a line break? |
Thanks @TjeuKayim for this contribution. I think there are issues in the API design that we need to fix before merging that PR. For example I am wondering if we could improve logical operators since I am not super fond of the following syntax:
I think the root issue is that the API is not composable ( What about just using
To That seems closer to the Java API principle, while leveraging Kotlin capabilities to provide a more readable syntax. Any thought? |
I don't think the two statements are the same. This: Criteria("title").isEqualTo("Moby-Dick")
.orOperator(Criteria("price").lt(1200), Criteria("price").gt(240)); is probably meant to be: (Book::title isEqualTo "Moby-Dick") and (Book::price lt 1200 or Book::price.gt 240) Note the swapped |
Alright then. Let's use top level functions, like before bc12a92. |
I did a quick refactor to change the syntax. mongoOperations.find<Book>(Query(
Book::name isEqualTo "Moby-Dick"
))
typedCriteria(
Book::name isEqualTo "Moby-Dick",
orOperator(
Book::price lt 1200,
Book::price gt 240
)
) |
I think these expressions should match: (Book::title isEqualTo "Moby-Dick") and ((Book::price lt 1200) or (Book::price gt 240))
Criteria().andOperator(
Criteria("title").isEqualTo("Moby-Dick"),
Criteria().orOperator(Criteria("price").lt(1200), Criteria("price").gt(240))
) |
|
Do you mean that |
@TjeuKayim Do you think it could be possible to make |
That's probably a good idea. |
10737a7
to
29f4bca
Compare
We should stick to |
@mp911de I agree with your last comment and your proposal to deal with that in 2 steps. |
@TjeuKayim Please ping me when I can review the PR updated according to @mp911de feedback, I would like to have a look before the merge. |
I also prefer this syntax What other features should be included in this pull request? Accidentally hit the "Close" button on my smartphone |
Exactly. Please also squash your commits. This makes it easier to merge. |
a5111dc
to
447ccb2
Compare
@sdeleuze, you can review the PR if you like. How can you set asciidoctor's output to HTML? (I'm using the Maven plugin) |
Not sure I follow. Do you want to generate the reference documentation? If so, then run Maven with the
You can find the generated documentation in |
Yes, I wanted to generate the reference documentation, but used the wrong maven command. With the distribute profile, it’s working. Thank you helping. Where should I add the documentation for this feature? I was thinking of a new subheading below “Additional Query Options”, and calling it “Typed Queries for Kotlin”. |
e348980
to
6907000
Compare
Thanks @TjeuKayim, the latest commit is ok for me. |
Awesome work @TjeuKayim. Let's move |
Great tot hear that. 😃 |
6907000
to
796a282
Compare
I placed the documentation after |
796a282
to
a8d8996
Compare
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.
Thanks a lot. We'll take this pull request from here.
We now support type-safe queries using Kotlin's DSL capabilities by accepting property references. Property references map to property paths and are translated to Criteria objects. mongoOperations.find<Book>( Query(Book::title isEqualTo "Moby-Dick") ) mongoOperations.find<Book>( Query(Book::title exists true) ) mongoOperations.find<Book>( Query(Criteria().andOperator( Book::price gt 5, Book::price lt 10) )) Original pull request: #622.
Rename NestedProperty to KPropertyPath to reflect the underlying concept in alignment with our own PropertyPath type. Rename nestedFieldName(…) method to asString(…) to align with Kotlin method terminology. Reformat. Slightly reword documentation. Add Type-safe Queries for Kotlin to What's New section. Original pull request: #622.
That's merged and polished now. Thanks a lot for this excellent pull request. |
https://jira.spring.io/browse/DATAMONGO-2138
I'm suggesting to add Kotlin extensions for "type-safe queries". This will prevent typos in field names, and improve the readability of a query.
New Query Syntax
We can achieve type safe queries with Kotlin's Property References.
To-Do
Criteria
features.