package me.prettyprint.hector.api.mutation;

import me.prettyprint.hector.api.Serializer;
import me.prettyprint.hector.api.beans.HColumn;
import me.prettyprint.hector.api.beans.HSuperColumn;

/**
 * A Mutator inserts or deletes values from the cluster.
 * There are two main ways to use a mutator:
 * 1. Use the insert/delete methods to immediately insert of delete values.
 * or 2. Use the addInsertion/addDeletion methods to schedule batch operations and then execute()
 * all of them in batch.
 *
 * The class is not thread-safe.
 *
 * @author Ran Tavory
 */
public interface Mutator<K> {

  // Simple and immediate insertion of a column
  <N, V> MutationResult insert(final K key, final String cf, final HColumn<N, V> c);

  // overloaded insert-super
  <SN, N, V> MutationResult insert(final K key, final String cf,
      final HSuperColumn<SN, N, V> superColumn);

  <N> MutationResult delete(final K key, final String cf, final N columnName,
      final Serializer<N> nameSerializer);

  /**
   * Deletes a subcolumn of a supercolumn
   * @param <SN> super column type
   * @param <N> subcolumn type
   */
  <SN, N> MutationResult subDelete(final K key, final String cf, final SN supercolumnName,
      final N columnName, final Serializer<SN> sNameSerializer, final Serializer<N> nameSerializer);

  // schedule an insertion to be executed in batch by the execute method
  // CAVEAT: a large number of calls with a typo in one of them will leave things in an
  // indeterminant state if we dont validate against LIVE (but cached of course)
  // keyspaces and CFs on each add/delete call
  // also, should throw a typed StatementValidationException or similar perhaps?
  <N, V> Mutator<K> addInsertion(K key, String cf, HColumn<N, V> c);

  /**
   * Schedule an insertion of a supercolumn to be inserted in batch mode by {@link #execute()}
   */
  <SN, N, V> Mutator<K> addInsertion(K key, String cf, HSuperColumn<SN, N, V> sc);

  /**
   * Adds a Deletion to the underlying batch_mutate call. The columnName argument can be null
   * in which case Deletion is created with only the Clock, in this case user defined,
   * resulting in the whole row being deleted.
   *
   * @param <N> column name type
   * @param key row key
   * @param cf column family
   * @param columnName column name. Use null to delete the whole row.
   * @param nameSerializer a name serializer
   * @return a mutator
   */
  <N> Mutator<K> addDeletion(K key, String cf, N columnName, Serializer<N> nameSerializer);

  /**
   * Adds a Deletion to the underlying batch_mutate call. The columnName argument can be null
   * in which case Deletion is created with only the Clock, in this case user defined,
   * resulting in the whole row being deleted.
   *
   * @param <N> column name type
   * @param key row key
   * @param cf column family
   * @param columnName column name. Use null to delete the whole row.
   * @param nameSerializer a name serializer
   * @param clock custom clock to use in the deletion
   * @return a mutator
   */
  <N> Mutator<K> addDeletion(K key, String cf, N columnName, Serializer<N> nameSerializer, long clock);

  
  <SN,N,V> Mutator<K> addSubDelete(K key, String cf, HSuperColumn<SN,N,V> sc);

  <SN,N,V> Mutator<K> addSubDelete(K key, String cf, HSuperColumn<SN,N,V> sc, long clock);
  
  
  /**
   * Batch executes all mutations scheduled to this Mutator instance by addInsertion, addDeletion etc.
   * May throw a HectorException which is a RuntimeException.
   * @return A MutationResult holds the status.
   */
  MutationResult execute();

  /**
   * Discards all pending mutations.
   */
  Mutator<K> discardPendingMutations();

}
@@ -976,32 +976,168 @@
 nameSerializer);
+%0A  %0A  %3CN%3E MutationResult delete(final K key, final String cf, final N columnName,%0A      final Serializer%3CN%3E nameSerializer, long clock);
 %0A%0A  /**%0A   * Del
@@ -1431,24 +1431,25 @@
 rializer);%0A%0A
+%0A
   // schedul

add overloaded version of delete for taking a clock