Skip to content

Commit 845453a

Browse files
committed
Explore returning Search Results.
1 parent 21a48f4 commit 845453a

19 files changed

+626
-68
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717

1818
import java.util.Iterator;
1919
import java.util.List;
20+
import java.util.function.BiFunction;
2021
import java.util.stream.Stream;
2122

2223
import org.jspecify.annotations.Nullable;
24+
2325
import org.springframework.dao.DataAccessException;
2426
import org.springframework.data.cassandra.core.convert.CassandraConverter;
2527
import org.springframework.data.cassandra.core.cql.CqlOperations;
@@ -33,6 +35,7 @@
3335
import com.datastax.oss.driver.api.core.CqlIdentifier;
3436
import com.datastax.oss.driver.api.core.cql.BatchType;
3537
import com.datastax.oss.driver.api.core.cql.ResultSet;
38+
import com.datastax.oss.driver.api.core.cql.Row;
3639
import com.datastax.oss.driver.api.core.cql.Statement;
3740

3841
/**
@@ -92,7 +95,7 @@ default CassandraBatchOperations batchOps() {
9295
/**
9396
* The table name used for the specified class by this template.
9497
*
95-
* @param entityClass The entity type must not be {@literal null}.
98+
* @param entityClass the entity type must not be {@literal null}.
9699
* @return the {@link CqlIdentifier}
97100
*/
98101
CqlIdentifier getTableName(Class<?> entityClass);
@@ -105,7 +108,7 @@ default CassandraBatchOperations batchOps() {
105108
* Execute a {@code SELECT} query and convert the resulting items to a {@link List} of entities.
106109
*
107110
* @param cql must not be {@literal null}.
108-
* @param entityClass The entity type must not be {@literal null}.
111+
* @param entityClass the entity type must not be {@literal null}.
109112
* @return the converted results
110113
* @throws DataAccessException if there is any problem executing the query.
111114
*/
@@ -129,7 +132,7 @@ default CassandraBatchOperations batchOps() {
129132
* Execute a {@code SELECT} query and convert the resulting item to an entity.
130133
*
131134
* @param cql must not be {@literal null}.
132-
* @param entityClass The entity type must not be {@literal null}.
135+
* @param entityClass the entity type must not be {@literal null}.
133136
* @return the converted object or {@literal null}.
134137
* @throws DataAccessException if there is any problem executing the query.
135138
*/
@@ -154,18 +157,32 @@ default CassandraBatchOperations batchOps() {
154157
* Execute a {@code SELECT} query and convert the resulting items to a {@link List} of entities.
155158
*
156159
* @param statement must not be {@literal null}.
157-
* @param entityClass The entity type must not be {@literal null}.
160+
* @param entityClass the entity type must not be {@literal null}.
158161
* @return the converted results
159162
* @throws DataAccessException if there is any problem executing the query.
160163
*/
161164
<T> List<T> select(Statement<?> statement, Class<T> entityClass) throws DataAccessException;
162165

166+
/**
167+
* Execute a {@code SELECT} query and convert the resulting items to a {@link List} of entities considering the given
168+
* {@link BiFunction mapping function}.
169+
*
170+
* @param statement must not be {@literal null}.
171+
* @param entityClass the entity type must not be {@literal null}.
172+
* @param mapper mapping function invoked after materializing {@code entityClass} must not be {@literal null}.
173+
* @return the converted results
174+
* @throws DataAccessException if there is any problem executing the query.
175+
* @since 5.0
176+
*/
177+
<S, T> List<T> select(Statement<?> statement, Class<S> entityClass, BiFunction<S, Row, T> mapper)
178+
throws DataAccessException;
179+
163180
/**
164181
* Execute a {@code SELECT} query with paging and convert the result set to a {@link Slice} of entities. A sliced
165182
* query translates the effective {@link Statement#getFetchSize() fetch size} to the page size.
166183
*
167184
* @param statement the CQL statement, must not be {@literal null}.
168-
* @param entityClass The entity type must not be {@literal null}.
185+
* @param entityClass the entity type must not be {@literal null}.
169186
* @return the converted results
170187
* @throws DataAccessException if there is any problem executing the query.
171188
* @since 2.0
@@ -190,7 +207,7 @@ default CassandraBatchOperations batchOps() {
190207
* Execute a {@code SELECT} query and convert the resulting item to an entity.
191208
*
192209
* @param statement must not be {@literal null}.
193-
* @param entityClass The entity type must not be {@literal null}.
210+
* @param entityClass the entity type must not be {@literal null}.
194211
* @return the converted object or {@literal null}.
195212
* @throws DataAccessException if there is any problem executing the query.
196213
*/
@@ -204,7 +221,7 @@ default CassandraBatchOperations batchOps() {
204221
* Execute a {@code SELECT} query and convert the resulting items to a {@link List} of entities.
205222
*
206223
* @param query must not be {@literal null}.
207-
* @param entityClass The entity type must not be {@literal null}.
224+
* @param entityClass the entity type must not be {@literal null}.
208225
* @return the converted results
209226
* @throws DataAccessException if there is any problem executing the query.
210227
* @since 2.0
@@ -215,7 +232,7 @@ default CassandraBatchOperations batchOps() {
215232
* Execute a {@code SELECT} query with paging and convert the result set to a {@link Slice} of entities.
216233
*
217234
* @param query the query object used to create a CQL statement, must not be {@literal null}.
218-
* @param entityClass The entity type must not be {@literal null}.
235+
* @param entityClass the entity type must not be {@literal null}.
219236
* @return the converted results
220237
* @throws DataAccessException if there is any problem executing the query.
221238
* @since 2.0
@@ -241,7 +258,7 @@ default CassandraBatchOperations batchOps() {
241258
* Execute a {@code SELECT} query and convert the resulting item to an entity.
242259
*
243260
* @param query must not be {@literal null}.
244-
* @param entityClass The entity type must not be {@literal null}.
261+
* @param entityClass the entity type must not be {@literal null}.
245262
* @return the converted object or {@literal null}.
246263
* @throws DataAccessException if there is any problem executing the query.
247264
* @since 2.0
@@ -253,7 +270,7 @@ default CassandraBatchOperations batchOps() {
253270
*
254271
* @param query must not be {@literal null}.
255272
* @param update must not be {@literal null}.
256-
* @param entityClass The entity type must not be {@literal null}.
273+
* @param entityClass the entity type must not be {@literal null}.
257274
* @throws DataAccessException if there is any problem executing the query.
258275
*/
259276
boolean update(Query query, Update update, Class<?> entityClass) throws DataAccessException;
@@ -262,7 +279,7 @@ default CassandraBatchOperations batchOps() {
262279
* Remove entities (rows)/columns from the table by {@link Query}.
263280
*
264281
* @param query must not be {@literal null}.
265-
* @param entityClass The entity type must not be {@literal null}.
282+
* @param entityClass the entity type must not be {@literal null}.
266283
* @throws DataAccessException if there is any problem executing the query.
267284
*/
268285
boolean delete(Query query, Class<?> entityClass) throws DataAccessException;
@@ -322,7 +339,7 @@ default CassandraBatchOperations batchOps() {
322339
* @param id the Id value. For single primary keys it's the plain value. For composite primary keys either the
323340
* {@link org.springframework.data.cassandra.core.mapping.PrimaryKeyClass} or
324341
* {@link org.springframework.data.cassandra.core.mapping.MapId}. Must not be {@literal null}.
325-
* @param entityClass The entity type must not be {@literal null}.
342+
* @param entityClass the entity type must not be {@literal null}.
326343
* @return the converted object or {@literal null}.
327344
* @throws DataAccessException if there is any problem executing the query.
328345
*/
@@ -407,15 +424,15 @@ default WriteResult delete(Object entity, DeleteOptions options) throws DataAcce
407424
* @param id the Id value. For single primary keys it's the plain value. For composite primary keys either the
408425
* {@link org.springframework.data.cassandra.core.mapping.PrimaryKeyClass} or
409426
* {@link org.springframework.data.cassandra.core.mapping.MapId}. Must not be {@literal null}.
410-
* @param entityClass The entity type must not be {@literal null}.
427+
* @param entityClass the entity type must not be {@literal null}.
411428
* @throws DataAccessException if there is any problem executing the query.
412429
*/
413430
boolean deleteById(Object id, Class<?> entityClass) throws DataAccessException;
414431

415432
/**
416433
* Execute a {@code TRUNCATE} query to remove all entities of a given class.
417434
*
418-
* @param entityClass The entity type must not be {@literal null}.
435+
* @param entityClass the entity type must not be {@literal null}.
419436
* @throws DataAccessException if there is any problem executing the query.
420437
*/
421438
void truncate(Class<?> entityClass) throws DataAccessException;

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.data.cassandra.core;
1717

1818
import java.util.List;
19+
import java.util.function.BiFunction;
1920
import java.util.function.Consumer;
2021
import java.util.function.Function;
2122
import java.util.function.Supplier;
@@ -349,14 +350,25 @@ public ResultSet execute(Statement<?> statement) {
349350

350351
@Override
351352
public <T> List<T> select(Statement<?> statement, Class<T> entityClass) {
353+
return select(statement, entityClass, (t, row) -> t);
354+
}
355+
356+
@Override
357+
public <S, T> List<T> select(Statement<?> statement, Class<S> entityClass, BiFunction<S, Row, T> mapper)
358+
throws DataAccessException {
352359

353360
Assert.notNull(statement, "Statement must not be null");
354361
Assert.notNull(entityClass, "Entity type must not be null");
362+
Assert.notNull(mapper, "Row Mapper function must not be null");
355363

356-
Function<Row, T> mapper = getMapper(EntityProjection.nonProjecting(entityClass),
364+
Function<Row, S> defaultMapper = getMapper(EntityProjection.nonProjecting(entityClass),
357365
EntityQueryUtils.getTableName(statement));
358366

359-
return doQuery(statement, (row, rowNum) -> mapper.apply(row));
367+
return doQuery(statement, (row, rowNum) -> {
368+
369+
S intermediate = defaultMapper.apply(row);
370+
return mapper.apply(intermediate, row);
371+
});
360372
}
361373

362374
@Override

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -767,12 +767,11 @@ private static com.datastax.oss.driver.api.querybuilder.select.Selector getSelec
767767
.stream().map(param -> {
768768

769769
if (param instanceof ColumnSelector s) {
770-
771-
return com.datastax.oss.driver.api.querybuilder.select.Selector.column(s.getExpression());
770+
return com.datastax.oss.driver.api.querybuilder.select.Selector.column(s.getIdentifier());
772771
}
773772

774773
if (param instanceof CqlIdentifier i) {
775-
return com.datastax.oss.driver.api.querybuilder.select.Selector.column(i.toString());
774+
return com.datastax.oss.driver.api.querybuilder.select.Selector.column(i);
776775
}
777776

778777
return new SimpleSelector(param.toString());

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/ColumnName.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public Optional<CqlIdentifier> getCqlIdentifier() {
169169

170170
@Override
171171
public String toCql() {
172-
return this.cqlIdentifier.toString();
172+
return this.cqlIdentifier.asInternal();
173173
}
174174

175175
@Override

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/Columns.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@
2626
import java.util.Optional;
2727
import java.util.function.Function;
2828

29+
import org.jspecify.annotations.Nullable;
30+
2931
import org.springframework.data.cassandra.core.convert.CassandraVector;
3032
import org.springframework.data.cassandra.core.mapping.SimilarityFunction;
3133
import org.springframework.data.domain.Vector;
32-
import org.jspecify.annotations.Nullable;
3334
import org.springframework.util.Assert;
3435
import org.springframework.util.ObjectUtils;
3536
import org.springframework.util.StringUtils;
@@ -340,6 +341,9 @@ default Selector as(String alias) {
340341
*/
341342
Selector as(CqlIdentifier alias);
342343

344+
/**
345+
* @return the expression that forms this selection.
346+
*/
343347
String getExpression();
344348

345349
Optional<CqlIdentifier> getAlias();
@@ -410,6 +414,10 @@ public Optional<CqlIdentifier> getAlias() {
410414
return alias;
411415
}
412416

417+
public CqlIdentifier getIdentifier() {
418+
return columnName.getCqlIdentifier().orElseGet(() -> CqlIdentifier.fromCql(columnName.toCql()));
419+
}
420+
413421
@Override
414422
public String getExpression() {
415423
return columnName.toCql();

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/query/SerializationUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private SerializationUtils() {}
5757
CriteriaDefinition.Predicate predicate = criteria.getPredicate();
5858

5959
return String.format("%s %s", criteria.getColumnName(),
60-
predicate.getOperator().toCql(serializeToCqlSafely(predicate.getValue())));
60+
predicate.getOperator().toCql(predicate != null ? serializeToCqlSafely(predicate.getValue()) : ""));
6161
}
6262

6363
/**

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,10 @@
1616
package org.springframework.data.cassandra.repository.query;
1717

1818
import org.jspecify.annotations.Nullable;
19+
1920
import org.springframework.core.convert.converter.Converter;
2021
import org.springframework.data.cassandra.core.CassandraOperations;
21-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.CollectionExecution;
22-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.ExistsExecution;
23-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.ResultProcessingConverter;
24-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.ResultProcessingExecution;
25-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.ResultSetQuery;
26-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.SingleEntityExecution;
27-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.SlicedExecution;
28-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.StreamExecution;
29-
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.WindowExecution;
22+
import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.*;
3023
import org.springframework.data.repository.query.ParameterAccessor;
3124
import org.springframework.data.repository.query.RepositoryQuery;
3225
import org.springframework.data.repository.query.ResultProcessor;
@@ -120,6 +113,8 @@ private CassandraQueryExecution getExecutionToWrap(CassandraParameterAccessor pa
120113
return new SlicedExecution(getOperations(), parameterAccessor.getPageable());
121114
} else if (getQueryMethod().isScrollQuery()) {
122115
return new WindowExecution(getOperations(), parameterAccessor.getScrollPosition(), parameterAccessor.getLimit());
116+
} else if (getQueryMethod().isSearchQuery()) {
117+
return new SearchExecution(getOperations(), parameterAccessor);
123118
} else if (getQueryMethod().isCollectionQuery()) {
124119
return new CollectionExecution(getOperations());
125120
} else if (getQueryMethod().isResultSetQuery()) {

0 commit comments

Comments
 (0)