def message_received(self, request_id, packet): # Response Flags: # bit 0: Cursor Not Found # bit 1: Query Failure # bit 2: Shard Config Stale # bit 3: Await Capable # bit 4-31: Reserved QUERY_FAILURE = 1 << 1 response_flag, cursor_id, start, length = struct.unpack("<iqii", packet[:20]) if response_flag == QUERY_FAILURE: self.query_failure(request_id, cursor_id, response_flag, bson.BSON(packet[20:]).decode()) return self.query_success(request_id, cursor_id, bson.decode_all(packet[20:]))
def message_received(self, request_id, packet): # Response Flags: # bit 0: Cursor Not Found # bit 1: Query Failure # bit 2: Shard Config Stale # bit 3: Await Capable # bit 4-31: Reserved QUERY_FAILURE = 1 << 1 response_flag, cursor_id, start, length = struct.unpack( "<iqii", packet[:20]) if response_flag == QUERY_FAILURE: self.query_failure(request_id, cursor_id, response_flag, bson.BSON(packet[20:]).decode()) return self.query_success(request_id, cursor_id, bson.decode_all(packet[20:]))
def _unpack_response(response, cursor_id=None, as_class=dict, tz_aware=False, uuid_subtype=OLD_UUID_SUBTYPE): """Unpack a response from the database. Check the response for errors and unpack, returning a dictionary containing the response data. :Parameters: - `response`: byte string as returned from the database - `cursor_id` (optional): cursor_id we sent to get this response - used for raising an informative exception when we get cursor id not valid at server response - `as_class` (optional): class to use for resulting documents """ response_flag = struct.unpack("<i", response[:4])[0] if response_flag & 1: # Shouldn't get this response if we aren't doing a getMore assert cursor_id is not None raise OperationFailure("cursor id '%s' not valid at server" % cursor_id) elif response_flag & 2: error_object = bson.BSON(response[20:]).decode() if error_object["$err"].startswith("not master"): raise AutoReconnect(error_object["$err"]) raise OperationFailure("database error: %s" % error_object["$err"]) result = {} result["cursor_id"] = struct.unpack("<q", response[4:12])[0] result["starting_from"] = struct.unpack("<i", response[12:16])[0] result["number_returned"] = struct.unpack("<i", response[16:20])[0] result["data"] = bson.decode_all(response[20:], as_class, tz_aware, uuid_subtype) assert len(result["data"]) == result["number_returned"] return result