Polishing.

Reuse H2 dialect settings in R2DBC-specific H2 dialect.
Refactor ArrayColumns support classes, into toplevel-types. Let R2DBC H2 sublass the relational H2Dialect to decouple from Postgres.

See #1287
Original pull request #1297
This commit is contained in:
Mark Paluch
2022-07-21 15:45:30 +02:00
committed by Jens Schauder
parent c2e163b5c2
commit 0d1ba211c5
9 changed files with 152 additions and 93 deletions

View File

@@ -1,34 +1,57 @@
/*
* Copyright 2019-2022 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.dialect;
import org.springframework.data.relational.core.dialect.AnsiDialect;
import org.springframework.data.relational.core.dialect.LockClause;
import org.springframework.data.relational.core.dialect.ArrayColumns;
import org.springframework.data.relational.core.dialect.ObjectArrayColumns;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.data.util.Lazy;
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
/**
* An SQL dialect for H2 in Postgres Compatibility mode.
* R2DBC dialect for H2.
*
* @author Mark Paluch
* @author Jens Schauder
* @author Diego Krupitza
*/
public class H2Dialect extends PostgresDialect {
public class H2Dialect extends org.springframework.data.relational.core.dialect.H2Dialect implements R2dbcDialect {
/**
* Singleton instance.
*/
public static final H2Dialect INSTANCE = new H2Dialect();
private static final BindMarkersFactory INDEXED = BindMarkersFactory.indexed("$", 1);
private final Lazy<ArrayColumns> arrayColumns = Lazy
.of(() -> new SimpleTypeArrayColumns(ObjectArrayColumns.INSTANCE, getSimpleTypeHolder()));
@Override
public BindMarkersFactory getBindMarkersFactory() {
return INDEXED;
}
@Override
public String renderForGeneratedValues(SqlIdentifier identifier) {
return identifier.getReference(getIdentifierProcessing());
}
@Override
public LockClause lock() {
// H2 Dialect does not support the same lock keywords as PostgreSQL, but it supports the ANSI SQL standard.
// see https://www.h2database.com/html/commands.html
// and https://www.h2database.com/html/features.html#compatibility
return AnsiDialect.INSTANCE.lock();
public ArrayColumns getArraySupport() {
return this.arrayColumns.get();
}
}

View File

@@ -24,8 +24,8 @@ import org.springframework.data.geo.Box;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.relational.core.dialect.ArrayColumns;
import org.springframework.data.relational.core.dialect.ObjectArrayColumns;
import org.springframework.data.util.Lazy;
import org.springframework.lang.NonNull;
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
@@ -79,9 +79,8 @@ public class PostgresDialect extends org.springframework.data.relational.core.di
private static final BindMarkersFactory INDEXED = BindMarkersFactory.indexed("$", 1);
private final Lazy<ArrayColumns> arrayColumns = Lazy.of(() -> new R2dbcArrayColumns(
org.springframework.data.relational.core.dialect.PostgresDialect.INSTANCE.getArraySupport(),
getSimpleTypeHolder()));
private final Lazy<ArrayColumns> arrayColumns = Lazy
.of(() -> new SimpleTypeArrayColumns(ObjectArrayColumns.INSTANCE, getSimpleTypeHolder()));
/*
* (non-Javadoc)
@@ -137,37 +136,6 @@ public class PostgresDialect extends org.springframework.data.relational.core.di
return converters;
}
private static class R2dbcArrayColumns implements ArrayColumns {
private final ArrayColumns delegate;
private final SimpleTypeHolder simpleTypeHolder;
R2dbcArrayColumns(ArrayColumns delegate, SimpleTypeHolder simpleTypeHolder) {
this.delegate = delegate;
this.simpleTypeHolder = simpleTypeHolder;
}
@Override
public boolean isSupported() {
return this.delegate.isSupported();
}
@Override
public Class<?> getArrayType(Class<?> userType) {
Class<?> typeToUse = userType;
while (typeToUse.getComponentType() != null) {
typeToUse = typeToUse.getComponentType();
}
if (!this.simpleTypeHolder.isSimpleType(typeToUse)) {
throw new IllegalArgumentException("Unsupported array type: " + ClassUtils.getQualifiedName(typeToUse));
}
return this.delegate.getArrayType(typeToUse);
}
}
/**
* If the class is present on the class path, invoke the specified consumer {@code action} with the class object,
* otherwise do nothing.

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2022 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.dialect;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.relational.core.dialect.ArrayColumns;
import org.springframework.util.ClassUtils;
/**
* {@link ArrayColumns} support based on {@link SimpleTypeHolder store-native simple types}.
*
* @author Mark Paluch
* @since 3.0
*/
record SimpleTypeArrayColumns(ArrayColumns delegate, SimpleTypeHolder simpleTypeHolder) implements ArrayColumns {
@Override
public boolean isSupported() {
return this.delegate.isSupported();
}
@Override
public Class<?> getArrayType(Class<?> userType) {
Class<?> typeToUse = ArrayColumns.unwrapComponentType(userType);
if (!this.simpleTypeHolder.isSimpleType(typeToUse)) {
throw new IllegalArgumentException(
"Unsupported array type: %s".formatted(ClassUtils.getQualifiedName(typeToUse)));
}
return this.delegate.getArrayType(typeToUse);
}
}