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

tech.ydb.yoj.repository.db.TableQueryBuilder Maven / Gradle / Ivy

Go to download

Core YOJ (YDB ORM for Java) abstractions and APIs for domain entities, repositories, transactions etc.

There is a newer version: 2.6.1
Show newest version
package tech.ydb.yoj.repository.db;

import com.google.common.base.Preconditions;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import tech.ydb.yoj.databind.expression.FilterBuilder;
import tech.ydb.yoj.databind.expression.FilterExpression;
import tech.ydb.yoj.databind.expression.OrderBuilder;
import tech.ydb.yoj.databind.expression.OrderExpression;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.UnaryOperator;

import static lombok.AccessLevel.PRIVATE;

public final class TableQueryBuilder> {
    private final Table table;

    private Set> ids;
    private Set keys;

    private String indexName = null;
    private Integer limit = null;
    private Long offset = null;

    private FilterExpression filter = null;
    private FilterBuilder filterBuilder = null;

    private OrderExpression orderBy = null;

    public TableQueryBuilder(@NonNull Table table) {
        this.table = table;
    }

    public long count() {
        Preconditions.checkState(ids == null && keys == null, "Count query doesn't support selecting by ids/keys");

        FilterExpression filter = getFinalFilter();
        if (filter == null) {
            return table.countAll();
        }
        return table.count(indexName, filter);
    }

    public boolean exists() {
        return findOne() != null;
    }

    @Nullable
    public T findOne() {
        List results = find(1);

        return results.isEmpty() ? null : results.get(0);
    }

    @Nullable
    public  V findOne(Class viewClass) {
        List results = limit(1).find(viewClass, false);

        return results.isEmpty() ? null : results.get(0);
    }

    @NonNull
    public List find() {
        return find(limit);
    }

    @NonNull
    public  List find(Class viewClass) {
        return find(viewClass, false);
    }

    private List find(Integer limit) {
        if (ids == null && keys == null) {
            return table.find(indexName, getFinalFilter(), orderBy, limit, offset);
        }

        Preconditions.checkState(offset == null, "Query selecting by ids/keys does not support offset");
        if (ids != null) {
            Preconditions.checkState(indexName == null, "Query searching by ids must use PK but the secondary index is specified");

            return table.find(ids, getFinalFilter(), orderBy, limit);
        } else {
            Preconditions.checkState(indexName != null, "Query searching by arbitrary keys requires an appropriate index");

            return table.find(indexName, keys, getFinalFilter(), orderBy, limit);
        }
    }

    public  List find(Class viewClass, boolean distinct) {
        if (ids == null && keys == null) {
            return table.find(viewClass, indexName, getFinalFilter(), orderBy, limit, offset, distinct);
        }

        Preconditions.checkState(!distinct, "Query searching by ids/keys does not support distinct");
        Preconditions.checkState(offset == null, "Query searching by ids/keys does not support offset");
        if (ids != null) {
            Preconditions.checkState(indexName == null, "Query searching by ids must use PK but the secondary index is specified");

            return table.find(viewClass, ids, getFinalFilter(), orderBy, limit);
        } else {
            Preconditions.checkState(indexName != null, "Query searching by arbitrary keys requires an appropriate index");

            return table.find(viewClass, indexName, keys, getFinalFilter(), orderBy, limit);
        }
    }

    @NonNull
    public > List findIds() {
        return table.findIds(indexName, getFinalFilter(), orderBy, limit, offset);
    }

    @NonNull
    public > TableQueryBuilder ids(Set ids) {
        Preconditions.checkState(keys == null, "You can't use both .ids and .keys methods");

        this.ids = ids;
        return this;
    }

    @NonNull
    public TableQueryBuilder keys(Set keys) {
        Preconditions.checkState(ids == null, "You can't use both .keys and .ids methods");

        this.keys = keys;
        return this;
    }

    @NonNull
    public TableQueryFieldFilterBuilder where(@NonNull String fieldPath) {
        return new TableQueryFieldFilterBuilder(filterBuilder().where(fieldPath));
    }

    @NonNull
    public TableQueryBuilder where(@NonNull UnaryOperator> filterBuilderOp) {
        return where(buildFilterExpression(filterBuilderOp));
    }

    @NonNull
    public TableQueryBuilder where(@NonNull FilterExpression filter) {
        filterBuilder = filterBuilder().where(filter);
        return this;
    }

    private FilterBuilder filterBuilder() {
        if (filterBuilder == null) {
            Preconditions.checkState(filter == null, "You can't use both .where/.and/.or and .filter methods");

            filterBuilder = EntityExpressions.newFilterBuilder(table.getType());
        }
        return filterBuilder;
    }

    @NonNull
    public TableQueryFieldFilterBuilder and(@NonNull String fieldPath) {
        return new TableQueryFieldFilterBuilder(filterBuilder().and(fieldPath));
    }

    @NonNull
    public TableQueryBuilder and(@Nullable FilterExpression filter) {
        filterBuilder = filterBuilder().and(filter);
        return this;
    }

    @NonNull
    public TableQueryBuilder and(@NonNull UnaryOperator> filterBuilderOp) {
        return and(buildFilterExpression(filterBuilderOp));
    }

    @NonNull
    public TableQueryFieldFilterBuilder or(@NonNull String fieldPath) {
        return new TableQueryFieldFilterBuilder(filterBuilder().or(fieldPath));
    }

    @NonNull
    public TableQueryBuilder or(@NonNull FilterExpression filter) {
        filterBuilder = filterBuilder().or(filter);
        return this;
    }

    @NonNull
    public TableQueryBuilder or(@NonNull UnaryOperator> filterBuilderOp) {
        return or(buildFilterExpression(filterBuilderOp));
    }

    @Nullable
    private FilterExpression getFinalFilter() {
        if (filter != null) {
            return filter;
        } else if (filterBuilder != null) {
            return filterBuilder.build();
        } else {
            return null;
        }
    }

    @NonNull
    public TableQueryBuilder orderBy(@Nullable OrderExpression orderBy) {
        this.orderBy = orderBy;
        return this;
    }

    @NonNull
    public TableQueryBuilder orderBy(@NonNull UnaryOperator> orderBuilderOp) {
        return orderBy(orderBuilderOp.apply(EntityExpressions.newOrderBuilder(table.getType())).build());
    }

    public TableQueryBuilder defaultOrder() {
        orderBy = EntityExpressions.defaultOrder(table.getType());
        return this;
    }

    @NonNull
    public TableQueryBuilder filter(@Nullable FilterExpression filter) {
        Preconditions.checkState(filterBuilder == null, "You can't use both .filter and .where/.and/.or methods");

        this.filter = filter;
        return this;
    }

    @NonNull
    public TableQueryBuilder filter(@NonNull UnaryOperator> filterBuilderOp) {
        return filter(buildFilterExpression(filterBuilderOp));
    }

    @NonNull
    public TableQueryBuilder offset(long offset) {
        this.offset = offset;
        return this;
    }

    @NonNull
    public TableQueryBuilder limit(long limit) {
        Preconditions.checkArgument(limit > 0, "'limit' must be greater than zero");

        this.limit = Math.toIntExact(limit);
        return this;
    }

    @NonNull
    public TableQueryBuilder index(String indexName) {
        this.indexName = indexName;
        return this;
    }

    private FilterExpression buildFilterExpression(UnaryOperator> filterBuilderOp) {
        return filterBuilderOp.apply(EntityExpressions.newFilterBuilder(table.getType())).build();
    }

    @RequiredArgsConstructor(access = PRIVATE)
    public class TableQueryFieldFilterBuilder {
        @NonNull
        private final FilterBuilder.FieldBuilder fieldBuilder;

        @NonNull
        @SafeVarargs
        public final  TableQueryBuilder in(@NonNull V possibleValue, @NonNull V... otherPossibleValues) {
            filterBuilder = fieldBuilder.in(possibleValue, otherPossibleValues);
            return TableQueryBuilder.this;
        }

        @NonNull
        public  TableQueryBuilder in(@NonNull Collection<@NonNull ? extends V> values) {
            filterBuilder = fieldBuilder.in(values);
            return TableQueryBuilder.this;
        }

        @NonNull
        @SafeVarargs
        public final  TableQueryBuilder notIn(@NonNull V impossibleValue, @NonNull V... otherImpossibleValues) {
            filterBuilder = fieldBuilder.notIn(impossibleValue, otherImpossibleValues);
            return TableQueryBuilder.this;
        }

        @NonNull
        public  TableQueryBuilder notIn(@NonNull Collection<@NonNull ? extends V> values) {
            filterBuilder = fieldBuilder.notIn(values);
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder eq(@Nullable Object value) {
            filterBuilder = fieldBuilder.eq(value);
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder neq(@Nullable Object value) {
            filterBuilder = fieldBuilder.neq(value);
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder lt(@NonNull Object value) {
            filterBuilder = fieldBuilder.lt(value);
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder lte(@NonNull Object value) {
            filterBuilder = fieldBuilder.lte(value);
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder gt(@NonNull Object value) {
            filterBuilder = fieldBuilder.gt(value);
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder gte(@NonNull Object value) {
            filterBuilder = fieldBuilder.gte(value);
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder between(@NonNull Object min, @NonNull Object max) {
            filterBuilder = fieldBuilder.between(min, max);
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder isNull() {
            filterBuilder = fieldBuilder.isNull();
            return TableQueryBuilder.this;
        }

        @NonNull
        public TableQueryBuilder isNotNull() {
            filterBuilder = fieldBuilder.isNotNull();
            return TableQueryBuilder.this;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy