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

info.archinnov.achilles.query.slice.CQLSliceQuery Maven / Gradle / Ivy

/**
 *
 * Copyright (C) 2012-2013 DuyHai DOAN
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package info.archinnov.achilles.query.slice;

import static info.archinnov.achilles.consistency.CQLConsistencyConvertor.getCQLLevel;
import info.archinnov.achilles.compound.CQLSliceQueryValidator;
import info.archinnov.achilles.entity.metadata.EntityMeta;
import info.archinnov.achilles.query.SliceQuery;
import info.archinnov.achilles.type.BoundingMode;
import info.archinnov.achilles.type.ConsistencyLevel;
import info.archinnov.achilles.type.OrderingMode;
import info.archinnov.achilles.validation.Validator;

import java.util.ArrayList;
import java.util.List;

import org.apache.cassandra.utils.Pair;

import com.datastax.driver.core.querybuilder.Ordering;
import com.datastax.driver.core.querybuilder.QueryBuilder;

public class CQLSliceQuery {

	private SliceQuery sliceQuery;
	private List fixedComponents;
	private Object lastStartComp;
	private Object lastEndComp;
	private CQLSliceQueryValidator validator = new CQLSliceQueryValidator();
	private ConsistencyLevel defaultReadLevel;

	public CQLSliceQuery(SliceQuery sliceQuery, ConsistencyLevel defaultReadLevel) {

		validator.validateComponentsForSliceQuery(sliceQuery);
		this.sliceQuery = sliceQuery;
		this.defaultReadLevel = defaultReadLevel;
		this.fixedComponents = determineFixedComponents(sliceQuery);
		Pair lastComponents = determineLastComponents(sliceQuery);
		this.lastStartComp = lastComponents.left;
		this.lastEndComp = lastComponents.right;
	}

	public List getFixedComponents() {
		return fixedComponents;
	}

	public Object getLastStartComponent() {
		return lastStartComp;
	}

	public Object getLastEndComponent() {
		return lastEndComp;
	}

	public int getLimit() {
		return sliceQuery.getLimit();
	}

	public com.datastax.driver.core.ConsistencyLevel getConsistencyLevel() {
		ConsistencyLevel consistencyLevel = sliceQuery.getConsistencyLevel() == null ? defaultReadLevel : sliceQuery
				.getConsistencyLevel();
		return getCQLLevel(consistencyLevel);
	}

	public BoundingMode getBounding() {
		return sliceQuery.getBounding();
	}

	public OrderingMode getOrdering() {
		return sliceQuery.getOrdering();
	}

	public Ordering getCQLOrdering() {
		OrderingMode ordering = sliceQuery.getOrdering();
		String orderingComponentName = sliceQuery.getMeta().getIdMeta().getOrderingComponent();
		if (ordering.isReverse()) {
			return QueryBuilder.desc(orderingComponentName);
		} else {

			return QueryBuilder.asc(orderingComponentName);
		}
	}

	public List getComponentNames() {
		return sliceQuery.getIdMeta().getComponentNames();
	}

	public String getVaryingComponentName() {
		return sliceQuery.getIdMeta().getVaryingComponentNameForQuery(fixedComponents.size());
	}

	public Class getVaryingComponentClass() {
		return sliceQuery.getIdMeta().getVaryingComponentClassForQuery(fixedComponents.size());
	}

	public EntityMeta getMeta() {
		return sliceQuery.getMeta();
	}

	public Class getEntityClass() {
		return sliceQuery.getEntityClass();
	}

	public int getBatchSize() {
		return sliceQuery.getBatchSize();
	}

	private List determineFixedComponents(SliceQuery sliceQuery) {
		List fixedComponents = new ArrayList();

		List startComponents = sliceQuery.getClusteringsFrom();

		List endComponents = sliceQuery.getClusteringsTo();

		int startIndex = validator.getLastNonNullIndex(startComponents);
		int endIndex = validator.getLastNonNullIndex(endComponents);

		int minIndex = Math.min(startIndex, endIndex);

		if (startIndex == endIndex) {
			for (int i = 0; i <= minIndex && startComponents.get(i).equals(endComponents.get(i)); i++) {
				fixedComponents.add(startComponents.get(i));
			}
		} else {
			for (int i = 0; i <= minIndex; i++) {
				fixedComponents.add(startComponents.get(i));
			}
		}

		return fixedComponents;
	}

	private Pair determineLastComponents(SliceQuery sliceQuery) {
		Object lastStartComp;
		Object lastEndComp;

		List startComponents = sliceQuery.getClusteringsFrom();
		List endComponents = sliceQuery.getClusteringsTo();

		int startIndex = validator.getLastNonNullIndex(startComponents);
		int endIndex = validator.getLastNonNullIndex(endComponents);

		if (startIndex == endIndex && !startComponents.get(startIndex).equals(endComponents.get(endIndex))) {
			lastStartComp = startComponents.get(startIndex);
			lastEndComp = endComponents.get(endIndex);
		} else if (startIndex < endIndex) {
			lastStartComp = null;
			lastEndComp = endComponents.get(endIndex);
		} else if (startIndex > endIndex) {
			lastStartComp = startComponents.get(startIndex);
			lastEndComp = null;
		} else {
			lastStartComp = null;
			lastEndComp = null;
		}

		return Pair.create(lastStartComp, lastEndComp);
	}

	public void validateSliceQueryForRemove() {
		Validator.validateTrue(lastStartComp == null && lastEndComp == null,
				"CQL does not support slice delete with varying compound components");
		Validator.validateFalse(sliceQuery.isLimitSet(), "CQL slice delete does not support LIMIT");
	}
}