Skip to content

Commit 3c3277e

Browse files
committed
#124 - Remove deprecated DatabaseClient.execute().sql(…) and TransactionalDatabaseClient.
1 parent b1e9703 commit 3c3277e

31 files changed

+175
-1351
lines changed

src/main/asciidoc/reference/r2dbc-core.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public class R2dbcApp {
139139
140140
DatabaseClient client = DatabaseClient.create(connectionFactory);
141141
142-
client.sql("CREATE TABLE person" +
142+
client.execute("CREATE TABLE person" +
143143
"(id VARCHAR(255) PRIMARY KEY," +
144144
"name VARCHAR(255)," +
145145
"age INT)")

src/main/asciidoc/reference/r2dbc-sql.adoc

+10-10
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ The following example shows what you need to include for minimal but fully funct
66

77
[source,java]
88
----
9-
Mono<Void> completion = client.sql("CREATE TABLE person (id VARCHAR(255) PRIMARY KEY, name VARCHAR(255), age INTEGER);")
9+
Mono<Void> completion = client.execute("CREATE TABLE person (id VARCHAR(255) PRIMARY KEY, name VARCHAR(255), age INTEGER);")
1010
.then();
1111
----
1212

1313
`DatabaseClient` is designed for a convenient fluent usage.
1414
It exposes intermediate, continuation, and terminal methods at each stage of the execution specification.
1515
The example above uses `then()` to return a completion `Publisher` that completes as soon as the query (or queries, if the SQL query contains multiple statements) completes.
1616

17-
NOTE: `sql(…)` accepts either the SQL query string or a query `Supplier<String>` to defer the actual query creation until execution.
17+
NOTE: `execute(…)` accepts either the SQL query string or a query `Supplier<String>` to defer the actual query creation until execution.
1818

1919
[[r2dbc.datbaseclient.queries]]
2020
== Running Queries
@@ -26,7 +26,7 @@ The following example shows an `UPDATE` statement that returns the number of upd
2626

2727
[source,java]
2828
----
29-
Mono<Integer> affectedRows = client.sql("UPDATE person SET name = 'Joe'")
29+
Mono<Integer> affectedRows = client.execute("UPDATE person SET name = 'Joe'")
3030
.fetch().rowsUpdated();
3131
----
3232

@@ -36,7 +36,7 @@ You might have noticed the use of `fetch()` in the previous example.
3636

3737
[source,java]
3838
----
39-
Mono<Map<String, Object>> first = client.sql("SELECT id, name FROM person")
39+
Mono<Map<String, Object>> first = client.execute("SELECT id, name FROM person")
4040
.fetch().first();
4141
----
4242

@@ -52,7 +52,7 @@ You can consume data with the following operators:
5252

5353
[source,java]
5454
----
55-
Flux<Person> all = client.sql("SELECT id, name FROM mytable")
55+
Flux<Person> all = client.execute("SELECT id, name FROM mytable")
5656
.as(Person.class)
5757
.fetch().all();
5858
----
@@ -69,7 +69,7 @@ The following example extracts the `id` column and emits its value:
6969

7070
[source,java]
7171
----
72-
Flux<String> names = client.sql("SELECT name FROM person")
72+
Flux<String> names = client.execute("SELECT name FROM person")
7373
.map((row, rowMetadata) -> row.get("id", String.class))
7474
.all();
7575
----
@@ -90,7 +90,7 @@ A typical application requires parameterized SQL statements to select or update
9090
These are typically `SELECT` statements constrained by a `WHERE` clause or `INSERT`/`UPDATE` statements accepting input parameters.
9191
Parameterized statements bear the risk of SQL injection if parameters are not escaped properly.
9292
`DatabaseClient` leverages R2DBC's Bind API to eliminate the risk of SQL injection for query parameters.
93-
You can provide a parameterized SQL statement with the `sql(…)` operator and bind parameters to the actual `Statement`.
93+
You can provide a parameterized SQL statement with the `execute(…)` operator and bind parameters to the actual `Statement`.
9494
Your R2DBC driver then executes the statement using prepared statements and parameter substitution.
9595

9696
Parameter binding supports various binding strategies:
@@ -102,7 +102,7 @@ The following example shows parameter binding for a query:
102102

103103
[source,java]
104104
----
105-
db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
105+
db.execute("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
106106
.bind("id", "joe")
107107
.bind("name", "Joe")
108108
.bind("age", 34);
@@ -140,7 +140,7 @@ List<Object[]> tuples = new ArrayList<>();
140140
tuples.add(new Object[] {"John", 35});
141141
tuples.add(new Object[] {"Ann", 50});
142142
143-
db.sql("SELECT id, name, state FROM table WHERE (name, age) IN (:tuples)")
143+
db.execute("SELECT id, name, state FROM table WHERE (name, age) IN (:tuples)")
144144
.bind("tuples", tuples);
145145
----
146146

@@ -150,6 +150,6 @@ A simpler variant using `IN` predicates:
150150

151151
[source,java]
152152
----
153-
db.sql("SELECT id, name, state FROM table WHERE age IN (:ages)")
153+
db.execute("SELECT id, name, state FROM table WHERE age IN (:ages)")
154154
.bind("ages", Arrays.asList(35, 50));
155155
----

src/main/asciidoc/reference/r2dbc-transactions.adoc

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ TransactionalOperator operator = TransactionalOperator.create(tm); <1>
1818
1919
DatabaseClient client = DatabaseClient.create(connectionFactory);
2020
21-
Mono<Void> atomicOperation = client.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
21+
Mono<Void> atomicOperation = client.execute("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
2222
.bind("id", "joe")
2323
.bind("name", "Joe")
2424
.bind("age", 34)
2525
.fetch().rowsUpdated()
26-
.then(client.sql("INSERT INTO contacts (id, name) VALUES(:id, :name)")
26+
.then(client.execute("INSERT INTO contacts (id, name) VALUES(:id, :name)")
2727
.bind("id", "joe")
2828
.bind("name", "Joe")
2929
.fetch().rowsUpdated())
@@ -69,12 +69,12 @@ class MyService {
6969
@Transactional
7070
public Mono<Void> insertPerson() {
7171
72-
return client.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
72+
return client.execute("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
7373
.bind("id", "joe")
7474
.bind("name", "Joe")
7575
.bind("age", 34)
7676
.fetch().rowsUpdated()
77-
.then(client.sql("INSERT INTO contacts (id, name) VALUES(:id, :name)")
77+
.then(client.execute("INSERT INTO contacts (id, name) VALUES(:id, :name)")
7878
.bind("id", "joe")
7979
.bind("name", "Joe")
8080
.fetch().rowsUpdated())

src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionFactoryUtils.java

+18-132
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import org.apache.commons.logging.Log;
2525
import org.apache.commons.logging.LogFactory;
26-
import org.reactivestreams.Publisher;
2726

2827
import org.springframework.core.Ordered;
2928
import org.springframework.dao.DataAccessResourceFailureException;
@@ -67,7 +66,7 @@ private ConnectionFactoryUtils() {}
6766
* @throws DataAccessResourceFailureException if the attempt to get a {@link io.r2dbc.spi.Connection} failed
6867
* @see #releaseConnection
6968
*/
70-
public static Mono<Tuple2<Connection, ConnectionFactory>> getConnection(ConnectionFactory connectionFactory) {
69+
public static Mono<Connection> getConnection(ConnectionFactory connectionFactory) {
7170
return doGetConnection(connectionFactory)
7271
.onErrorMap(e -> new DataAccessResourceFailureException("Failed to obtain R2DBC Connection", e));
7372
}
@@ -82,7 +81,7 @@ public static Mono<Tuple2<Connection, ConnectionFactory>> getConnection(Connecti
8281
* @param connectionFactory the {@link ConnectionFactory} to obtain Connections from.
8382
* @return a R2DBC {@link io.r2dbc.spi.Connection} from the given {@link ConnectionFactory}.
8483
*/
85-
public static Mono<Tuple2<Connection, ConnectionFactory>> doGetConnection(ConnectionFactory connectionFactory) {
84+
public static Mono<Connection> doGetConnection(ConnectionFactory connectionFactory) {
8685

8786
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
8887

@@ -138,56 +137,11 @@ public static Mono<Tuple2<Connection, ConnectionFactory>> doGetConnection(Connec
138137

139138
return con;
140139
}) //
141-
.map(conn -> Tuples.of(conn, connectionFactory)) //
142140
.onErrorResume(NoTransactionException.class, e -> {
143-
144-
return Mono.subscriberContext().flatMap(it -> {
145-
146-
if (it.hasKey(ReactiveTransactionSynchronization.class)) {
147-
148-
ReactiveTransactionSynchronization synchronization = it.get(ReactiveTransactionSynchronization.class);
149-
150-
return obtainConnection(synchronization, connectionFactory);
151-
}
152-
return Mono.empty();
153-
}).switchIfEmpty(Mono.defer(() -> {
154-
return Mono.from(connectionFactory.create()).map(it -> Tuples.of(it, connectionFactory));
155-
}));
141+
return Mono.from(connectionFactory.create());
156142
});
157143
}
158144

159-
private static Mono<Tuple2<Connection, ConnectionFactory>> obtainConnection(
160-
ReactiveTransactionSynchronization synchronization, ConnectionFactory connectionFactory) {
161-
162-
if (synchronization.isSynchronizationActive()) {
163-
164-
if (logger.isDebugEnabled()) {
165-
logger.debug("Registering transaction synchronization for R2DBC Connection");
166-
}
167-
168-
TransactionResources txContext = synchronization.getCurrentTransaction();
169-
ConnectionFactory resource = txContext.getResource(ConnectionFactory.class);
170-
171-
Mono<Tuple2<Connection, ConnectionFactory>> attachNewConnection = Mono
172-
.defer(() -> Mono.from(connectionFactory.create()).map(it -> {
173-
174-
if (logger.isDebugEnabled()) {
175-
logger.debug("Fetching new R2DBC Connection from ConnectionFactory");
176-
}
177-
178-
SingletonConnectionFactory s = new SingletonConnectionFactory(connectionFactory.getMetadata(), it);
179-
txContext.registerResource(ConnectionFactory.class, s);
180-
181-
return Tuples.of(it, connectionFactory);
182-
}));
183-
184-
return Mono.justOrEmpty(resource).flatMap(ConnectionFactoryUtils::createConnection)
185-
.switchIfEmpty(attachNewConnection);
186-
}
187-
188-
return Mono.empty();
189-
}
190-
191145
/**
192146
* Actually fetch a {@link Connection} from the given {@link ConnectionFactory}, defensively turning an unexpected
193147
* {@code null} return value from {@link ConnectionFactory#create()} into an {@link IllegalStateException}.
@@ -198,12 +152,7 @@ private static Mono<Tuple2<Connection, ConnectionFactory>> obtainConnection(
198152
* @see ConnectionFactory#create()
199153
*/
200154
private static Mono<Connection> fetchConnection(ConnectionFactory connectionFactory) {
201-
202-
Publisher<? extends Connection> con = connectionFactory.create();
203-
if (con == null) { // TODO: seriously why would it do that?
204-
throw new IllegalStateException("ConnectionFactory returned null from getConnection(): " + connectionFactory);
205-
}
206-
return Mono.from(con);
155+
return Mono.from(connectionFactory.create());
207156
}
208157

209158
/**
@@ -226,40 +175,24 @@ public static Mono<Void> releaseConnection(@Nullable io.r2dbc.spi.Connection con
226175
* Actually close the given {@link io.r2dbc.spi.Connection}, obtained from the given {@link ConnectionFactory}. Same
227176
* as {@link #releaseConnection}, but preserving the original exception.
228177
*
229-
* @param con the {@link io.r2dbc.spi.Connection} to close if necessary.
178+
* @param connection the {@link io.r2dbc.spi.Connection} to close if necessary.
230179
* @param connectionFactory the {@link ConnectionFactory} that the Connection was obtained from (may be
231180
* {@literal null}).
232181
* @see #doGetConnection
233182
*/
234-
public static Mono<Void> doReleaseConnection(@Nullable io.r2dbc.spi.Connection con,
183+
public static Mono<Void> doReleaseConnection(@Nullable io.r2dbc.spi.Connection connection,
235184
@Nullable ConnectionFactory connectionFactory) {
236185

237186
return TransactionSynchronizationManager.forCurrentTransaction().flatMap(it -> {
238187

239188
ConnectionHolder conHolder = (ConnectionHolder) it.getResource(connectionFactory);
240-
if (conHolder != null && connectionEquals(conHolder, con)) {
189+
if (conHolder != null && connectionEquals(conHolder, connection)) {
241190
// It's the transactional Connection: Don't close it.
242191
conHolder.released();
243192
}
244-
return Mono.from(con.close());
193+
return Mono.from(connection.close());
245194
}).onErrorResume(NoTransactionException.class, e -> {
246-
247-
if (connectionFactory instanceof SingletonConnectionFactory) {
248-
249-
SingletonConnectionFactory factory = (SingletonConnectionFactory) connectionFactory;
250-
251-
if (logger.isDebugEnabled()) {
252-
logger.debug("Releasing R2DBC Connection");
253-
}
254-
255-
return factory.close(con);
256-
}
257-
258-
if (logger.isDebugEnabled()) {
259-
logger.debug("Closing R2DBC Connection");
260-
}
261-
262-
return Mono.from(con.close());
195+
return doCloseConnection(connection, connectionFactory);
263196
});
264197
}
265198

@@ -287,55 +220,23 @@ public static Mono<Void> closeConnection(Connection connection, ConnectionFactor
287220
*/
288221
public static Mono<Void> doCloseConnection(Connection connection, @Nullable ConnectionFactory connectionFactory) {
289222

290-
if (!(connectionFactory instanceof SingletonConnectionFactory)
291-
|| ((SingletonConnectionFactory) connectionFactory).shouldClose(connection)) {
223+
if (!(connectionFactory instanceof SmartConnectionFactory)
224+
|| ((SmartConnectionFactory) connectionFactory).shouldClose(connection)) {
292225

293-
SingletonConnectionFactory factory = (SingletonConnectionFactory) connectionFactory;
294-
return factory.close(connection).then(Mono.from(connection.close()));
226+
if (logger.isDebugEnabled()) {
227+
logger.debug("Closing R2DBC Connection");
228+
}
229+
230+
return Mono.from(connection.close());
295231
}
296232

297233
return Mono.empty();
298234
}
299235

300-
/**
301-
* Obtain the currently {@link ReactiveTransactionSynchronization} from the current subscriber
302-
* {@link reactor.util.context.Context}.
303-
*
304-
* @throws NoTransactionException if no active {@link ReactiveTransactionSynchronization} is associated with the
305-
* current subscription.
306-
* @see Mono#subscriberContext()
307-
* @see ReactiveTransactionSynchronization
308-
*/
309-
public static Mono<ReactiveTransactionSynchronization> currentReactiveTransactionSynchronization() {
310-
311-
return Mono.subscriberContext().filter(it -> it.hasKey(ReactiveTransactionSynchronization.class)) //
312-
.switchIfEmpty(Mono.error(new NoTransactionException(
313-
"Transaction management is not enabled. Make sure to register ReactiveTransactionSynchronization in the subscriber Context!"))) //
314-
.map(it -> it.get(ReactiveTransactionSynchronization.class));
315-
}
316-
317-
/**
318-
* Obtain the currently active {@link ReactiveTransactionSynchronization} from the current subscriber
319-
* {@link reactor.util.context.Context}.
320-
*
321-
* @throws NoTransactionException if no active {@link ReactiveTransactionSynchronization} is associated with the
322-
* current subscription.
323-
* @see Mono#subscriberContext()
324-
* @see ReactiveTransactionSynchronization
325-
*/
326-
public static Mono<ReactiveTransactionSynchronization> currentActiveReactiveTransactionSynchronization() {
327-
328-
return currentReactiveTransactionSynchronization()
329-
.filter(ReactiveTransactionSynchronization::isSynchronizationActive) //
330-
.switchIfEmpty(Mono.error(new NoTransactionException("ReactiveTransactionSynchronization not active!")));
331-
}
332-
333236
/**
334237
* Obtain the {@link io.r2dbc.spi.ConnectionFactory} from the current subscriber {@link reactor.util.context.Context}.
335238
*
336-
* @see Mono#subscriberContext()
337-
* @see ReactiveTransactionSynchronization
338-
* @see TransactionResources
239+
* @see TransactionSynchronizationManager
339240
*/
340241
public static Mono<ConnectionFactory> currentConnectionFactory(ConnectionFactory connectionFactory) {
341242

@@ -347,8 +248,7 @@ public static Mono<ConnectionFactory> currentConnectionFactory(ConnectionFactory
347248
return true;
348249
}
349250
return false;
350-
}).map(it -> connectionFactory) //
351-
.onErrorResume(NoTransactionException.class, ConnectionFactoryUtils::obtainDefaultConnectionFactory);
251+
}).map(it -> connectionFactory);
352252
}
353253

354254
/**
@@ -410,20 +310,6 @@ private static int getConnectionSynchronizationOrder(ConnectionFactory connectio
410310
return order;
411311
}
412312

413-
/**
414-
* @param e
415-
* @return an {@link Mono#error(Throwable) error} if not transaction present.
416-
*/
417-
private static Mono<? extends ConnectionFactory> obtainDefaultConnectionFactory(NoTransactionException e) {
418-
419-
return currentActiveReactiveTransactionSynchronization().map(synchronization -> {
420-
421-
TransactionResources currentSynchronization = synchronization.getCurrentTransaction();
422-
return currentSynchronization.getResource(ConnectionFactory.class);
423-
}).switchIfEmpty(Mono.error(
424-
new DataAccessResourceFailureException("Cannot extract ConnectionFactory from current TransactionContext!")));
425-
}
426-
427313
/**
428314
* Create a {@link Connection} via the given {@link ConnectionFactory#create() factory} and return a {@link Tuple2}
429315
* associating the {@link Connection} with its creating {@link ConnectionFactory}.

0 commit comments

Comments
 (0)