From 102e1cb1fa2c2a6635a40e243b65b04902ff917b Mon Sep 17 00:00:00 2001 From: Kirill Marchuk Date: Sun, 5 Apr 2020 13:51:20 +0300 Subject: [PATCH] added "currentSchema" as an alias for "schema"; moved "schema" to connection options (instead of `SET SCHEMA TO` command execution upon connection) --- README.md | 2 +- .../PostgresqlConnectionConfiguration.java | 27 ++++++++++++------- .../PostgresqlConnectionFactory.java | 11 -------- .../PostgresqlConnectionFactoryProvider.java | 15 +++++++++-- ...PostgresqlConnectionConfigurationTest.java | 13 ++++++--- .../PostgresqlConnectionFactoryTest.java | 2 +- 6 files changed, 42 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 927bbad0..69532996 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Mono connectionMono = Mono.from(connectionFactory.create()); | `forceBinary` | Whether to force binary transfer. Defaults to `false`. _(Optional)_ | `preparedStatementCacheQueries` | Determine the number of queries that are cached in each connection. The default is `-1`, meaning there's no limit. The value of `0` disables the cache. Any other value specifies the cache size. | `options` | A `Map` of connection parameters. These are applied to each database connection created by the `ConnectionFactory`. Useful for setting generic [PostgreSQL connection parameters][psql-runtime-config]. _(Optional)_ -| `schema` | The schema to set. _(Optional)_ +| `schema` | The search path to set. _(Optional)_ | `sslMode` | SSL mode to use, see `SSLMode` enum. Supported values: `DISABLE`, `ALLOW`, `PREFER`, `REQUIRE`, `VERIFY_CA`, `VERIFY_FULL`. _(Optional)_ | `sslRootCert` | Path to SSL CA certificate in PEM format. _(Optional)_ | `sslKey` | Path to SSL key for TLS authentication in PEM format. _(Optional)_ diff --git a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionConfiguration.java b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionConfiguration.java index 8d4e9f01..cdce044e 100644 --- a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionConfiguration.java +++ b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionConfiguration.java @@ -34,6 +34,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.ServiceLoader; import java.util.function.Function; import java.util.function.Supplier; @@ -74,8 +75,6 @@ public final class PostgresqlConnectionConfiguration { private final int port; - private final String schema; - private final String socket; private final String username; @@ -97,16 +96,30 @@ private PostgresqlConnectionConfiguration(String applicationName, boolean autode this.fetchSize = fetchSize; this.forceBinary = forceBinary; this.host = host; - this.options = options; + this.options = initOptions(options); this.password = password; this.port = port; - this.schema = schema; + addToOptions(schema); this.socket = socket; this.username = Assert.requireNonNull(username, "username must not be null"); this.sslConfig = sslConfig; this.preparedStatementCacheQueries = preparedStatementCacheQueries; } + private Map initOptions(@Nullable Map options) { + if (options == null) { + return new HashMap<>(); + } else { + return options; + } + } + + private void addToOptions(String schema) { + if (schema != null && !schema.isEmpty()) { + options.put("search_path", schema); + } + } + /** * Returns a new {@link Builder}. * @@ -131,7 +144,6 @@ public String toString() { ", options='" + this.options + '\'' + ", password='" + obfuscate(this.password != null ? this.password.length() : 0) + '\'' + ", port=" + this.port + - ", schema='" + this.schema + '\'' + ", username='" + this.username + '\'' + '}'; } @@ -192,11 +204,6 @@ int getPort() { return this.port; } - @Nullable - String getSchema() { - return this.schema; - } - @Nullable String getSocket() { return this.socket; diff --git a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactory.java b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactory.java index 674d9463..75bb6cc5 100644 --- a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactory.java +++ b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactory.java @@ -201,7 +201,6 @@ private Mono tryConnectWithConfig(SSLConfig sslConfig, @Nullable Map prepareConnection(PostgresqlConnection connection, ByteBufAllocator byteBufAllocator, DefaultCodecs codecs) { List> publishers = new ArrayList<>(); - publishers.add(setSchema(connection)); this.extensions.forEach(CodecRegistrar.class, it -> { publishers.add(it.register(connection, byteBufAllocator, codecs)); @@ -269,16 +268,6 @@ private Mono getIsolationLevel(io.r2dbc.postgresql.api.Postgresq })).defaultIfEmpty(IsolationLevel.READ_COMMITTED).last(); } - private Mono setSchema(PostgresqlConnection connection) { - if (this.configuration.getSchema() == null) { - return Mono.empty(); - } - - return connection.createStatement(String.format("SET SCHEMA '%s'", this.configuration.getSchema())) - .execute() - .then(); - } - static class PostgresConnectionException extends R2dbcNonTransientResourceException { public PostgresConnectionException(String msg, @Nullable Throwable cause) { diff --git a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryProvider.java b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryProvider.java index f3e9c82b..f4df2aae 100644 --- a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryProvider.java +++ b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryProvider.java @@ -73,10 +73,15 @@ public final class PostgresqlConnectionFactoryProvider implements ConnectionFact public static final String LEGACY_POSTGRESQL_DRIVER = "postgres"; /** - * Schema. + * Schema search path (alias for "currentSchema"). */ public static final Option SCHEMA = Option.valueOf("schema"); + /** + * Schema search path. + */ + public static final Option CURRENT_SCHEMA = Option.valueOf("currentSchema"); + /** * Unix domain socket. */ @@ -247,7 +252,13 @@ private static PostgresqlConnectionConfiguration.Builder fromConnectionFactoryOp builder.connectTimeout(connectionFactoryOptions.getValue(CONNECT_TIMEOUT)); builder.database(connectionFactoryOptions.getValue(DATABASE)); builder.password(connectionFactoryOptions.getValue(PASSWORD)); - builder.schema(connectionFactoryOptions.getValue(SCHEMA)); + + if (connectionFactoryOptions.getValue(CURRENT_SCHEMA) != null) { + builder.schema(connectionFactoryOptions.getValue(CURRENT_SCHEMA)); + } else { + builder.schema(connectionFactoryOptions.getValue(SCHEMA)); + } + builder.username(connectionFactoryOptions.getRequiredValue(USER)); String applicationName = connectionFactoryOptions.getValue(APPLICATION_NAME); diff --git a/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionConfigurationTest.java b/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionConfigurationTest.java index 2180f953..da464e06 100644 --- a/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionConfigurationTest.java +++ b/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionConfigurationTest.java @@ -80,12 +80,16 @@ void configuration() { .hasFieldOrPropertyWithValue("connectTimeout", Duration.ofMillis(1000)) .hasFieldOrPropertyWithValue("database", "test-database") .hasFieldOrPropertyWithValue("host", "test-host") - .hasFieldOrPropertyWithValue("options", options) + .hasFieldOrProperty("options") .hasFieldOrPropertyWithValue("password", null) .hasFieldOrPropertyWithValue("port", 100) - .hasFieldOrPropertyWithValue("schema", "test-schema") .hasFieldOrPropertyWithValue("username", "test-username") .hasFieldOrProperty("sslConfig"); + + assertThat(configuration.getOptions()) + .containsEntry("lock_timeout", "10s") + .containsEntry("statement_timeout", "60000") + .containsEntry("search_path", "test-schema"); } @Test @@ -104,9 +108,12 @@ void configurationDefaults() { .hasFieldOrPropertyWithValue("host", "test-host") .hasFieldOrPropertyWithValue("password", "test-password") .hasFieldOrPropertyWithValue("port", 5432) - .hasFieldOrPropertyWithValue("schema", "test-schema") + .hasFieldOrProperty("options") .hasFieldOrPropertyWithValue("username", "test-username") .hasFieldOrProperty("sslConfig"); + + assertThat(configuration.getOptions()) + .containsEntry("search_path", "test-schema"); } @Test diff --git a/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryTest.java b/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryTest.java index 215a3ff3..c3d2d932 100644 --- a/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryTest.java +++ b/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryTest.java @@ -63,7 +63,7 @@ void createAuthenticationMD5Password() { // @formatter:off Client client = TestClient.builder() .window() - .expectRequest(new StartupMessage("test-application-name", "test-database", "test-username", null)).thenRespond(new AuthenticationMD5Password(TEST.buffer(4).writeInt(100))) + .expectRequest(new StartupMessage("test-application-name", "test-database", "test-username", Collections.emptyMap())).thenRespond(new AuthenticationMD5Password(TEST.buffer(4).writeInt(100))) .expectRequest(new PasswordMessage("md55e9836cdb369d50e3bc7d127e88b4804")).thenRespond(AuthenticationOk.INSTANCE) .done() .build();