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

com.netflix.astyanax.cql.reads.CFColumnQueryGen Maven / Gradle / Ivy

package com.netflix.astyanax.cql.reads;

import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;

import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.querybuilder.Select.Builder;
import com.datastax.driver.core.querybuilder.Select.Where;
import com.netflix.astyanax.cql.schema.CqlColumnFamilyDefinitionImpl;
import com.netflix.astyanax.ddl.ColumnDefinition;
import com.netflix.astyanax.model.ColumnFamily;
import com.netflix.astyanax.serializers.AnnotatedCompositeSerializer;
import com.netflix.astyanax.serializers.AnnotatedCompositeSerializer.ComponentSerializer;

public class CFColumnQueryGen {

	private AtomicReference sessionRef = new AtomicReference(null);
	private final String keyspace; 
	private final CqlColumnFamilyDefinitionImpl cfDef;

	private final String partitionKeyCol;
	private final List clusteringKeyCols;
	private final List regularCols;
	
	private boolean isCompositeColumn = false;
	private boolean isFlatTable = false;
	
	private static final String BIND_MARKER = "?";

	

	public CFColumnQueryGen(Session session, String keyspaceName, CqlColumnFamilyDefinitionImpl cfDefinition) {

		this.keyspace = keyspaceName;
		this.cfDef = cfDefinition;
		this.sessionRef.set(session);
		
		partitionKeyCol = cfDef.getPartitionKeyColumnDefinition().getName();
		clusteringKeyCols = cfDef.getClusteringKeyColumnDefinitionList();
		regularCols = cfDef.getRegularColumnDefinitionList();
		
		isCompositeColumn = (clusteringKeyCols.size() > 1);
		isFlatTable = (clusteringKeyCols.size() == 0);
	}
	
	private QueryGenCache> ColumnQueryWithClusteringKey = new QueryGenCache>(sessionRef) {

		@Override
		public Callable getQueryGen(final CqlColumnQueryImpl columnQuery) {
			
			return new Callable() {

				@Override
				public RegularStatement call() throws Exception {
					if (clusteringKeyCols.size() != 1) {
						throw new RuntimeException("Cannot use this query for this schema, clustetingKeyCols.size: " + clusteringKeyCols.size());
					}
					
					String valueColName = regularCols.get(0).getName();

					return QueryBuilder.select()
							.column(valueColName).ttl(valueColName).writeTime(valueColName)
							.from(keyspace, cfDef.getName())
							.where(eq(partitionKeyCol, BIND_MARKER))
							.and(eq(clusteringKeyCols.get(0).getName(), BIND_MARKER));
				}
			};
		}

		@Override
		public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnQueryImpl columnQuery) {
			return pStatement.bind(columnQuery.getRowKey(), columnQuery.getColumnName());		
		}
	};
	
	private QueryGenCache> ColumnQueryWithCompositeColumn = new QueryGenCache>(sessionRef) {

		@Override
		public Callable getQueryGen(final CqlColumnQueryImpl columnQuery) {
			
			return new Callable() {

				@Override
				public RegularStatement call() throws Exception {
					
					if (clusteringKeyCols.size() <= 1) {
						throw new RuntimeException("Cannot use this query for this schema, clustetingKeyCols.size: " + clusteringKeyCols.size());
					}
					
					String valueColName = regularCols.get(0).getName();

					ColumnFamily cf = columnQuery.getCF();
					AnnotatedCompositeSerializer compSerializer = (AnnotatedCompositeSerializer) cf.getColumnSerializer();
					List> components = compSerializer.getComponents();

					// select the individual columns as dictated by the no of component serializers
					Builder select = QueryBuilder.select()
							.column(valueColName).ttl(valueColName).writeTime(valueColName);

					Where where = select.from(keyspace, cfDef.getName()).where(eq(partitionKeyCol, BIND_MARKER));

					for (int index = 0; index columnQuery) {
		
			List values = new ArrayList();
			values.add(columnQuery.getRowKey());
			
			ColumnFamily cf = columnQuery.getCF();
			AnnotatedCompositeSerializer compSerializer = (AnnotatedCompositeSerializer) cf.getColumnSerializer();
			List> components = compSerializer.getComponents();

			Object columnName = columnQuery.getColumnName();
			for (ComponentSerializer component : components) {
				values.add(component.getFieldValueDirectly(columnName));
			}

			return pStatement.bind(values.toArray());
		}
	};
	
	
	private QueryGenCache> FlatTableColumnQuery = new QueryGenCache>(sessionRef) {

		@Override
		public Callable getQueryGen(final CqlColumnQueryImpl columnQuery) {
			
			return new Callable() {

				@Override
				public RegularStatement call() throws Exception {
					
					if (clusteringKeyCols.size() != 0) {
						throw new RuntimeException("Cannot use this query for this schema, clustetingKeyCols.size: " + clusteringKeyCols.size());
					}

					String columnNameString = (String)columnQuery.getColumnName();
					return QueryBuilder.select()
							.column(columnNameString).ttl(columnNameString).writeTime(columnNameString)
							.from(keyspace, cfDef.getName())
							.where(eq(partitionKeyCol, BIND_MARKER));				}
				
			};
		}

		@Override
		public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnQueryImpl columnQuery) {
			return pStatement.bind(columnQuery.getRowKey());
		}
	};
	
	public BoundStatement getQueryStatement(CqlColumnQueryImpl columnQuery, boolean useCaching) {

		if (isFlatTable) {
			return FlatTableColumnQuery.getBoundStatement(columnQuery, useCaching);
		}
		
		if (isCompositeColumn) {
			return ColumnQueryWithCompositeColumn.getBoundStatement(columnQuery, useCaching);
		} else {
			return ColumnQueryWithClusteringKey.getBoundStatement(columnQuery, useCaching);
		}
	}
}