All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.infobip.spring.data.r2dbc.ReactiveQuerydslR2dbcPredicateExecutor Maven / Gradle / Ivy

package com.infobip.spring.data.r2dbc;

import java.util.function.Function;

import com.infobip.spring.data.common.Querydsl;
import com.querydsl.core.types.*;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.core.types.dsl.SimpleExpression;
import com.querydsl.sql.*;
import org.reactivestreams.Publisher;
import org.springframework.data.domain.Sort;
import org.springframework.data.querydsl.QSort;
import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor;
import org.springframework.data.r2dbc.convert.EntityRowMapper;
import org.springframework.data.r2dbc.convert.R2dbcConverter;
import org.springframework.data.repository.query.FluentQuery;
import org.springframework.lang.Nullable;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.r2dbc.core.RowsFetchSpec;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Transactional(readOnly = true)
public class ReactiveQuerydslR2dbcPredicateExecutor implements ReactiveQuerydslPredicateExecutor {

    private final ConstructorExpression constructorExpression;
    private final RelationalPath path;
    private final SQLQueryFactory sqlQueryFactory;
    private final Querydsl querydsl;
    private final DatabaseClient databaseClient;
    private final R2dbcConverter converter;

    public ReactiveQuerydslR2dbcPredicateExecutor(ConstructorExpression constructorExpression,
                                                  RelationalPath path,
                                                  SQLQueryFactory sqlQueryFactory,
                                                  Querydsl querydsl,
                                                  DatabaseClient databaseClient,
                                                  R2dbcConverter converter) {
        this.constructorExpression = constructorExpression;
        this.path = path;
        this.sqlQueryFactory = sqlQueryFactory;
        this.querydsl = querydsl;
        this.databaseClient = databaseClient;
        this.converter = converter;
    }

    @Override
    public Mono findOne(Predicate predicate) {
        SQLQuery sqlQuery = sqlQueryFactory.query()
                                              .select(constructorExpression)
                                              .where(predicate)
                                              .from(path);
        return query(sqlQuery).one();
    }

    @Override
    public Flux findAll(Predicate predicate) {
        SQLQuery query = sqlQueryFactory.query().select(constructorExpression).from(path).where(predicate);
        return query(query).all();
    }

    @Override
    public Flux findAll(Predicate predicate, OrderSpecifier... orders) {

        Assert.notNull(predicate, "Predicate must not be null!");
        Assert.notNull(orders, "Order specifiers must not be null!");

        return executeSorted(createQuery(predicate).select(constructorExpression), orders);
    }

    @Override
    public Flux findAll(Predicate predicate, Sort sort) {

        Assert.notNull(predicate, "Predicate must not be null!");
        Assert.notNull(sort, "Sort must not be null!");

        return executeSorted(createQuery(predicate).select(constructorExpression), sort);
    }

    @Override
    public Flux findAll(OrderSpecifier... orders) {

        Assert.notNull(orders, "Order specifiers must not be null!");

        return executeSorted(createQuery(new Predicate[0]).select(constructorExpression), orders);
    }

    @Override
    public Mono count(Predicate predicate) {
        NumberExpression count = ((SimpleExpression) constructorExpression.getArgs().get(0)).count();
        SQLQuery sqlQuery = sqlQueryFactory.query()
                                                 .select(count)
                                                 .where(predicate)
                                                 .from(path);
        return query(sqlQuery).one();
    }

    @Override
    public Mono exists(Predicate predicate) {
        return count(predicate).map(result -> result > 0);
    }

    @Override
    public > P findBy(Predicate predicate, Function, P> queryFunction) {
        throw new UnsupportedOperationException();
    }

    protected SQLQuery createQuery(Predicate... predicate) {

        Assert.notNull(predicate, "Predicate must not be null!");

        return doCreateQuery(predicate);
    }

    private SQLQuery doCreateQuery(@Nullable Predicate... predicate) {

        SQLQuery query = querydsl.createQuery(path);

        if (predicate != null) {
            query = query.where(predicate);
        }

        return query;
    }

    private Flux executeSorted(SQLQuery query, OrderSpecifier... orders) {
        return executeSorted(query, new QSort(orders));
    }

    private Flux executeSorted(SQLQuery query, Sort sort) {
        SQLQuery sqlQuery = querydsl.applySorting(sort, query);
        return query(sqlQuery).all();
    }

    private  RowsFetchSpec query(SQLQuery query) {
        query.setUseLiterals(true);
        String sql = query.getSQL().getSQL();
        EntityRowMapper mapper = new EntityRowMapper<>(query.getType(), converter);
        return databaseClient.sql(sql)
                             .map(mapper);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy