DATAJDBC-479 - Use SqlIdentifier in SQL AST.
We now use SqlIdentifier to encapsulate names and aliases of tables, columns and functions. We now use proper delegation to ConditionVisitor to render a JOIN condition. Previously, we used toString() of Condition segments which rendered an approximation of the condition. ConditionVisitor applies RenderContext settings that consider identifier quoting and normalization strategies. Original pull request: #187.
This commit is contained in:
committed by
Jens Schauder
parent
595559bf28
commit
592f483699
@@ -18,10 +18,8 @@ package org.springframework.data.jdbc.core.convert;
|
||||
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||
import org.springframework.data.relational.core.sql.Column;
|
||||
import org.springframework.data.relational.core.sql.SQL;
|
||||
import org.springframework.data.relational.core.sql.Table;
|
||||
import org.springframework.data.relational.core.sql.IdentifierProcessing;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.data.relational.core.sql.Table;
|
||||
|
||||
/**
|
||||
* Utility to get from path to SQL DSL elements.
|
||||
@@ -35,21 +33,19 @@ class SqlContext {
|
||||
|
||||
private final RelationalPersistentEntity<?> entity;
|
||||
private final Table table;
|
||||
private final IdentifierProcessing identifierProcessing;
|
||||
|
||||
SqlContext(RelationalPersistentEntity<?> entity, IdentifierProcessing identifierProcessing) {
|
||||
SqlContext(RelationalPersistentEntity<?> entity) {
|
||||
|
||||
this.identifierProcessing = identifierProcessing;
|
||||
this.entity = entity;
|
||||
this.table = SQL.table(entity.getTableName().toSql(this.identifierProcessing));
|
||||
this.table = Table.create(entity.getTableName());
|
||||
}
|
||||
|
||||
Column getIdColumn() {
|
||||
return table.column(entity.getIdColumn().toSql(identifierProcessing));
|
||||
return table.column(entity.getIdColumn());
|
||||
}
|
||||
|
||||
Column getVersionColumn() {
|
||||
return table.column(entity.getRequiredVersionProperty().getColumnName().toSql(identifierProcessing));
|
||||
return table.column(entity.getRequiredVersionProperty().getColumnName());
|
||||
}
|
||||
|
||||
Table getTable() {
|
||||
@@ -59,17 +55,15 @@ class SqlContext {
|
||||
Table getTable(PersistentPropertyPathExtension path) {
|
||||
|
||||
SqlIdentifier tableAlias = path.getTableAlias();
|
||||
Table table = SQL.table(path.getTableName().toSql(identifierProcessing));
|
||||
return tableAlias == null ? table : table.as(tableAlias.toSql(identifierProcessing));
|
||||
Table table = Table.create(path.getTableName());
|
||||
return tableAlias == null ? table : table.as(tableAlias);
|
||||
}
|
||||
|
||||
Column getColumn(PersistentPropertyPathExtension path) {
|
||||
return getTable(path).column(path.getColumnName().toSql(identifierProcessing))
|
||||
.as(path.getColumnAlias().toSql(identifierProcessing));
|
||||
return getTable(path).column(path.getColumnName()).as(path.getColumnAlias());
|
||||
}
|
||||
|
||||
Column getReverseColumn(PersistentPropertyPathExtension path) {
|
||||
return getTable(path).column(path.getReverseColumnName().toSql(identifierProcessing))
|
||||
.as(path.getReverseColumnNameAlias().toSql(identifierProcessing));
|
||||
return getTable(path).column(path.getReverseColumnName()).as(path.getReverseColumnNameAlias());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
|
||||
import org.springframework.data.relational.core.sql.*;
|
||||
import org.springframework.data.relational.core.sql.render.RenderContext;
|
||||
import org.springframework.data.relational.core.sql.render.SqlRenderer;
|
||||
import org.springframework.data.relational.domain.Identifier;
|
||||
import org.springframework.data.util.Lazy;
|
||||
@@ -64,7 +65,7 @@ class SqlGenerator {
|
||||
private final JdbcConverter converter;
|
||||
private final RelationalPersistentEntity<?> entity;
|
||||
private final MappingContext<RelationalPersistentEntity<?>, RelationalPersistentProperty> mappingContext;
|
||||
private final IdentifierProcessing identifierProcessing;
|
||||
private final RenderContext renderContext;
|
||||
|
||||
private final SqlContext sqlContext;
|
||||
private final SqlRenderer sqlRenderer;
|
||||
@@ -92,16 +93,15 @@ class SqlGenerator {
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param dialect must not be {@literal null}.
|
||||
*/
|
||||
SqlGenerator(RelationalMappingContext mappingContext, JdbcConverter converter, RelationalPersistentEntity<?> entity,
|
||||
Dialect dialect) {
|
||||
SqlGenerator(RelationalMappingContext mappingContext, JdbcConverter converter,RelationalPersistentEntity<?> entity, Dialect dialect) {
|
||||
|
||||
this.mappingContext = mappingContext;
|
||||
this.converter = converter;
|
||||
this.entity = entity;
|
||||
this.identifierProcessing = dialect.getIdentifierProcessing();
|
||||
this.sqlContext = new SqlContext(entity, this.identifierProcessing);
|
||||
this.sqlContext = new SqlContext(entity);
|
||||
this.sqlRenderer = SqlRenderer.create(new RenderContextFactory(dialect).createRenderContext());
|
||||
this.columns = new Columns(entity, mappingContext, converter);
|
||||
this.renderContext = new RenderContextFactory(dialect).createRenderContext();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,10 +125,9 @@ class SqlGenerator {
|
||||
return rootCondition.apply(filterColumn);
|
||||
}
|
||||
|
||||
Table subSelectTable = SQL.table(parentPath.getTableName().toSql(identifierProcessing));
|
||||
Column idColumn = subSelectTable.column(parentPath.getIdColumnName().toSql(identifierProcessing));
|
||||
Column selectFilterColumn = subSelectTable
|
||||
.column(parentPath.getEffectiveIdColumnName().toSql(identifierProcessing));
|
||||
Table subSelectTable = Table.create(parentPath.getTableName());
|
||||
Column idColumn = subSelectTable.column(parentPath.getIdColumnName());
|
||||
Column selectFilterColumn = subSelectTable.column(parentPath.getEffectiveIdColumnName());
|
||||
|
||||
Condition innerCondition;
|
||||
|
||||
@@ -151,7 +150,7 @@ class SqlGenerator {
|
||||
}
|
||||
|
||||
private BindMarker getBindMarker(SqlIdentifier columnName) {
|
||||
return SQL.bindMarker(":" + parameterPattern.matcher(columnName.getReference(identifierProcessing)).replaceAll(""));
|
||||
return SQL.bindMarker(":" + parameterPattern.matcher(renderReference(columnName)).replaceAll(""));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,21 +209,19 @@ class SqlGenerator {
|
||||
Assert.isTrue(keyColumn != null || !ordered,
|
||||
"If the SQL statement should be ordered a keyColumn to order by must be provided.");
|
||||
|
||||
Table table = getTable();
|
||||
|
||||
SelectBuilder.SelectWhere builder = selectBuilder( //
|
||||
keyColumn == null //
|
||||
? Collections.emptyList() //
|
||||
: Collections.singleton(keyColumn.toSql(identifierProcessing)) //
|
||||
: Collections.singleton(keyColumn) //
|
||||
);
|
||||
|
||||
Table table = getTable();
|
||||
|
||||
Condition condition = buildConditionForBackReference(parentIdentifier, table);
|
||||
SelectBuilder.SelectWhereAndOr withWhereClause = builder.where(condition);
|
||||
|
||||
Select select = ordered //
|
||||
? withWhereClause
|
||||
.orderBy(table.column(keyColumn.toSql(identifierProcessing)).as(keyColumn.toSql(identifierProcessing)))
|
||||
.build() //
|
||||
? withWhereClause.orderBy(table.column(keyColumn).as(keyColumn)).build() //
|
||||
: withWhereClause.build();
|
||||
|
||||
return render(select);
|
||||
@@ -235,8 +232,7 @@ class SqlGenerator {
|
||||
Condition condition = null;
|
||||
for (SqlIdentifier backReferenceColumn : parentIdentifier.toMap().keySet()) {
|
||||
|
||||
Condition newCondition = table.column(backReferenceColumn.toSql(identifierProcessing))
|
||||
.isEqualTo(getBindMarker(backReferenceColumn));
|
||||
Condition newCondition = table.column(backReferenceColumn).isEqualTo(getBindMarker(backReferenceColumn));
|
||||
condition = condition == null ? newCondition : condition.and(newCondition);
|
||||
}
|
||||
|
||||
@@ -372,7 +368,7 @@ class SqlGenerator {
|
||||
return selectBuilder(Collections.emptyList());
|
||||
}
|
||||
|
||||
private SelectBuilder.SelectWhere selectBuilder(Collection<String> keyColumns) {
|
||||
private SelectBuilder.SelectWhere selectBuilder(Collection<SqlIdentifier> keyColumns) {
|
||||
|
||||
Table table = getTable();
|
||||
|
||||
@@ -396,7 +392,7 @@ class SqlGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
for (String keyColumn : keyColumns) {
|
||||
for (SqlIdentifier keyColumn : keyColumns) {
|
||||
columnExpressions.add(table.column(keyColumn).as(keyColumn));
|
||||
}
|
||||
|
||||
@@ -485,8 +481,8 @@ class SqlGenerator {
|
||||
|
||||
return new Join( //
|
||||
currentTable, //
|
||||
currentTable.column(path.getReverseColumnName().toSql(identifierProcessing)), //
|
||||
parentTable.column(idDefiningParentPath.getIdColumnName().toSql(identifierProcessing)) //
|
||||
currentTable.column(path.getReverseColumnName()), //
|
||||
parentTable.column(idDefiningParentPath.getIdColumnName()) //
|
||||
);
|
||||
}
|
||||
|
||||
@@ -526,14 +522,14 @@ class SqlGenerator {
|
||||
|
||||
Table table = getTable();
|
||||
|
||||
Set<SqlIdentifier> columnNamesForInsert = new TreeSet<>(Comparator.comparing(id -> id.toSql(identifierProcessing)));
|
||||
Set<SqlIdentifier> columnNamesForInsert = new TreeSet<>(Comparator.comparing(SqlIdentifier::getReference));
|
||||
columnNamesForInsert.addAll(columns.getInsertableColumns());
|
||||
columnNamesForInsert.addAll(additionalColumns);
|
||||
|
||||
InsertBuilder.InsertIntoColumnsAndValuesWithBuild insert = Insert.builder().into(table);
|
||||
|
||||
for (SqlIdentifier cn : columnNamesForInsert) {
|
||||
insert = insert.column(table.column(cn.toSql(identifierProcessing)));
|
||||
insert = insert.column(table.column(cn));
|
||||
}
|
||||
|
||||
InsertBuilder.InsertValuesWithBuild insertWithValues = null;
|
||||
@@ -551,8 +547,7 @@ class SqlGenerator {
|
||||
private String createUpdateWithVersionSql() {
|
||||
|
||||
Update update = createBaseUpdate() //
|
||||
.and(getVersionColumn()
|
||||
.isEqualTo(SQL.bindMarker(":" + VERSION_SQL_PARAMETER.getReference(identifierProcessing)))) //
|
||||
.and(getVersionColumn().isEqualTo(SQL.bindMarker(":" + renderReference(VERSION_SQL_PARAMETER)))) //
|
||||
.build();
|
||||
|
||||
return render(update);
|
||||
@@ -565,7 +560,7 @@ class SqlGenerator {
|
||||
List<AssignValue> assignments = columns.getUpdateableColumns() //
|
||||
.stream() //
|
||||
.map(columnName -> Assignments.value( //
|
||||
table.column(columnName.toSql(identifierProcessing)), //
|
||||
table.column(columnName), //
|
||||
getBindMarker(columnName))) //
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -582,8 +577,7 @@ class SqlGenerator {
|
||||
private String createDeleteByIdAndVersionSql() {
|
||||
|
||||
Delete delete = createBaseDeleteById(getTable()) //
|
||||
.and(getVersionColumn()
|
||||
.isEqualTo(SQL.bindMarker(":" + VERSION_SQL_PARAMETER.getReference(identifierProcessing)))) //
|
||||
.and(getVersionColumn().isEqualTo(SQL.bindMarker(":" + renderReference(VERSION_SQL_PARAMETER)))) //
|
||||
.build();
|
||||
|
||||
return render(delete);
|
||||
@@ -591,19 +585,19 @@ class SqlGenerator {
|
||||
|
||||
private DeleteBuilder.DeleteWhereAndOr createBaseDeleteById(Table table) {
|
||||
return Delete.builder().from(table)
|
||||
.where(getIdColumn().isEqualTo(SQL.bindMarker(":" + ID_SQL_PARAMETER.getReference(identifierProcessing))));
|
||||
.where(getIdColumn().isEqualTo(SQL.bindMarker(":" + renderReference(ID_SQL_PARAMETER))));
|
||||
}
|
||||
|
||||
private String createDeleteByPathAndCriteria(PersistentPropertyPathExtension path,
|
||||
Function<Column, Condition> rootCondition) {
|
||||
|
||||
Table table = SQL.table(path.getTableName().toSql(identifierProcessing));
|
||||
Table table = Table.create(path.getTableName());
|
||||
|
||||
DeleteBuilder.DeleteWhere builder = Delete.builder() //
|
||||
.from(table);
|
||||
Delete delete;
|
||||
|
||||
Column filterColumn = table.column(path.getReverseColumnName().toSql(identifierProcessing));
|
||||
Column filterColumn = table.column(path.getReverseColumnName());
|
||||
|
||||
if (path.getLength() == 1) {
|
||||
|
||||
@@ -659,6 +653,10 @@ class SqlGenerator {
|
||||
return sqlContext.getVersionColumn();
|
||||
}
|
||||
|
||||
private String renderReference(SqlIdentifier identifier) {
|
||||
return identifier.getReference(renderContext.getIdentifierProcessing());
|
||||
}
|
||||
|
||||
private List<OrderByField> extractOrderByFields(Sort sort) {
|
||||
return sort.stream()
|
||||
.map(order -> OrderByField.from(Column.create(order.getProperty(), this.getTable()), order.getDirection()))
|
||||
|
||||
@@ -40,14 +40,16 @@ public class SqlGeneratorSource {
|
||||
private final Dialect dialect;
|
||||
|
||||
/**
|
||||
* @return the {@link Dialect} used by the created {@link SqlGenerator} instances. Guaranteed to be not {@literal null}.
|
||||
* @return the {@link Dialect} used by the created {@link SqlGenerator} instances. Guaranteed to be not
|
||||
* {@literal null}.
|
||||
*/
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
SqlGenerator getSqlGenerator(Class<?> domainType) {
|
||||
return CACHE.computeIfAbsent(domainType, t -> new SqlGenerator(context, converter,
|
||||
return CACHE.computeIfAbsent(domainType,
|
||||
t -> new SqlGenerator(context, converter,
|
||||
context.getRequiredPersistentEntity(t), dialect));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,10 @@ public class JdbcMappingContext extends RelationalMappingContext {
|
||||
@Override
|
||||
protected RelationalPersistentProperty createPersistentProperty(Property property,
|
||||
RelationalPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
return new BasicJdbcPersistentProperty(property, owner, simpleTypeHolder, this.getNamingStrategy());
|
||||
BasicJdbcPersistentProperty persistentProperty = new BasicJdbcPersistentProperty(property, owner, simpleTypeHolder,
|
||||
this.getNamingStrategy());
|
||||
persistentProperty.setForceQuote(isForceQuote());
|
||||
return persistentProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.jdbc.core.convert;
|
||||
|
||||
import org.springframework.data.relational.core.dialect.AbstractDialect;
|
||||
import org.springframework.data.relational.core.dialect.Dialect;
|
||||
import org.springframework.data.relational.core.dialect.HsqlDbDialect;
|
||||
import org.springframework.data.relational.core.dialect.LimitClause;
|
||||
import org.springframework.data.relational.core.sql.IdentifierProcessing;
|
||||
|
||||
/**
|
||||
* {@link Dialect} adapter that delegates to the given {@link IdentifierProcessing}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class IdentifierProcessingAdapter extends AbstractDialect implements Dialect {
|
||||
|
||||
private final IdentifierProcessing identifierProcessing;
|
||||
|
||||
public IdentifierProcessingAdapter(IdentifierProcessing identifierProcessing) {
|
||||
this.identifierProcessing = identifierProcessing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LimitClause limit() {
|
||||
return HsqlDbDialect.INSTANCE.limit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierProcessing getIdentifierProcessing() {
|
||||
return identifierProcessing;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import java.util.function.Consumer;
|
||||
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||
import org.springframework.data.jdbc.core.mapping.PersistentPropertyPathTestUtils;
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.assertj.core.api.SoftAssertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.jdbc.core.PropertyPathTestingUtils;
|
||||
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||
@@ -33,6 +34,7 @@ import org.springframework.data.relational.core.mapping.PersistentPropertyPathEx
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||
import org.springframework.data.relational.core.sql.Aliased;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link SqlGenerator} in a context of the {@link Embedded} annotation.
|
||||
@@ -49,6 +51,7 @@ public class SqlGeneratorEmbeddedUnitTests {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.context.setForceQuote(false);
|
||||
this.sqlGenerator = createSqlGenerator(DummyEntity.class);
|
||||
}
|
||||
|
||||
@@ -201,7 +204,8 @@ public class SqlGeneratorEmbeddedUnitTests {
|
||||
|
||||
assertThat(generatedColumn("embeddable.test", DummyEntity.class)) //
|
||||
.extracting(c -> c.getName(), c -> c.getTable().getName(), c -> getAlias(c.getTable()), this::getAlias)
|
||||
.containsExactly("test", "dummy_entity", null, "test");
|
||||
.containsExactly(SqlIdentifier.unquoted("test"), SqlIdentifier.unquoted("dummy_entity"), null,
|
||||
SqlIdentifier.unquoted("test"));
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-340
|
||||
@@ -224,7 +228,8 @@ public class SqlGeneratorEmbeddedUnitTests {
|
||||
|
||||
assertThat(generatedColumn("prefixedEmbeddable.test", DummyEntity.class)) //
|
||||
.extracting(c -> c.getName(), c -> c.getTable().getName(), c -> getAlias(c.getTable()), this::getAlias)
|
||||
.containsExactly("prefix_test", "dummy_entity", null, "prefix_test");
|
||||
.containsExactly(SqlIdentifier.unquoted("prefix_test"), SqlIdentifier.unquoted("dummy_entity"), null,
|
||||
SqlIdentifier.unquoted("prefix_test"));
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-340
|
||||
@@ -240,7 +245,8 @@ public class SqlGeneratorEmbeddedUnitTests {
|
||||
|
||||
assertThat(generatedColumn("embeddable.embeddable.attr1", DummyEntity.class)) //
|
||||
.extracting(c -> c.getName(), c -> c.getTable().getName(), c -> getAlias(c.getTable()), this::getAlias)
|
||||
.containsExactly("attr1", "dummy_entity", null, "attr1");
|
||||
.containsExactly(SqlIdentifier.unquoted("attr1"), SqlIdentifier.unquoted("dummy_entity"), null,
|
||||
SqlIdentifier.unquoted("attr1"));
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-340
|
||||
@@ -250,11 +256,11 @@ public class SqlGeneratorEmbeddedUnitTests {
|
||||
|
||||
SoftAssertions.assertSoftly(softly -> {
|
||||
|
||||
softly.assertThat(join.getJoinTable().getName()).isEqualTo("other_entity");
|
||||
softly.assertThat(join.getJoinTable().getName()).isEqualTo(SqlIdentifier.unquoted("other_entity"));
|
||||
softly.assertThat(join.getJoinColumn().getTable()).isEqualTo(join.getJoinTable());
|
||||
softly.assertThat(join.getJoinColumn().getName()).isEqualTo("dummy_entity2");
|
||||
softly.assertThat(join.getParentId().getName()).isEqualTo("id");
|
||||
softly.assertThat(join.getParentId().getTable().getName()).isEqualTo("dummy_entity2");
|
||||
softly.assertThat(join.getJoinColumn().getName()).isEqualTo(SqlIdentifier.unquoted("dummy_entity2"));
|
||||
softly.assertThat(join.getParentId().getName()).isEqualTo(SqlIdentifier.unquoted("id"));
|
||||
softly.assertThat(join.getParentId().getTable().getName()).isEqualTo(SqlIdentifier.unquoted("dummy_entity2"));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -263,7 +269,8 @@ public class SqlGeneratorEmbeddedUnitTests {
|
||||
|
||||
assertThat(generatedColumn("embedded.other.value", DummyEntity2.class)) //
|
||||
.extracting(c -> c.getName(), c -> c.getTable().getName(), c -> getAlias(c.getTable()), this::getAlias)
|
||||
.containsExactly("value", "other_entity", "prefix_other", "prefix_other_value");
|
||||
.containsExactly(SqlIdentifier.unquoted("value"), SqlIdentifier.unquoted("other_entity"),
|
||||
SqlIdentifier.quoted("prefix_other"), SqlIdentifier.unquoted("prefix_other_value"));
|
||||
}
|
||||
|
||||
private SqlGenerator.Join generateJoin(String path, Class<?> type) {
|
||||
@@ -271,7 +278,7 @@ public class SqlGeneratorEmbeddedUnitTests {
|
||||
.getJoin(new PersistentPropertyPathExtension(context, PropertyPathTestingUtils.toPath(path, type, context)));
|
||||
}
|
||||
|
||||
private String getAlias(Object maybeAliased) {
|
||||
private SqlIdentifier getAlias(Object maybeAliased) {
|
||||
|
||||
if (maybeAliased instanceof Aliased) {
|
||||
return ((Aliased) maybeAliased).getAlias();
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||
import org.springframework.data.jdbc.core.mapping.PersistentPropertyPathTestUtils;
|
||||
import org.springframework.data.jdbc.testing.AnsiDialect;
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
import org.springframework.data.relational.core.dialect.HsqlDbDialect;
|
||||
import org.springframework.data.relational.core.mapping.NamingStrategy;
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||
|
||||
@@ -47,6 +47,10 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
|
||||
import org.springframework.data.relational.core.sql.Aliased;
|
||||
import org.springframework.data.relational.core.sql.IdentifierProcessing;
|
||||
import org.springframework.data.relational.core.sql.IdentifierProcessing.LetterCasing;
|
||||
import org.springframework.data.relational.core.sql.IdentifierProcessing.Quoting;
|
||||
import org.springframework.data.relational.core.sql.SqlIdentifier;
|
||||
import org.springframework.data.relational.core.sql.Table;
|
||||
import org.springframework.data.relational.domain.Identifier;
|
||||
|
||||
@@ -555,11 +559,11 @@ public class SqlGeneratorUnitTests {
|
||||
|
||||
SoftAssertions.assertSoftly(softly -> {
|
||||
|
||||
softly.assertThat(join.getJoinTable().getName()).isEqualTo("\"REFERENCED_ENTITY\"");
|
||||
softly.assertThat(join.getJoinTable().getName()).isEqualTo(SqlIdentifier.quoted("REFERENCED_ENTITY"));
|
||||
softly.assertThat(join.getJoinColumn().getTable()).isEqualTo(join.getJoinTable());
|
||||
softly.assertThat(join.getJoinColumn().getName()).isEqualTo("\"DUMMY_ENTITY\"");
|
||||
softly.assertThat(join.getParentId().getName()).isEqualTo("\"id1\"");
|
||||
softly.assertThat(join.getParentId().getTable().getName()).isEqualTo("\"DUMMY_ENTITY\"");
|
||||
softly.assertThat(join.getJoinColumn().getName()).isEqualTo(SqlIdentifier.quoted("DUMMY_ENTITY"));
|
||||
softly.assertThat(join.getParentId().getName()).isEqualTo(SqlIdentifier.quoted("id1"));
|
||||
softly.assertThat(join.getParentId().getTable().getName()).isEqualTo(SqlIdentifier.quoted("DUMMY_ENTITY"));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -587,11 +591,12 @@ public class SqlGeneratorUnitTests {
|
||||
|
||||
SoftAssertions.assertSoftly(softly -> {
|
||||
|
||||
softly.assertThat(join.getJoinTable().getName()).isEqualTo("\"SECOND_LEVEL_REFERENCED_ENTITY\"");
|
||||
softly.assertThat(join.getJoinTable().getName())
|
||||
.isEqualTo(SqlIdentifier.quoted("SECOND_LEVEL_REFERENCED_ENTITY"));
|
||||
softly.assertThat(join.getJoinColumn().getTable()).isEqualTo(join.getJoinTable());
|
||||
softly.assertThat(join.getJoinColumn().getName()).isEqualTo("\"REFERENCED_ENTITY\"");
|
||||
softly.assertThat(join.getParentId().getName()).isEqualTo("\"X_L1ID\"");
|
||||
softly.assertThat(join.getParentId().getTable().getName()).isEqualTo("\"REFERENCED_ENTITY\"");
|
||||
softly.assertThat(join.getJoinColumn().getName()).isEqualTo(SqlIdentifier.quoted("REFERENCED_ENTITY"));
|
||||
softly.assertThat(join.getParentId().getName()).isEqualTo(SqlIdentifier.quoted("X_L1ID"));
|
||||
softly.assertThat(join.getParentId().getTable().getName()).isEqualTo(SqlIdentifier.quoted("REFERENCED_ENTITY"));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -603,13 +608,14 @@ public class SqlGeneratorUnitTests {
|
||||
|
||||
SoftAssertions.assertSoftly(softly -> {
|
||||
|
||||
softly.assertThat(joinTable.getName()).isEqualTo("\"NO_ID_CHILD\"");
|
||||
softly.assertThat(joinTable.getName()).isEqualTo(SqlIdentifier.quoted("NO_ID_CHILD"));
|
||||
softly.assertThat(joinTable).isInstanceOf(Aliased.class);
|
||||
softly.assertThat(((Aliased) joinTable).getAlias()).isEqualTo("\"child\"");
|
||||
softly.assertThat(((Aliased) joinTable).getAlias()).isEqualTo(SqlIdentifier.quoted("child"));
|
||||
softly.assertThat(join.getJoinColumn().getTable()).isEqualTo(joinTable);
|
||||
softly.assertThat(join.getJoinColumn().getName()).isEqualTo("\"PARENT_OF_NO_ID_CHILD\"");
|
||||
softly.assertThat(join.getParentId().getName()).isEqualTo("\"X_ID\"");
|
||||
softly.assertThat(join.getParentId().getTable().getName()).isEqualTo("\"PARENT_OF_NO_ID_CHILD\"");
|
||||
softly.assertThat(join.getJoinColumn().getName()).isEqualTo(SqlIdentifier.quoted("PARENT_OF_NO_ID_CHILD"));
|
||||
softly.assertThat(join.getParentId().getName()).isEqualTo(SqlIdentifier.quoted("X_ID"));
|
||||
softly.assertThat(join.getParentId().getTable().getName())
|
||||
.isEqualTo(SqlIdentifier.quoted("PARENT_OF_NO_ID_CHILD"));
|
||||
|
||||
});
|
||||
}
|
||||
@@ -624,7 +630,8 @@ public class SqlGeneratorUnitTests {
|
||||
|
||||
assertThat(generatedColumn("id", DummyEntity.class)) //
|
||||
.extracting(c -> c.getName(), c -> c.getTable().getName(), c -> getAlias(c.getTable()), this::getAlias)
|
||||
.containsExactly("\"id1\"", "\"DUMMY_ENTITY\"", null, "\"id1\"");
|
||||
.containsExactly(SqlIdentifier.quoted("id1"), SqlIdentifier.quoted("DUMMY_ENTITY"), null,
|
||||
SqlIdentifier.quoted("id1"));
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-340
|
||||
@@ -632,7 +639,8 @@ public class SqlGeneratorUnitTests {
|
||||
|
||||
assertThat(generatedColumn("ref.l1id", DummyEntity.class)) //
|
||||
.extracting(c -> c.getName(), c -> c.getTable().getName(), c -> getAlias(c.getTable()), this::getAlias) //
|
||||
.containsExactly("\"X_L1ID\"", "\"REFERENCED_ENTITY\"", "\"ref\"", "\"REF_X_L1ID\"");
|
||||
.containsExactly(SqlIdentifier.quoted("X_L1ID"), SqlIdentifier.quoted("REFERENCED_ENTITY"),
|
||||
SqlIdentifier.quoted("ref"), SqlIdentifier.quoted("REF_X_L1ID"));
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-340
|
||||
@@ -646,11 +654,11 @@ public class SqlGeneratorUnitTests {
|
||||
|
||||
assertThat(generatedColumn("child", ParentOfNoIdChild.class)) //
|
||||
.extracting(c -> c.getName(), c -> c.getTable().getName(), c -> getAlias(c.getTable()), this::getAlias) //
|
||||
.containsExactly("\"PARENT_OF_NO_ID_CHILD\"", "\"NO_ID_CHILD\"", "\"child\"",
|
||||
"\"CHILD_PARENT_OF_NO_ID_CHILD\"");
|
||||
.containsExactly(SqlIdentifier.quoted("PARENT_OF_NO_ID_CHILD"), SqlIdentifier.quoted("NO_ID_CHILD"),
|
||||
SqlIdentifier.quoted("child"), SqlIdentifier.quoted("CHILD_PARENT_OF_NO_ID_CHILD"));
|
||||
}
|
||||
|
||||
private String getAlias(Object maybeAliased) {
|
||||
private SqlIdentifier getAlias(Object maybeAliased) {
|
||||
|
||||
if (maybeAliased instanceof Aliased) {
|
||||
return ((Aliased) maybeAliased).getAlias();
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.jdbc.core.convert;
|
||||
|
||||
import org.springframework.data.relational.core.dialect.AbstractDialect;
|
||||
import org.springframework.data.relational.core.dialect.Dialect;
|
||||
import org.springframework.data.relational.core.dialect.HsqlDbDialect;
|
||||
import org.springframework.data.relational.core.dialect.LimitClause;
|
||||
import org.springframework.data.relational.core.sql.IdentifierProcessing;
|
||||
import org.springframework.data.relational.core.sql.IdentifierProcessing.LetterCasing;
|
||||
import org.springframework.data.relational.core.sql.IdentifierProcessing.Quoting;
|
||||
|
||||
/**
|
||||
* Simple {@link Dialect} that provides unquoted {@link IdentifierProcessing}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class UnquotedDialect extends AbstractDialect implements Dialect {
|
||||
|
||||
public static final UnquotedDialect INSTANCE = new UnquotedDialect();
|
||||
|
||||
private UnquotedDialect() {}
|
||||
|
||||
@Override
|
||||
public LimitClause limit() {
|
||||
return HsqlDbDialect.INSTANCE.limit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierProcessing getIdentifierProcessing() {
|
||||
return IdentifierProcessing.create(new Quoting(""), LetterCasing.AS_IS);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user