Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.netflix.astyanax.cql.writes.CFMutationQueryGen Maven / Gradle / Ivy
package com.netflix.astyanax.cql.writes;
import java.util.Iterator;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datastax.driver.core.BatchStatement;
import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.Session;
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;
import com.netflix.astyanax.serializers.ComparatorType;
public class CFMutationQueryGen {
private static final Logger Logger = LoggerFactory.getLogger(CFMutationQueryGen.class);
public static enum MutationType {
ColumnUpdate, ColumnDelete, RowDelete, CounterColumnUpdate;
}
// Constants that are used frequently for constructing the query
private static final String INSERT_INTO = "INSERT INTO ";
private static final String OPEN_PARA = " (";
private static final String CLOSE_PARA = ") ";
private static final String VALUES = ") VALUES (";
private static final String BIND_MARKER = "?,";
private static final String LAST_BIND_MARKER = "?";
private static final String COMMA = ",";
private static final String USING = " USING ";
private static final String TTL = " TTL ";
private static final String AND = " AND ";
private static final String TIMESTAMP = " TIMESTAMP ";
private static final String DELETE_FROM = "DELETE FROM ";
private static final String WHERE = " WHERE ";
private static final String EQUALS = " = ";
private static final String UPDATE = " UPDATE ";
private static final String SET = " SET ";
private final String keyspace;
private final CqlColumnFamilyDefinitionImpl cfDef;
private final Session session;
public CFMutationQueryGen(Session session, String keyspaceName, CqlColumnFamilyDefinitionImpl cfDefinition) {
this.keyspace = keyspaceName;
this.cfDef = cfDefinition;
this.session = session;
}
private static void appendWriteOptions(StringBuilder sb, Integer ttl, Long timestamp) {
if (ttl != null || timestamp != null) {
sb.append(USING);
}
if (ttl != null) {
sb.append(TTL + ttl);
}
if (timestamp != null) {
if (ttl != null) {
sb.append(AND);
}
sb.append(TIMESTAMP + timestamp);
}
}
abstract class MutationQueryCache {
private final AtomicReference cachedStatement = new AtomicReference(null);
public abstract Callable getQueryGen(M mutation);
public void addToBatch(BatchStatement batch, M mutation, boolean useCaching) {
batch.add(getBoundStatement(mutation, useCaching));
}
public BoundStatement getBoundStatement(M mutation, boolean useCaching) {
PreparedStatement pStatement = getPreparedStatement(mutation, useCaching);
return bindValues(pStatement, mutation);
}
public abstract BoundStatement bindValues(PreparedStatement pStatement, M mutation);
public PreparedStatement getPreparedStatement(M mutation, boolean useCaching) {
PreparedStatement pStatement = null;
if (useCaching) {
pStatement = cachedStatement.get();
}
if (pStatement == null) {
try {
String query = getQueryGen(mutation).call();
pStatement = session.prepare(query);
if (Logger.isDebugEnabled()) {
Logger.debug("Query: " + pStatement.getQueryString());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
if (useCaching && cachedStatement.get() == null) {
cachedStatement.set(pStatement);
}
return pStatement;
}
}
private MutationQueryCache> DeleteRowQuery = new MutationQueryCache>() {
private final Callable queryGen = new Callable() {
@Override
public String call() throws Exception {
return DELETE_FROM + keyspace + "." + cfDef.getName() +
WHERE + cfDef.getPartitionKeyColumnDefinition().getName() + EQUALS + LAST_BIND_MARKER;
}
};
@Override
public Callable getQueryGen(CqlColumnListMutationImpl, ?> mutation) {
return queryGen;
}
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnListMutationImpl, ?> mutation) {
return pStatement.bind(mutation.getRowKey());
}
};
abstract class BaseClusteringKeyMutation extends MutationQueryCache> {
public abstract boolean isDeleteQuery();
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnMutationImpl,?> colMutation) {
int size = cfDef.getPartitionKeyColumnDefinitionList().size() + cfDef.getClusteringKeyColumnDefinitionList().size();
if (!isDeleteQuery()) {
size += cfDef.getRegularColumnDefinitionList().size();
} else {
// we don't need to add the value component here. Just the partition key and the clustering key
}
Object[] arr = new Object[size];
int index = 0;
arr[index++] = colMutation.getRowKey();
ColumnFamily,?> cf = colMutation.cfContext.getColumnFamily();
boolean isCompositeColumn = cf.getColumnSerializer().getComparatorType() == ComparatorType.COMPOSITETYPE;
if (isCompositeColumn) {
AnnotatedCompositeSerializer> compSerializer = (AnnotatedCompositeSerializer>) cf.getColumnSerializer();
for (ComponentSerializer> component : compSerializer.getComponents()) {
try {
arr[index++] = component.getFieldValueDirectly(colMutation.columnName);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} else {
arr[index++] = colMutation.columnName;
}
if (!isDeleteQuery()) {
arr[index++] = colMutation.columnValue;
}
return pStatement.bind(arr);
}
}
private BaseClusteringKeyMutation InsertColumnWithClusteringKey = new BaseClusteringKeyMutation() {
@Override
public Callable getQueryGen(final CqlColumnMutationImpl, ?> mutation) {
return new Callable() {
@Override
public String call() throws Exception {
return genQuery().toString();
}
private StringBuilder genQuery() {
/**
* e.g
* insert into t (key, column1, value) values ('a', '2' , 'a2') using ttl 86400 and timestamp = 1234444;
*/
int columnCount = 0;
StringBuilder sb = new StringBuilder(INSERT_INTO);
sb.append(keyspace + "." + cfDef.getName());
sb.append(OPEN_PARA);
Iterator iter = cfDef.getPartitionKeyColumnDefinitionList().iterator();
while (iter.hasNext()) {
sb.append(iter.next().getName());
columnCount++;
if (iter.hasNext()) {
sb.append(COMMA);
}
}
iter = cfDef.getClusteringKeyColumnDefinitionList().iterator();
if (iter.hasNext()) {
sb.append(COMMA);
while (iter.hasNext()) {
sb.append(iter.next().getName());
columnCount++;
if (iter.hasNext()) {
sb.append(COMMA);
}
}
}
iter = cfDef.getRegularColumnDefinitionList().iterator();
if (iter.hasNext()) {
sb.append(COMMA);
while (iter.hasNext()) {
sb.append(iter.next().getName());
columnCount++;
if (iter.hasNext()) {
sb.append(COMMA);
}
}
}
sb.append(VALUES);
for (int i=0; i getQueryGen(final CqlColumnMutationImpl, ?> mutation) {
return new Callable() {
@Override
public String call() throws Exception {
return genQuery().toString();
}
private StringBuilder genQuery() {
StringBuilder sb = new StringBuilder(DELETE_FROM);
sb.append(keyspace + "." + cfDef.getName());
appendWriteOptions(sb, mutation.getTTL(), mutation.getTimestamp());
Iterator iter = cfDef.getPartitionKeyColumnDefinitionList().iterator();
sb.append(WHERE);
while (iter.hasNext()) {
sb.append(iter.next().getName()).append(EQUALS).append(LAST_BIND_MARKER);
if (iter.hasNext()) {
sb.append(AND);
}
}
iter = cfDef.getClusteringKeyColumnDefinitionList().iterator();
if (iter.hasNext()) {
sb.append(AND);
while (iter.hasNext()) {
sb.append(iter.next().getName()).append(EQUALS).append(LAST_BIND_MARKER);
if (iter.hasNext()) {
sb.append(AND);
}
}
}
return sb;
}
};
}
@Override
public boolean isDeleteQuery() {
return true;
}
};
private MutationQueryCache> CounterColumnUpdate = new MutationQueryCache>() {
@Override
public Callable getQueryGen(final CqlColumnMutationImpl, ?> mutation) {
return new Callable() {
@Override
public String call() throws Exception {
String valueAlias = cfDef.getRegularColumnDefinitionList().get(0).getName();
StringBuilder sb = new StringBuilder();
sb.append(UPDATE + keyspace + "." + cfDef.getName());
appendWriteOptions(sb, mutation.getTTL(), mutation.getTimestamp());
sb.append(SET + valueAlias + " = " + valueAlias + " + ? ");
Iterator iter = cfDef.getPartitionKeyColumnDefinitionList().iterator();
sb.append(WHERE);
while (iter.hasNext()) {
sb.append(iter.next().getName()).append(EQUALS).append(LAST_BIND_MARKER);
if (iter.hasNext()) {
sb.append(AND);
}
}
iter = cfDef.getClusteringKeyColumnDefinitionList().iterator();
if (iter.hasNext()) {
sb.append(AND);
while (iter.hasNext()) {
sb.append(iter.next().getName()).append(EQUALS).append(LAST_BIND_MARKER);
if (iter.hasNext()) {
sb.append(AND);
}
}
}
return sb.toString();
}
};
}
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnMutationImpl, ?> mutation) {
int size = 1 + cfDef.getPartitionKeyColumnDefinitionList().size() + cfDef.getClusteringKeyColumnDefinitionList().size();
Object[] arr = new Object[size];
int index = 0;
arr[index++] = mutation.columnValue;
arr[index++] = mutation.getRowKey();
ColumnFamily,?> cf = mutation.cfContext.getColumnFamily();
boolean isCompositeColumn = cf.getColumnSerializer().getComparatorType() == ComparatorType.COMPOSITETYPE;
if (isCompositeColumn) {
AnnotatedCompositeSerializer> compSerializer = (AnnotatedCompositeSerializer>) cf.getColumnSerializer();
for (ComponentSerializer> component : compSerializer.getComponents()) {
try {
arr[index++] = component.getFieldValueDirectly(mutation.columnName);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} else {
arr[index++] = mutation.columnName;
}
return pStatement.bind(arr);
}
};
private MutationQueryCache> InsertOrDeleteWithClusteringKey = new MutationQueryCache>() {
@Override
public void addToBatch(BatchStatement batch, CqlColumnListMutationImpl,?> colListMutation, boolean useCaching) {
for (CqlColumnMutationImpl,?> colMutation : colListMutation.getMutationList()) {
switch (colMutation.getType()) {
case UpdateColumn :
InsertColumnWithClusteringKey.addToBatch(batch, colMutation, useCaching);
break;
case DeleteColumn :
DeleteColumnWithClusteringKey.addToBatch(batch, colMutation, useCaching);
break;
case CounterColumn :
throw new RuntimeException("Counter column update not allowed with other updates");
default:
throw new RuntimeException("Unsupported type: " + colMutation.getType());
};
}
}
@Override
public Callable getQueryGen(CqlColumnListMutationImpl, ?> colListMutation) {
throw new RuntimeException("Not Supported");
}
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnListMutationImpl, ?> colListMutation) {
throw new RuntimeException("Not Supported");
}
};
private MutationQueryCache> InsertOrDeleteColumnListWithClusteringKey = new MutationQueryCache>() {
@Override
public void addToBatch(BatchStatement batch, CqlColumnListMutationImpl,?> colListMutation, boolean useCaching) {
for (CqlColumnMutationImpl,?> colMutation : colListMutation.getMutationList()) {
InsertOrDeleteColumnWithClusteringKey.addToBatch(batch, colMutation, useCaching);
}
}
@Override
public Callable getQueryGen(CqlColumnListMutationImpl, ?> colListMutation) {
throw new RuntimeException("Not Supported");
}
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnListMutationImpl, ?> colListMutation) {
throw new RuntimeException("Not Supported");
}
};
private MutationQueryCache> InsertOrDeleteColumnWithClusteringKey = new MutationQueryCache>() {
@Override
public BoundStatement getBoundStatement(CqlColumnMutationImpl, ?> mutation, boolean useCaching) {
switch (mutation.getType()) {
case UpdateColumn :
return InsertColumnWithClusteringKey.getBoundStatement(mutation, useCaching);
case DeleteColumn :
return DeleteColumnWithClusteringKey.getBoundStatement(mutation, useCaching);
case CounterColumn :
return CounterColumnUpdate.getBoundStatement(mutation, useCaching);
default:
throw new RuntimeException("Unsupported type: " + mutation.getType());
}
}
@Override
public Callable getQueryGen(CqlColumnMutationImpl, ?> colMutation) {
throw new RuntimeException("Not Supported");
}
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnMutationImpl, ?> colMutation) {
throw new RuntimeException("Not Supported");
}
};
private MutationQueryCache> CounterColumnList = new MutationQueryCache>() {
@Override
public void addToBatch(BatchStatement batch, CqlColumnListMutationImpl,?> colListMutation, boolean useCaching) {
for (CqlColumnMutationImpl,?> colMutation : colListMutation.getMutationList()) {
CounterColumnUpdate.addToBatch(batch, colMutation, useCaching);
}
}
@Override
public Callable getQueryGen(CqlColumnListMutationImpl, ?> colListMutation) {
throw new RuntimeException("Not Supported");
}
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnListMutationImpl, ?> colListMutation) {
throw new RuntimeException("Not Supported");
}
};
private MutationQueryCache> FlatTableInsertQuery = new MutationQueryCache> () {
@Override
public void addToBatch(BatchStatement batch, CqlColumnListMutationImpl, ?> colListMutation, boolean useCaching) {
StringBuilder sb = new StringBuilder();
sb.append(INSERT_INTO).append(keyspace + "." + cfDef.getName());
sb.append(OPEN_PARA);
// Init the object array for the bind values
int size = colListMutation.getMutationList().size() + 1;
Object[] values = new Object[size];
int index = 0;
// Add in the primary key
sb.append(cfDef.getPartitionKeyColumnDefinition().getName()).append(COMMA);
values[index++] = colListMutation.getRowKey();
for (CqlColumnMutationImpl,?> colMutation : colListMutation.getMutationList()) {
sb.append(colMutation.columnName);
values[index++] = colMutation.columnValue;
if (index < size) {
sb.append(COMMA);
}
}
sb.append(VALUES);
for (int i=0; i getQueryGen(CqlColumnListMutationImpl, ?> mutation) {
throw new RuntimeException("Not Supported");
}
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnListMutationImpl, ?> mutation) {
throw new RuntimeException("Not Supported");
}
};
private MutationQueryCache> FlatTableInsertQueryForColumn = new MutationQueryCache> () {
@Override
public Callable getQueryGen(CqlColumnMutationImpl, ?> mutation) {
throw new RuntimeException("Not Supported");
}
@Override
public BoundStatement bindValues(PreparedStatement pStatement, CqlColumnMutationImpl, ?> mutation) {
throw new RuntimeException("Not Supported");
}
@Override
public void addToBatch(BatchStatement batch, CqlColumnMutationImpl, ?> mutation, boolean useCaching) {
throw new RuntimeException("Not Supported");
}
@Override
public BoundStatement getBoundStatement(CqlColumnMutationImpl, ?> mutation, boolean useCaching) {
StringBuilder sb = new StringBuilder();
sb.append(INSERT_INTO).append(keyspace + "." + cfDef.getName());
sb.append(OPEN_PARA);
sb.append(cfDef.getPartitionKeyColumnDefinition().getName());
sb.append(COMMA);
sb.append(mutation.columnName);
sb.append(VALUES);
sb.append(BIND_MARKER);
sb.append(LAST_BIND_MARKER);
sb.append(CLOSE_PARA);
appendWriteOptions(sb, mutation.getTTL(), mutation.getTimestamp());
String query = sb.toString();
if (Logger.isDebugEnabled()) {
Logger.debug("Query: " + query);
}
// Init the object array for the bind values
Object[] values = new Object[2];
values[0] = mutation.getRowKey();
values[1] = mutation.columnValue;
try {
PreparedStatement pStatement = session.prepare(query);
return pStatement.bind(values);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
public void addColumnListMutationToBatch(BatchStatement batch, CqlColumnListMutationImpl,?> colListMutation, boolean useCaching) {
switch (colListMutation.getType()) {
case RowDelete:
DeleteRowQuery.addToBatch(batch, colListMutation, useCaching);
break;
case ColumnsUpdate:
if (cfDef.getClusteringKeyColumnDefinitionList().size() == 0) {
// THIS IS A FLAT TABLE QUERY
FlatTableInsertQuery.addToBatch(batch, colListMutation, useCaching);
} else {
InsertOrDeleteWithClusteringKey.addToBatch(batch, colListMutation, useCaching);
}
break;
case CounterColumnsUpdate:
CounterColumnList.addToBatch(batch, colListMutation, useCaching);
break;
default:
throw new RuntimeException("Unrecognized ColumnListMutation Type");
}
}
public BoundStatement getColumnMutationStatement(CqlColumnMutationImpl,?> mutation, boolean useCaching) {
if (cfDef.getClusteringKeyColumnDefinitionList().size() == 0) {
// THIS IS A FLAT TABLE QUERY
return FlatTableInsertQueryForColumn.getBoundStatement(mutation, useCaching);
} else {
return InsertOrDeleteColumnWithClusteringKey.getBoundStatement(mutation, useCaching);
}
}
}