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

com.github.lontime.extjooq.batch.JooqBatch Maven / Gradle / Ivy

The newest version!
package com.github.lontime.extjooq.batch;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import com.github.lontime.base.pagination.Page;
import com.github.lontime.base.pagination.PageImpl;
import com.github.lontime.base.pagination.Pageable;
import com.github.lontime.base.commonj.utils.AssertHelper;
import com.github.lontime.base.commonj.utils.CollectionHelper;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.InsertQuery;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.Result;
import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.UpdateQuery;
import org.jooq.impl.DSL;

/**
 * JooqBatch.
 *
 * @author lontime
 * @since 1.0
 */
public abstract class JooqBatch implements Batch {

    @Override
    public Page page(DSLContext context, Table table, List fields, Condition condition, Pageable pageable, boolean searchCount) {
        AssertHelper.checkNotNull(table, "Table is not null");
        AssertHelper.checkNotNull(condition, "Condition is not null");
        final List> sorts = pageable.getSort().get().map(c -> table.field(c.getProperty())).filter(Objects::nonNull).collect(Collectors.toList());
        final CompletableFuture>> future;
        if (searchCount) {
            future = context.selectCount().from(table).where(condition).
                    fetchAsync().toCompletableFuture();
        } else {
            future = null;
        }
        final CompletableFuture> future1 = context.select
                        (CollectionHelper.isEmpty(fields) ? Arrays.asList(table.fields()) : fields)
                .from(table).where(condition)
                .orderBy(sorts).limit(pageable.getOffset(), pageable.getPageSize())
                .fetchAsync().toCompletableFuture();
        if (future == null) {
            return new PageImpl(future1.join(), pageable, -1);
        }
        final Result> join = future.join();
        final Integer total = join.get(0).value1();
        if (total == 0) {
            return new PageImpl(Collections.emptyList(), pageable, 0);
        }
        return new PageImpl(future1.join(), pageable, total);
    }

    @Override
    public  CompletableFuture updateAsync(DSLContext context, Table table,
                                                                        Field keyField, Collection records) {
        return Optional.ofNullable(buildUpdateQuery(context, table, keyField, records)).
                map(c -> c.executeAsync().toCompletableFuture()).
                orElse(CompletableFuture.completedFuture(new Integer(-1)));
    }

    @Override
    public  CompletableFuture updateAsync(DSLContext context, Table table,
                                                                     List> keyField, Collection records) {
        return Optional.ofNullable(buildUpdateQuery(context, table, keyField, records)).
                map(c -> c.executeAsync().toCompletableFuture()).
                orElse(CompletableFuture.completedFuture(new Integer(-1)));
    }

    @Override
    public  CompletableFuture insertAsync(DSLContext context, Table table,
                                                                     Collection records) {
        return buildInsertQuery(context, table, records).executeAsync().toCompletableFuture();
    }

    /**
     * get concat.
     *
     * @return String
     */
    abstract protected String getFuncConcat();

    private  InsertQuery buildInsertQuery(DSLContext context, Table table,
                                                               Collection records) {
        final InsertQuery query = context.insertQuery(table);
        for (R record : records) {
            for (int i = 0; i < record.size(); i++) {
                query.addValue((Field) record.field(i), record.get(i));
            }
            query.newRecord();
        }
        return query;
    }

    private  UpdateQuery buildUpdateQuery(DSLContext context, Table table,
                                                               List> keyFields, Collection records) {
        final Field[] allFields = table.fields();
        final UpdateQuery query = context.updateQuery(table);
        if (keyFields == null || keyFields.isEmpty()) {
            return null;
        }
        final List keyValues = records.stream().map(c -> getValue(keyFields, c)).
                filter(Objects::nonNull).filter(c -> c.length() > 0).collect(Collectors.toList());
        if (keyValues.isEmpty()) {
            return null;
        }
        final List> newKeyFields = new ArrayList<>(keyFields.size() + 1);
        newKeyFields.add(DSL.field("','"));
        newKeyFields.addAll(keyFields.stream().collect(Collectors.toList()));
        final Field condField = DSL.function(getFuncConcat(), String.class,
                Arrays.copyOf(newKeyFields.toArray(), newKeyFields.size(), Field[].class));
        boolean found = false;
        for (int i = 0; i < allFields.length; i++) {
            final Field field = allFields[i];
            if (keyFields.contains(field)) {
                continue;
            }
            final Map map = new HashMap<>();
            for (Record record : records) {
                final String keyValue = getValue(keyFields, record);
                final Object value = record.getValue(field);
                if (Objects.isNull(keyValue) || keyValue.length() == 0 || Objects.isNull(value)) {
                    continue;
                }
                map.put(keyValue, value);
            }
            if (!map.isEmpty()) {
                query.addValue(field, DSL.choose(condField).mapValues(map).otherwise((Field) field));
                found = true;
            }
        }
        if (!found) {
            return null;
        }
        query.addConditions(condField.in(keyValues));
        return query;
    }

    private  UpdateQuery buildUpdateQuery(DSLContext context, Table table,
                                                                  Field keyField, Collection records) {
        final Field[] allFields = table.fields();
        final UpdateQuery query = context.updateQuery(table);
        if (keyField == null) {
            return null;
        }
        final List keyValues = records.stream().map(c -> c.get(keyField)).
                filter(Objects::nonNull).collect(Collectors.toList());
        if (keyValues.isEmpty()) {
            return null;
        }
        boolean found = false;
        for (int i = 0; i < allFields.length; i++) {
            final Field field = allFields[i];
            if (field.equals(keyField)) {
                continue;
            }
            final Map map = new HashMap<>();
            for (Record record : records) {
                final T keyValue = record.get(keyField);
                final Object value = record.getValue(field);
                if (Objects.isNull(keyValue) || Objects.isNull(value)) {
                    continue;
                }
                map.put(keyValue, value);
            }
            if (!map.isEmpty()) {
                query.addValue(field, DSL.choose(keyField).mapValues(map).otherwise((Field) field));
                found = true;
            }
        }
        if (!found) {
            return null;
        }
        query.addConditions(keyField.in(keyValues));
        return query;
    }

    private String getValue(List> fields, Record record) {
        return fields.stream().map(s -> record.get(s)).filter(Objects::nonNull).map(s -> s.toString())
                .collect(Collectors.joining(","));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy