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

com.jporm.rx.session.SqlExecutorImpl Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright 2015 Francesco Cina'
 *
 * 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
 *
 *   http://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 com.jporm.rx.session;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jporm.commons.core.exception.JpoException;
import com.jporm.commons.core.function.IntBiFunction;
import com.jporm.commons.core.session.ASqlExecutor;
import com.jporm.commons.core.util.BigDecimalUtil;
import com.jporm.rx.connection.RxConnection;
import com.jporm.rx.connection.RxConnectionProvider;
import com.jporm.rx.query.update.UpdateResult;
import com.jporm.rx.query.update.UpdateResultImpl;
import com.jporm.types.TypeConverterFactory;
import com.jporm.types.io.BatchPreparedStatementSetter;
import com.jporm.types.io.GeneratedKeyReader;
import com.jporm.types.io.ResultEntry;
import com.jporm.types.io.Statement;

import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;

public class SqlExecutorImpl extends ASqlExecutor implements SqlExecutor {

    private static final int[] EMPTY_INT_ARRAY = new int[0];
    private static final Function SQL_PRE_PROCESSOR_DEFAULT = (sql) -> sql;
    private final static Logger LOGGER = LoggerFactory.getLogger(SqlExecutorImpl.class);
    private final Function sqlPreProcessor;
    private final RxConnectionProvider connectionProvider;

    public SqlExecutorImpl(final TypeConverterFactory typeFactory, final RxConnectionProvider connectionProvider) {
        this(typeFactory, connectionProvider, SQL_PRE_PROCESSOR_DEFAULT);
    }

    public SqlExecutorImpl(final TypeConverterFactory typeFactory, final RxConnectionProvider connectionProvider,
            Function sqlPreProcessor) {
        super(typeFactory);
        this.connectionProvider = connectionProvider;
        this.sqlPreProcessor = sqlPreProcessor;
    }

    @Override
    public Single batchUpdate(final Collection sqls) throws JpoException {
        return connectionProvider.getConnection(true, connection -> {
            return connection.batchUpdate(sqls, sqlPreProcessor).toObservable();
        }).single(EMPTY_INT_ARRAY);

    }

    @Override
    public Single batchUpdate(final String sql, final BatchPreparedStatementSetter psc) throws JpoException {
        return connectionProvider.getConnection(true, connection -> {
            return connection.batchUpdate(sqlPreProcessor.apply(sql), psc).toObservable();
        }).single(EMPTY_INT_ARRAY);
    }

    @Override
    public Single batchUpdate(final String sql, final Collection args) throws JpoException {
        String sqlProcessed = sqlPreProcessor.apply(sql);
        Collection> statements = new ArrayList<>();
        args.forEach(array -> statements.add(new PrepareStatementSetterArrayWrapper(array)));
        return connectionProvider.getConnection(true, connection -> {
            return connection.batchUpdate(sqlProcessed, statements).toObservable();
        }).single(EMPTY_INT_ARRAY);
    }

    @Override
    public Completable execute(final String sql) throws JpoException {
        String sqlProcessed = sqlPreProcessor.apply(sql);
        return connectionProvider.getConnection(true, connection -> {
            return connection.execute(sqlProcessed).toObservable();
        }).ignoreElements();
    }

    @Override
    protected Logger getLogger() {
        return LOGGER;
    }

    @Override
    public  Observable query(final String sql, final Collection args, final IntBiFunction rsrr) {
        String sqlProcessed = sqlPreProcessor.apply(sql);
        return connectionProvider.getConnection(false, connection -> {
            return connection.query(sqlProcessed, new PrepareStatementSetterCollectionWrapper(args), rsrr::apply);
        });
    }

    @Override
    public  Observable query(final String sql, final Object[] args, final IntBiFunction rse) {
        String sqlProcessed = sqlPreProcessor.apply(sql);
        return connectionProvider.getConnection(false, connection -> {
            return connection.query(sqlProcessed, new PrepareStatementSetterArrayWrapper(args), rse::apply);
        });
    }

    @Override
    public Maybe queryForBigDecimal(final String sql, final Collection args) {
        return this.query(sql, args, (ResultEntry re, int count) -> {
            return re.getBigDecimal(0);
        }).firstElement();
    }

    @Override
    public Maybe queryForBigDecimal(final String sql, final Object... args) {
        return this.query(sql, args, (ResultEntry re, int count) -> {
            return re.getBigDecimal(0);
        }).firstElement();
    }

    @Override
    public final Single queryForBigDecimalUnique(final String sql, final Collection args) {
        return queryForBigDecimal(sql, args).toSingle();
    }

    @Override
    public final Single queryForBigDecimalUnique(final String sql, final Object... args) {
        return queryForBigDecimal(sql, args).toSingle();
    }

    @Override
    public Single> queryForBigDecimalOptional(final String sql, final Collection args) {
        return queryForBigDecimal(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Single> queryForBigDecimalOptional(final String sql, final Object... args) {
        return queryForBigDecimal(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Maybe queryForBoolean(final String sql, final Collection args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toBoolean);
    }

    @Override
    public Maybe queryForBoolean(final String sql, final Object... args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toBoolean);
    }

    @Override
    public final Single queryForBooleanUnique(final String sql, final Collection args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toBoolean);
    }

    @Override
    public final Single queryForBooleanUnique(final String sql, final Object... args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toBoolean);
    }

    @Override
    public Single> queryForBooleanOptional(final String sql, final Collection args) {
        return this.queryForBoolean(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Single> queryForBooleanOptional(final String sql, final Object... args) {
        return this.queryForBoolean(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Maybe queryForDouble(final String sql, final Collection args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toDouble);
    }

    @Override
    public Maybe queryForDouble(final String sql, final Object... args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toDouble);
    }

    @Override
    public final Single queryForDoubleUnique(final String sql, final Collection args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toDouble);
    }

    @Override
    public final Single queryForDoubleUnique(final String sql, final Object... args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toDouble);
    }

    @Override
    public Single> queryForDoubleOptional(final String sql, final Collection args) {
        return this.queryForDouble(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Single> queryForDoubleOptional(final String sql, final Object... args) {
        return this.queryForDouble(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Maybe queryForFloat(final String sql, final Collection args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toFloat);
    }

    @Override
    public Maybe queryForFloat(final String sql, final Object... args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toFloat);
    }

    @Override
    public final Single queryForFloatUnique(final String sql, final Collection args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toFloat);
    }

    @Override
    public final Single queryForFloatUnique(final String sql, final Object... args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toFloat);
    }

    @Override
    public Single> queryForFloatOptional(final String sql, final Collection args) {
        return this.queryForFloat(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Single> queryForFloatOptional(final String sql, final Object... args) {
        return this.queryForFloat(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Maybe queryForInt(final String sql, final Collection args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toInteger);
    }

    @Override
    public Maybe queryForInt(final String sql, final Object... args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toInteger);
    }

    @Override
    public final Single queryForIntUnique(final String sql, final Collection args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toInteger);
    }

    @Override
    public final Single queryForIntUnique(final String sql, final Object... args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toInteger);
    }

    @Override
    public Single> queryForIntOptional(final String sql, final Collection args) {
        return this.queryForInt(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Single> queryForIntOptional(final String sql, final Object... args) {
        return this.queryForInt(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Maybe queryForLong(final String sql, final Collection args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toLong);
    }

    @Override
    public Maybe queryForLong(final String sql, final Object... args) {
        return this.queryForBigDecimal(sql, args).map(BigDecimalUtil::toLong);
    }

    @Override
    public final Single queryForLongUnique(final String sql, final Collection args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toLong);
    }

    @Override
    public final Single queryForLongUnique(final String sql, final Object... args) {
        return this.queryForBigDecimalUnique(sql, args).map(BigDecimalUtil::toLong);
    }

    @Override
    public Single> queryForLongOptional(final String sql, final Collection args) {
        return this.queryForLong(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Single> queryForLongOptional(final String sql, final Object... args) {
        return this.queryForLong(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Maybe queryForString(final String sql, final Collection args) {
        return this.query(sql, args, (rs, count) -> {
            return rs.getString(0);
        }).firstElement();
    }

    @Override
    public Maybe queryForString(final String sql, final Object... args) {
        return this.query(sql, args, (rs, count) -> {
            return rs.getString(0);
        }).firstElement();
    }

    @Override
    public final Single queryForStringUnique(final String sql, final Collection args) {
        return this.queryForString(sql, args).toSingle();
    }

    @Override
    public final Single queryForStringUnique(final String sql, final Object... args) {
        return this.queryForString(sql, args).toSingle();
    }

    @Override
    public Single> queryForStringOptional(final String sql, final Collection args) {
        return this.queryForString(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public Single> queryForStringOptional(final String sql, final Object... args) {
        return this.queryForString(sql, args).map(value -> Optional.of(value)).defaultIfEmpty(Optional.empty()).toSingle();
    }

    @Override
    public  Single queryForUnique(final String sql, final Collection args, final IntBiFunction resultSetRowReader) {
        return query(sql, args, resultSetRowReader).singleOrError();
    }

    @Override
    public  Single queryForUnique(final String sql, final Object[] args, final IntBiFunction resultSetRowReader) {
        return query(sql, args, resultSetRowReader).singleOrError();
    }

    @Override
    public Single update(final String sql, final Collection args) {
        Consumer pss = new PrepareStatementSetterCollectionWrapper(args);
        return update(sql, pss);
    }

    @Override
    public  Single update(final String sql, final Collection args, final GeneratedKeyReader generatedKeyReader) {
        Consumer pss = new PrepareStatementSetterCollectionWrapper(args);
        return update(sql, pss, generatedKeyReader);
    }

    @Override
    public Single update(final String sql, final Object... args) {
        Consumer pss = new PrepareStatementSetterArrayWrapper(args);
        return update(sql, pss);
    }

    @Override
    public  Single update(final String sql, final Object[] args, final GeneratedKeyReader generatedKeyReader) {
        Consumer pss = new PrepareStatementSetterArrayWrapper(args);
        return update(sql, pss, generatedKeyReader);
    }

    @Override
    public Single update(final String sql, final Consumer psc) {
        String sqlProcessed = sqlPreProcessor.apply(sql);
        return connectionProvider.getConnection(true, connection -> {
            return connection.update(sqlProcessed, psc). map(updated -> new UpdateResultImpl(updated)).toObservable();
        }).singleOrError();
    }

    @Override
    public  Single update(final String sql, final Consumer psc, final GeneratedKeyReader generatedKeyReader) {
        String sqlProcessed = sqlPreProcessor.apply(sql);
        return connectionProvider.getConnection(true, connection -> {
            return connection.update(sqlProcessed, generatedKeyReader, psc).toObservable();
        }).singleOrError();
    }

    @Override
    public  Single> queryForOptional(String sql, Collection args, IntBiFunction resultSetRowReader) throws JpoException {
        return queryForOptional(sql, new PrepareStatementSetterCollectionWrapper(args), resultSetRowReader);
    }

    @Override
    public  Single> queryForOptional(String sql, Object[] args, IntBiFunction resultSetRowReader) throws JpoException {
        return queryForOptional(sql, new PrepareStatementSetterArrayWrapper(args), resultSetRowReader);
    }

    private  Single> queryForOptional(String sql, Consumer psConsumer, IntBiFunction resultSetRowReader) {
        String sqlProcessed = sqlPreProcessor.apply(sql);
        return connectionProvider.getConnection(false, connection -> {
            Observable> result = connection.query(sqlProcessed, psConsumer, (onSubscriber, rs) -> {
                try {
                    if (rs.hasNext()) {
                        onSubscriber.onNext(Optional.ofNullable(resultSetRowReader.apply(rs.next(), 0)));
                    } else {
                        onSubscriber.onNext(Optional.empty());
                    }
                    onSubscriber.onComplete();
                } catch (Throwable e) {
                    onSubscriber.onError(e);
                }
            });
            return result;
        }).singleOrError();



    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy