From 3379ea95a5e896fdd78b4b2d493227f1c7e007ac Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 15 Mar 2021 11:26:15 +0100 Subject: [PATCH] Add support for Oracle bind marker scheme using R2DBC We now support Oracle's bind marker scheme that identifies dynamic parameters using names that are prefixed with a colon such as `:P0_myparam`. Closes gh-26680 --- .../binding/BindMarkersFactoryResolver.java | 6 +- .../BindMarkersFactoryResolverUnitTests.java | 108 ++++++++++++++++++ 2 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolverUnitTests.java diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java index e8eead572f83..31fc1ef9a198 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -118,10 +118,12 @@ static class BuiltInBindMarkersFactoryProvider implements BindMarkerFactoryProvi static { BUILTIN.put("H2", BindMarkersFactory.indexed("$", 1)); + BUILTIN.put("MariaDB", BindMarkersFactory.anonymous("?")); BUILTIN.put("Microsoft SQL Server", BindMarkersFactory.named("@", "P", 32, BuiltInBindMarkersFactoryProvider::filterBindMarker)); BUILTIN.put("MySQL", BindMarkersFactory.anonymous("?")); - BUILTIN.put("MariaDB", BindMarkersFactory.anonymous("?")); + BUILTIN.put("Oracle", BindMarkersFactory.named(":", "P", 32, + BuiltInBindMarkersFactoryProvider::filterBindMarker)); BUILTIN.put("PostgreSQL", BindMarkersFactory.indexed("$", 1)); } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolverUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolverUnitTests.java new file mode 100644 index 000000000000..2314b782b7ea --- /dev/null +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolverUnitTests.java @@ -0,0 +1,108 @@ +/* + * Copyright 2002-2021 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.r2dbc.core.binding; + +import io.r2dbc.spi.Connection; +import io.r2dbc.spi.ConnectionFactory; +import io.r2dbc.spi.ConnectionFactoryMetadata; +import org.junit.jupiter.api.Test; +import org.reactivestreams.Publisher; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Unit tests for {@link BindMarkersFactoryResolver}. + * + * @author Mark Paluch + */ +class BindMarkersFactoryResolverUnitTests { + + @Test + void shouldReturnBindMarkersFactoryForH2() { + + BindMarkers bindMarkers = BindMarkersFactoryResolver + .resolve(new MockConnectionFactory("H2")).create(); + + assertThat(bindMarkers.next().getPlaceholder()).isEqualTo("$1"); + } + + @Test + void shouldReturnBindMarkersFactoryForMariaDB() { + + BindMarkers bindMarkers = BindMarkersFactoryResolver + .resolve(new MockConnectionFactory("MariaDB")).create(); + + assertThat(bindMarkers.next().getPlaceholder()).isEqualTo("?"); + } + + @Test + void shouldReturnBindMarkersFactoryForMicrosoftSQLServer() { + + BindMarkers bindMarkers = BindMarkersFactoryResolver + .resolve(new MockConnectionFactory("Microsoft SQL Server")).create(); + + assertThat(bindMarkers.next("foo").getPlaceholder()).isEqualTo("@P0_foo"); + } + + @Test + void shouldReturnBindMarkersFactoryForMySQL() { + + BindMarkers bindMarkers = BindMarkersFactoryResolver + .resolve(new MockConnectionFactory("MySQL")).create(); + + assertThat(bindMarkers.next().getPlaceholder()).isEqualTo("?"); + } + + @Test + void shouldReturnBindMarkersFactoryForOracle() { + + BindMarkers bindMarkers = BindMarkersFactoryResolver + .resolve(new MockConnectionFactory("Oracle Database")).create(); + + assertThat(bindMarkers.next("foo").getPlaceholder()).isEqualTo(":P0_foo"); + } + + @Test + void shouldReturnBindMarkersFactoryForPostgreSQL() { + + BindMarkers bindMarkers = BindMarkersFactoryResolver + .resolve(new MockConnectionFactory("PostgreSQL")).create(); + + assertThat(bindMarkers.next().getPlaceholder()).isEqualTo("$1"); + } + + static class MockConnectionFactory implements ConnectionFactory { + + private final String driverName; + + MockConnectionFactory(String driverName) { + this.driverName = driverName; + } + + @Override + public Publisher create() { + throw new UnsupportedOperationException(); + } + + @Override + public ConnectionFactoryMetadata getMetadata() { + return () -> driverName; + } + + } + +}