def prepare(query, params):
    # For every match of the form ":param_name", call marshal
    # on kwargs['param_name'] and replace that section of the query
    # with the result
    new, count = re.subn(_param_re, lambda m: marshal(params[m.group(1)[1:]]), query)
    if len(params) > count:
        raise cql.ProgrammingError("More keywords were provided than parameters")
    return new
Exemple #2
0
 def execute(self, cql_query, params={}):
     self.__checksock()
     self.rs_idx = 0
     self.rowcount = 0
     self.description = None
     try:
         prepared_q = self.prepare(cql_query, params)
     except KeyError, e:
         raise cql.ProgrammingError("Unmatched named substitution: " +
                                    "%s not given for %s" % (e, cql_query))
Exemple #3
0
 def prepare_query(self, query):
     if isinstance(query, unicode):
         raise ValueError("CQL query must be bytes, not unicode")
     prepared_q_text, paramnames = prepare_query(query)
     compressed_q, compression = self.compress_query_text(prepared_q_text)
     presult = self._connection.client.prepare_cql_query(
         compressed_q, compression)
     assert presult.count == len(paramnames)
     if presult.variable_types is None and presult.count > 0:
         raise cql.ProgrammingError(
             "Cassandra did not provide types for bound"
             " parameters. Prepared statements are only"
             " supported with cql3.")
     return PreparedQuery(query, presult.itemId, presult.variable_types,
                          paramnames)
Exemple #4
0
def prepare(query, params):
    """
    For every match of the form ":param_name", call marshal
    on kwargs['param_name'] and replace that section of the query
    with the result
    """
    def repl(match):
        name = match.group(1)[1:]
        if name in params:
            return marshal(params[name])
        return ":%s" % name

    new, count = re.subn(_param_re, repl, query)

    if len(params) > count:
        raise cql.ProgrammingError("More keywords were provided "
                                   "than parameters")
    return new
Exemple #5
0
    def register_watcher(self, eventtype, cb):
        """
        Request that any events of the given type be passed to the given
        callback when they arrive. Note that the callback may not be called
        immediately upon the arrival of the event packet; it may have to wait
        until something else waits on a result, or until wait_for_even() is
        called.

        If the event type has not been registered for already, this may
        block while a new REGISTER message is sent to the server.

        The available event types are in the cql.native.known_event_types
        list.

        When an event arrives, a dictionary will be passed to the callback
        with the info about the event. Some example result dictionaries:

        (For STATUS_CHANGE events:)

          {'changetype': u'DOWN', 'address': ('12.114.19.76', 8000)}

        (For TOPOLOGY_CHANGE events:)

          {'changetype': u'NEW_NODE', 'address': ('19.10.122.13', 8000)}
        """

        if isinstance(eventtype, str):
            eventtype = eventtype.decode('utf8')
        try:
            watchers = self.event_watchers[eventtype]
        except KeyError:
            ans = self.wait_for_request(
                RegisterMessage(eventlist=(eventtype, )))
            if isinstance(ans, ErrorMessage):
                raise cql.ProgrammingError("Server did not accept registration"
                                           " for %s events: %s" %
                                           (eventtype, ans.summarymsg()))
            watchers = self.event_watchers.setdefault(eventtype, [])
        watchers.append(cb)
Exemple #6
0
class Cursor:

    _keyspace_re = re.compile("USE (\w+);?", re.I | re.M)
    _cfamily_re = re.compile("\s*SELECT\s+.+\s+FROM\s+[\']?(\w+)", re.I | re.M)
    _ddl_re = re.compile("\s*(CREATE|ALTER|DROP)\s+", re.I | re.M)

    def __init__(self, parent_connection):
        self.open_socket = True
        self.parent_connection = parent_connection

        self.description = None  # A list of 7-tuples:
        #  (column_name, type_code, none, none,
        #   none, none, nulls_ok=True)
        # Populate on execute()

        self.arraysize = 1
        self.rowcount = -1  # Populate on execute()
        self.compression = 'GZIP'

        self._query_ks = self.parent_connection.keyspace
        self._query_cf = None
        self.decoder = SchemaDecoder(self.__get_schema())

    ###
    # Cursor API
    ###

    def close(self):
        self.open_socket = False

    def prepare(self, query, params):
        prepared_query = prepare(query, params)
        self._schema_update_needed = False

        # Snag the keyspace or column family and stash it for later use in
        # decoding columns.  These regexes don't match every query, but the
        # current column family only needs to be current for SELECTs.
        match = Cursor._cfamily_re.match(prepared_query)
        if match:
            self._query_cf = match.group(1)
            return prepared_query
        match = Cursor._keyspace_re.match(prepared_query)
        if match:
            self._query_ks = match.group(1)
            return prepared_query

        # If this is a CREATE, then refresh the schema for decoding purposes.
        match = Cursor._ddl_re.match(prepared_query)
        if match:
            self._schema_update_needed = True
        return prepared_query

    def __get_schema(self):
        def columns(metadata):
            results = {}
            for col in metadata:
                results[col.name] = col.validation_class
            return results

        def column_families(cf_defs):
            d = {}
            for cf in cf_defs:
                d[cf.name] = {
                    'comparator': cf.comparator_type,
                    'default_validation_class': cf.default_validation_class,
                    'key_validation_class': cf.key_validation_class,
                    'columns': columns(cf.column_metadata),
                    'key_alias': cf.key_alias
                }
            return d

        schema = {}
        client = self.parent_connection.client
        for ksdef in client.describe_keyspaces():
            schema[ksdef.name] = column_families(ksdef.cf_defs)
        return schema

    def execute(self, cql_query, params={}):
        self.__checksock()
        self.rs_idx = 0
        self.rowcount = 0
        self.description = None
        try:
            prepared_q = self.prepare(cql_query, params)
        except KeyError, e:
            raise cql.ProgrammingError("Unmatched named substitution: " +
                                       "%s not given for %s" % (e, cql_query))

        if self.compression == 'GZIP':
            compressed_q = zlib.compress(prepared_q)
        else:
            compressed_q = prepared_q
        request_compression = getattr(Compression, self.compression)

        try:
            client = self.parent_connection.client
            response = client.execute_cql_query(compressed_q,
                                                request_compression)
        except InvalidRequestException, ire:
            raise cql.ProgrammingError("Bad Request: %s" % ire.why)
 def make_reqid(self):
     if self.reqid_slots == 0:
         raise cql.ProgrammingError("Unable to acquire a stream id")
     slot = ctzb(self.reqid_slots)
     self.reqid_slots &= ~(1 << slot)
     return slot
Exemple #8
0
 def prepare_inline(self, query, params):
     try:
         return prepare_inline(query, params, self.cql_major_version)
     except KeyError, e:
         raise cql.ProgrammingError("Unmatched named substitution: " +
                                    "%s not given for %r" % (e, query))
Exemple #9
0
 def __checksock(self):
     if self._connection is None or not self._connection.open_socket:
         raise cql.ProgrammingError("Cursor has been closed.")
Exemple #10
0
 def handle_cql_execution_errors(self, executor, *args, **kwargs):
     try:
         return executor(*args, **kwargs)
     except InvalidRequestException, ire:
         raise cql.ProgrammingError("Bad Request: %s" % ire.why)