<commit_before>/*
 * Copyright 2020, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.server.event.store;

import com.google.protobuf.Timestamp;
import io.spine.core.Event;
import io.spine.core.EventId;
import io.spine.query.Direction;
import io.spine.query.RecordQuery;
import io.spine.query.RecordQueryBuilder;
import io.spine.server.event.EventFilter;
import io.spine.server.event.EventStreamQuery;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.spine.server.event.store.EventColumn.created;

/**
 * Converts {@link EventStreamQuery} to {@link RecordQuery}.
 */
final class Queries {

    private Queries() {
    }

    /**
     * Converts the {@code EventStreamQuery} to the record query.
     */
    static RecordQuery<EventId, Event> convert(EventStreamQuery query) {
        checkNotNull(query);

        RecordQueryBuilder<EventId, Event> builder = RecordQuery.newBuilder(Event.class);
        if (!query.includeAll()) {
            addTimeBounds(query, builder);
            addTypeParams(query, builder);
        }
        RecordQuery<EventId, Event> result = addOrderAndLimit(query, builder);
        return result;
    }

    private static void addTimeBounds(EventStreamQuery query,
                                      RecordQueryBuilder<EventId, Event> builder) {
        if (query.hasAfter()) {
            Timestamp timestamp = query.getAfter();
            builder.where(created)
                   .isGreaterThan(timestamp);
        }
        if (query.hasBefore()) {
            Timestamp timestamp = query.getBefore();
            builder.where(created)
                   .isLessThan(timestamp);
        }
    }

    private static void addTypeParams(EventStreamQuery query,
                                      RecordQueryBuilder<EventId, Event> builder) {
        //TODO:2020-07-17:alex.tymchenko: find out if this is true.<commit_msg>Avoid the redundant copying of the type params.<commit_after>/*
 * Copyright 2020, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.server.event.store;

import com.google.protobuf.Timestamp;
import io.spine.core.Event;
import io.spine.core.EventId;
import io.spine.query.Direction;
import io.spine.query.RecordQuery;
import io.spine.query.RecordQueryBuilder;
import io.spine.server.event.EventFilter;
import io.spine.server.event.EventStreamQuery;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.spine.server.event.store.EventColumn.created;

/**
 * Converts {@link EventStreamQuery} to {@link RecordQuery}.
 */
final class Queries {

    private Queries() {
    }

    /**
     * Converts the {@code EventStreamQuery} to the record query.
     */
    static RecordQuery<EventId, Event> convert(EventStreamQuery query) {
        checkNotNull(query);

        RecordQueryBuilder<EventId, Event> builder = RecordQuery.newBuilder(Event.class);
        if (!query.includeAll()) {
            addTimeBounds(query, builder);
            addTypeParams(query, builder);
        }
        RecordQuery<EventId, Event> result = addOrderAndLimit(query, builder);
        return result;
    }

    private static void addTimeBounds(EventStreamQuery query,
                                      RecordQueryBuilder<EventId, Event> builder) {
        if (query.hasAfter()) {
            Timestamp timestamp = query.getAfter();
            builder.where(created)
                   .isGreaterThan(timestamp);
        }
        if (query.hasBefore()) {
            Timestamp timestamp = query.getBefore();
            builder.where(created)
                   .isLessThan(timestamp);
        }
    }

    private static void addTypeParams(EventStreamQuery query,
                                      RecordQueryBuilder<EventId, Event> builder) {
        if(query.getFilterCount() == 0) {
            return;
        }
        //TODO:2020-07-17:alex.tymchenko: find out if this is true.
{'fraction_non_alphanumeric': 0.08542454451701616, 'fraction_numerical': 0.004297009281540048, 'mean_word_length': 2.996565934065934, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4152396', 'n_tokens_mistral': 1623, 'n_tokens_neox': 1482, 'n_words': 505}