Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.tonivade.puredbc.R2dbcTemplate Maven / Gradle / Ivy
/*
* Copyright (c) 2020-2024, Antonio Gabriel Muñoz Conejo
* Distributed under the terms of the MIT License
*/
package com.github.tonivade.puredbc;
import static com.github.tonivade.purefun.core.Precondition.checkNonNull;
import static com.github.tonivade.purefun.core.Unit.unit;
import java.util.List;
import org.reactivestreams.Publisher;
import com.github.tonivade.puredbc.sql.Field;
import com.github.tonivade.purefun.core.Function1;
import com.github.tonivade.purefun.core.Unit;
import com.github.tonivade.purefun.data.Range;
import com.github.tonivade.purefun.data.Sequence;
import com.github.tonivade.purefun.type.Option;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public final class R2dbcTemplate {
private final ConnectionFactory connectionFactory;
public R2dbcTemplate(ConnectionFactory connectionFactory) {
this.connectionFactory = checkNonNull(connectionFactory);
}
public Mono update(String query, Sequence> params) {
return Mono.from(connectionFactory.create())
.flatMap(conn -> doUpdate(query, params, conn)
.delayUntil(result -> conn.commitTransaction())
.doFinally(stmt -> conn.close()))
.thenReturn(unit());
}
public Mono> updateWithKeys(String query, Sequence> params, Field field) {
return Mono.from(connectionFactory.create())
.flatMap(conn -> doUpdateWithKeys(query, params, conn, field)
.flatMap(result -> Mono.from(applyToRow(row -> row.get(field), result)))
.delayUntil(result -> conn.commitTransaction())
.doFinally(stmt -> conn.close()))
.map(Option::some).defaultIfEmpty(Option.none());
}
public Mono> queryMeta(String query, Sequence> params, Function1 rowMapper) {
return doQuery(query, params)
.flatMap(result -> Mono.from(applyToMeta(rowMapper, result)))
.map(Option::some).defaultIfEmpty(Option.none());
}
public Mono> queryOne(String query, Sequence> params, Function1 rowMapper) {
return doQuery(query, params)
.flatMap(result -> Mono.from(applyToRow(rowMapper, result)))
.map(Option::some).defaultIfEmpty(Option.none());
}
public Flux> queryIterable(String query, Sequence> params, Function1 rowMapper) {
return doQuery(query, params)
.flatMapMany(result -> Flux.from(applyToRow(rowMapper, result))).buffer(10);
}
private Mono doUpdate(String query, Sequence> params, Connection conn) {
return Mono.from(conn.beginTransaction())
.then(createStatement(query, params, conn)
.flatMap(stmt -> Mono.from(stmt.execute())));
}
private Mono doUpdateWithKeys(String query, Sequence> params, Connection conn, Field> field) {
return Mono.from(conn.beginTransaction())
.then(createStatement(query, params, conn).map(stmt -> stmt.returnGeneratedValues(field.name()))
.flatMap(stmt -> Mono.from(stmt.execute())));
}
private Mono doQuery(String query, Sequence> params) {
return Mono.from(connectionFactory.create())
.flatMap(conn -> createStatement(query, params, conn)
.flatMap(stmt -> Mono.from(stmt.execute()))
.doFinally(stmt -> Mono.from(conn.close()).then(Mono.empty())));
}
private Mono createStatement(String query, Sequence> params, Connection conn) {
return Mono.just(conn.createStatement(query))
.map(stmt -> {
int i = 0;
for (var param : params) {
switch (param) {
case Range(var begin, var end) -> {
stmt.bind(i++, begin);
stmt.bind(i++, end);
}
case Iterable> iterable -> {
for (var p : iterable) {
stmt.bind(i++, p);
}
}
case null, default -> stmt.bind(i++, param);
}
}
return stmt;
});
}
private Publisher applyToRow(Function1 rowMapper, io.r2dbc.spi.Result result) {
return result.map((row, meta) -> rowMapper.compose(R2dbcRow::new).apply(row));
}
private Publisher applyToMeta(Function1 rowMapper, io.r2dbc.spi.Result result) {
return result.map((row, meta) -> rowMapper.compose(R2dbcRowMetaData::new).apply(meta));
}
}