def handle(self): magic = self.request.recv(4) (length, ) = struct.unpack("<L", self.request.recv(4)) if length != 0: self.request.recv(length) self.request.sendall("SUCCESS\0") while (True): header = self.request.recv(4) if len(header) == 0: break (length, ) = struct.unpack("<L", header) data = self.request.recv(length) query = p.Query() query.ParseFromString(data) response = p.Response() response.token = query.token response.type = p.Response.SUCCESS_ATOM datum = response.response.add() datum.type = p.Datum.R_NULL response_protobuf = response.SerializeToString() response_header = struct.pack("<L", len(response_protobuf)) self.request.sendall(response_header + response_protobuf)
def _send_query(self, query, term, opts={}): # Error if this connection has closed if not self.socket: raise RqlDriverError("Connection is closed.") # Send protobuf query_protobuf = query.SerializeToString() query_header = struct.pack("<L", len(query_protobuf)) self.socket.sendall(query_header + query_protobuf) if opts.has_key('noreply') and opts['noreply']: return None # Get response response_buf = '' try: response_header = '' while len(response_header) < 4: chunk = self.socket.recv(4) if len(chunk) == 0: raise RqlDriverError("Connection is closed.") response_header += chunk # The first 4 bytes give the expected length of this response (response_len,) = struct.unpack("<L", response_header) while len(response_buf) < response_len: chunk = self.socket.recv(response_len - len(response_buf)) if chunk == '': raise RqlDriverError("Connection is broken.") response_buf += chunk except KeyboardInterrupt as err: # When interrupted while waiting for a response cancel the outstanding # requests by resetting this connection self.reconnect() raise err # Construct response response = p.Response() response.ParseFromString(response_buf) # Check that this is the response we were expecting if response.token != query.token: # This response is corrupted or not intended for us. raise RqlDriverError("Unexpected response received.") time_format = 'native' if opts.has_key('time_format'): time_format = opts['time_format'] # Error responses if response.type == p.Response.RUNTIME_ERROR: message = Datum.deconstruct(response.response[0]) backtrace = response.backtrace frames = backtrace.frames or [] raise RqlRuntimeError(message, term, frames) elif response.type == p.Response.COMPILE_ERROR: message = Datum.deconstruct(response.response[0]) backtrace = response.backtrace frames = backtrace.frames or [] raise RqlCompileError(message, term, frames) elif response.type == p.Response.CLIENT_ERROR: message = Datum.deconstruct(response.response[0]) backtrace = response.backtrace frames = backtrace.frames or [] raise RqlClientError(message, term, frames) # Sequence responses elif response.type == p.Response.SUCCESS_PARTIAL or response.type == p.Response.SUCCESS_SEQUENCE: chunk = [Datum.deconstruct(datum, time_format) for datum in response.response] return Cursor(self, opts, query, term, chunk, response.type == p.Response.SUCCESS_SEQUENCE) # Atom response elif response.type == p.Response.SUCCESS_ATOM: if len(response.response) < 1: return None return Datum.deconstruct(response.response[0], time_format) # Default for unknown response types else: raise RqlDriverError("Unknown Response type %d encountered in response." % response.type)