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

org.nohope.cassandra.mapservice.CMapStatementGenerator Maven / Gradle / Ivy

The newest version!
package org.nohope.cassandra.mapservice;

import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.Delete;
import com.datastax.driver.core.querybuilder.Insert;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.querybuilder.Select;
import com.google.common.collect.Sets;
import org.nohope.cassandra.mapservice.cfilter.CFilter;
import org.nohope.cassandra.mapservice.columns.CColumn;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;

import static com.datastax.driver.core.querybuilder.QueryBuilder.timestamp;
import static com.datastax.driver.core.querybuilder.QueryBuilder.ttl;

/**
 */
final class CMapStatementGenerator {
    private static final String EXPECTED_COLUMNS_ERROR_MESSAGE = "Expected {0} columns {1}, but {2} were passed: {3}";
    private static final String UNEXPECTED_COLUMNS_ERROR_MESSAGE = "Unexpected columns passed {0}. Expected columns: {1}";

    private final TableScheme scheme;

    CMapStatementGenerator(final TableScheme scheme) {
        this.scheme = scheme;
    }

    private static void addConsistencyLevelToQuery(final ConsistencyLevel consistency,
                                                   final Select query) {
        if (null != consistency) {
            query.setConsistencyLevel(consistency);
        }
        query.disableTracing();
    }

    private static boolean noOrderingsInQuery(final CQuery cQuery) {
        return cQuery.getOrderBy().isEmpty();
    }

    public Select.Where get(final CQuery cQuery, final ConsistencyLevel consistency) {
        CFilterCheckTransporter.verifyQueryDueToScheme(scheme, cQuery);
        return prepareGetQuery(cQuery, consistency);
    }

    public Select all() {
        Select.Selection query = QueryBuilder.select();
        return query.from(scheme.getTableNameQuoted());
    }

    public RegularStatement remove(final CQuery cQuery, final ConsistencyLevel consistency) {
        return createDeleteQuery(cQuery, consistency);
    }

    public void put(final CPutQuery cPutQuery) {
        put(cPutQuery, null);
    }

    public Insert put(final CPutQuery cPutQuery, final ConsistencyLevel consistencyLevel) {
        return createPutStatement(cPutQuery, consistencyLevel);
    }

    public Statement count(final CQuery cQuery) {
        final Select.Builder query = QueryBuilder.select().countAll();
        return addWhereStatementToQuery(cQuery, query.from(scheme.getTableNameQuoted()));
    }

    /**
     * Package-local method for Batch operations
     *
     * @param cQuery           {@link org.nohope.cassandra.mapservice.CQuery query}
     * @param consistencyLevel {@link com.datastax.driver.core.ConsistencyLevel cassandra-driver consistency level}
     * @return {@link com.datastax.driver.core.RegularStatement cassandra-driver regular statement}
     */
    RegularStatement createRemoveOperation(final CQuery cQuery, final ConsistencyLevel consistencyLevel) {
        return createDeleteQuery(cQuery, consistencyLevel);
    }

    /**
     * Package-local method for Batch operations
     *
     * @param cPutQuery        the value tuple
     * @param consistencyLevel {@link com.datastax.driver.core.ConsistencyLevel cassandra-driver consistency level}
     * @return {@link com.datastax.driver.core.RegularStatement cassandra regular statement}
     */
    RegularStatement createPutOperation(final CPutQuery cPutQuery, final ConsistencyLevel consistencyLevel) {
        return createPutStatement(cPutQuery, consistencyLevel);
    }

    /**
     * Create delete query.
     * For inner delete query and batch operations.
     *
     * @param cQuery           {@link org.nohope.cassandra.mapservice.CQuery query}
     * @param consistencyLevel {@link com.datastax.driver.core.ConsistencyLevel consistency }.
     * @return the regular statement  {@link com.datastax.driver.core.RegularStatement cassandra regulate statement }.
     */
    RegularStatement createDeleteQuery(final CQuery cQuery, final ConsistencyLevel consistencyLevel) {
        final Delete.Where query = applyFiltersToDeleteQuery(cQuery);
        if (null != consistencyLevel) {
            query.setConsistencyLevel(consistencyLevel);
        }
        return query;
    }

    private Select.Where addWhereStatementToQuery(final CQuery cQuery, final Select query) {
        final Select.Where where = query.where();
        for (final CFilter filter : cQuery.getFilters()) {
            // FIXME: type checking not works in case of _in_ operator
            //final CColumn filterCol = filter.getValue().getColumn();
            //if (!scheme.getColumns().get(filterCol.getName()).equals(filterCol)) {
            //    throw new IllegalStateException();
            //}
            where.and(filter.apply());
        }
        return where;
    }

    private Select addExpectedColumnsToQuery(final CQuery cQuery) {
        final Select.Selection query = QueryBuilder.select();
        for (final CColumn column : cQuery.getExpectedColumnsCollection()) {
            query.column(column.getName());
        }
        return query.from(scheme.getTableNameQuoted());
    }

    private Select.Where prepareGetQuery(final CQuery cQuery, final ConsistencyLevel consistency) {
        final Select query = addExpectedColumnsToQuery(cQuery);
        addConsistencyLevelToQuery(consistency, query);

        if (cQuery.getLimit().isPresent()) {
            query.limit(cQuery.getLimit().get());
        }

        if (cQuery.isAllowFiltering()) {
            addAllowFilteringAndOrderingsToQuery(cQuery, query);
        }

        return addWhereStatementToQuery(cQuery, query);
    }

    private void addAllowFilteringAndOrderingsToQuery(final CQuery cQuery, final Select query) {
        if (noOrderingsInQuery(cQuery)) {
            query.allowFiltering();
        } else {
            addWhereStatementToQuery(cQuery, query)
                    .orderBy(cQuery.getOrderingAsCassandraOrderings()).allowFiltering();
        }
    }

    private Delete.Where applyFiltersToDeleteQuery(final CQuery cQuery) {
        final Delete.Where query = QueryBuilder.delete().from(scheme.getTableNameQuoted()).where();
        for (final CFilter filter : getPrimaryKeysSet(cQuery)) {
            final CColumn filterCol = filter.getValue().getColumn();
            if (!scheme.getColumns().get(filterCol.getName()).equals(filterCol)) {
                throw new IllegalStateException(); // FIXME!
            }
            query.and(filter.apply());
        }

        return query;
    }

    private Iterable> getPrimaryKeysSet(final CQuery cQuery) {
        final Collection> primaries = new ArrayList<>();

        for (final CFilter filter : cQuery.getFilters()) {
            final CColumn column = filter.getValue().getColumn();
            if (scheme.isPartitionKey(column) || scheme.isClusteringKey(column)) {
                primaries.add(filter);
            }
        }

        return primaries;
    }

    private void verifyColumns(final Collection> columns) {
        if (columns.size() != scheme.getColumnsSet().size()) {
            throw new CQueryException(MessageFormat.format(
                    EXPECTED_COLUMNS_ERROR_MESSAGE,
                    scheme.getColumnsSet().size(),
                    columns.size(),
                    columns)
            );
        }
        if (!scheme.getColumnsSet().containsAll(columns)) {
            throw new CQueryException(MessageFormat.format(
                    UNEXPECTED_COLUMNS_ERROR_MESSAGE,
                    Sets.difference(Sets.newHashSet(columns), scheme.getColumnsSet()),
                    scheme.getColumnsSet()
            ));
        }
    }

    private Insert createPutStatement(final CPutQuery cPutQuery, final ConsistencyLevel consistencyLevel) {
        verifyColumns(cPutQuery.getValueTuple().get().getColumns().values());

        final Insert query = QueryBuilder.insertInto(scheme.getTableNameQuoted());
        final ValueTuple valueToPut = cPutQuery.getValueTuple().get();

        if (cPutQuery.getTTL().isPresent()) {
            query.using(ttl(cPutQuery.getTTL().get()));
        }
        if (cPutQuery.getTimestamp().isPresent()) {
            query.using(timestamp(cPutQuery.getTimestamp().get()));
        }
        if (null != consistencyLevel) {
            query.setConsistencyLevel(consistencyLevel);
        }

        for (final Value value : valueToPut.getValues().values()) {
            final Object cassandraValue = BindUtils.maybeBindable(value);
            query.getQueryString(); // FIXME: ??
            query.value(value.getColumn().getName(), cassandraValue);
        }

        return query;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy