-
Notifications
You must be signed in to change notification settings - Fork 30
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
Add Criteria-Based Filtering #894
Conversation
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
I see both working together:
Instead of having one API for each other, |
api/src/main/java/jakarta/data/metamodel/FilterableAttribute.java
Outdated
Show resolved
Hide resolved
api/src/main/java/jakarta/data/repository/CriteriaRepository.java
Outdated
Show resolved
Hide resolved
api/src/main/java/jakarta/data/metamodel/FilterableAttribute.java
Outdated
Show resolved
Hide resolved
Some comments:
Apart from those comments this is pretty much along the lines of what I was hoping for. |
Yes, this is generally the right ideas.
agree
agree (I actually have some of this coded up locally using the name Restriction, but hadn't finished it yet)
I've been going back and forth on how best to handle not/negate. There are other options as well beyond what is in this PR. I need to think about this some more.
yes
First, I don't think we need a CriteriaRepository. But the same issue would arise regardless when a user composes a method with multiple restrictions. The way I wrote it up (and which I've also tried locally) is to have Restrict.all(Restriction...) and Restrict.any(Restriction...) which basically covers item 4 above (ignoring that I'm still considering options for item 3 on not/negate)
I'm very much in favor of |
Yup, that's exactly what I meant by following the precedent already established by |
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Done
Do you have any suggestion of how?
My initial thought was, by default, working only with
I've created a collection representation, what do you think? |
@njr-11 could you bring it to this PR? |
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
@njr-11 @gavinking does it makes sense? |
OK, so this is quite a bit different now. :) I have two questions:
|
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
For sure, we can change it |
This is an excellent idea. It eliminates the problem that would have occurred if any annotation processors were supplying their own *Attribute implementations rather than using the provided ones. With the default methods in place, even if they were doing that, there will be no breaking change at all. |
Co-authored-by: Nathan Rauh <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
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.
feel free to open PR as well.
We do have all of the Restriction changes only (minus JavaDoc which I don't think we should be adding yet while there are so many API changes still going on) split out under #895 which Gavin has reviewed.
Regarding Pattern, we are getting closer. Here is my review of what you have for the Pattern class under this PR. A general comment is that it's important to account for the possibility that the Strings supplied to endsWith, contains, and so forth will include wildcard characters within them and will behave as patterns as well. My code suggestions included covering that possibility.
* </pre> | ||
* | ||
*/ | ||
public record Pattern(String value, boolean ignoreCase) { |
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.
You should not have ignoreCase as a field of Pattern. I understand logically it could make sense, but it is already a field of Restriction, and it is confusing to have it in both places where users will wonder which takes precedence,
employees.search(
Restriction.like(new Pattern(prefixPattern, ignoreCase = false)).ignoreCase());
It would also be confusing in places like this:
employees.findByLastNameIgnoreCaseLike(new Pattern(prefixPattern, ignoreCase = false));
Omit it from Pattern and none of the above will even be possible.
Also, value
is confusing. Specifically, this is a pattern for LIKE. If someone does,
String prefix = "Jakarta";
Pattern jakartaPrefixPattern = new Pattern(prefix
it won't actually behave as a prefix. We are going to need to make this very clear so it isn't misused (any maybe we don't even want to use a record with a public constructor)
I'm not sure what best to call it. Here is something I thought of quickly,
public record Pattern(String value, boolean ignoreCase) { | |
public record Pattern(String like) { |
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.
You should not have ignoreCase as a field of Pattern.
I don't agree with this. One of the main nice things about Pattern
is that it encapsulates case-sensitivity.
By original proposal was:
public record Pattern(String pattern, boolean caseSensitive) {
public Pattern ignoringCase() {
return new Pattern(pattern, false);
}
public static Pattern is(String literal) {
return new Pattern(escape(literal), true);
}
public static Pattern matches(String pattern) {
return new Pattern(pattern, true);
}
public static Pattern matches(String pattern,
char characterWildcard, char stringWildcard) {
final String standardized =
escape(pattern)
.replace(characterWildcard, '_')
.replace(stringWildcard, '%');
return new Pattern(standardized, true);
}
public static Pattern startsWith(String prefix) {
return new Pattern(escape(prefix) + '%', true);
}
public static Pattern endsWith(String suffix) {
return new Pattern('%' + escape(suffix), true);
}
public static Pattern contains(String substring) {
return new Pattern('%' + escape(substring) + '%', true);
}
private static String escape(String literal) {
return literal.replace("_", "\\_").replace("%", "\\%");
}
}
Where, the idea was that users would not usually call the constructor to obtain a Pattern
.
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.
Irrespective of the discussion on ignoringCase, the automatic escaping that you proposed above seems very useful, and helps users avoid unintentional wildcards in their prefix/suffix/substring, which can be literals now instead of patterns. I like that better than what is under this PR.
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.
Nice, I agreed.
I moved this class to our PR.
Co-authored-by: Nathan Rauh <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
About Pattern, I used the same Gavin. On your PR, I moved without keeping out the NOT condition, at least for now. |
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Signed-off-by: Otavio Santana <[email protected]>
Hey, I've covered all the mentioned points, and I believe what we have here is good enough to merge and become our first draft version. Once merged, we can go more scalable, I mean, create an Epic task where we can work on: Spec documentation Note: I believe that is a long journey. I would like to propose the first step here. |
This isn't making progress because you are trying to do too much at once in a single PR. I stopped reviewing the rest of the code under this PR because I don't agree with what is being done in Pattern and it is unclear to me at this point whether or not we should even have Pattern and Range. Decisions such as whether to have those, or whether or not to have |
I got your point. In my opinion, those should work as a single one; they should either go together or not go, mainly, because those new types,
I don't mind working the whole year in a single branch, but those features should work together. |
If #895 shows that to be the case because it has provided
which is much cleaner than what you have them doing in your PR,
Note that you have ignoreCase as default for Pattern with the only way to avoid it being to construct a Pattern instance. Even if you correct that, you end up with something like,
Not only is it unnecessary for Restriction and Pattern to go together, in almost all cases where users want Restrictions, adding in Pattern will only be unwanted extra typing that doesn't provide any additional value to the user. |
About About you said, we have access to exactly same methods, thus: You can do those as well:
|
I don't think you are understanding the point. You seem to be arguing that it would be invalid to add Restriction without Pattern because then you could only do,
but not also,
Those latter two examples are redundant, more verbose, and provide no additional value. This is not a valid reason to claim that Pattern must be introduced along with Restriction. |
Yeap, I am lost here because at default Restriction<T> like(Pattern pattern)... Thus, we can do this since
We also have Plus, we also have support for Thus, we have those as supported. Right now, Do you want to remove the method? default Restriction<T> like(Pattern pattern)... |
This PR introduces enhanced attribute-based querying capabilities to Jakarta Data, consolidating query construction into Attribute, SortableAttribute, and TextAttribute interfaces with corresponding implementations. These updates provide: