Exemplo n.º 1
0
    def _SendBlob_(self, blob):
        dt = tagVariantDataType.sdVT_ARRAY | tagVariantDataType.sdVT_UI1
        if isinstance(blob, str):
            dt = tagVariantDataType.sdVT_BSTR
        q = CScopeUQueue.Lock()
        q.SaveObject(blob)
        dt = q.LoadUShort()
        bytes = q.LoadUInt()
        byte_len = q.GetSize()

        q0 = CScopeUQueue.Lock()
        byte_len += 10  # sizeof(ushort) + sizeof(uint) + sizeof(uint) extra 4 bytes for string null termination
        q0.SaveUInt(byte_len).SaveUShort(dt).SaveUInt(q.GetSize())
        ret = self.SendResult(q0, DB_CONSTS.idStartBLOB)
        CScopeUQueue.Unlock(q0)
        if ret == CClientPeer.REQUEST_CANCELED or ret == CClientPeer.SOCKET_NOT_FOUND:
            CScopeUQueue.Unlock(q)
            return False
        byte_len = q.GetSize()
        while byte_len > DB_CONSTS.DEFAULT_BIG_FIELD_CHUNK_SIZE:
            buffer = (c_ubyte *
                      DB_CONSTS.DEFAULT_BIG_FIELD_CHUNK_SIZE).from_buffer(
                          q._m_bytes_, q._m_position_)
            ret = scl.SendReturnData(self.Handle, DB_CONSTS.idChunk,
                                     DB_CONSTS.DEFAULT_BIG_FIELD_CHUNK_SIZE,
                                     buffer)
            if ret == CClientPeer.REQUEST_CANCELED or ret == CClientPeer.SOCKET_NOT_FOUND:
                CScopeUQueue.Unlock(q)
                return False
            q.Discard(ret)
            byte_len = q.GetSize()
        ret = self.SendResult(q, DB_CONSTS.idEndBLOB)
        CScopeUQueue.Unlock(q)
        return ret != CClientPeer.REQUEST_CANCELED and ret != CClientPeer.SOCKET_NOT_FOUND
Exemplo n.º 2
0
 def SendRows(self, vData):
     if not vData:
         vData = []
     q = CScopeUQueue.Lock()
     for vt in vData:
         if isinstance(vt, str):
             if len(vt) <= DB_CONSTS.DEFAULT_BIG_FIELD_CHUNK_SIZE:
                 q.SaveObject(vt)
             else:
                 if q.Size > 0 and not self._SendRows_(q, True):
                     CScopeUQueue.Unlock(q)
                     return False
                 if not self._SendBlob_(vt):
                     CScopeUQueue.Unlock(q)
                     return False
         elif isinstance(vt, bytearray):
             if len(vt) <= 2 * DB_CONSTS.DEFAULT_BIG_FIELD_CHUNK_SIZE:
                 q.SaveObject(vt)
             else:
                 if q.Size > 0 and not self._SendRows_(q, True):
                     CScopeUQueue.Unlock(q)
                     return False
                 if not self._SendBlob_(vt):
                     CScopeUQueue.Unlock(q)
                     return False
         else:
             q.SaveObject(vt)
     ret = self.SendResult(q, DB_CONSTS.idEndRows)
     return ret != CClientPeer.REQUEST_CANCELED and ret != CClientPeer.SOCKET_NOT_FOUND
Exemplo n.º 3
0
 def Dequeue(self, key, d, timeout=0, discarded=None):
     """
     Dequeue messages from a persistent message queue file at server side in batch
     :param key: An ASCII string for identifying a queue at server side
     :param d: A callback for tracking data like remaining message count within a server queue file, queue file size in bytes, message dequeued within this batch and bytes dequeued within this batch
     :param timeout: A time-out number in milliseconds
     :param discarded A callback for tracking socket close or request cancel event
     :return: true for sending the request successfully, and false for failure
     """
     if not key:
         key = ''
     with self._csQ_:
         self._dDequeue_ = d
         self._keyQueue_ = key
     buffer = CScopeUQueue.Lock().SaveAString(key).SaveUInt(timeout)
     ok = None
     if not d:
         ok = self.SendRequest(CAsyncQueue.idDequeue, buffer, None,
                               discarded)
     else:
         ok = self.SendRequest(
             CAsyncQueue.idDequeue, buffer,
             lambda ar: d(ar.AsyncServiceHandler, ar.LoadULong(
             ), ar.LoadULong(), ar.LoadUInt(), ar.LoadUInt()), discarded)
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 4
0
 def SendMeta(self, meta, index):
     q = CScopeUQueue.Lock()
     meta.SaveTo(q)
     q.SaveULong(index)
     ret = self.SendResult(q, DB_CONSTS.idRowsetHeader)
     CScopeUQueue.Unlock(q)
     return ret != CClientPeer.REQUEST_CANCELED and ret != CClientPeer.SOCKET_NOT_FOUND
Exemplo n.º 5
0
 def Enqueue(self, key, idMessage, q, e=None, discarded=None):
     """
     Enqueue a message into a queue file identified by a key
     :param key: An ASCII string for identifying a queue at server side
     :param idMessage: A unsigned short number to identify a message
     :param q: an instance of SPA.CUQueue containing a message
     :param e: A callback for tracking returning index
     :param discarded A callback for tracking socket close or request cancel event
     :return: true for sending the request successfully, and false for failure
     """
     if not key:
         key = ''
     buffer = CScopeUQueue.Lock().SaveAString(key).SaveUShort(idMessage)
     if q:
         buffer.Push(q.IntenalBuffer, q.GetSize())
     ok = None
     if not e:
         ok = self.SendRequest(CAsyncQueue.idEnqueue, buffer, None,
                               discarded)
     else:
         ok = self.SendRequest(
             CAsyncQueue.idEnqueue, buffer,
             lambda ar: e(ar.AsyncServiceHandler, ar.LoadULong()),
             discarded)
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 6
0
 def FlushQueue(self,
                key,
                f,
                option=tagOptimistic.oMemoryCached,
                discarded=None):
     """
     May flush memory data into either operation system memory or hard disk, and return message count and queue file size in bytes. Note the method only returns message count and queue file size in bytes if the option is oMemoryCached
     :param key: An ASCII string for identifying a queue at server side
     :param f: A callback for tracking returning message count and queue file size in bytes
     :param option: one of tagOptimistic options, oMemoryCached, oSystemMemoryCached and oDiskCommitted
     :param discarded A callback for tracking socket close or request cancel event
     :return: true for sending the request successfully, and false for failure
     """
     if not key:
         key = ''
     buffer = CScopeUQueue.Lock().SaveAString(key).SaveInt(option)
     ok = None
     if not f:
         ok = self.SendRequest(CAsyncQueue.idFlush, buffer, None, discarded)
     else:
         ok = self.SendRequest(
             CAsyncQueue.idFlush, buffer, lambda ar: f(
                 ar.AsyncServiceHandler, ar.LoadULong(), ar.LoadULong()),
             discarded)
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 7
0
 def EndQueueTrans(self, rollback=False, qt=None, discarded=None):
     """
     End enqueuing messages with transaction style. Currently, total size of queued messages must be less than 4 G bytes
     :param rollback: true for rollback, and false for committing
     :param qt: A callback for tracking returning error code, which can be one of QUEUE_OK, QUEUE_TRANS_NOT_STARTED_YET, and so on
     :param discarded A callback for tracking socket close or request cancel event
     :return: true for sending the request successfully, and false for failure
     """
     buffer = CScopeUQueue.Lock().SaveBool(rollback)
     ok = None
     if not qt:
         ok = self.SendRequest(CAsyncQueue.idEndTrans, buffer, None,
                               discarded)
     else:
         ok = self.SendRequest(
             CAsyncQueue.idEndTrans, buffer,
             lambda ar: qt(ar.AsyncServiceHandler, ar.LoadInt()), discarded)
     cq = self.AttachedClientSocket.ClientQueue
     if cq.Available:
         if rollback:
             cq.AbortJob()
         else:
             cq.EndJob()
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 8
0
 def Enqueue(self, key, idMessage, q, e=None, discarded=None, se=None):
     """
     Enqueue a message into a queue file identified by a key
     :param key: An ASCII string for identifying a queue at server side
     :param idMessage: A unsigned short number to identify a message
     :param q: None or an instance of SPA.CUQueue or SPA.CScopeUQueue containing a message
     :param e: A callback for tracking returning index
     :param discarded A callback for tracking socket close or request cancel event
     :param se A callback for tracking an exception from server
     :return: True if communication channel is sendable, and False if communication channel is not sendable
     """
     if not key:
         key = ''
     buffer = CScopeUQueue.Lock().SaveAString(key).SaveUShort(idMessage)
     if isinstance(q, CScopeUQueue):
         q = q.UQueue
     if q:
         buffer.Push(q.IntenalBuffer, q.GetSize())
     ok = None
     if not e:
         ok = self.SendRequest(CAsyncQueue.idEnqueue, buffer, None,
                               discarded, se)
     else:
         ok = self.SendRequest(
             CAsyncQueue.idEnqueue, buffer,
             lambda ar: e(ar.AsyncServiceHandler, ar.LoadULong()),
             discarded, se)
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 9
0
 def CloseQueue(self,
                key,
                c=None,
                discarded=None,
                permanent=False,
                se=None):
     """
     Try to close or delete a persistent queue opened at server side
     :param key: An ASCII string for identifying a queue at server side
     :param c: A callback for tracking returning error code, which can be one of QUEUE_OK, QUEUE_DEQUEUING, and so on
     :param permanent: true for deleting a queue file, and false for closing a queue file
     :param discarded A callback for tracking socket close or request cancel event
     :param se A callback for tracking an exception from server
     :return: True if communication channel is sendable, and False if communication channel is not sendable
     """
     if not key:
         key = ''
     buffer = CScopeUQueue.Lock().SaveAString(key).SaveBool(permanent)
     ok = None
     if not c:
         ok = self.SendRequest(CAsyncQueue.idClose, buffer, None, discarded,
                               se)
     else:
         ok = self.SendRequest(
             CAsyncQueue.idClose, buffer,
             lambda ar: c(ar.AsyncServiceHandler, ar.LoadInt()), discarded,
             se)
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 10
0
 def StartQueueTrans(self, key, qt=None, discarded=None, se=None):
     """
     Start enqueuing messages with transaction style.
     Currently, total size of queued messages must be less than 4 G bytes
     :param key: An ASCII string for identifying a queue at server side
     :param qt: A callback for tracking returning error code,
     which can be one of QUEUE_OK, QUEUE_TRANS_ALREADY_STARTED, and so on
     :param discarded A callback for tracking socket close or request cancel event
     :param se A callback for tracking an exception from server
     :return: True if communication channel is sendable, and False if communication channel is not sendable
     """
     if not key:
         key = ''
     buffer = CScopeUQueue.Lock().SaveAString(key)
     ok = None
     cq = self.Socket.ClientQueue
     if cq.Available:
         cq.StartJob()
     if not qt:
         ok = self.SendRequest(CAsyncQueue.idStartTrans, buffer, None,
                               discarded, se)
     else:
         ok = self.SendRequest(
             CAsyncQueue.idStartTrans, buffer,
             lambda ar: qt(ar.AsyncServiceHandler, ar.LoadInt()), discarded,
             se)
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 11
0
 def GetCachedTables(self, defaultDb, handler, row, rh, flags=DB_CONSTS.ENABLE_TABLE_UPDATE_MESSAGES):
     q = CScopeUQueue.Lock()
     index = self.GetCallIndex();
     with self._csCache:
         self._mapRowset[index] = Pair(rh, row)
         self._mapHandler[index] = handler
     q.SaveString(defaultDb).SaveUInt(flags).SaveULong(index)
     ok = self.SendRequest(DB_CONSTS.idGetCachedTables, q, None)
     CScopeUQueue.Unlock(q)
     if not ok:
         with self._csCache:
             self._mapHandler.pop(index)
             self._mapRowset.pop(index)
     return ok
