package com.netflix.astyanax.cql.writes;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.datastax.driver.core.BatchStatement;
import com.datastax.driver.core.BatchStatement.Type;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Statement;
import com.google.common.util.concurrent.ListenableFuture;
import com.netflix.astyanax.CassandraOperationType;
import com.netflix.astyanax.Clock;
import com.netflix.astyanax.ColumnListMutation;
import com.netflix.astyanax.MutationBatch;
import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.cql.ConsistencyLevelMapping;
import com.netflix.astyanax.cql.CqlAbstractExecutionImpl;
import com.netflix.astyanax.cql.CqlKeyspaceImpl.KeyspaceContext;
import com.netflix.astyanax.cql.writes.CqlColumnListMutationImpl.ColListMutationType;
import com.netflix.astyanax.model.ColumnFamily;
import com.netflix.astyanax.model.ConsistencyLevel;
import com.netflix.astyanax.retry.RetryPolicy;
public class CqlMutationBatchImpl extends AbstractMutationBatchImpl {
private final KeyspaceContext ksContext;
// Control to turn use of prepared statement caching ON/OFF
private boolean useCaching = false;
public CqlMutationBatchImpl(KeyspaceContext ksCtx, Clock clock, ConsistencyLevel consistencyLevel, RetryPolicy retry) {
super(clock, consistencyLevel, retry);
this.ksContext = ksCtx;
}
@Override
public <K, C> ColumnListMutation<C> createColumnListMutation(String keyspace, ColumnFamily<K, C> cf, K rowKey) {
return new CqlColumnListMutationImpl<K, C>(ksContext, cf, rowKey, getConsistencyLevel(), timestamp);
}
@Override
public void mergeColumnListMutation(ColumnListMutation<?> from, ColumnListMutation<?> to) {
CqlColumnListMutationImpl<?, ?> fromCqlListMutation = (CqlColumnListMutationImpl<?, ?>) from;
CqlColumnListMutationImpl<?, ?> toCqlListMutation = (CqlColumnListMutationImpl<?, ?>) to;
toCqlListMutation.mergeColumnListMutation(fromCqlListMutation);
}
@Override
public OperationResult<Void> execute() throws ConnectionException {
return new CqlAbstractExecutionImpl<Void>(ksContext, getRetryPolicy()) {
@Override
public CassandraOperationType getOperationType() {
return CassandraOperationType.BATCH_MUTATE;
}
@Override
public Statement getQuery() {
return getCachedPreparedStatement();
}
@Override
public Void parseResultSet(ResultSet resultSet) {
return null; // do nothing for mutations
}
}.execute();
}
@Override
public ListenableFuture<OperationResult<Void>> executeAsync() throws ConnectionException {
return new CqlAbstractExecutionImpl<Void>(ksContext, getRetryPolicy()) {
@Override
public CassandraOperationType getOperationType() {
return CassandraOperationType.BATCH_MUTATE;
}
@Override
public Statement getQuery() {
return getCachedPreparedStatement();
}
@Override
public Void parseResultSet(ResultSet resultSet) {
return null; // do nothing for mutations
}
}.executeAsync();
}
private List<CqlColumnListMutationImpl<?, ?>> getColumnMutations() {
List<CqlColumnListMutationImpl<?,?>> colListMutation = new ArrayList<CqlColumnListMutationImpl<?,?>>();
for (Entry<ByteBuffer, Map<String, ColumnListMutation<?>>> entry : super.getMutationMap().entrySet()) {
for (ColumnListMutation<?> colMutation : entry.getValue().values()) {
colListMutation.add((CqlColumnListMutationImpl<?, ?>) colMutation);
}
}
return colListMutation;
}
private BatchStatement getCachedPreparedStatement() {
final List<CqlColumnListMutationImpl<?, ?>> colListMutations = getColumnMutations();
if (colListMutations == null || colListMutations.size() == 0) {
return new BatchStatement(Type.UNLOGGED);
}
ColListMutationType mutationType = colListMutations.get(0).getType();
BatchStatement batch = new BatchStatement(Type.UNLOGGED);
if (mutationType == ColListMutationType.CounterColumnsUpdate) {
batch = new BatchStatement(Type.COUNTER);
} else if (useAtomicBatch()) {
batch = new BatchStatement(Type.LOGGED);
}
for (CqlColumnListMutationImpl<?, ?> colListMutation : colListMutations) {
CFMutationQueryGen queryGen = colListMutation.getMutationQueryGen();
queryGen.addColumnListMutationToBatch(batch, colListMutation, useCaching);
}
batch.setConsistencyLevel(ConsistencyLevelMapping.getCL(this.getConsistencyLevel()));
return batch;
}
@Override
public MutationBatch withCaching(boolean condition) {
useCaching = condition;
return this;
}
}