Ejemplo n.º 1
0
 def __recvCallback(self, msg):
     #DEALER response contains empty delimiter!
     if len(msg[0]) != 0:
         print >>sys.stderr, "Received malformed message: ", msg
         return
     msg = msg[1:]
     #Currently we don't check the response type
     YakDBConnectionBase._checkHeaderFrame(msg)
     #Struct unpack yields 1-element tuple!
     headerFrame = msg[0]
     assert(len(headerFrame) == 8) #4 bytes response + 4 bytes request ID
     requestId = struct.unpack("<I", YakDBConnectionBase._extractRequestId(headerFrame))[0]
     callback, params = self.requests[requestId]
     #Postprocess, depending on request type.
     responseType = headerFrame[2]
     dataFrames = msg[1:]
     if responseType == "\x13": #Scan
         if params["mapData"]:
             data = YakDBConnectionBase(dataFrames)
         else:
             data = YakDBConnectionBase._mapScanToTupleList(dataFrames)
     elif responseType == "\x10": #Read
         if params["mapKeys"]:
             data = YakDBConnectionBase._mapReadKeyValues(params["keys"], dataFrames)
         else:
             data = dataFrames
     else:
         raise YakDBProtocolException("Received correct response, but cannot handle response code %d" % ord(responseType))
     #Cleanup
     del self.requests[requestId]
     #Call original callback
     callback(data)
Ejemplo n.º 2
0
    def read(self, tableNo, keys, mapKeys=False, requestId=b""):
        """
        Read one or multiples values, identified by their keys, from a table.

        @param tableNo The table number to read from
        @param keys A list, tuple or single value.
                        Must only contain strings, ints or floats.
                        integral types are automatically mapped to signed 32-bit little-endian binary,
                        floating point types are mapped to signed little-endian 64-bit IEEE754 values.
                        If you'd like to use another binary representation, use a binary string instead.
        @param mapKeys If this is set to true, a mapping from the original keys to
                        values is performed, the return value is a dictionary key->value
                        rather than a value list. Mapping keys introduces additional overhead.
        @return A list of values, correspondent to the key order (or a dict, depends on mapKeys parameter)
        """
        #Check if this connection instance is setup correctly
        self._checkSingleConnection()
        self._checkRequestReply()
        #Check parameters and create binary-string only key list
        YakDBConnectionBase._checkParameterType(tableNo, int, "tableNo")
        convertedKeys = ZMQBinaryUtil.convertToBinaryList(keys)
        #Send header frame
        self.socket.send(b"\x31\x01\x10" + requestId, zmq.SNDMORE)
        #Send the table number frame
        self._sendBinary32(tableNo)
        #Send key list
        nextToSend = None  #Needed because the last value shall be sent w/out SNDMORE
        for key in convertedKeys:
            #Send the value from the last loop iteration
            if nextToSend is not None:
                self.socket.send(nextToSend, zmq.SNDMORE)
            #Send the key and enqueue the value
            nextToSend = key
        #Send last key, without SNDMORE flag
        self.socket.send(nextToSend)
        #Wait for reply
        msgParts = self.socket.recv_multipart(copy=True)
        YakDBConnectionBase._checkHeaderFrame(msgParts, b'\x10')
        #Return data frames
        values = msgParts[1:]
        if mapKeys:
            values = YakDBConnectionBase._mapReadKeyValues(keys, values)
        return values
Ejemplo n.º 3
0
    def read(self, tableNo, keys, mapKeys=False, requestId=b""):
        """
        Read one or multiples values, identified by their keys, from a table.

        @param tableNo The table number to read from
        @param keys A list, tuple or single value.
                        Must only contain strings/bytes, ints or floats.
                        integral types are automatically mapped to signed 32-bit little-endian binary,
                        floating point types are mapped to signed little-endian 64-bit IEEE754 values.
                        If you'd like to use another binary representation, use a binary string instead.
        @param mapKeys If this is set to true, a mapping from the original keys to
                        values is performed, the return value is a dictionary key->value
                        rather than a value list. Mapping keys introduces additional overhead.
        @return A list of values, correspondent to the key order (or a dict, depends on mapKeys parameter)
        """
        #Check if this connection instance is setup correctly
        self._checkSingleConnection()
        self._checkRequestReply()
        #Check parameters and create binary-string only key list
        YakDBConnectionBase._checkParameterType(tableNo, int, "tableNo")
        convertedKeys = ZMQBinaryUtil.convertToBinaryList(keys)
        #Send header frame
        self.socket.send(b"\x31\x01\x10" + requestId, zmq.SNDMORE)
        #Send the table number frame
        self._sendBinary32(tableNo)
        #Send key list
        nextToSend = None #Needed because the last value shall be sent w/out SNDMORE
        for key in convertedKeys:
            #Send the value from the last loop iteration
            if nextToSend is not None: self.socket.send(nextToSend, zmq.SNDMORE)
            #Send the key and enqueue the value
            nextToSend = key
        #Send last key, without SNDMORE flag
        self.socket.send(nextToSend)
        #Wait for reply
        msgParts = self.socket.recv_multipart(copy=True)
        YakDBConnectionBase._checkHeaderFrame(msgParts, b'\x10')
        #Return data frames
        values = msgParts[1:]
        if mapKeys:
            values = YakDBConnectionBase._mapReadKeyValues(keys, values)
        return values