#330 - Adapt to Criteria objects in Spring Data Relational.
This commit is contained in:
@@ -34,9 +34,9 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.r2dbc.mapping.SettableValue;
|
||||
import org.springframework.data.r2dbc.query.Criteria;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.r2dbc.support.R2dbcExceptionTranslator;
|
||||
import org.springframework.data.relational.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -529,11 +529,11 @@ public interface DatabaseClient {
|
||||
S project(SqlIdentifier... selectedFields);
|
||||
|
||||
/**
|
||||
* Configure a filter {@link Criteria}.
|
||||
* Configure a filter {@link CriteriaDefinition}.
|
||||
*
|
||||
* @param criteria must not be {@literal null}.
|
||||
*/
|
||||
S matching(Criteria criteria);
|
||||
S matching(CriteriaDefinition criteria);
|
||||
|
||||
/**
|
||||
* Configure {@link Sort}.
|
||||
@@ -705,8 +705,18 @@ public interface DatabaseClient {
|
||||
* Specify an {@link Update} object containing assignments.
|
||||
*
|
||||
* @param update must not be {@literal null}.
|
||||
* @deprecated since 1.1, use {@link #using(org.springframework.data.relational.core.query.Update)}.
|
||||
*/
|
||||
@Deprecated
|
||||
UpdateMatchingSpec using(Update update);
|
||||
|
||||
/**
|
||||
* Specify an {@link Update} object containing assignments.
|
||||
*
|
||||
* @param update must not be {@literal null}.
|
||||
* @since 1.1
|
||||
*/
|
||||
UpdateMatchingSpec using(org.springframework.data.relational.core.query.Update update);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -750,11 +760,11 @@ public interface DatabaseClient {
|
||||
interface UpdateMatchingSpec extends UpdateSpec {
|
||||
|
||||
/**
|
||||
* Configure a filter {@link Criteria}.
|
||||
* Configure a filter {@link CriteriaDefinition}.
|
||||
*
|
||||
* @param criteria must not be {@literal null}.
|
||||
*/
|
||||
UpdateSpec matching(Criteria criteria);
|
||||
UpdateSpec matching(CriteriaDefinition criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -801,11 +811,11 @@ public interface DatabaseClient {
|
||||
TypedDeleteSpec<T> table(SqlIdentifier tableName);
|
||||
|
||||
/**
|
||||
* Configure a filter {@link Criteria}.
|
||||
* Configure a filter {@link CriteriaDefinition}.
|
||||
*
|
||||
* @param criteria must not be {@literal null}.
|
||||
*/
|
||||
DeleteSpec matching(Criteria criteria);
|
||||
DeleteSpec matching(CriteriaDefinition criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -814,11 +824,11 @@ public interface DatabaseClient {
|
||||
interface DeleteMatchingSpec extends DeleteSpec {
|
||||
|
||||
/**
|
||||
* Configure a filter {@link Criteria}.
|
||||
* Configure a filter {@link CriteriaDefinition}.
|
||||
*
|
||||
* @param criteria must not be {@literal null}.
|
||||
*/
|
||||
DeleteSpec matching(Criteria criteria);
|
||||
DeleteSpec matching(CriteriaDefinition criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,6 +60,7 @@ import org.springframework.data.r2dbc.mapping.SettableValue;
|
||||
import org.springframework.data.r2dbc.query.Criteria;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.r2dbc.support.R2dbcExceptionTranslator;
|
||||
import org.springframework.data.relational.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -683,7 +684,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
|
||||
final SqlIdentifier table;
|
||||
final List<SqlIdentifier> projectedFields;
|
||||
final @Nullable Criteria criteria;
|
||||
final @Nullable CriteriaDefinition criteria;
|
||||
final Sort sort;
|
||||
final Pageable page;
|
||||
|
||||
@@ -698,7 +699,8 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
this.page = Pageable.unpaged();
|
||||
}
|
||||
|
||||
DefaultSelectSpecSupport(SqlIdentifier table, List<SqlIdentifier> projectedFields, @Nullable Criteria criteria,
|
||||
DefaultSelectSpecSupport(SqlIdentifier table, List<SqlIdentifier> projectedFields,
|
||||
@Nullable CriteriaDefinition criteria,
|
||||
Sort sort, Pageable page) {
|
||||
this.table = table;
|
||||
this.projectedFields = projectedFields;
|
||||
@@ -717,7 +719,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
return createInstance(this.table, projectedFields, this.criteria, this.sort, this.page);
|
||||
}
|
||||
|
||||
public DefaultSelectSpecSupport where(Criteria whereCriteria) {
|
||||
public DefaultSelectSpecSupport where(CriteriaDefinition whereCriteria) {
|
||||
|
||||
Assert.notNull(whereCriteria, "Criteria must not be null!");
|
||||
|
||||
@@ -753,12 +755,13 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
}
|
||||
|
||||
protected abstract DefaultSelectSpecSupport createInstance(SqlIdentifier table, List<SqlIdentifier> projectedFields,
|
||||
@Nullable Criteria criteria, Sort sort, Pageable page);
|
||||
@Nullable CriteriaDefinition criteria, Sort sort, Pageable page);
|
||||
}
|
||||
|
||||
private class DefaultGenericSelectSpec extends DefaultSelectSpecSupport implements GenericSelectSpec {
|
||||
|
||||
DefaultGenericSelectSpec(SqlIdentifier table, List<SqlIdentifier> projectedFields, @Nullable Criteria criteria,
|
||||
DefaultGenericSelectSpec(SqlIdentifier table, List<SqlIdentifier> projectedFields,
|
||||
@Nullable CriteriaDefinition criteria,
|
||||
Sort sort, Pageable page) {
|
||||
super(table, projectedFields, criteria, sort, page);
|
||||
}
|
||||
@@ -806,7 +809,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultGenericSelectSpec matching(Criteria criteria) {
|
||||
public DefaultGenericSelectSpec matching(CriteriaDefinition criteria) {
|
||||
return (DefaultGenericSelectSpec) super.where(criteria);
|
||||
}
|
||||
|
||||
@@ -842,7 +845,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
|
||||
@Override
|
||||
protected DefaultGenericSelectSpec createInstance(SqlIdentifier table, List<SqlIdentifier> projectedFields,
|
||||
@Nullable Criteria criteria, Sort sort, Pageable page) {
|
||||
@Nullable CriteriaDefinition criteria, Sort sort, Pageable page) {
|
||||
return new DefaultGenericSelectSpec(table, projectedFields, criteria, sort, page);
|
||||
}
|
||||
}
|
||||
@@ -864,7 +867,8 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
this.mappingFunction = dataAccessStrategy.getRowMapper(typeToRead);
|
||||
}
|
||||
|
||||
DefaultTypedSelectSpec(SqlIdentifier table, List<SqlIdentifier> projectedFields, @Nullable Criteria criteria,
|
||||
DefaultTypedSelectSpec(SqlIdentifier table, List<SqlIdentifier> projectedFields,
|
||||
@Nullable CriteriaDefinition criteria,
|
||||
Sort sort, Pageable page, Class<T> typeToRead, BiFunction<Row, RowMetadata, T> mappingFunction) {
|
||||
|
||||
super(table, projectedFields, criteria, sort, page);
|
||||
@@ -912,7 +916,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultTypedSelectSpec<T> matching(Criteria criteria) {
|
||||
public DefaultTypedSelectSpec<T> matching(CriteriaDefinition criteria) {
|
||||
return (DefaultTypedSelectSpec<T>) super.where(criteria);
|
||||
}
|
||||
|
||||
@@ -956,7 +960,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
|
||||
@Override
|
||||
protected DefaultTypedSelectSpec<T> createInstance(SqlIdentifier table, List<SqlIdentifier> projectedFields,
|
||||
@Nullable Criteria criteria, Sort sort, Pageable page) {
|
||||
@Nullable CriteriaDefinition criteria, Sort sort, Pageable page) {
|
||||
return new DefaultTypedSelectSpec<>(table, projectedFields, criteria, sort, page, this.typeToRead,
|
||||
this.mappingFunction);
|
||||
}
|
||||
@@ -1204,11 +1208,12 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
|
||||
private final @Nullable Class<?> typeToUpdate;
|
||||
private final @Nullable SqlIdentifier table;
|
||||
private final @Nullable Update assignments;
|
||||
private final @Nullable Criteria where;
|
||||
private final @Nullable org.springframework.data.relational.core.query.Update assignments;
|
||||
private final @Nullable CriteriaDefinition where;
|
||||
|
||||
DefaultGenericUpdateSpec(@Nullable Class<?> typeToUpdate, @Nullable SqlIdentifier table,
|
||||
@Nullable Update assignments, @Nullable Criteria where) {
|
||||
@Nullable org.springframework.data.relational.core.query.Update assignments,
|
||||
@Nullable CriteriaDefinition where) {
|
||||
this.typeToUpdate = typeToUpdate;
|
||||
this.table = table;
|
||||
this.assignments = assignments;
|
||||
@@ -1220,11 +1225,20 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
|
||||
return new DefaultGenericUpdateSpec(this.typeToUpdate, this.table,
|
||||
org.springframework.data.relational.core.query.Update.from(update.getAssignments()), this.where);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateMatchingSpec using(org.springframework.data.relational.core.query.Update update) {
|
||||
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
|
||||
return new DefaultGenericUpdateSpec(this.typeToUpdate, this.table, update, this.where);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateSpec matching(Criteria criteria) {
|
||||
public UpdateSpec matching(CriteriaDefinition criteria) {
|
||||
|
||||
Assert.notNull(criteria, "Criteria must not be null");
|
||||
|
||||
@@ -1333,11 +1347,12 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
}
|
||||
Object id = columns.remove(ids.get(0)); // do not update the Id column.
|
||||
|
||||
Update update = null;
|
||||
org.springframework.data.relational.core.query.Update update = null;
|
||||
|
||||
for (SqlIdentifier column : columns.keySet()) {
|
||||
if (update == null) {
|
||||
update = Update.update(dataAccessStrategy.toSql(column), columns.get(column));
|
||||
update = org.springframework.data.relational.core.query.Update.update(dataAccessStrategy.toSql(column),
|
||||
columns.get(column));
|
||||
} else {
|
||||
update = update.set(dataAccessStrategy.toSql(column), columns.get(column));
|
||||
}
|
||||
@@ -1376,16 +1391,17 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
|
||||
private final @Nullable Class<T> typeToDelete;
|
||||
private final @Nullable SqlIdentifier table;
|
||||
private final @Nullable Criteria where;
|
||||
private final @Nullable CriteriaDefinition where;
|
||||
|
||||
DefaultDeleteSpec(@Nullable Class<T> typeToDelete, @Nullable SqlIdentifier table, @Nullable Criteria where) {
|
||||
DefaultDeleteSpec(@Nullable Class<T> typeToDelete, @Nullable SqlIdentifier table,
|
||||
@Nullable CriteriaDefinition where) {
|
||||
this.typeToDelete = typeToDelete;
|
||||
this.table = table;
|
||||
this.where = where;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeleteSpec matching(Criteria criteria) {
|
||||
public DeleteSpec matching(CriteriaDefinition criteria) {
|
||||
|
||||
Assert.notNull(criteria, "Criteria must not be null!");
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.springframework.util.Assert;
|
||||
* Default {@link StatementMapper} implementation.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Roman Chigvintsev
|
||||
*/
|
||||
class DefaultStatementMapper implements StatementMapper {
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.TransientDataAccessResourceException;
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
|
||||
/**
|
||||
* Interface specifying a basic set of reactive R2DBC operations using entities. Implemented by
|
||||
|
||||
@@ -37,11 +37,12 @@ import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.projection.ProjectionInformation;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.r2dbc.query.Criteria;
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
|
||||
import org.springframework.data.relational.core.query.Criteria;
|
||||
import org.springframework.data.relational.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
import org.springframework.data.relational.core.sql.Expression;
|
||||
import org.springframework.data.relational.core.sql.Functions;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
@@ -181,7 +182,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
|
||||
return spec.withProjection(Functions.count(table.column(entity.getRequiredIdProperty().getColumnName())));
|
||||
});
|
||||
|
||||
Optional<Criteria> criteria = query.getCriteria();
|
||||
Optional<CriteriaDefinition> criteria = query.getCriteria();
|
||||
if (criteria.isPresent()) {
|
||||
selectSpec = criteria.map(selectSpec::withCriteria).orElse(selectSpec);
|
||||
}
|
||||
@@ -220,7 +221,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
|
||||
.withProjection(columnName) //
|
||||
.limit(1);
|
||||
|
||||
Optional<Criteria> criteria = query.getCriteria();
|
||||
Optional<CriteriaDefinition> criteria = query.getCriteria();
|
||||
if (criteria.isPresent()) {
|
||||
selectSpec = criteria.map(selectSpec::withCriteria).orElse(selectSpec);
|
||||
}
|
||||
@@ -266,7 +267,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
|
||||
selectSpec = selectSpec.withSort(query.getSort());
|
||||
}
|
||||
|
||||
Optional<Criteria> criteria = query.getCriteria();
|
||||
Optional<CriteriaDefinition> criteria = query.getCriteria();
|
||||
if (criteria.isPresent()) {
|
||||
selectSpec = criteria.map(selectSpec::withCriteria).orElse(selectSpec);
|
||||
}
|
||||
@@ -314,7 +315,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
|
||||
StatementMapper.UpdateSpec selectSpec = statementMapper //
|
||||
.createUpdate(tableName, update);
|
||||
|
||||
Optional<Criteria> criteria = query.getCriteria();
|
||||
Optional<CriteriaDefinition> criteria = query.getCriteria();
|
||||
if (criteria.isPresent()) {
|
||||
selectSpec = criteria.map(selectSpec::withCriteria).orElse(selectSpec);
|
||||
}
|
||||
@@ -343,7 +344,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
|
||||
StatementMapper.DeleteSpec selectSpec = statementMapper //
|
||||
.createDelete(tableName);
|
||||
|
||||
Optional<Criteria> criteria = query.getCriteria();
|
||||
Optional<CriteriaDefinition> criteria = query.getCriteria();
|
||||
if (criteria.isPresent()) {
|
||||
selectSpec = criteria.map(selectSpec::withCriteria).orElse(selectSpec);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.data.r2dbc.core;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.data.r2dbc.core;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.data.r2dbc.core;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.data.r2dbc.core;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -17,8 +17,8 @@ package org.springframework.data.r2dbc.core;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,8 +17,8 @@ package org.springframework.data.r2dbc.core;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.r2dbc.dialect.BindMarkers;
|
||||
import org.springframework.data.r2dbc.mapping.SettableValue;
|
||||
import org.springframework.data.r2dbc.query.Criteria;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.relational.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.relational.core.sql.Expression;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.data.relational.core.sql.Table;
|
||||
@@ -43,6 +43,7 @@ import org.springframework.lang.Nullable;
|
||||
* and vendor-specific SQL differences.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Roman Chigvintsev
|
||||
*/
|
||||
public interface StatementMapper {
|
||||
|
||||
@@ -142,7 +143,7 @@ public interface StatementMapper {
|
||||
* @param table
|
||||
* @return the {@link UpdateSpec}.
|
||||
*/
|
||||
default UpdateSpec createUpdate(String table, Update update) {
|
||||
default UpdateSpec createUpdate(String table, org.springframework.data.relational.core.query.Update update) {
|
||||
return UpdateSpec.create(table, update);
|
||||
}
|
||||
|
||||
@@ -153,7 +154,7 @@ public interface StatementMapper {
|
||||
* @return the {@link UpdateSpec}.
|
||||
* @since 1.1
|
||||
*/
|
||||
default UpdateSpec createUpdate(SqlIdentifier table, Update update) {
|
||||
default UpdateSpec createUpdate(SqlIdentifier table, org.springframework.data.relational.core.query.Update update) {
|
||||
return UpdateSpec.create(table, update);
|
||||
}
|
||||
|
||||
@@ -196,13 +197,13 @@ public interface StatementMapper {
|
||||
private final Table table;
|
||||
private final List<String> projectedFields;
|
||||
private final List<Expression> selectList;
|
||||
private final Criteria criteria;
|
||||
private final CriteriaDefinition criteria;
|
||||
private final Sort sort;
|
||||
private final long offset;
|
||||
private final int limit;
|
||||
|
||||
protected SelectSpec(Table table, List<String> projectedFields, List<Expression> selectList,
|
||||
@Nullable Criteria criteria, Sort sort, int limit, long offset) {
|
||||
@Nullable CriteriaDefinition criteria, Sort sort, int limit, long offset) {
|
||||
this.table = table;
|
||||
this.projectedFields = projectedFields;
|
||||
this.selectList = selectList;
|
||||
@@ -300,7 +301,7 @@ public interface StatementMapper {
|
||||
* @param criteria
|
||||
* @return the {@link SelectSpec}.
|
||||
*/
|
||||
public SelectSpec withCriteria(Criteria criteria) {
|
||||
public SelectSpec withCriteria(CriteriaDefinition criteria) {
|
||||
return new SelectSpec(this.table, this.projectedFields, this.selectList, criteria, this.sort, this.limit,
|
||||
this.offset);
|
||||
}
|
||||
@@ -381,7 +382,7 @@ public interface StatementMapper {
|
||||
return Collections.unmodifiableList(selectList);
|
||||
}
|
||||
|
||||
public Criteria getCriteria() {
|
||||
public CriteriaDefinition getCriteria() {
|
||||
return this.criteria;
|
||||
}
|
||||
|
||||
@@ -473,11 +474,12 @@ public interface StatementMapper {
|
||||
class UpdateSpec {
|
||||
|
||||
private final SqlIdentifier table;
|
||||
@Nullable private final Update update;
|
||||
@Nullable private final org.springframework.data.relational.core.query.Update update;
|
||||
|
||||
private final Criteria criteria;
|
||||
private final CriteriaDefinition criteria;
|
||||
|
||||
protected UpdateSpec(SqlIdentifier table, @Nullable Update update, Criteria criteria) {
|
||||
protected UpdateSpec(SqlIdentifier table, @Nullable org.springframework.data.relational.core.query.Update update,
|
||||
CriteriaDefinition criteria) {
|
||||
|
||||
this.table = table;
|
||||
this.update = update;
|
||||
@@ -490,7 +492,7 @@ public interface StatementMapper {
|
||||
* @param table
|
||||
* @return the {@link InsertSpec}.
|
||||
*/
|
||||
public static UpdateSpec create(String table, Update update) {
|
||||
public static UpdateSpec create(String table, org.springframework.data.relational.core.query.Update update) {
|
||||
return create(SqlIdentifier.unquoted(table), update);
|
||||
}
|
||||
|
||||
@@ -501,7 +503,7 @@ public interface StatementMapper {
|
||||
* @return the {@link InsertSpec}.
|
||||
* @since 1.1
|
||||
*/
|
||||
public static UpdateSpec create(SqlIdentifier table, Update update) {
|
||||
public static UpdateSpec create(SqlIdentifier table, org.springframework.data.relational.core.query.Update update) {
|
||||
return new UpdateSpec(table, update, Criteria.empty());
|
||||
}
|
||||
|
||||
@@ -511,7 +513,7 @@ public interface StatementMapper {
|
||||
* @param criteria
|
||||
* @return the {@link UpdateSpec}.
|
||||
*/
|
||||
public UpdateSpec withCriteria(Criteria criteria) {
|
||||
public UpdateSpec withCriteria(CriteriaDefinition criteria) {
|
||||
return new UpdateSpec(this.table, this.update, criteria);
|
||||
}
|
||||
|
||||
@@ -520,11 +522,11 @@ public interface StatementMapper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Update getUpdate() {
|
||||
public org.springframework.data.relational.core.query.Update getUpdate() {
|
||||
return this.update;
|
||||
}
|
||||
|
||||
public Criteria getCriteria() {
|
||||
public CriteriaDefinition getCriteria() {
|
||||
return this.criteria;
|
||||
}
|
||||
}
|
||||
@@ -536,9 +538,9 @@ public interface StatementMapper {
|
||||
|
||||
private final SqlIdentifier table;
|
||||
|
||||
private final Criteria criteria;
|
||||
private final CriteriaDefinition criteria;
|
||||
|
||||
protected DeleteSpec(SqlIdentifier table, Criteria criteria) {
|
||||
protected DeleteSpec(SqlIdentifier table, CriteriaDefinition criteria) {
|
||||
this.table = table;
|
||||
this.criteria = criteria;
|
||||
}
|
||||
@@ -570,7 +572,7 @@ public interface StatementMapper {
|
||||
* @param criteria
|
||||
* @return the {@link DeleteSpec}.
|
||||
*/
|
||||
public DeleteSpec withCriteria(Criteria criteria) {
|
||||
public DeleteSpec withCriteria(CriteriaDefinition criteria) {
|
||||
return new DeleteSpec(this.table, criteria);
|
||||
}
|
||||
|
||||
@@ -578,7 +580,7 @@ public interface StatementMapper {
|
||||
return this.table;
|
||||
}
|
||||
|
||||
public Criteria getCriteria() {
|
||||
public CriteriaDefinition getCriteria() {
|
||||
return this.criteria;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.relational.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -45,8 +46,10 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Oliver Drotbohm
|
||||
* @deprecated since 1.1, use {@link org.springframework.data.relational.core.query.Criteria} instead.
|
||||
*/
|
||||
public class Criteria {
|
||||
@Deprecated
|
||||
public class Criteria implements CriteriaDefinition {
|
||||
|
||||
private static final Criteria EMPTY = new Criteria(SqlIdentifier.EMPTY, Comparator.INITIAL, null);
|
||||
|
||||
@@ -69,8 +72,7 @@ public class Criteria {
|
||||
}
|
||||
|
||||
private Criteria(@Nullable Criteria previous, Combinator combinator, List<Criteria> group,
|
||||
@Nullable SqlIdentifier column, @Nullable Comparator comparator, @Nullable Object value,
|
||||
boolean ignoreCase) {
|
||||
@Nullable SqlIdentifier column, @Nullable Comparator comparator, @Nullable Object value, boolean ignoreCase) {
|
||||
|
||||
this.previous = previous;
|
||||
this.combinator = previous != null && previous.isEmpty() ? Combinator.INITIAL : combinator;
|
||||
@@ -263,14 +265,14 @@ public class Criteria {
|
||||
* @see #hasPrevious()
|
||||
*/
|
||||
@Nullable
|
||||
Criteria getPrevious() {
|
||||
public Criteria getPrevious() {
|
||||
return previous;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if this {@link Criteria} has a previous one.
|
||||
*/
|
||||
boolean hasPrevious() {
|
||||
public boolean hasPrevious() {
|
||||
return previous != null;
|
||||
}
|
||||
|
||||
@@ -321,18 +323,21 @@ public class Criteria {
|
||||
/**
|
||||
* @return {@literal true} if this {@link Criteria} is empty.
|
||||
*/
|
||||
boolean isGroup() {
|
||||
@Override
|
||||
public boolean isGroup() {
|
||||
return !this.group.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link Combinator} to combine this criteria with a previous one.
|
||||
*/
|
||||
Combinator getCombinator() {
|
||||
@Override
|
||||
public Combinator getCombinator() {
|
||||
return combinator;
|
||||
}
|
||||
|
||||
List<Criteria> getGroup() {
|
||||
@Override
|
||||
public List<Criteria> getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
@@ -340,7 +345,8 @@ public class Criteria {
|
||||
* @return the column/property name.
|
||||
*/
|
||||
@Nullable
|
||||
SqlIdentifier getColumn() {
|
||||
@Override
|
||||
public SqlIdentifier getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
@@ -348,7 +354,8 @@ public class Criteria {
|
||||
* @return {@link Comparator}.
|
||||
*/
|
||||
@Nullable
|
||||
Comparator getComparator() {
|
||||
@Override
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@@ -356,7 +363,8 @@ public class Criteria {
|
||||
* @return the comparison value. Can be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
Object getValue() {
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -365,18 +373,11 @@ public class Criteria {
|
||||
*
|
||||
* @return {@literal true} if comparison should be done in case-insensitive way
|
||||
*/
|
||||
boolean isIgnoreCase() {
|
||||
@Override
|
||||
public boolean isIgnoreCase() {
|
||||
return ignoreCase;
|
||||
}
|
||||
|
||||
enum Comparator {
|
||||
INITIAL, EQ, NEQ, LT, LTE, GT, GTE, IS_NULL, IS_NOT_NULL, LIKE, NOT_LIKE, NOT_IN, IN, IS_TRUE, IS_FALSE
|
||||
}
|
||||
|
||||
enum Combinator {
|
||||
INITIAL, AND, OR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface declaring terminal builder methods to build a {@link Criteria}.
|
||||
*/
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.r2dbc.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Query object representing {@link Criteria}, columns, {@link Sort}, and limit/offset for a SQL query. {@link Query} is
|
||||
* created with a fluent API creating immutable objects.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 1.1
|
||||
* @see Criteria
|
||||
* @see Sort
|
||||
* @see Pageable
|
||||
*/
|
||||
public class Query {
|
||||
|
||||
private final @Nullable Criteria criteria;
|
||||
|
||||
private final List<SqlIdentifier> columns;
|
||||
private final Sort sort;
|
||||
private final int limit;
|
||||
private final long offset;
|
||||
|
||||
/**
|
||||
* Static factory method to create a {@link Query} using the provided {@link Criteria}.
|
||||
*
|
||||
* @param criteria must not be {@literal null}.
|
||||
* @return a new {@link Query} for the given {@link Criteria}.
|
||||
*/
|
||||
public static Query query(Criteria criteria) {
|
||||
return new Query(criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Query} using the given {@link Criteria}.
|
||||
*
|
||||
* @param criteria must not be {@literal null}.
|
||||
*/
|
||||
private Query(@Nullable Criteria criteria) {
|
||||
this(criteria, Collections.emptyList(), Sort.unsorted(), -1, -1);
|
||||
}
|
||||
|
||||
private Query(@Nullable Criteria criteria, List<SqlIdentifier> columns, Sort sort, int limit, long offset) {
|
||||
|
||||
this.criteria = criteria;
|
||||
this.columns = columns;
|
||||
this.sort = sort;
|
||||
this.limit = limit;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty {@link Query}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Query empty() {
|
||||
return new Query(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns to the query.
|
||||
*
|
||||
* @param columns
|
||||
* @return a new {@link Query} object containing the former settings with {@code columns} applied.
|
||||
*/
|
||||
public Query columns(String... columns) {
|
||||
|
||||
Assert.notNull(columns, "Columns must not be null");
|
||||
|
||||
return withColumns(Arrays.stream(columns).map(SqlIdentifier::unquoted).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns to the query.
|
||||
*
|
||||
* @param columns
|
||||
* @return a new {@link Query} object containing the former settings with {@code columns} applied.
|
||||
*/
|
||||
public Query columns(Collection<String> columns) {
|
||||
|
||||
Assert.notNull(columns, "Columns must not be null");
|
||||
|
||||
return withColumns(columns.stream().map(SqlIdentifier::unquoted).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns to the query.
|
||||
*
|
||||
* @param columns
|
||||
* @return a new {@link Query} object containing the former settings with {@code columns} applied.
|
||||
* @since 1.1
|
||||
*/
|
||||
public Query columns(SqlIdentifier... columns) {
|
||||
|
||||
Assert.notNull(columns, "Columns must not be null");
|
||||
|
||||
return withColumns(Arrays.asList(columns));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns to the query.
|
||||
*
|
||||
* @param columns
|
||||
* @return a new {@link Query} object containing the former settings with {@code columns} applied.
|
||||
*/
|
||||
private Query withColumns(Collection<SqlIdentifier> columns) {
|
||||
|
||||
Assert.notNull(columns, "Columns must not be null");
|
||||
|
||||
List<SqlIdentifier> newColumns = new ArrayList<>(this.columns);
|
||||
newColumns.addAll(columns);
|
||||
return new Query(this.criteria, newColumns, this.sort, this.limit, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set number of rows to skip before returning results.
|
||||
*
|
||||
* @param offset
|
||||
* @return a new {@link Query} object containing the former settings with {@code offset} applied.
|
||||
*/
|
||||
public Query offset(long offset) {
|
||||
return new Query(this.criteria, this.columns, this.sort, this.limit, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the number of returned documents to {@code limit}.
|
||||
*
|
||||
* @param limit
|
||||
* @return a new {@link Query} object containing the former settings with {@code limit} applied.
|
||||
*/
|
||||
public Query limit(int limit) {
|
||||
return new Query(this.criteria, this.columns, this.sort, limit, this.offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given pagination information on the {@link Query} instance. Will transparently set {@code offset} and
|
||||
* {@code limit} as well as applying the {@link Sort} instance defined with the {@link Pageable}.
|
||||
*
|
||||
* @param pageable
|
||||
* @return a new {@link Query} object containing the former settings with {@link Pageable} applied.
|
||||
*/
|
||||
public Query with(Pageable pageable) {
|
||||
|
||||
if (pageable.isUnpaged()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
assertNoCaseSort(pageable.getSort());
|
||||
|
||||
return new Query(this.criteria, this.columns, this.sort.and(sort), pageable.getPageSize(), pageable.getOffset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link Sort} to the {@link Query} instance.
|
||||
*
|
||||
* @param sort
|
||||
* @return a new {@link Query} object containing the former settings with {@link Sort} applied.
|
||||
*/
|
||||
public Query sort(Sort sort) {
|
||||
|
||||
Assert.notNull(sort, "Sort must not be null!");
|
||||
|
||||
if (sort.isUnsorted()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
assertNoCaseSort(sort);
|
||||
|
||||
return new Query(this.criteria, this.columns, this.sort.and(sort), this.limit, this.offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link Criteria} to be applied.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Optional<Criteria> getCriteria() {
|
||||
return Optional.ofNullable(this.criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the columns that this query should project.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<SqlIdentifier> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@literal true} if the {@link Query} has a sort parameter.
|
||||
*
|
||||
* @return {@literal true} if sorted.
|
||||
* @see Sort#isSorted()
|
||||
*/
|
||||
public boolean isSorted() {
|
||||
return sort.isSorted();
|
||||
}
|
||||
|
||||
public Sort getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of rows to skip.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getOffset() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum number of rows to be return.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getLimit() {
|
||||
return this.limit;
|
||||
}
|
||||
|
||||
private static void assertNoCaseSort(Sort sort) {
|
||||
|
||||
for (Sort.Order order : sort) {
|
||||
if (order.isIgnoreCase()) {
|
||||
throw new IllegalArgumentException(String.format("Given sort contained an Order for %s with ignore case;"
|
||||
+ " R2DBC does not support sorting ignoring case currently", order.getProperty()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
@@ -35,10 +34,10 @@ import org.springframework.data.r2dbc.dialect.Bindings;
|
||||
import org.springframework.data.r2dbc.dialect.MutableBindings;
|
||||
import org.springframework.data.r2dbc.dialect.R2dbcDialect;
|
||||
import org.springframework.data.r2dbc.mapping.SettableValue;
|
||||
import org.springframework.data.r2dbc.query.Criteria.Combinator;
|
||||
import org.springframework.data.r2dbc.query.Criteria.Comparator;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
|
||||
import org.springframework.data.relational.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.relational.core.query.CriteriaDefinition.Comparator;
|
||||
import org.springframework.data.relational.core.sql.*;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
@@ -50,6 +49,7 @@ import org.springframework.util.ClassUtils;
|
||||
* Maps {@link Criteria} and {@link Sort} objects considering mapping metadata and dialect-specific conversion.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Roman Chigvintsev
|
||||
*/
|
||||
public class QueryMapper {
|
||||
|
||||
@@ -179,6 +179,34 @@ public class QueryMapper {
|
||||
throw new IllegalArgumentException(String.format("Cannot map %s", expression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a {@link CriteriaDefinition} object into {@link Condition} and consider value/{@code NULL} {@link Bindings}.
|
||||
*
|
||||
* @param markers bind markers object, must not be {@literal null}.
|
||||
* @param criteria criteria definition to map, must not be {@literal null}.
|
||||
* @param table must not be {@literal null}.
|
||||
* @param entity related {@link RelationalPersistentEntity}, can be {@literal null}.
|
||||
* @return the mapped {@link BoundCondition}.
|
||||
* @since 1.1
|
||||
*/
|
||||
public BoundCondition getMappedObject(BindMarkers markers, CriteriaDefinition criteria, Table table,
|
||||
@Nullable RelationalPersistentEntity<?> entity) {
|
||||
|
||||
Assert.notNull(markers, "BindMarkers must not be null!");
|
||||
Assert.notNull(criteria, "CriteriaDefinition must not be null!");
|
||||
Assert.notNull(table, "Table must not be null!");
|
||||
|
||||
MutableBindings bindings = new MutableBindings(markers);
|
||||
|
||||
if (criteria.isEmpty()) {
|
||||
throw new IllegalArgumentException("Cannot map empty Criteria");
|
||||
}
|
||||
|
||||
Condition mapped = unroll(criteria, table, entity, bindings);
|
||||
|
||||
return new BoundCondition(bindings, mapped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a {@link Criteria} object into {@link Condition} and consider value/{@code NULL} {@link Bindings}.
|
||||
*
|
||||
@@ -187,7 +215,9 @@ public class QueryMapper {
|
||||
* @param table must not be {@literal null}.
|
||||
* @param entity related {@link RelationalPersistentEntity}, can be {@literal null}.
|
||||
* @return the mapped {@link BoundCondition}.
|
||||
* @deprecated since 1.1.
|
||||
*/
|
||||
@Deprecated
|
||||
public BoundCondition getMappedObject(BindMarkers markers, Criteria criteria, Table table,
|
||||
@Nullable RelationalPersistentEntity<?> entity) {
|
||||
|
||||
@@ -206,13 +236,13 @@ public class QueryMapper {
|
||||
return new BoundCondition(bindings, mapped);
|
||||
}
|
||||
|
||||
private Condition unroll(Criteria criteria, Table table, @Nullable RelationalPersistentEntity<?> entity,
|
||||
private Condition unroll(CriteriaDefinition criteria, Table table, @Nullable RelationalPersistentEntity<?> entity,
|
||||
MutableBindings bindings) {
|
||||
|
||||
Criteria current = criteria;
|
||||
CriteriaDefinition current = criteria;
|
||||
|
||||
// reverse unroll criteria chain
|
||||
Map<Criteria, Criteria> forwardChain = new HashMap<>();
|
||||
Map<CriteriaDefinition, CriteriaDefinition> forwardChain = new HashMap<>();
|
||||
|
||||
while (current.hasPrevious()) {
|
||||
forwardChain.put(current.getPrevious(), current);
|
||||
@@ -223,7 +253,7 @@ public class QueryMapper {
|
||||
Condition mapped = getCondition(current, bindings, table, entity);
|
||||
while (forwardChain.containsKey(current)) {
|
||||
|
||||
Criteria criterion = forwardChain.get(current);
|
||||
CriteriaDefinition criterion = forwardChain.get(current);
|
||||
Condition result = null;
|
||||
|
||||
Condition condition = getCondition(criterion, bindings, table, entity);
|
||||
@@ -245,11 +275,12 @@ public class QueryMapper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Condition unrollGroup(List<Criteria> criteria, Table table, Combinator combinator,
|
||||
@Nullable RelationalPersistentEntity<?> entity, MutableBindings bindings) {
|
||||
private Condition unrollGroup(List<? extends CriteriaDefinition> criteria, Table table,
|
||||
CriteriaDefinition.Combinator combinator, @Nullable RelationalPersistentEntity<?> entity,
|
||||
MutableBindings bindings) {
|
||||
|
||||
Condition mapped = null;
|
||||
for (Criteria criterion : criteria) {
|
||||
for (CriteriaDefinition criterion : criteria) {
|
||||
|
||||
if (criterion.isEmpty()) {
|
||||
continue;
|
||||
@@ -264,7 +295,7 @@ public class QueryMapper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Condition getCondition(Criteria criteria, MutableBindings bindings, Table table,
|
||||
private Condition getCondition(CriteriaDefinition criteria, MutableBindings bindings, Table table,
|
||||
@Nullable RelationalPersistentEntity<?> entity) {
|
||||
|
||||
if (criteria.isEmpty()) {
|
||||
@@ -281,14 +312,14 @@ public class QueryMapper {
|
||||
return mapCondition(criteria, bindings, table, entity);
|
||||
}
|
||||
|
||||
private Condition combine(Criteria criteria, @Nullable Condition currentCondition, Combinator combinator,
|
||||
Condition nextCondition) {
|
||||
private Condition combine(CriteriaDefinition criteria, @Nullable Condition currentCondition,
|
||||
CriteriaDefinition.Combinator combinator, Condition nextCondition) {
|
||||
|
||||
if (currentCondition == null) {
|
||||
currentCondition = nextCondition;
|
||||
} else if (combinator == Combinator.AND) {
|
||||
} else if (combinator == CriteriaDefinition.Combinator.AND) {
|
||||
currentCondition = currentCondition.and(nextCondition);
|
||||
} else if (combinator == Combinator.OR) {
|
||||
} else if (combinator == CriteriaDefinition.Combinator.OR) {
|
||||
currentCondition = currentCondition.or(nextCondition);
|
||||
} else {
|
||||
throw new IllegalStateException("Combinator " + criteria.getCombinator() + " not supported");
|
||||
@@ -297,7 +328,7 @@ public class QueryMapper {
|
||||
return currentCondition;
|
||||
}
|
||||
|
||||
private Condition mapCondition(Criteria criteria, MutableBindings bindings, Table table,
|
||||
private Condition mapCondition(CriteriaDefinition criteria, MutableBindings bindings, Table table,
|
||||
@Nullable RelationalPersistentEntity<?> entity) {
|
||||
|
||||
Field propertyField = createPropertyField(entity, criteria.getColumn(), this.mappingContext);
|
||||
@@ -320,8 +351,7 @@ public class QueryMapper {
|
||||
typeHint = actualType.getType();
|
||||
}
|
||||
|
||||
return createCondition(column, mappedValue, typeHint, bindings, criteria.getComparator(),
|
||||
criteria.isIgnoreCase());
|
||||
return createCondition(column, mappedValue, typeHint, bindings, criteria.getComparator(), criteria.isIgnoreCase());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,16 +412,16 @@ public class QueryMapper {
|
||||
}
|
||||
|
||||
if (comparator == Comparator.IS_TRUE) {
|
||||
return column.isEqualTo(SQL.literalOf((Object) ("TRUE")));
|
||||
return column.isEqualTo(SQL.literalOf(true));
|
||||
}
|
||||
|
||||
if (comparator == Comparator.IS_FALSE) {
|
||||
return column.isEqualTo(SQL.literalOf((Object) ("FALSE")));
|
||||
return column.isEqualTo(SQL.literalOf(false));
|
||||
}
|
||||
|
||||
Expression columnExpression = column;
|
||||
if (ignoreCase && String.class == valueType) {
|
||||
columnExpression = new Upper(column);
|
||||
columnExpression = Functions.upper(column);
|
||||
}
|
||||
|
||||
if (comparator == Comparator.NOT_IN || comparator == Comparator.IN) {
|
||||
@@ -459,7 +489,7 @@ public class QueryMapper {
|
||||
}
|
||||
case NOT_LIKE: {
|
||||
Expression expression = bind(mappedValue, valueType, bindings, bindMarker, ignoreCase);
|
||||
return NotLike.create(columnExpression, expression);
|
||||
return Conditions.notLike(columnExpression, expression);
|
||||
}
|
||||
default:
|
||||
throw new UnsupportedOperationException("Comparator " + comparator + " not supported");
|
||||
@@ -502,7 +532,7 @@ public class QueryMapper {
|
||||
bindings.bindNull(bindMarker, valueType);
|
||||
}
|
||||
|
||||
return ignoreCase ? new Upper(SQL.bindMarker(bindMarker.getPlaceholder()))
|
||||
return ignoreCase ? Functions.upper(SQL.bindMarker(bindMarker.getPlaceholder()))
|
||||
: SQL.bindMarker(bindMarker.getPlaceholder());
|
||||
}
|
||||
|
||||
@@ -646,102 +676,6 @@ public class QueryMapper {
|
||||
}
|
||||
}
|
||||
|
||||
static class PassThruIdentifier implements SqlIdentifier {
|
||||
|
||||
final String name;
|
||||
|
||||
PassThruIdentifier(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReference(IdentifierProcessing processing) {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSql(IdentifierProcessing processing) {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlIdentifier transform(UnaryOperator<String> transformationFunction) {
|
||||
return new PassThruIdentifier(transformationFunction.apply(name));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o instanceof SqlIdentifier) {
|
||||
return toString().equals(o.toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return toSql(IdentifierProcessing.ANSI);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: include support of NOT LIKE operator into spring-data-relational
|
||||
/**
|
||||
* Negated LIKE {@link Condition} comparing two {@link Expression}s.
|
||||
* <p/>
|
||||
* Results in a rendered condition: {@code <left> NOT LIKE <right>}.
|
||||
*/
|
||||
private static class NotLike implements Segment, Condition {
|
||||
private final Comparison delegate;
|
||||
|
||||
private NotLike(Expression leftColumnOrExpression, Expression rightColumnOrExpression) {
|
||||
this.delegate = Comparison.create(leftColumnOrExpression, "NOT LIKE", rightColumnOrExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new instance of this class with the given {@link Expression}s.
|
||||
*
|
||||
* @param leftColumnOrExpression the left {@link Expression}
|
||||
* @param rightColumnOrExpression the right {@link Expression}
|
||||
* @return {@link NotLike} condition
|
||||
*/
|
||||
public static NotLike create(Expression leftColumnOrExpression, Expression rightColumnOrExpression) {
|
||||
Assert.notNull(leftColumnOrExpression, "Left expression must not be null!");
|
||||
Assert.notNull(rightColumnOrExpression, "Right expression must not be null!");
|
||||
return new NotLike(leftColumnOrExpression, rightColumnOrExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Visitor visitor) {
|
||||
Assert.notNull(visitor, "Visitor must not be null!");
|
||||
delegate.visit(visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: include support of functions in WHERE conditions into spring-data-relational
|
||||
/**
|
||||
* Models the ANSI SQL {@code UPPER} function.
|
||||
* <p>
|
||||
|
||||
@@ -28,7 +28,9 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Oliver Drotbohm
|
||||
* @deprecated since 1.1, use {@link org.springframework.data.relational.core.query.Update} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class Update {
|
||||
|
||||
private static final Update EMPTY = new Update(Collections.emptyMap());
|
||||
|
||||
@@ -63,12 +63,33 @@ public class UpdateMapper extends QueryMapper {
|
||||
* @param table must not be {@literal null}.
|
||||
* @param entity related {@link RelationalPersistentEntity}, can be {@literal null}.
|
||||
* @return the mapped {@link BoundAssignments}.
|
||||
* @deprecated since 1.1, use
|
||||
* {@link #getMappedObject(BindMarkers, org.springframework.data.relational.core.query.Update, Table, RelationalPersistentEntity)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public BoundAssignments getMappedObject(BindMarkers markers, Update update, Table table,
|
||||
@Nullable RelationalPersistentEntity<?> entity) {
|
||||
return getMappedObject(markers, update.getAssignments(), table, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a {@link org.springframework.data.relational.core.query.Update} object to {@link BoundAssignments} and consider
|
||||
* value/{@code NULL} {@link Bindings}.
|
||||
*
|
||||
* @param markers bind markers object, must not be {@literal null}.
|
||||
* @param update update definition to map, must not be {@literal null}.
|
||||
* @param table must not be {@literal null}.
|
||||
* @param entity related {@link RelationalPersistentEntity}, can be {@literal null}.
|
||||
* @return the mapped {@link BoundAssignments}.
|
||||
* @since 1.1
|
||||
*/
|
||||
public BoundAssignments getMappedObject(BindMarkers markers,
|
||||
org.springframework.data.relational.core.query.Update update, Table table,
|
||||
@Nullable RelationalPersistentEntity<?> entity) {
|
||||
return getMappedObject(markers, update.getAssignments(), table, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a {@code assignments} object to {@link BoundAssignments} and consider value/{@code NULL} {@link Bindings}.
|
||||
*
|
||||
|
||||
@@ -26,8 +26,8 @@ import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
|
||||
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
|
||||
import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy;
|
||||
import org.springframework.data.r2dbc.query.Criteria;
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.repository.query.RelationalEntityInformation;
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
import org.springframework.data.util.Lazy;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.data.r2dbc.core
|
||||
|
||||
import kotlinx.coroutines.reactive.awaitSingle
|
||||
import org.springframework.data.r2dbc.query.Update
|
||||
import org.springframework.data.relational.core.query.Update
|
||||
|
||||
/**
|
||||
* Extensions for [ReactiveUpdateOperation].
|
||||
|
||||
@@ -32,11 +32,11 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.r2dbc.dialect.PostgresDialect;
|
||||
import org.springframework.data.r2dbc.mapping.SettableValue;
|
||||
import org.springframework.data.r2dbc.query.Criteria;
|
||||
import org.springframework.data.r2dbc.query.Query;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.r2dbc.testing.StatementRecorder;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.query.Criteria;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link R2dbcEntityTemplate}.
|
||||
|
||||
@@ -29,8 +29,8 @@ import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.r2dbc.dialect.BindTarget;
|
||||
import org.springframework.data.r2dbc.dialect.MySqlDialect;
|
||||
import org.springframework.data.r2dbc.mapping.SettableValue;
|
||||
import org.springframework.data.r2dbc.query.Criteria;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.relational.core.query.Criteria;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ReactiveDataAccessStrategy}.
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
package org.springframework.data.r2dbc.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.r2dbc.query.Criteria.*;
|
||||
import static org.springframework.data.r2dbc.query.Query.*;
|
||||
import static org.springframework.data.relational.core.query.Criteria.*;
|
||||
import static org.springframework.data.relational.core.query.Query.*;
|
||||
|
||||
import io.r2dbc.spi.test.MockResult;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
package org.springframework.data.r2dbc.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.r2dbc.query.Criteria.*;
|
||||
import static org.springframework.data.r2dbc.query.Query.*;
|
||||
import static org.springframework.data.relational.core.query.Criteria.*;
|
||||
import static org.springframework.data.relational.core.query.Query.*;
|
||||
|
||||
import io.r2dbc.spi.test.MockColumnMetadata;
|
||||
import io.r2dbc.spi.test.MockResult;
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.data.r2dbc.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.r2dbc.query.Criteria.*;
|
||||
import static org.springframework.data.r2dbc.query.Query.*;
|
||||
import static org.springframework.data.relational.core.query.Query.*;
|
||||
|
||||
import io.r2dbc.spi.test.MockResult;
|
||||
import reactor.test.StepVerifier;
|
||||
@@ -28,9 +28,9 @@ import org.junit.Test;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.r2dbc.dialect.PostgresDialect;
|
||||
import org.springframework.data.r2dbc.mapping.SettableValue;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.r2dbc.testing.StatementRecorder;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
|
||||
/**
|
||||
* Unit test for {@link ReactiveUpdateOperation}.
|
||||
|
||||
@@ -25,8 +25,8 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.r2dbc.core.StatementMapper.UpdateSpec;
|
||||
import org.springframework.data.r2dbc.dialect.BindTarget;
|
||||
import org.springframework.data.r2dbc.dialect.PostgresDialect;
|
||||
import org.springframework.data.r2dbc.query.Criteria;
|
||||
import org.springframework.data.r2dbc.query.Update;
|
||||
import org.springframework.data.relational.core.query.Criteria;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DefaultStatementMapper}.
|
||||
|
||||
@@ -21,7 +21,7 @@ import io.mockk.verify
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
import org.springframework.data.r2dbc.query.Update
|
||||
import org.springframework.data.relational.core.query.Update
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user