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

de.comhix.twitch.database.dao.Query Maven / Gradle / Ivy

package de.comhix.twitch.database.dao;

import de.comhix.twitch.database.objects.QueryResult;
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.query.FindOptions;

import java.util.Optional;

/**
 * @author Benjamin Beeker
 */
public class Query {

    private final org.mongodb.morphia.query.Query query;
    private final FindOptions options = new FindOptions();

    protected Query(Class typeClass, Datastore datastore) {
        query = datastore.createQuery(typeClass);
    }

    public  Query with(String field, Operation operation, AllowedValueType value) {
        if (operation == Operation.EQ) {
            query.field(field).equal(value);
        }
        else if (operation == Operation.NEQ) {
            query.field(field).notEqual(value);
        }
        else if (operation == Operation.GT) {
            query.field(field).greaterThan(value);
        }
        else if (operation == Operation.GEQ) {
            query.field(field).greaterThanOrEq(value);
        }
        else if (operation == Operation.LT) {
            query.field(field).lessThan(value);
        }
        else if (operation == Operation.LEQ) {
            query.field(field).lessThanOrEq(value);
        }
        else if (operation == Operation.EXISTS) {
            if ((Boolean) value) {
                query.field(field).exists();
            }
            else {
                query.field(field).doesNotExist();
            }
        }
        else if (operation == Operation.IN) {
            query.field(field).in((Iterable) value);
        }
        else if (operation == Operation.NOT_IN) {
            query.field(field).notIn((Iterable) value);
        }
        else if (operation == Operation.HAS) {
            query.field(field).hasThisOne(value);
        }
        else if (operation == Operation.HAS_ANY) {
            query.field(field).hasAnyOf((Iterable) value);
        }
        else if (operation == Operation.HAS_NONE) {
            query.field(field).hasNoneOf((Iterable) value);
        }
        else if (operation == Operation.HAS_ALL) {
            query.field(field).hasAllOf((Iterable) value);
        }

        return this;
    }

    public Query limit(int limit) {
        options.limit(limit);
        return this;
    }

    public Query skip(int skip) {
        options.skip(skip);
        return this;
    }

    public Query order(String field) {
        query.order(field);
        return this;
    }

    public Observable> query() {
        return Observable.zip(Observable.fromCallable(() -> query.asList(options)),
                Observable.fromCallable(query::count),
                QueryResult::new)
                .subscribeOn(Schedulers.io());
    }

    public Observable> find() {
        limit(1);
        return query().map(results -> {
            if (results.isEmpty()) {
                return Optional.empty();
            }
            else {
                return Optional.of(results.get(0));
            }
        });
    }

    @SuppressWarnings("unused")
    public static class Operation {
        public static final Operation EQ = new Operation<>();
        public static final Operation NEQ = new Operation<>();
        public static final Operation GT = new Operation<>();
        public static final Operation GEQ = new Operation<>();
        public static final Operation LT = new Operation<>();
        public static final Operation LEQ = new Operation<>();
        public static final Operation EXISTS = new Operation<>();
        public static final Operation IN = new Operation<>();
        public static final Operation NOT_IN = new Operation<>();
        public static final Operation HAS = new Operation<>();
        public static final Operation HAS_ANY = new Operation<>();
        public static final Operation HAS_NONE = new Operation<>();
        public static final Operation HAS_ALL = new Operation<>();

        private Operation() {
        }
    }
}