def _unpack_response(response, cursor_id=None): """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 """ 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:]).to_dict() if error_object["$err"] == "not master": raise AutoReconnect("master has changed") raise OperationFailure("database error: %s" % error_object["$err"]) else: assert response_flag == 0 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._to_dicts(response[20:]) assert len(result["data"]) == result["number_returned"] return result
def send_message(operation, message): db = self.__collection.database() kwargs = { "_sock": self.__socket, "_must_use_master": self.__must_use_master } if self.__connection_id is not None: kwargs["_connection_to_use"] = self.__connection_id response = db.connection()._receive_message( operation, message, **kwargs) if isinstance(response, types.TupleType): (connection_id, response) = response else: connection_id = None response_flag = struct.unpack("<i", response[:4])[0] if response_flag == 1: raise OperationFailure("cursor id '%s' not valid at server" % self.__id) elif response_flag == 2: error_object = bson.BSON(response[20:]).to_dict() if error_object["$err"] == "not master": db.connection()._reset() raise AutoReconnect("master has changed") raise OperationFailure("database error: %s" % error_object["$err"]) else: assert response_flag == 0 self.__id = struct.unpack("<q", response[4:12])[0] self.__connection_id = connection_id assert struct.unpack("<i", response[12:16])[0] == self.__retrieved number_returned = struct.unpack("<i", response[16:20])[0] self.__retrieved += number_returned if self.__limit and self.__id and self.__limit <= self.__retrieved: self.__die() self.__data = bson._to_dicts(response[20:]) assert len(self.__data) == number_returned
def send_message(operation, message): db = self.__collection.database() kwargs = {"_sock": self.__socket, "_must_use_master": self.__must_use_master} if self.__connection_id is not None: kwargs["_connection_to_use"] = self.__connection_id response = db.connection()._receive_message(operation, message, **kwargs) if isinstance(response, types.TupleType): (connection_id, response) = response else: connection_id = None response_flag = struct.unpack("<i", response[:4])[0] if response_flag == 1: raise OperationFailure("cursor id '%s' not valid at server" % self.__id) elif response_flag == 2: error_object = bson.BSON(response[20:]).to_dict() if error_object["$err"] == "not master": db.connection()._reset() raise AutoReconnect("master has changed") raise OperationFailure("database error: %s" % error_object["$err"]) else: assert response_flag == 0 self.__id = struct.unpack("<q", response[4:12])[0] self.__connection_id = connection_id assert struct.unpack("<i", response[12:16])[0] == self.__retrieved number_returned = struct.unpack("<i", response[16:20])[0] self.__retrieved += number_returned if self.__limit and self.__id and self.__limit <= self.__retrieved: self.__die() self.__data = bson._to_dicts(response[20:]) assert len(self.__data) == number_returned
def messageReceived(self, request_id, packet): response_flag, cursor_id, start, length = struct.unpack("<iqii", packet[:20]) if response_flag == 1: self.queryFailure(request_id, cursor_id, response_flag, packet[20:]) return self.querySuccess(request_id, cursor_id, bson._to_dicts(packet[20:]))