From ccfe820dab21645c824dbe958eb38d32450accdb Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 27 May 2020 09:59:57 +0200 Subject: [PATCH] DATAJDBC-547 - Polishing. Let SqlIdentifier implement Streamable to allow iteration of composed identifiers. Adapt dialect to iteration changes. Rewrite simple if blocks to using ternary operators. Original pull request: #221. --- .../core/dialect/PostgresDialect.java | 14 ++++++++--- .../core/mapping/DerivedSqlIdentifier.java | 18 ++++++++----- .../RelationalPersistentEntityImpl.java | 2 +- .../core/sql/CompositeSqlIdentifier.java | 23 +++++++++++------ .../core/sql/DefaultSqlIdentifier.java | 18 ++++++++----- .../relational/core/sql/SqlIdentifier.java | 25 +++++++++++-------- 6 files changed, 66 insertions(+), 34 deletions(-) diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java index 5db3031fd..a9e6c72be 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java @@ -21,6 +21,7 @@ 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.LockOptions; +import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.data.relational.core.sql.Table; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -132,9 +133,16 @@ public class PostgresDialect extends AbstractDialect { return ""; } - String tableName = tables.get(0) // get the first table - .getName().getSimpleIdentifier() // without schema - .toSql(this.identifierProcessing); + // get the first table and obtain last part if the identifier is a composed one. + SqlIdentifier identifier = tables.get(0).getName(); + SqlIdentifier last = identifier; + + for (SqlIdentifier sqlIdentifier : identifier) { + last = sqlIdentifier; + } + + // without schema + String tableName = last.toSql(this.identifierProcessing); switch (lockOptions.getLockMode()) { diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifier.java index 34dcde8f3..2e13e0d5f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DerivedSqlIdentifier.java @@ -15,6 +15,8 @@ */ package org.springframework.data.relational.core.mapping; +import java.util.Collections; +import java.util.Iterator; import java.util.function.UnaryOperator; import org.springframework.data.relational.core.sql.IdentifierProcessing; @@ -40,6 +42,15 @@ class DerivedSqlIdentifier implements SqlIdentifier { this.quoted = quoted; } + /* + * (non-Javadoc) + * @see org.springframework.data.relational.domain.SqlIdentifier#iterator() + */ + @Override + public Iterator iterator() { + return Collections. singleton(this).iterator(); + } + /* * (non-Javadoc) * @see org.springframework.data.relational.domain.SqlIdentifier#transform(java.util.function.UnaryOperator) @@ -106,11 +117,6 @@ class DerivedSqlIdentifier implements SqlIdentifier { */ @Override public String toString() { - - if (quoted) { - return toSql(IdentifierProcessing.ANSI); - } - - return this.name; + return quoted ? toSql(IdentifierProcessing.ANSI) : this.name; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImpl.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImpl.java index cc02ad641..c15686066 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImpl.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentEntityImpl.java @@ -103,6 +103,6 @@ class RelationalPersistentEntityImpl extends BasicPersistentEntity", getType()); + return String.format("RelationalPersistentEntityImpl<%s>", getType()); } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/CompositeSqlIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/CompositeSqlIdentifier.java index 84297b038..5ac50fbca 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/CompositeSqlIdentifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/CompositeSqlIdentifier.java @@ -15,6 +15,8 @@ */ package org.springframework.data.relational.core.sql; +import java.util.Arrays; +import java.util.Iterator; import java.util.StringJoiner; import java.util.function.UnaryOperator; @@ -40,6 +42,15 @@ class CompositeSqlIdentifier implements SqlIdentifier { this.parts = parts; } + /* + * (non-Javadoc) + * @see org.springframework.data.relational.domain.SqlIdentifier#iterator() + */ + @Override + public Iterator iterator() { + return Arrays.asList(parts).iterator(); + } + /* * (non-Javadoc) * @see org.springframework.data.relational.domain.SqlIdentifier#transform(java.util.function.UnaryOperator) @@ -71,12 +82,7 @@ class CompositeSqlIdentifier implements SqlIdentifier { */ @Override public String getReference(IdentifierProcessing processing) { - throw new UnsupportedOperationException("A Composite SQL Identifiers can't be used as a reference name"); - } - - @Override - public SqlIdentifier getSimpleIdentifier() { - return parts[parts.length - 1]; + throw new UnsupportedOperationException("Composite SQL Identifiers can't be used for reference name retrieval"); } /* @@ -86,11 +92,14 @@ class CompositeSqlIdentifier implements SqlIdentifier { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; + } + if (o instanceof SqlIdentifier) { return toString().equals(o.toString()); } + return false; } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSqlIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSqlIdentifier.java index 9e44f2531..c51ab3df1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSqlIdentifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/DefaultSqlIdentifier.java @@ -15,6 +15,8 @@ */ package org.springframework.data.relational.core.sql; +import java.util.Collections; +import java.util.Iterator; import java.util.function.UnaryOperator; import org.springframework.util.Assert; @@ -39,6 +41,15 @@ class DefaultSqlIdentifier implements SqlIdentifier { this.quoted = quoted; } + /* + * (non-Javadoc) + * @see org.springframework.data.relational.domain.SqlIdentifier#iterator() + */ + @Override + public Iterator iterator() { + return Collections. singleton(this).iterator(); + } + /* * (non-Javadoc) * @see org.springframework.data.relational.domain.SqlIdentifier#transform(java.util.function.UnaryOperator) @@ -102,11 +113,6 @@ class DefaultSqlIdentifier implements SqlIdentifier { */ @Override public String toString() { - - if (quoted) { - return toSql(IdentifierProcessing.ANSI); - } - - return this.name; + return quoted ? toSql(IdentifierProcessing.ANSI) : this.name; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SqlIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SqlIdentifier.java index 356fef708..cfd449c2f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SqlIdentifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/SqlIdentifier.java @@ -15,8 +15,12 @@ */ package org.springframework.data.relational.core.sql; +import java.util.Collections; +import java.util.Iterator; import java.util.function.UnaryOperator; +import org.springframework.data.util.Streamable; + /** * Represents a named object that exists in the database like a table name or a column name. SQL identifiers are created * from a {@link String name} with specifying whether the name should be quoted or unquoted. @@ -28,18 +32,27 @@ import java.util.function.UnaryOperator; *

* {@link SqlIdentifier} objects are immutable. Calling transformational methods such as * {@link #transform(UnaryOperator)} creates a new instance. + *

+ * {@link SqlIdentifier} are composable so an identifier may consist of a single identifier part or can be composed from + * multiple parts. Composed identifier can be traversed with {@link #stream()} or {@link #iterator()}. The iteration + * order depends on the actual composition ordering. * * @author Jens Schauder * @author Mark Paluch * @since 2.0 */ -public interface SqlIdentifier { +public interface SqlIdentifier extends Streamable { /** * Null-object. */ SqlIdentifier EMPTY = new SqlIdentifier() { + @Override + public Iterator iterator() { + return Collections.emptyIterator(); + } + @Override public SqlIdentifier transform(UnaryOperator transformationFunction) { return this; @@ -99,16 +112,6 @@ public interface SqlIdentifier { */ SqlIdentifier transform(UnaryOperator transformationFunction); - /** - * Returns the last part of an identifier. For a fully qualified column name {@literal schema.table.column} it will - * just return the column part. If the identifier consists of only a single part, that part is returned. - * - * @return Guaranteed to be not {@literal null}. - */ - default SqlIdentifier getSimpleIdentifier() { - return this; - } - /** * Create a new quoted identifier given {@code name}. *