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

com.eventsourcing.queries.LatestAssociatedEntryQuery Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2016, All Contributors (see CONTRIBUTORS file)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package com.eventsourcing.queries;

import com.eventsourcing.Entity;
import com.eventsourcing.EntityHandle;
import com.eventsourcing.Model;
import com.eventsourcing.hlc.HybridTimestamp;
import com.eventsourcing.index.EntityIndex;
import com.googlecode.cqengine.query.Query;
import com.googlecode.cqengine.query.option.EngineThresholds;
import com.googlecode.cqengine.resultset.ResultSet;

import java.util.Iterator;
import java.util.Optional;
import java.util.UUID;

import static com.eventsourcing.index.EntityQueryFactory.*;

/**
 * Provides a query for retrieving the latest entry, associated with a model. For example,
 * to retrieve the latest e-mail change:
 *
 * 
 *     latestAssociatedEntity(EmailChanged.class, EmailChanged.REFERENCE_ID, EmailChanged.TIMESTAMP)
 * 
 */
public interface LatestAssociatedEntryQuery extends Model {

    /**
     * Invokes {@link #latestAssociatedEntity(Class, EntityIndex, EntityIndex, Query[])} with no additional queries
     *
     * @param klass Entity class
     * @param keyAttribute Entity attribute that references model's ID
     * @param timestampAttribute Entity attribute that holds the timestamp
     * @param  Entity type
     * @return Non-empty {@link Optional} if the entity is found, an empty one otherwise.
     */
    default  Optional latestAssociatedEntity(Class klass,
                                                                  EntityIndex keyAttribute,
                                                                  EntityIndex timestampAttribute) {
        @SuppressWarnings("unchecked")
        Optional last = latestAssociatedEntity(klass, keyAttribute, timestampAttribute, (Query>[]) new Query[]{});
        return last;
    }

    /**
     * Invokes {@link #latestAssociatedEntity(Class, EntityIndex, EntityIndex, Query[])} with one additional query
     * @param klass Entity class
     * @param keyAttribute Entity attribute that references model's ID
     * @param timestampAttribute Entity attribute that holds the timestamp
     * @param additionalQuery An additional condition
     * @param  Entity type
     * @return Non-empty {@link Optional} if the entity is found, an empty one otherwise.
     */
    default  Optional latestAssociatedEntity(Class klass,
                                                                  EntityIndex keyAttribute,
                                                                  EntityIndex timestampAttribute,
                                                                  Query> additionalQuery
    ) {
        @SuppressWarnings("unchecked")
        Optional last = latestAssociatedEntity(klass, keyAttribute, timestampAttribute, (Query>[]) new Query[]{additionalQuery});
        return last;
    }

    /**
     * Queries the latest entity associated with the model. For example,
     * to retrieve the latest e-mail change:
     *
     * 
     *     latestAssociatedEntity(EmailChanged.class, EmailChanged.REFERENCE_ID, EmailChanged.TIMESTAMP)
     * 
     *
     * If additional conditions are required, they can be added to the end of the method call:
     *
     * 
     *     latestAssociatedEntity(EmailChanged.class, EmailChanged.REFERENCE_ID, EmailChanged.TIMESTAMP,
     *                            equal(EmailChanged.APPROVED, true))
     * 
     *
     * @param klass Entity class
     * @param keyAttribute Entity attribute that references model's ID
     * @param timestampAttribute Entity attribute that holds the timestamp
     * @param additionalQueries Additional conditions
     * @param  Entity type
     * @return Non-empty {@link Optional} if the entity is found, an empty one otherwise.
     */
    default  Optional
    latestAssociatedEntity(Class klass,
                           EntityIndex keyAttribute, EntityIndex timestampAttribute,
                           Query> ...additionalQueries) {
        Query> query = equal(keyAttribute, getId());
        for (Query> q : additionalQueries) {
            query = and(query, q);
        }
        try (ResultSet> resultSet = getRepository()
                .query(klass, query,
                       queryOptions(orderBy(descending(timestampAttribute)),
                                    applyThresholds(threshold(EngineThresholds.INDEX_ORDERING_SELECTIVITY, 0.5))))) {
            Iterator> iterator = resultSet.iterator();
            if (!iterator.hasNext()) {
                return Optional.empty();
            } else {
                return Optional.of(iterator.next().get());
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy