-
Notifications
You must be signed in to change notification settings - Fork 311
Add Ahead of Time Repository support #1600
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
|
|
||
| return switch (like.getType()) { | ||
|
|
||
| case CONTAINING -> "\"%\" + " + parameterName + " + \"%\""; |
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.
is there a need to escape the value of the parameter?
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.
...dra/src/main/java/org/springframework/data/cassandra/repository/aot/CassandraCodeBlocks.java
Outdated
Show resolved
Hide resolved
| expressionString = "#{" + expressionString + "}"; | ||
| } | ||
|
|
||
| builder.add("evaluateExpression($L, $S$L)", context.getExpressionMarker().enclosingMethod(), expressionString, |
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.
Having a CodeBlock that concats $S with $L given the provided arguments makes me think parameterNames should maybe be represented differently. Right now it seems to render a magic switch that separates arguments used to call a specific variant of the evaluateExpressionMethod making this piece pretty hard to understand.
|
|
||
| if (StringUtils.hasText(context.getDynamicProjectionParameterName())) { | ||
|
|
||
| builder.addStatement("$1T<$2T> $3L = $4L.query($5L).as($6L)", |
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.
no need to use index numbers when there're no repeating arguments. doesn't harm having them.
| } else if (query.isExists()) { | ||
| terminatingMethod = "count() > 0"; | ||
| } else if (query.isLimited()) { | ||
| terminatingMethod = "firstValue()"; |
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.
does a limited query only return the first available result? Not too familiar with the cassandra domain, but shouldn't this be like a limit to a certain number of results at most (aka TopN results)?
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.
isLimited is a fallback. TopN for collection queries is handled through .isCollectionQuery() a few lines above. This instance here is for User findFirst(…) while User findTop10(…) could work as well.
416569d to
f6b7103
Compare
…ts, and building statement fragments from collections providing argument inputs.
| it.addAll(query, ".and(", (criteria, builder) -> { | ||
| builder.add("$1T.where($2S)", Criteria.class, criteria.getColumnName().toCql()); | ||
| appendPredicate(criteria, builder); | ||
| builder.add(")"); |
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.
addAll seems to be a nice shortcut for appending multiple parts at once.
I wonder if readability suffers a bit from it, like having the closing bracket being added in a nested builder is confusing.
|
|
||
| boolean first = true; | ||
| for (Sort.Order order : sort) { | ||
| invocation.arguments(sort, (order, builder) -> { |
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.
would it make sense to split the argument from the rendering? thinking of invocation.addArgument(sort).as((argument) -> ... return ) where we do not pass in the builder but have a function that returns a new code block.
as might event be optional if the argument can be rendered as is using $L.
We now provide AOT support to generate repository implementations during build-time for Cassandra repository query methods.
Supported Features
@Queryand named query methods.Window,Slice,Stream, andOptionalreturn typesMind that using Value Expressions requires expression parsing and contextual information to evaluate the expression)
Limitation
Excluded methods
CrudRepositoryand other base interface methods as their implementation is provided by the base class respective fragmentsExample repository:
Generated fragment:
Metadata (truncated):
{ "name": "org.springframework.data.cassandra.repository.aot.PersonRepository", "module": "Cassandra", "type": "IMPERATIVE", "methods": [ { "name": "findByFirstname", "signature": "public abstract org.springframework.data.cassandra.domain.Person org.springframework.data.cassandra.repository.aot.PersonRepository.findByFirstname(java.lang.String)", "query": { "query": "SELECT * FROM person WHERE firstname=?" } }, { "name": "streamDtoProjectionByFirstname", "signature": "public abstract java.util.stream.Stream<org.springframework.data.cassandra.repository.aot.PersonRepository$PersonDto> org.springframework.data.cassandra.repository.aot.PersonRepository.streamDtoProjectionByFirstname(java.lang.String)", "query": { "query": "SELECT * FROM person WHERE firstname=?" } }, { "name": "findDeclaredNumberOfChildrenByFirstname", "signature": "public abstract int org.springframework.data.cassandra.repository.aot.PersonRepository.findDeclaredNumberOfChildrenByFirstname(java.lang.String)", "query": { "query": "select numberOfChildren from person where firstname = ?" } }, { "name": "findWindowByLastname", "signature": "public abstract org.springframework.data.domain.Window<org.springframework.data.cassandra.domain.Person> org.springframework.data.cassandra.repository.aot.PersonRepository.findWindowByLastname(java.lang.String,org.springframework.data.domain.ScrollPosition,org.springframework.data.domain.Limit)", "query": { "query": "SELECT * FROM person WHERE lastname=?" } } ] }