Exemplo n.º 12
0
 def EndQueueTrans(self, rollback=False, qt=None):
     """
     End enqueuing messages with transaction style. Currently, total size of queued messages must be less than 4 G bytes
     :param rollback: true for rollback, and false for committing
     :param qt: A callback for tracking returning error code, which can be one of QUEUE_OK, QUEUE_TRANS_NOT_STARTED_YET, and so on
     :return: true for sending the request successfully, and false for failure
     """
     buffer = CScopeUQueue.Lock().SaveBool(rollback)
     ok = None
     if not qt:
         ok = self.SendRequest(CAsyncQueue.idEndTrans, buffer, None)
     else:
         ok = self.SendRequest(CAsyncQueue.idEndTrans, buffer,
                               lambda ar: qt(ar.LoadInt()))
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 13
0
 def StartQueueTrans(self, key, qt):
     """
     Start enqueuing messages with transaction style. Currently, total size of queued messages must be less than 4 G bytes
     :param key: An ASCII string for identifying a queue at server side
     :param qt: A callback for tracking returning error code, which can be one of QUEUE_OK, QUEUE_TRANS_ALREADY_STARTED, and so on
     :return: true for sending the request successfully, and false for failure
     """
     if not key:
         key = ''
     buffer = CScopeUQueue.Lock().SaveAString(key)
     ok = None
     if not qt:
         ok = self.SendRequest(CAsyncQueue.idStartTrans, buffer, None)
     else:
         ok = self.SendRequest(CAsyncQueue.idStartTrans, buffer,
                               lambda ar: qt(ar.LoadInt()))
     CScopeUQueue.Unlock(buffer)
     return ok
Exemplo n.º 14
0
 def CloseQueue(self, key, c=None, permanent=False):
     """
     Try to close or delete a persistent queue opened at server side
     :param key: An ASCII string for identifying a queue at server side
     :param c: A callback for tracking returning error code, which can be one of QUEUE_OK, QUEUE_DEQUEUING, and so on
     :param permanent: true for deleting a queue file, and false for closing a queue file
     :return: true for sending the request successfully, and false for failure
     """
     if not key:
         key = ''
     buffer = CScopeUQueue.Lock().SaveAString(key).SaveBool(permanent)
     ok = None
     if not c:
         ok = self.SendRequest(CAsyncQueue.idClose, buffer, None)
     else:
         ok = self.SendRequest(CAsyncQueue.idClose, buffer,
                               lambda ar: c(ar.LoadInt()))
     CScopeUQueue.Unlock(buffer)
     return ok