#
# Autogenerated by Thrift Compiler (0.8.0)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
#  options string: py
#

from thrift.Thrift import TType, TMessageType, TException

from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol, TProtocol
try:
  from thrift.protocol import fastbinary
except:
  fastbinary = None


class ConsistencyLevel:
  """
  The ConsistencyLevel is an enum that controls both read and write
  behavior based on the ReplicationFactor of the keyspace.  The
  different consistency levels have different meanings, depending on
  if you're doing a write or read operation.

  If W + R > ReplicationFactor, where W is the number of nodes to
  block for on write, and R the number to block for on reads, you
  will have strongly consistent behavior; that is, readers will
  always see the most recent write. Of these, the most interesting is
  to do QUORUM reads and writes, which gives you consistency while
  still allowing availability in the face of node failures up to half
  of <ReplicationFactor>. Of course if latency is more important than
  consistency then you can use lower values for either or both.

  Some ConsistencyLevels (ONE, TWO, THREE) refer to a specific number
  of replicas rather than a logical concept that adjusts
  automatically with the replication factor.  Of these, only ONE is
  commonly used; TWO and (even more rarely) THREE are only useful
  when you care more about guaranteeing a certain level of
  durability, than consistency.

  Write consistency levels make the following guarantees before reporting success to the client:
    ANY          Ensure that the write has been written once somewhere, including possibly being hinted in a non-target node.
    ONE          Ensure that the write has been written to at least 1 node's commit log and memory table
    TWO          Ensure that the write has been written to at least 2 node's commit log and memory table
    THREE        Ensure that the write has been written to at least 3 node's commit log and memory table
    QUORUM       Ensure that the write has been written to <ReplicationFactor> / 2 + 1 nodes
    LOCAL_QUORUM Ensure that the write has been written to <ReplicationFactor> / 2 + 1 nodes, within the local datacenter (requires NetworkTopologyStrategy)
    EACH_QUORUM  Ensure that the write has been written to <ReplicationFactor> / 2 + 1 nodes in each datacenter (requires NetworkTopologyStrategy)
    ALL          Ensure that the write is written to <code>&lt;ReplicationFactor&gt;</code> nodes before responding to the client.

  Read consistency levels make the following guarantees before returning successful results to the client:
    ANY          Not supported. You probably want ONE instead.
    ONE          Returns the record obtained from a single replica.
    TWO          Returns the record with the most recent timestamp once two replicas have replied.
    THREE        Returns the record with the most recent timestamp once three replicas have replied.
    QUORUM       Returns the record with the most recent timestamp once a majority of replicas have replied.
    LOCAL_QUORUM Returns the record with the most recent timestamp once a majority of replicas within the local datacenter have replied.
    EACH_QUORUM  Returns the record with the most recent timestamp once a majority of replicas within each datacenter have replied.
    ALL          Returns the record with the most recent timestamp once all replicas have replied (implies no replica may be down)..
  """
  ONE = 1
  QUORUM = 2
  LOCAL_QUORUM = 3
  EACH_QUORUM = 4
  ALL = 5
  ANY = 6
  TWO = 7
  THREE = 8

  _VALUES_TO_NAMES = {
    1: "ONE",
    2: "QUORUM",
    3: "LOCAL_QUORUM",
    4: "EACH_QUORUM",
    5: "ALL",
    6: "ANY",
    7: "TWO",
    8: "THREE",
  }

  _NAMES_TO_VALUES = {
    "ONE": 1,
    "QUORUM": 2,
    "LOCAL_QUORUM": 3,
    "EACH_QUORUM": 4,
    "ALL": 5,
    "ANY": 6,
    "TWO": 7,
    "THREE": 8,
  }

class IndexOperator:
  EQ = 0
  GTE = 1
  GT = 2
  LTE = 3
  LT = 4

  _VALUES_TO_NAMES = {
    0: "EQ",
    1: "GTE",
    2: "GT",
    3: "LTE",
    4: "LT",
  }

  _NAMES_TO_VALUES = {
    "EQ": 0,
    "GTE": 1,
    "GT": 2,
    "LTE": 3,
    "LT": 4,
  }

class IndexType:
  KEYS = 0
  CUSTOM = 1

  _VALUES_TO_NAMES = {
    0: "KEYS",
    1: "CUSTOM",
  }

  _NAMES_TO_VALUES = {
    "KEYS": 0,
    "CUSTOM": 1,
  }

class Compression:
  """
  CQL query compression
  """
  GZIP = 1
  NONE = 2

  _VALUES_TO_NAMES = {
    1: "GZIP",
    2: "NONE",
  }

  _NAMES_TO_VALUES = {
    "GZIP": 1,
    "NONE": 2,
  }

class CqlResultType:
  ROWS = 1
  VOID = 2
  INT = 3

  _VALUES_TO_NAMES = {
    1: "ROWS",
    2: "VOID",
    3: "INT",
  }

  _NAMES_TO_VALUES = {
    "ROWS": 1,
    "VOID": 2,
    "INT": 3,
  }


class Column:
  """
  Basic unit of data within a ColumnFamily.
  @param name, the name by which this column is set and retrieved.  Maximum 64KB long.
  @param value. The data associated with the name.  Maximum 2GB long, but in practice you should limit it to small numbers of MB (since Thrift must read the full value into memory to operate on it).
  @param timestamp. The timestamp is used for conflict detection/resolution when two columns with same name need to be compared.
  @param ttl. An optional, positive delay (in seconds) after which the column will be automatically deleted.

  Attributes:
   - name
   - value
   - timestamp
   - ttl
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.STRING, 'value', None, None, ), # 2
    (3, TType.I64, 'timestamp', None, None, ), # 3
    (4, TType.I32, 'ttl', None, None, ), # 4
  )

  def __init__(self, name=None, value=None, timestamp=None, ttl=None,):
    self.name = name
    self.value = value
    self.timestamp = timestamp
    self.ttl = ttl

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.value = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I64:
          self.timestamp = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.ttl = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('Column')
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name)
      oprot.writeFieldEnd()
    if self.value is not None:
      oprot.writeFieldBegin('value', TType.STRING, 2)
      oprot.writeString(self.value)
      oprot.writeFieldEnd()
    if self.timestamp is not None:
      oprot.writeFieldBegin('timestamp', TType.I64, 3)
      oprot.writeI64(self.timestamp)
      oprot.writeFieldEnd()
    if self.ttl is not None:
      oprot.writeFieldBegin('ttl', TType.I32, 4)
      oprot.writeI32(self.ttl)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class SuperColumn:
  """
  A named list of columns.
  @param name. see Column.name.
  @param columns. A collection of standard Columns.  The columns within a super column are defined in an adhoc manner.
                  Columns within a super column do not have to have matching structures (similarly named child columns).

  Attributes:
   - name
   - columns
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.LIST, 'columns', (TType.STRUCT,(Column, Column.thrift_spec)), None, ), # 2
  )

  def __init__(self, name=None, columns=None,):
    self.name = name
    self.columns = columns

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.columns = []
          (_etype3, _size0) = iprot.readListBegin()
          for _i4 in range(_size0):
            _elem5 = Column()
            _elem5.read(iprot)
            self.columns.append(_elem5)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('SuperColumn')
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name)
      oprot.writeFieldEnd()
    if self.columns is not None:
      oprot.writeFieldBegin('columns', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.columns))
      for iter6 in self.columns:
        iter6.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    if self.columns is None:
      raise TProtocol.TProtocolException(message='Required field columns is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class CounterColumn:
  """
  Attributes:
   - name
   - value
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.I64, 'value', None, None, ), # 2
  )

  def __init__(self, name=None, value=None,):
    self.name = name
    self.value = value

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.value = iprot.readI64();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('CounterColumn')
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name)
      oprot.writeFieldEnd()
    if self.value is not None:
      oprot.writeFieldBegin('value', TType.I64, 2)
      oprot.writeI64(self.value)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    if self.value is None:
      raise TProtocol.TProtocolException(message='Required field value is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class CounterSuperColumn:
  """
  Attributes:
   - name
   - columns
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.LIST, 'columns', (TType.STRUCT,(CounterColumn, CounterColumn.thrift_spec)), None, ), # 2
  )

  def __init__(self, name=None, columns=None,):
    self.name = name
    self.columns = columns

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.columns = []
          (_etype10, _size7) = iprot.readListBegin()
          for _i11 in range(_size7):
            _elem12 = CounterColumn()
            _elem12.read(iprot)
            self.columns.append(_elem12)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('CounterSuperColumn')
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name)
      oprot.writeFieldEnd()
    if self.columns is not None:
      oprot.writeFieldBegin('columns', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.columns))
      for iter13 in self.columns:
        iter13.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    if self.columns is None:
      raise TProtocol.TProtocolException(message='Required field columns is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class ColumnOrSuperColumn:
  """
  Methods for fetching rows/records from Cassandra will return either a single instance of ColumnOrSuperColumn or a list
  of ColumnOrSuperColumns (get_slice()). If you're looking up a SuperColumn (or list of SuperColumns) then the resulting
  instances of ColumnOrSuperColumn will have the requested SuperColumn in the attribute super_column. For queries resulting
  in Columns, those values will be in the attribute column. This change was made between 0.3 and 0.4 to standardize on
  single query methods that may return either a SuperColumn or Column.

  If the query was on a counter column family, you will either get a counter_column (instead of a column) or a
  counter_super_column (instead of a super_column)

  @param column. The Column returned by get() or get_slice().
  @param super_column. The SuperColumn returned by get() or get_slice().
  @param counter_column. The Counterolumn returned by get() or get_slice().
  @param counter_super_column. The CounterSuperColumn returned by get() or get_slice().

  Attributes:
   - column
   - super_column
   - counter_column
   - counter_super_column
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'column', (Column, Column.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'super_column', (SuperColumn, SuperColumn.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'counter_column', (CounterColumn, CounterColumn.thrift_spec), None, ), # 3
    (4, TType.STRUCT, 'counter_super_column', (CounterSuperColumn, CounterSuperColumn.thrift_spec), None, ), # 4
  )

  def __init__(self, column=None, super_column=None, counter_column=None, counter_super_column=None,):
    self.column = column
    self.super_column = super_column
    self.counter_column = counter_column
    self.counter_super_column = counter_super_column

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.column = Column()
          self.column.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.super_column = SuperColumn()
          self.super_column.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.counter_column = CounterColumn()
          self.counter_column.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.counter_super_column = CounterSuperColumn()
          self.counter_super_column.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('ColumnOrSuperColumn')
    if self.column is not None:
      oprot.writeFieldBegin('column', TType.STRUCT, 1)
      self.column.write(oprot)
      oprot.writeFieldEnd()
    if self.super_column is not None:
      oprot.writeFieldBegin('super_column', TType.STRUCT, 2)
      self.super_column.write(oprot)
      oprot.writeFieldEnd()
    if self.counter_column is not None:
      oprot.writeFieldBegin('counter_column', TType.STRUCT, 3)
      self.counter_column.write(oprot)
      oprot.writeFieldEnd()
    if self.counter_super_column is not None:
      oprot.writeFieldBegin('counter_super_column', TType.STRUCT, 4)
      self.counter_super_column.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class NotFoundException(TException):
  """
  A specific column was requested that does not exist.
  """

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('NotFoundException')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class InvalidRequestException(TException):
  """
  Invalid request could mean keyspace or column family does not exist, required parameters are missing, or a parameter is malformed.
  why contains an associated error message.

  Attributes:
   - why
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'why', None, None, ), # 1
  )

  def __init__(self, why=None,):
    self.why = why

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.why = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('InvalidRequestException')
    if self.why is not None:
      oprot.writeFieldBegin('why', TType.STRING, 1)
      oprot.writeString(self.why)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.why is None:
      raise TProtocol.TProtocolException(message='Required field why is unset!')
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class UnavailableException(TException):
  """
  Not all the replicas required could be created and/or read.
  """

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('UnavailableException')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class TimedOutException(TException):
  """
  RPC timeout was exceeded.  either a node failed mid-operation, or load was too high, or the requested op was too large.
  """

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('TimedOutException')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class AuthenticationException(TException):
  """
  invalid authentication request (invalid keyspace, user does not exist, or credentials invalid)

  Attributes:
   - why
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'why', None, None, ), # 1
  )

  def __init__(self, why=None,):
    self.why = why

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.why = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('AuthenticationException')
    if self.why is not None:
      oprot.writeFieldBegin('why', TType.STRING, 1)
      oprot.writeString(self.why)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.why is None:
      raise TProtocol.TProtocolException(message='Required field why is unset!')
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class AuthorizationException(TException):
  """
  invalid authorization request (user does not have access to keyspace)

  Attributes:
   - why
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'why', None, None, ), # 1
  )

  def __init__(self, why=None,):
    self.why = why

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.why = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('AuthorizationException')
    if self.why is not None:
      oprot.writeFieldBegin('why', TType.STRING, 1)
      oprot.writeString(self.why)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.why is None:
      raise TProtocol.TProtocolException(message='Required field why is unset!')
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class SchemaDisagreementException(TException):
  """
  schemas are not in agreement across all nodes
  """

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('SchemaDisagreementException')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class ColumnParent:
  """
  ColumnParent is used when selecting groups of columns from the same ColumnFamily. In directory structure terms, imagine
  ColumnParent as ColumnPath + '/../'.

  See also <a href="cassandra.html#Struct_ColumnPath">ColumnPath</a>

  Attributes:
   - column_family
   - super_column
  """

  thrift_spec = (
    None, # 0
    None, # 1
    None, # 2
    (3, TType.STRING, 'column_family', None, None, ), # 3
    (4, TType.STRING, 'super_column', None, None, ), # 4
  )

  def __init__(self, column_family=None, super_column=None,):
    self.column_family = column_family
    self.super_column = super_column

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 3:
        if ftype == TType.STRING:
          self.column_family = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.super_column = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('ColumnParent')
    if self.column_family is not None:
      oprot.writeFieldBegin('column_family', TType.STRING, 3)
      oprot.writeString(self.column_family)
      oprot.writeFieldEnd()
    if self.super_column is not None:
      oprot.writeFieldBegin('super_column', TType.STRING, 4)
      oprot.writeString(self.super_column)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.column_family is None:
      raise TProtocol.TProtocolException(message='Required field column_family is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class ColumnPath:
  """
  The ColumnPath is the path to a single column in Cassandra. It might make sense to think of ColumnPath and
  ColumnParent in terms of a directory structure.

  ColumnPath is used to looking up a single column.

  @param column_family. The name of the CF of the column being looked up.
  @param super_column. The super column name.
  @param column. The column name.

  Attributes:
   - column_family
   - super_column
   - column
  """

  thrift_spec = (
    None, # 0
    None, # 1
    None, # 2
    (3, TType.STRING, 'column_family', None, None, ), # 3
    (4, TType.STRING, 'super_column', None, None, ), # 4
    (5, TType.STRING, 'column', None, None, ), # 5
  )

  def __init__(self, column_family=None, super_column=None, column=None,):
    self.column_family = column_family
    self.super_column = super_column
    self.column = column

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 3:
        if ftype == TType.STRING:
          self.column_family = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.super_column = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.STRING:
          self.column = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('ColumnPath')
    if self.column_family is not None:
      oprot.writeFieldBegin('column_family', TType.STRING, 3)
      oprot.writeString(self.column_family)
      oprot.writeFieldEnd()
    if self.super_column is not None:
      oprot.writeFieldBegin('super_column', TType.STRING, 4)
      oprot.writeString(self.super_column)
      oprot.writeFieldEnd()
    if self.column is not None:
      oprot.writeFieldBegin('column', TType.STRING, 5)
      oprot.writeString(self.column)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.column_family is None:
      raise TProtocol.TProtocolException(message='Required field column_family is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class SliceRange:
  """
  A slice range is a structure that stores basic range, ordering and limit information for a query that will return
  multiple columns. It could be thought of as Cassandra's version of LIMIT and ORDER BY

  @param start. The column name to start the slice with. This attribute is not required, though there is no default value,
                and can be safely set to '', i.e., an empty byte array, to start with the first column name. Otherwise, it
                must a valid value under the rules of the Comparator defined for the given ColumnFamily.
  @param finish. The column name to stop the slice at. This attribute is not required, though there is no default value,
                 and can be safely set to an empty byte array to not stop until 'count' results are seen. Otherwise, it
                 must also be a valid value to the ColumnFamily Comparator.
  @param reversed. Whether the results should be ordered in reversed order. Similar to ORDER BY blah DESC in SQL.
  @param count. How many columns to return. Similar to LIMIT in SQL. May be arbitrarily large, but Thrift will
                materialize the whole result into memory before returning it to the client, so be aware that you may
                be better served by iterating through slices by passing the last value of one call in as the 'start'
                of the next instead of increasing 'count' arbitrarily large.

  Attributes:
   - start
   - finish
   - reversed
   - count
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'start', None, None, ), # 1
    (2, TType.STRING, 'finish', None, None, ), # 2
    (3, TType.BOOL, 'reversed', None, False, ), # 3
    (4, TType.I32, 'count', None, 100, ), # 4
  )

  def __init__(self, start=None, finish=None, reversed=thrift_spec[3][4], count=thrift_spec[4][4],):
    self.start = start
    self.finish = finish
    self.reversed = reversed
    self.count = count

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.start = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.finish = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.BOOL:
          self.reversed = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.count = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('SliceRange')
    if self.start is not None:
      oprot.writeFieldBegin('start', TType.STRING, 1)
      oprot.writeString(self.start)
      oprot.writeFieldEnd()
    if self.finish is not None:
      oprot.writeFieldBegin('finish', TType.STRING, 2)
      oprot.writeString(self.finish)
      oprot.writeFieldEnd()
    if self.reversed is not None:
      oprot.writeFieldBegin('reversed', TType.BOOL, 3)
      oprot.writeBool(self.reversed)
      oprot.writeFieldEnd()
    if self.count is not None:
      oprot.writeFieldBegin('count', TType.I32, 4)
      oprot.writeI32(self.count)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.start is None:
      raise TProtocol.TProtocolException(message='Required field start is unset!')
    if self.finish is None:
      raise TProtocol.TProtocolException(message='Required field finish is unset!')
    if self.reversed is None:
      raise TProtocol.TProtocolException(message='Required field reversed is unset!')
    if self.count is None:
      raise TProtocol.TProtocolException(message='Required field count is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class SlicePredicate:
  """
  A SlicePredicate is similar to a mathematic predicate (see http://en.wikipedia.org/wiki/Predicate_(mathematical_logic)),
  which is described as "a property that the elements of a set have in common."

  SlicePredicate's in Cassandra are described with either a list of column_names or a SliceRange.  If column_names is
  specified, slice_range is ignored.

  @param column_name. A list of column names to retrieve. This can be used similar to Memcached's "multi-get" feature
                      to fetch N known column names. For instance, if you know you wish to fetch columns 'Joe', 'Jack',
                      and 'Jim' you can pass those column names as a list to fetch all three at once.
  @param slice_range. A SliceRange describing how to range, order, and/or limit the slice.

  Attributes:
   - column_names
   - slice_range
  """

  thrift_spec = (
    None, # 0
    (1, TType.LIST, 'column_names', (TType.STRING,None), None, ), # 1
    (2, TType.STRUCT, 'slice_range', (SliceRange, SliceRange.thrift_spec), None, ), # 2
  )

  def __init__(self, column_names=None, slice_range=None,):
    self.column_names = column_names
    self.slice_range = slice_range

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.LIST:
          self.column_names = []
          (_etype17, _size14) = iprot.readListBegin()
          for _i18 in range(_size14):
            _elem19 = iprot.readString();
            self.column_names.append(_elem19)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.slice_range = SliceRange()
          self.slice_range.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('SlicePredicate')
    if self.column_names is not None:
      oprot.writeFieldBegin('column_names', TType.LIST, 1)
      oprot.writeListBegin(TType.STRING, len(self.column_names))
      for iter20 in self.column_names:
        oprot.writeString(iter20)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.slice_range is not None:
      oprot.writeFieldBegin('slice_range', TType.STRUCT, 2)
      self.slice_range.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class IndexExpression:
  """
  Attributes:
   - column_name
   - op
   - value
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'column_name', None, None, ), # 1
    (2, TType.I32, 'op', None, None, ), # 2
    (3, TType.STRING, 'value', None, None, ), # 3
  )

  def __init__(self, column_name=None, op=None, value=None,):
    self.column_name = column_name
    self.op = op
    self.value = value

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.column_name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.op = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.value = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('IndexExpression')
    if self.column_name is not None:
      oprot.writeFieldBegin('column_name', TType.STRING, 1)
      oprot.writeString(self.column_name)
      oprot.writeFieldEnd()
    if self.op is not None:
      oprot.writeFieldBegin('op', TType.I32, 2)
      oprot.writeI32(self.op)
      oprot.writeFieldEnd()
    if self.value is not None:
      oprot.writeFieldBegin('value', TType.STRING, 3)
      oprot.writeString(self.value)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.column_name is None:
      raise TProtocol.TProtocolException(message='Required field column_name is unset!')
    if self.op is None:
      raise TProtocol.TProtocolException(message='Required field op is unset!')
    if self.value is None:
      raise TProtocol.TProtocolException(message='Required field value is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class IndexClause:
  """
  @Deprecated: use a KeyRange with row_filter in get_range_slices instead

  Attributes:
   - expressions
   - start_key
   - count
  """

  thrift_spec = (
    None, # 0
    (1, TType.LIST, 'expressions', (TType.STRUCT,(IndexExpression, IndexExpression.thrift_spec)), None, ), # 1
    (2, TType.STRING, 'start_key', None, None, ), # 2
    (3, TType.I32, 'count', None, 100, ), # 3
  )

  def __init__(self, expressions=None, start_key=None, count=thrift_spec[3][4],):
    self.expressions = expressions
    self.start_key = start_key
    self.count = count

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.LIST:
          self.expressions = []
          (_etype24, _size21) = iprot.readListBegin()
          for _i25 in range(_size21):
            _elem26 = IndexExpression()
            _elem26.read(iprot)
            self.expressions.append(_elem26)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.start_key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.count = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('IndexClause')
    if self.expressions is not None:
      oprot.writeFieldBegin('expressions', TType.LIST, 1)
      oprot.writeListBegin(TType.STRUCT, len(self.expressions))
      for iter27 in self.expressions:
        iter27.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.start_key is not None:
      oprot.writeFieldBegin('start_key', TType.STRING, 2)
      oprot.writeString(self.start_key)
      oprot.writeFieldEnd()
    if self.count is not None:
      oprot.writeFieldBegin('count', TType.I32, 3)
      oprot.writeI32(self.count)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.expressions is None:
      raise TProtocol.TProtocolException(message='Required field expressions is unset!')
    if self.start_key is None:
      raise TProtocol.TProtocolException(message='Required field start_key is unset!')
    if self.count is None:
      raise TProtocol.TProtocolException(message='Required field count is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class KeyRange:
  """
  The semantics of start keys and tokens are slightly different.
  Keys are start-inclusive; tokens are start-exclusive.  Token
  ranges may also wrap -- that is, the end token may be less
  than the start one.  Thus, a range from keyX to keyX is a
  one-element range, but a range from tokenY to tokenY is the
  full ring.

  Attributes:
   - start_key
   - end_key
   - start_token
   - end_token
   - row_filter
   - count
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'start_key', None, None, ), # 1
    (2, TType.STRING, 'end_key', None, None, ), # 2
    (3, TType.STRING, 'start_token', None, None, ), # 3
    (4, TType.STRING, 'end_token', None, None, ), # 4
    (5, TType.I32, 'count', None, 100, ), # 5
    (6, TType.LIST, 'row_filter', (TType.STRUCT,(IndexExpression, IndexExpression.thrift_spec)), None, ), # 6
  )

  def __init__(self, start_key=None, end_key=None, start_token=None, end_token=None, row_filter=None, count=thrift_spec[5][4],):
    self.start_key = start_key
    self.end_key = end_key
    self.start_token = start_token
    self.end_token = end_token
    self.row_filter = row_filter
    self.count = count

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.start_key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.end_key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.start_token = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.end_token = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.LIST:
          self.row_filter = []
          (_etype31, _size28) = iprot.readListBegin()
          for _i32 in range(_size28):
            _elem33 = IndexExpression()
            _elem33.read(iprot)
            self.row_filter.append(_elem33)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.count = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('KeyRange')
    if self.start_key is not None:
      oprot.writeFieldBegin('start_key', TType.STRING, 1)
      oprot.writeString(self.start_key)
      oprot.writeFieldEnd()
    if self.end_key is not None:
      oprot.writeFieldBegin('end_key', TType.STRING, 2)
      oprot.writeString(self.end_key)
      oprot.writeFieldEnd()
    if self.start_token is not None:
      oprot.writeFieldBegin('start_token', TType.STRING, 3)
      oprot.writeString(self.start_token)
      oprot.writeFieldEnd()
    if self.end_token is not None:
      oprot.writeFieldBegin('end_token', TType.STRING, 4)
      oprot.writeString(self.end_token)
      oprot.writeFieldEnd()
    if self.count is not None:
      oprot.writeFieldBegin('count', TType.I32, 5)
      oprot.writeI32(self.count)
      oprot.writeFieldEnd()
    if self.row_filter is not None:
      oprot.writeFieldBegin('row_filter', TType.LIST, 6)
      oprot.writeListBegin(TType.STRUCT, len(self.row_filter))
      for iter34 in self.row_filter:
        iter34.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.count is None:
      raise TProtocol.TProtocolException(message='Required field count is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class KeySlice:
  """
  A KeySlice is key followed by the data it maps to. A collection of KeySlice is returned by the get_range_slice operation.

  @param key. a row key
  @param columns. List of data represented by the key. Typically, the list is pared down to only the columns specified by
                  a SlicePredicate.

  Attributes:
   - key
   - columns
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.LIST, 'columns', (TType.STRUCT,(ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec)), None, ), # 2
  )

  def __init__(self, key=None, columns=None,):
    self.key = key
    self.columns = columns

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.columns = []
          (_etype38, _size35) = iprot.readListBegin()
          for _i39 in range(_size35):
            _elem40 = ColumnOrSuperColumn()
            _elem40.read(iprot)
            self.columns.append(_elem40)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('KeySlice')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.columns is not None:
      oprot.writeFieldBegin('columns', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.columns))
      for iter41 in self.columns:
        iter41.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.columns is None:
      raise TProtocol.TProtocolException(message='Required field columns is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class KeyCount:
  """
  Attributes:
   - key
   - count
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.I32, 'count', None, None, ), # 2
  )

  def __init__(self, key=None, count=None,):
    self.key = key
    self.count = count

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.count = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('KeyCount')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.count is not None:
      oprot.writeFieldBegin('count', TType.I32, 2)
      oprot.writeI32(self.count)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.count is None:
      raise TProtocol.TProtocolException(message='Required field count is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class Deletion:
  """
  Note that the timestamp is only optional in case of counter deletion.

  Attributes:
   - timestamp
   - super_column
   - predicate
  """

  thrift_spec = (
    None, # 0
    (1, TType.I64, 'timestamp', None, None, ), # 1
    (2, TType.STRING, 'super_column', None, None, ), # 2
    (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ), # 3
  )

  def __init__(self, timestamp=None, super_column=None, predicate=None,):
    self.timestamp = timestamp
    self.super_column = super_column
    self.predicate = predicate

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.I64:
          self.timestamp = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.super_column = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.predicate = SlicePredicate()
          self.predicate.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('Deletion')
    if self.timestamp is not None:
      oprot.writeFieldBegin('timestamp', TType.I64, 1)
      oprot.writeI64(self.timestamp)
      oprot.writeFieldEnd()
    if self.super_column is not None:
      oprot.writeFieldBegin('super_column', TType.STRING, 2)
      oprot.writeString(self.super_column)
      oprot.writeFieldEnd()
    if self.predicate is not None:
      oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
      self.predicate.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class Mutation:
  """
  A Mutation is either an insert (represented by filling column_or_supercolumn) or a deletion (represented by filling the deletion attribute).
  @param column_or_supercolumn. An insert to a column or supercolumn (possibly counter column or supercolumn)
  @param deletion. A deletion of a column or supercolumn

  Attributes:
   - column_or_supercolumn
   - deletion
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'column_or_supercolumn', (ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'deletion', (Deletion, Deletion.thrift_spec), None, ), # 2
  )

  def __init__(self, column_or_supercolumn=None, deletion=None,):
    self.column_or_supercolumn = column_or_supercolumn
    self.deletion = deletion

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.column_or_supercolumn = ColumnOrSuperColumn()
          self.column_or_supercolumn.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.deletion = Deletion()
          self.deletion.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('Mutation')
    if self.column_or_supercolumn is not None:
      oprot.writeFieldBegin('column_or_supercolumn', TType.STRUCT, 1)
      self.column_or_supercolumn.write(oprot)
      oprot.writeFieldEnd()
    if self.deletion is not None:
      oprot.writeFieldBegin('deletion', TType.STRUCT, 2)
      self.deletion.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class EndpointDetails:
  """
  Attributes:
   - host
   - datacenter
   - rack
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'host', None, None, ), # 1
    (2, TType.STRING, 'datacenter', None, None, ), # 2
    (3, TType.STRING, 'rack', None, None, ), # 3
  )

  def __init__(self, host=None, datacenter=None, rack=None,):
    self.host = host
    self.datacenter = datacenter
    self.rack = rack

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.host = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.datacenter = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.rack = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('EndpointDetails')
    if self.host is not None:
      oprot.writeFieldBegin('host', TType.STRING, 1)
      oprot.writeString(self.host)
      oprot.writeFieldEnd()
    if self.datacenter is not None:
      oprot.writeFieldBegin('datacenter', TType.STRING, 2)
      oprot.writeString(self.datacenter)
      oprot.writeFieldEnd()
    if self.rack is not None:
      oprot.writeFieldBegin('rack', TType.STRING, 3)
      oprot.writeString(self.rack)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class TokenRange:
  """
  A TokenRange describes part of the Cassandra ring, it is a mapping from a range to
  endpoints responsible for that range.
  @param start_token The first token in the range
  @param end_token The last token in the range
  @param endpoints The endpoints responsible for the range (listed by their configured listen_address)
  @param rpc_endpoints The endpoints responsible for the range (listed by their configured rpc_address)

  Attributes:
   - start_token
   - end_token
   - endpoints
   - rpc_endpoints
   - endpoint_details
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'start_token', None, None, ), # 1
    (2, TType.STRING, 'end_token', None, None, ), # 2
    (3, TType.LIST, 'endpoints', (TType.STRING,None), None, ), # 3
    (4, TType.LIST, 'rpc_endpoints', (TType.STRING,None), None, ), # 4
    (5, TType.LIST, 'endpoint_details', (TType.STRUCT,(EndpointDetails, EndpointDetails.thrift_spec)), None, ), # 5
  )

  def __init__(self, start_token=None, end_token=None, endpoints=None, rpc_endpoints=None, endpoint_details=None,):
    self.start_token = start_token
    self.end_token = end_token
    self.endpoints = endpoints
    self.rpc_endpoints = rpc_endpoints
    self.endpoint_details = endpoint_details

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.start_token = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.end_token = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.LIST:
          self.endpoints = []
          (_etype45, _size42) = iprot.readListBegin()
          for _i46 in range(_size42):
            _elem47 = iprot.readString();
            self.endpoints.append(_elem47)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.LIST:
          self.rpc_endpoints = []
          (_etype51, _size48) = iprot.readListBegin()
          for _i52 in range(_size48):
            _elem53 = iprot.readString();
            self.rpc_endpoints.append(_elem53)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.LIST:
          self.endpoint_details = []
          (_etype57, _size54) = iprot.readListBegin()
          for _i58 in range(_size54):
            _elem59 = EndpointDetails()
            _elem59.read(iprot)
            self.endpoint_details.append(_elem59)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('TokenRange')
    if self.start_token is not None:
      oprot.writeFieldBegin('start_token', TType.STRING, 1)
      oprot.writeString(self.start_token)
      oprot.writeFieldEnd()
    if self.end_token is not None:
      oprot.writeFieldBegin('end_token', TType.STRING, 2)
      oprot.writeString(self.end_token)
      oprot.writeFieldEnd()
    if self.endpoints is not None:
      oprot.writeFieldBegin('endpoints', TType.LIST, 3)
      oprot.writeListBegin(TType.STRING, len(self.endpoints))
      for iter60 in self.endpoints:
        oprot.writeString(iter60)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.rpc_endpoints is not None:
      oprot.writeFieldBegin('rpc_endpoints', TType.LIST, 4)
      oprot.writeListBegin(TType.STRING, len(self.rpc_endpoints))
      for iter61 in self.rpc_endpoints:
        oprot.writeString(iter61)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.endpoint_details is not None:
      oprot.writeFieldBegin('endpoint_details', TType.LIST, 5)
      oprot.writeListBegin(TType.STRUCT, len(self.endpoint_details))
      for iter62 in self.endpoint_details:
        iter62.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.start_token is None:
      raise TProtocol.TProtocolException(message='Required field start_token is unset!')
    if self.end_token is None:
      raise TProtocol.TProtocolException(message='Required field end_token is unset!')
    if self.endpoints is None:
      raise TProtocol.TProtocolException(message='Required field endpoints is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class AuthenticationRequest:
  """
  Authentication requests can contain any data, dependent on the IAuthenticator used

  Attributes:
   - credentials
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'credentials', (TType.STRING,None,TType.STRING,None), None, ), # 1
  )

  def __init__(self, credentials=None,):
    self.credentials = credentials

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.MAP:
          self.credentials = {}
          (_ktype64, _vtype65, _size63 ) = iprot.readMapBegin() 
          for _i67 in range(_size63):
            _key68 = iprot.readString();
            _val69 = iprot.readString();
            self.credentials[_key68] = _val69
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('AuthenticationRequest')
    if self.credentials is not None:
      oprot.writeFieldBegin('credentials', TType.MAP, 1)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.credentials))
      for kiter70,viter71 in list(self.credentials.items()):
        oprot.writeString(kiter70)
        oprot.writeString(viter71)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.credentials is None:
      raise TProtocol.TProtocolException(message='Required field credentials is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class ColumnDef:
  """
  Attributes:
   - name
   - validation_class
   - index_type
   - index_name
   - index_options
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.STRING, 'validation_class', None, None, ), # 2
    (3, TType.I32, 'index_type', None, None, ), # 3
    (4, TType.STRING, 'index_name', None, None, ), # 4
    (5, TType.MAP, 'index_options', (TType.STRING,None,TType.STRING,None), None, ), # 5
  )

  def __init__(self, name=None, validation_class=None, index_type=None, index_name=None, index_options=None,):
    self.name = name
    self.validation_class = validation_class
    self.index_type = index_type
    self.index_name = index_name
    self.index_options = index_options

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.validation_class = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.index_type = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.index_name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.MAP:
          self.index_options = {}
          (_ktype73, _vtype74, _size72 ) = iprot.readMapBegin() 
          for _i76 in range(_size72):
            _key77 = iprot.readString();
            _val78 = iprot.readString();
            self.index_options[_key77] = _val78
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('ColumnDef')
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name)
      oprot.writeFieldEnd()
    if self.validation_class is not None:
      oprot.writeFieldBegin('validation_class', TType.STRING, 2)
      oprot.writeString(self.validation_class)
      oprot.writeFieldEnd()
    if self.index_type is not None:
      oprot.writeFieldBegin('index_type', TType.I32, 3)
      oprot.writeI32(self.index_type)
      oprot.writeFieldEnd()
    if self.index_name is not None:
      oprot.writeFieldBegin('index_name', TType.STRING, 4)
      oprot.writeString(self.index_name)
      oprot.writeFieldEnd()
    if self.index_options is not None:
      oprot.writeFieldBegin('index_options', TType.MAP, 5)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.index_options))
      for kiter79,viter80 in list(self.index_options.items()):
        oprot.writeString(kiter79)
        oprot.writeString(viter80)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    if self.validation_class is None:
      raise TProtocol.TProtocolException(message='Required field validation_class is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class CfDef:
  """
  Attributes:
   - keyspace
   - name
   - column_type
   - comparator_type
   - subcomparator_type
   - comment
   - read_repair_chance
   - column_metadata
   - gc_grace_seconds
   - default_validation_class
   - id
   - min_compaction_threshold
   - max_compaction_threshold
   - replicate_on_write
   - key_validation_class
   - key_alias
   - compaction_strategy
   - compaction_strategy_options
   - compression_options
   - bloom_filter_fp_chance
   - caching
   - column_aliases
   - value_alias
   - dclocal_read_repair_chance
   - row_cache_size: @deprecated
   - key_cache_size: @deprecated
   - row_cache_save_period_in_seconds: @deprecated
   - key_cache_save_period_in_seconds: @deprecated
   - memtable_flush_after_mins: @deprecated
   - memtable_throughput_in_mb: @deprecated
   - memtable_operations_in_millions: @deprecated
   - merge_shards_chance: @deprecated
   - row_cache_provider: @deprecated
   - row_cache_keys_to_save: @deprecated
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'keyspace', None, None, ), # 1
    (2, TType.STRING, 'name', None, None, ), # 2
    (3, TType.STRING, 'column_type', None, "Standard", ), # 3
    None, # 4
    (5, TType.STRING, 'comparator_type', None, "BytesType", ), # 5
    (6, TType.STRING, 'subcomparator_type', None, None, ), # 6
    None, # 7
    (8, TType.STRING, 'comment', None, None, ), # 8
    (9, TType.DOUBLE, 'row_cache_size', None, None, ), # 9
    None, # 10
    (11, TType.DOUBLE, 'key_cache_size', None, None, ), # 11
    (12, TType.DOUBLE, 'read_repair_chance', None, None, ), # 12
    (13, TType.LIST, 'column_metadata', (TType.STRUCT,(ColumnDef, ColumnDef.thrift_spec)), None, ), # 13
    (14, TType.I32, 'gc_grace_seconds', None, None, ), # 14
    (15, TType.STRING, 'default_validation_class', None, None, ), # 15
    (16, TType.I32, 'id', None, None, ), # 16
    (17, TType.I32, 'min_compaction_threshold', None, None, ), # 17
    (18, TType.I32, 'max_compaction_threshold', None, None, ), # 18
    (19, TType.I32, 'row_cache_save_period_in_seconds', None, None, ), # 19
    (20, TType.I32, 'key_cache_save_period_in_seconds', None, None, ), # 20
    (21, TType.I32, 'memtable_flush_after_mins', None, None, ), # 21
    (22, TType.I32, 'memtable_throughput_in_mb', None, None, ), # 22
    (23, TType.DOUBLE, 'memtable_operations_in_millions', None, None, ), # 23
    (24, TType.BOOL, 'replicate_on_write', None, None, ), # 24
    (25, TType.DOUBLE, 'merge_shards_chance', None, None, ), # 25
    (26, TType.STRING, 'key_validation_class', None, None, ), # 26
    (27, TType.STRING, 'row_cache_provider', None, None, ), # 27
    (28, TType.STRING, 'key_alias', None, None, ), # 28
    (29, TType.STRING, 'compaction_strategy', None, None, ), # 29
    (30, TType.MAP, 'compaction_strategy_options', (TType.STRING,None,TType.STRING,None), None, ), # 30
    (31, TType.I32, 'row_cache_keys_to_save', None, None, ), # 31
    (32, TType.MAP, 'compression_options', (TType.STRING,None,TType.STRING,None), None, ), # 32
    (33, TType.DOUBLE, 'bloom_filter_fp_chance', None, None, ), # 33
    (34, TType.STRING, 'caching', None, "keys_only", ), # 34
    (35, TType.LIST, 'column_aliases', (TType.STRING,None), None, ), # 35
    (36, TType.STRING, 'value_alias', None, None, ), # 36
    (37, TType.DOUBLE, 'dclocal_read_repair_chance', None, 0, ), # 37
  )

  def __init__(self, keyspace=None, name=None, column_type=thrift_spec[3][4], comparator_type=thrift_spec[5][4], subcomparator_type=None, comment=None, read_repair_chance=None, column_metadata=None, gc_grace_seconds=None, default_validation_class=None, id=None, min_compaction_threshold=None, max_compaction_threshold=None, replicate_on_write=None, key_validation_class=None, key_alias=None, compaction_strategy=None, compaction_strategy_options=None, compression_options=None, bloom_filter_fp_chance=None, caching=thrift_spec[34][4], column_aliases=None, value_alias=None, dclocal_read_repair_chance=thrift_spec[37][4], row_cache_size=None, key_cache_size=None, row_cache_save_period_in_seconds=None, key_cache_save_period_in_seconds=None, memtable_flush_after_mins=None, memtable_throughput_in_mb=None, memtable_operations_in_millions=None, merge_shards_chance=None, row_cache_provider=None, row_cache_keys_to_save=None,):
    self.keyspace = keyspace
    self.name = name
    self.column_type = column_type
    self.comparator_type = comparator_type
    self.subcomparator_type = subcomparator_type
    self.comment = comment
    self.read_repair_chance = read_repair_chance
    self.column_metadata = column_metadata
    self.gc_grace_seconds = gc_grace_seconds
    self.default_validation_class = default_validation_class
    self.id = id
    self.min_compaction_threshold = min_compaction_threshold
    self.max_compaction_threshold = max_compaction_threshold
    self.replicate_on_write = replicate_on_write
    self.key_validation_class = key_validation_class
    self.key_alias = key_alias
    self.compaction_strategy = compaction_strategy
    self.compaction_strategy_options = compaction_strategy_options
    self.compression_options = compression_options
    self.bloom_filter_fp_chance = bloom_filter_fp_chance
    self.caching = caching
    self.column_aliases = column_aliases
    self.value_alias = value_alias
    self.dclocal_read_repair_chance = dclocal_read_repair_chance
    self.row_cache_size = row_cache_size
    self.key_cache_size = key_cache_size
    self.row_cache_save_period_in_seconds = row_cache_save_period_in_seconds
    self.key_cache_save_period_in_seconds = key_cache_save_period_in_seconds
    self.memtable_flush_after_mins = memtable_flush_after_mins
    self.memtable_throughput_in_mb = memtable_throughput_in_mb
    self.memtable_operations_in_millions = memtable_operations_in_millions
    self.merge_shards_chance = merge_shards_chance
    self.row_cache_provider = row_cache_provider
    self.row_cache_keys_to_save = row_cache_keys_to_save

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.keyspace = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.column_type = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.STRING:
          self.comparator_type = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.STRING:
          self.subcomparator_type = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 8:
        if ftype == TType.STRING:
          self.comment = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 12:
        if ftype == TType.DOUBLE:
          self.read_repair_chance = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 13:
        if ftype == TType.LIST:
          self.column_metadata = []
          (_etype84, _size81) = iprot.readListBegin()
          for _i85 in range(_size81):
            _elem86 = ColumnDef()
            _elem86.read(iprot)
            self.column_metadata.append(_elem86)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 14:
        if ftype == TType.I32:
          self.gc_grace_seconds = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 15:
        if ftype == TType.STRING:
          self.default_validation_class = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 16:
        if ftype == TType.I32:
          self.id = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 17:
        if ftype == TType.I32:
          self.min_compaction_threshold = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 18:
        if ftype == TType.I32:
          self.max_compaction_threshold = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 24:
        if ftype == TType.BOOL:
          self.replicate_on_write = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 26:
        if ftype == TType.STRING:
          self.key_validation_class = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 28:
        if ftype == TType.STRING:
          self.key_alias = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 29:
        if ftype == TType.STRING:
          self.compaction_strategy = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 30:
        if ftype == TType.MAP:
          self.compaction_strategy_options = {}
          (_ktype88, _vtype89, _size87 ) = iprot.readMapBegin() 
          for _i91 in range(_size87):
            _key92 = iprot.readString();
            _val93 = iprot.readString();
            self.compaction_strategy_options[_key92] = _val93
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 32:
        if ftype == TType.MAP:
          self.compression_options = {}
          (_ktype95, _vtype96, _size94 ) = iprot.readMapBegin() 
          for _i98 in range(_size94):
            _key99 = iprot.readString();
            _val100 = iprot.readString();
            self.compression_options[_key99] = _val100
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 33:
        if ftype == TType.DOUBLE:
          self.bloom_filter_fp_chance = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 34:
        if ftype == TType.STRING:
          self.caching = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 35:
        if ftype == TType.LIST:
          self.column_aliases = []
          (_etype104, _size101) = iprot.readListBegin()
          for _i105 in range(_size101):
            _elem106 = iprot.readString();
            self.column_aliases.append(_elem106)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 36:
        if ftype == TType.STRING:
          self.value_alias = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 37:
        if ftype == TType.DOUBLE:
          self.dclocal_read_repair_chance = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 9:
        if ftype == TType.DOUBLE:
          self.row_cache_size = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 11:
        if ftype == TType.DOUBLE:
          self.key_cache_size = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 19:
        if ftype == TType.I32:
          self.row_cache_save_period_in_seconds = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 20:
        if ftype == TType.I32:
          self.key_cache_save_period_in_seconds = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 21:
        if ftype == TType.I32:
          self.memtable_flush_after_mins = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 22:
        if ftype == TType.I32:
          self.memtable_throughput_in_mb = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 23:
        if ftype == TType.DOUBLE:
          self.memtable_operations_in_millions = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 25:
        if ftype == TType.DOUBLE:
          self.merge_shards_chance = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 27:
        if ftype == TType.STRING:
          self.row_cache_provider = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 31:
        if ftype == TType.I32:
          self.row_cache_keys_to_save = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('CfDef')
    if self.keyspace is not None:
      oprot.writeFieldBegin('keyspace', TType.STRING, 1)
      oprot.writeString(self.keyspace)
      oprot.writeFieldEnd()
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 2)
      oprot.writeString(self.name)
      oprot.writeFieldEnd()
    if self.column_type is not None:
      oprot.writeFieldBegin('column_type', TType.STRING, 3)
      oprot.writeString(self.column_type)
      oprot.writeFieldEnd()
    if self.comparator_type is not None:
      oprot.writeFieldBegin('comparator_type', TType.STRING, 5)
      oprot.writeString(self.comparator_type)
      oprot.writeFieldEnd()
    if self.subcomparator_type is not None:
      oprot.writeFieldBegin('subcomparator_type', TType.STRING, 6)
      oprot.writeString(self.subcomparator_type)
      oprot.writeFieldEnd()
    if self.comment is not None:
      oprot.writeFieldBegin('comment', TType.STRING, 8)
      oprot.writeString(self.comment)
      oprot.writeFieldEnd()
    if self.row_cache_size is not None:
      oprot.writeFieldBegin('row_cache_size', TType.DOUBLE, 9)
      oprot.writeDouble(self.row_cache_size)
      oprot.writeFieldEnd()
    if self.key_cache_size is not None:
      oprot.writeFieldBegin('key_cache_size', TType.DOUBLE, 11)
      oprot.writeDouble(self.key_cache_size)
      oprot.writeFieldEnd()
    if self.read_repair_chance is not None:
      oprot.writeFieldBegin('read_repair_chance', TType.DOUBLE, 12)
      oprot.writeDouble(self.read_repair_chance)
      oprot.writeFieldEnd()
    if self.column_metadata is not None:
      oprot.writeFieldBegin('column_metadata', TType.LIST, 13)
      oprot.writeListBegin(TType.STRUCT, len(self.column_metadata))
      for iter107 in self.column_metadata:
        iter107.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.gc_grace_seconds is not None:
      oprot.writeFieldBegin('gc_grace_seconds', TType.I32, 14)
      oprot.writeI32(self.gc_grace_seconds)
      oprot.writeFieldEnd()
    if self.default_validation_class is not None:
      oprot.writeFieldBegin('default_validation_class', TType.STRING, 15)
      oprot.writeString(self.default_validation_class)
      oprot.writeFieldEnd()
    if self.id is not None:
      oprot.writeFieldBegin('id', TType.I32, 16)
      oprot.writeI32(self.id)
      oprot.writeFieldEnd()
    if self.min_compaction_threshold is not None:
      oprot.writeFieldBegin('min_compaction_threshold', TType.I32, 17)
      oprot.writeI32(self.min_compaction_threshold)
      oprot.writeFieldEnd()
    if self.max_compaction_threshold is not None:
      oprot.writeFieldBegin('max_compaction_threshold', TType.I32, 18)
      oprot.writeI32(self.max_compaction_threshold)
      oprot.writeFieldEnd()
    if self.row_cache_save_period_in_seconds is not None:
      oprot.writeFieldBegin('row_cache_save_period_in_seconds', TType.I32, 19)
      oprot.writeI32(self.row_cache_save_period_in_seconds)
      oprot.writeFieldEnd()
    if self.key_cache_save_period_in_seconds is not None:
      oprot.writeFieldBegin('key_cache_save_period_in_seconds', TType.I32, 20)
      oprot.writeI32(self.key_cache_save_period_in_seconds)
      oprot.writeFieldEnd()
    if self.memtable_flush_after_mins is not None:
      oprot.writeFieldBegin('memtable_flush_after_mins', TType.I32, 21)
      oprot.writeI32(self.memtable_flush_after_mins)
      oprot.writeFieldEnd()
    if self.memtable_throughput_in_mb is not None:
      oprot.writeFieldBegin('memtable_throughput_in_mb', TType.I32, 22)
      oprot.writeI32(self.memtable_throughput_in_mb)
      oprot.writeFieldEnd()
    if self.memtable_operations_in_millions is not None:
      oprot.writeFieldBegin('memtable_operations_in_millions', TType.DOUBLE, 23)
      oprot.writeDouble(self.memtable_operations_in_millions)
      oprot.writeFieldEnd()
    if self.replicate_on_write is not None:
      oprot.writeFieldBegin('replicate_on_write', TType.BOOL, 24)
      oprot.writeBool(self.replicate_on_write)
      oprot.writeFieldEnd()
    if self.merge_shards_chance is not None:
      oprot.writeFieldBegin('merge_shards_chance', TType.DOUBLE, 25)
      oprot.writeDouble(self.merge_shards_chance)
      oprot.writeFieldEnd()
    if self.key_validation_class is not None:
      oprot.writeFieldBegin('key_validation_class', TType.STRING, 26)
      oprot.writeString(self.key_validation_class)
      oprot.writeFieldEnd()
    if self.row_cache_provider is not None:
      oprot.writeFieldBegin('row_cache_provider', TType.STRING, 27)
      oprot.writeString(self.row_cache_provider)
      oprot.writeFieldEnd()
    if self.key_alias is not None:
      oprot.writeFieldBegin('key_alias', TType.STRING, 28)
      oprot.writeString(self.key_alias)
      oprot.writeFieldEnd()
    if self.compaction_strategy is not None:
      oprot.writeFieldBegin('compaction_strategy', TType.STRING, 29)
      oprot.writeString(self.compaction_strategy)
      oprot.writeFieldEnd()
    if self.compaction_strategy_options is not None:
      oprot.writeFieldBegin('compaction_strategy_options', TType.MAP, 30)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.compaction_strategy_options))
      for kiter108,viter109 in list(self.compaction_strategy_options.items()):
        oprot.writeString(kiter108)
        oprot.writeString(viter109)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.row_cache_keys_to_save is not None:
      oprot.writeFieldBegin('row_cache_keys_to_save', TType.I32, 31)
      oprot.writeI32(self.row_cache_keys_to_save)
      oprot.writeFieldEnd()
    if self.compression_options is not None:
      oprot.writeFieldBegin('compression_options', TType.MAP, 32)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.compression_options))
      for kiter110,viter111 in list(self.compression_options.items()):
        oprot.writeString(kiter110)
        oprot.writeString(viter111)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.bloom_filter_fp_chance is not None:
      oprot.writeFieldBegin('bloom_filter_fp_chance', TType.DOUBLE, 33)
      oprot.writeDouble(self.bloom_filter_fp_chance)
      oprot.writeFieldEnd()
    if self.caching is not None:
      oprot.writeFieldBegin('caching', TType.STRING, 34)
      oprot.writeString(self.caching)
      oprot.writeFieldEnd()
    if self.column_aliases is not None:
      oprot.writeFieldBegin('column_aliases', TType.LIST, 35)
      oprot.writeListBegin(TType.STRING, len(self.column_aliases))
      for iter112 in self.column_aliases:
        oprot.writeString(iter112)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.value_alias is not None:
      oprot.writeFieldBegin('value_alias', TType.STRING, 36)
      oprot.writeString(self.value_alias)
      oprot.writeFieldEnd()
    if self.dclocal_read_repair_chance is not None:
      oprot.writeFieldBegin('dclocal_read_repair_chance', TType.DOUBLE, 37)
      oprot.writeDouble(self.dclocal_read_repair_chance)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.keyspace is None:
      raise TProtocol.TProtocolException(message='Required field keyspace is unset!')
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class KsDef:
  """
  Attributes:
   - name
   - strategy_class
   - strategy_options
   - replication_factor: @deprecated, ignored
   - cf_defs
   - durable_writes
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.STRING, 'strategy_class', None, None, ), # 2
    (3, TType.MAP, 'strategy_options', (TType.STRING,None,TType.STRING,None), None, ), # 3
    (4, TType.I32, 'replication_factor', None, None, ), # 4
    (5, TType.LIST, 'cf_defs', (TType.STRUCT,(CfDef, CfDef.thrift_spec)), None, ), # 5
    (6, TType.BOOL, 'durable_writes', None, True, ), # 6
  )

  def __init__(self, name=None, strategy_class=None, strategy_options=None, replication_factor=None, cf_defs=None, durable_writes=thrift_spec[6][4],):
    self.name = name
    self.strategy_class = strategy_class
    self.strategy_options = strategy_options
    self.replication_factor = replication_factor
    self.cf_defs = cf_defs
    self.durable_writes = durable_writes

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.strategy_class = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.MAP:
          self.strategy_options = {}
          (_ktype114, _vtype115, _size113 ) = iprot.readMapBegin() 
          for _i117 in range(_size113):
            _key118 = iprot.readString();
            _val119 = iprot.readString();
            self.strategy_options[_key118] = _val119
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.replication_factor = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.LIST:
          self.cf_defs = []
          (_etype123, _size120) = iprot.readListBegin()
          for _i124 in range(_size120):
            _elem125 = CfDef()
            _elem125.read(iprot)
            self.cf_defs.append(_elem125)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.BOOL:
          self.durable_writes = iprot.readBool();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('KsDef')
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name)
      oprot.writeFieldEnd()
    if self.strategy_class is not None:
      oprot.writeFieldBegin('strategy_class', TType.STRING, 2)
      oprot.writeString(self.strategy_class)
      oprot.writeFieldEnd()
    if self.strategy_options is not None:
      oprot.writeFieldBegin('strategy_options', TType.MAP, 3)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.strategy_options))
      for kiter126,viter127 in list(self.strategy_options.items()):
        oprot.writeString(kiter126)
        oprot.writeString(viter127)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.replication_factor is not None:
      oprot.writeFieldBegin('replication_factor', TType.I32, 4)
      oprot.writeI32(self.replication_factor)
      oprot.writeFieldEnd()
    if self.cf_defs is not None:
      oprot.writeFieldBegin('cf_defs', TType.LIST, 5)
      oprot.writeListBegin(TType.STRUCT, len(self.cf_defs))
      for iter128 in self.cf_defs:
        iter128.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.durable_writes is not None:
      oprot.writeFieldBegin('durable_writes', TType.BOOL, 6)
      oprot.writeBool(self.durable_writes)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    if self.strategy_class is None:
      raise TProtocol.TProtocolException(message='Required field strategy_class is unset!')
    if self.cf_defs is None:
      raise TProtocol.TProtocolException(message='Required field cf_defs is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class CqlRow:
  """
  Row returned from a CQL query

  Attributes:
   - key
   - columns
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.LIST, 'columns', (TType.STRUCT,(Column, Column.thrift_spec)), None, ), # 2
  )

  def __init__(self, key=None, columns=None,):
    self.key = key
    self.columns = columns

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.columns = []
          (_etype132, _size129) = iprot.readListBegin()
          for _i133 in range(_size129):
            _elem134 = Column()
            _elem134.read(iprot)
            self.columns.append(_elem134)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('CqlRow')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.columns is not None:
      oprot.writeFieldBegin('columns', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.columns))
      for iter135 in self.columns:
        iter135.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.columns is None:
      raise TProtocol.TProtocolException(message='Required field columns is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class CqlMetadata:
  """
  Attributes:
   - name_types
   - value_types
   - default_name_type
   - default_value_type
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'name_types', (TType.STRING,None,TType.STRING,None), None, ), # 1
    (2, TType.MAP, 'value_types', (TType.STRING,None,TType.STRING,None), None, ), # 2
    (3, TType.STRING, 'default_name_type', None, None, ), # 3
    (4, TType.STRING, 'default_value_type', None, None, ), # 4
  )

  def __init__(self, name_types=None, value_types=None, default_name_type=None, default_value_type=None,):
    self.name_types = name_types
    self.value_types = value_types
    self.default_name_type = default_name_type
    self.default_value_type = default_value_type

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.MAP:
          self.name_types = {}
          (_ktype137, _vtype138, _size136 ) = iprot.readMapBegin() 
          for _i140 in range(_size136):
            _key141 = iprot.readString();
            _val142 = iprot.readString();
            self.name_types[_key141] = _val142
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.MAP:
          self.value_types = {}
          (_ktype144, _vtype145, _size143 ) = iprot.readMapBegin() 
          for _i147 in range(_size143):
            _key148 = iprot.readString();
            _val149 = iprot.readString();
            self.value_types[_key148] = _val149
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.default_name_type = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.default_value_type = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('CqlMetadata')
    if self.name_types is not None:
      oprot.writeFieldBegin('name_types', TType.MAP, 1)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.name_types))
      for kiter150,viter151 in list(self.name_types.items()):
        oprot.writeString(kiter150)
        oprot.writeString(viter151)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.value_types is not None:
      oprot.writeFieldBegin('value_types', TType.MAP, 2)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.value_types))
      for kiter152,viter153 in list(self.value_types.items()):
        oprot.writeString(kiter152)
        oprot.writeString(viter153)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.default_name_type is not None:
      oprot.writeFieldBegin('default_name_type', TType.STRING, 3)
      oprot.writeString(self.default_name_type)
      oprot.writeFieldEnd()
    if self.default_value_type is not None:
      oprot.writeFieldBegin('default_value_type', TType.STRING, 4)
      oprot.writeString(self.default_value_type)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name_types is None:
      raise TProtocol.TProtocolException(message='Required field name_types is unset!')
    if self.value_types is None:
      raise TProtocol.TProtocolException(message='Required field value_types is unset!')
    if self.default_name_type is None:
      raise TProtocol.TProtocolException(message='Required field default_name_type is unset!')
    if self.default_value_type is None:
      raise TProtocol.TProtocolException(message='Required field default_value_type is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class CqlResult:
  """
  Attributes:
   - type
   - rows
   - num
   - schema
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'type', None, None, ), # 1
    (2, TType.LIST, 'rows', (TType.STRUCT,(CqlRow, CqlRow.thrift_spec)), None, ), # 2
    (3, TType.I32, 'num', None, None, ), # 3
    (4, TType.STRUCT, 'schema', (CqlMetadata, CqlMetadata.thrift_spec), None, ), # 4
  )

  def __init__(self, type=None, rows=None, num=None, schema=None,):
    self.type = type
    self.rows = rows
    self.num = num
    self.schema = schema

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.I32:
          self.type = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.rows = []
          (_etype157, _size154) = iprot.readListBegin()
          for _i158 in range(_size154):
            _elem159 = CqlRow()
            _elem159.read(iprot)
            self.rows.append(_elem159)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.num = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.schema = CqlMetadata()
          self.schema.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('CqlResult')
    if self.type is not None:
      oprot.writeFieldBegin('type', TType.I32, 1)
      oprot.writeI32(self.type)
      oprot.writeFieldEnd()
    if self.rows is not None:
      oprot.writeFieldBegin('rows', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.rows))
      for iter160 in self.rows:
        iter160.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.num is not None:
      oprot.writeFieldBegin('num', TType.I32, 3)
      oprot.writeI32(self.num)
      oprot.writeFieldEnd()
    if self.schema is not None:
      oprot.writeFieldBegin('schema', TType.STRUCT, 4)
      self.schema.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.type is None:
      raise TProtocol.TProtocolException(message='Required field type is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class CqlPreparedResult:
  """
  Attributes:
   - itemId
   - count
   - variable_types
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'itemId', None, None, ), # 1
    (2, TType.I32, 'count', None, None, ), # 2
    (3, TType.LIST, 'variable_types', (TType.STRING,None), None, ), # 3
  )

  def __init__(self, itemId=None, count=None, variable_types=None,):
    self.itemId = itemId
    self.count = count
    self.variable_types = variable_types

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.I32:
          self.itemId = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.count = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.LIST:
          self.variable_types = []
          (_etype164, _size161) = iprot.readListBegin()
          for _i165 in range(_size161):
            _elem166 = iprot.readString();
            self.variable_types.append(_elem166)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('CqlPreparedResult')
    if self.itemId is not None:
      oprot.writeFieldBegin('itemId', TType.I32, 1)
      oprot.writeI32(self.itemId)
      oprot.writeFieldEnd()
    if self.count is not None:
      oprot.writeFieldBegin('count', TType.I32, 2)
      oprot.writeI32(self.count)
      oprot.writeFieldEnd()
    if self.variable_types is not None:
      oprot.writeFieldBegin('variable_types', TType.LIST, 3)
      oprot.writeListBegin(TType.STRING, len(self.variable_types))
      for iter167 in self.variable_types:
        oprot.writeString(iter167)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.itemId is None:
      raise TProtocol.TProtocolException(message='Required field itemId is unset!')
    if self.count is None:
      raise TProtocol.TProtocolException(message='Required field count is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)
