def execute(self, sql_or_array, row=None, rh=None, meta=True, lastInsertId=True): reqId = DB_CONSTS.idExecute if isinstance(sql_or_array, list): reqId = DB_CONSTS.idExecuteParameters elif isinstance(sql_or_array, tuple): reqId = DB_CONSTS.idExecuteParameters f = future() def arh(ah, res, err_msg, affected, fail_ok, last_id): if f.done(): return f.set_result({ 'ec': res, 'em': err_msg, 'affected': affected, 'oks': (fail_ok & 0xffffffff), 'fails': (fail_ok >> 32), 'lastId': last_id }) if not self.Execute(sql_or_array, arh, row, rh, meta, lastInsertId, CAsyncDBHandler.get_aborted(f, reqId), CAsyncDBHandler.get_se(f)): self.throw(f) return f
def executeBatch(self, isolation, sql, vParam, row=None, rh=None, delimiter=';', batchHeader=None, meta=True, plan=tagRollbackPlan.rpDefault, vPInfo=None, lastInsertId=True): f = future() def arh(ah, res, err_msg, affected, fail_ok, last_id): if f.done(): return f.set_result({ 'ec': res, 'em': err_msg, 'affected': affected, 'oks': (fail_ok & 0xffffffff), 'fails': (fail_ok >> 32), 'lastId': last_id }) if not self.ExecuteBatch( isolation, sql, vParam, arh, row, rh, delimiter, batchHeader, CAsyncDBHandler.get_aborted(f, DB_CONSTS.idExecuteBatch), meta, plan, vPInfo, lastInsertId, CAsyncDBHandler.get_se(f)): self.throw(f) return f
def download(self, localFile, remoteFile, trans=None, flags=FILE_OPEN_TRUNCACTED): """ Post a context to download a remote file at server side to a local file at client side :param localFile: A path to a local file at client side for downloading :param remoteFile: A path to a remote file at server side :param trans: A callback for tracking downloading progress :param flags: An integer bit-wise option flags for one or more options such as FILE_OPEN_TRUNCACTED|FILE_OPEN_APPENDED and FILE_OPEN_SHARE_WRITE :return: A future for a final result ({'ec':res, 'em':errmsg}) of downloading, which contains an int and an error message """ f = future() def cb_download(file, res, errmsg): if f.done(): return f.set_result({'ec': res, 'em': errmsg}) ok = self.Download( localFile, remoteFile, cb_download, trans, CStreamingFile.get_aborted(f, CStreamingFile.idDownload), flags, CStreamingFile.get_se(f)) return f
def close(self): f = future() def arh(ah, res, err_msg): if f.done(): return f.set_result({'ec': res, 'em': err_msg}) if not self.Close(arh, CAsyncDBHandler.get_aborted( f, DB_CONSTS.idClose), CAsyncDBHandler.get_se(f)): self.throw(f) return f
def open(self, strConnection, flags=0): f = future() def arh(ah, res, err_msg): if f.done(): return f.set_result({'ec': res, 'em': err_msg}) if not self.Open(strConnection, arh, flags, CAsyncDBHandler.get_aborted(f, DB_CONSTS.idOpen), CAsyncDBHandler.get_se(f)): self.throw(f) return f
def endTrans(self, plan=tagRollbackPlan.rpDefault): f = future() def arh(ah, res, err_msg): if f.done(): return f.set_result({'ec': res, 'em': err_msg}) if not self.EndTrans( plan, arh, CAsyncDBHandler.get_aborted( f, DB_CONSTS.idEndTrans), CAsyncDBHandler.get_se(f)): self.throw(f) return f
def endQueueTrans(self, rollback=False): f = future() def cb(aq, ec): if f.done(): return f.set_result(ec) if not self.EndQueueTrans( rollback, cb, CAsyncQueue.get_aborted( f, CAsyncQueue.idEndTrans), CAsyncQueue.get_se(f)): self.throw(f) return f
def startQueueTrans(self, key): f = future() def cb(aq, ec): if f.done(): return f.set_result(ec) if not self.StartQueueTrans( key, cb, CAsyncQueue.get_aborted(f, CAsyncQueue.idStartTrans), CAsyncQueue.get_se(f)): self.throw(f) return f
def prepare(self, sql, lstParameterInfo=[]): f = future() def arh(ah, res, err_msg): if f.done(): return f.set_result({'ec': res, 'em': err_msg}) if not self.Prepare( sql, arh, lstParameterInfo, CAsyncDBHandler.get_aborted(f, DB_CONSTS.idPrepare), CAsyncDBHandler.get_se(f)): self.throw(f) return f
def beginTrans(self, isolation=tagTransactionIsolation.tiReadCommited): f = future() def arh(ah, res, err_msg): if f.done(): return f.set_result({'ec': res, 'em': err_msg}) if not self.BeginTrans( isolation, arh, CAsyncDBHandler.get_aborted(f, DB_CONSTS.idBeginTrans), CAsyncDBHandler.get_se(f)): self.throw(f) return f
def sendRequest(self, reqId, q): """ Send a request onto a remote server for processing, and return a future immediately without blocking :param reqId: An unique request id within a service handler :param q: An instance of CScopeUQueue or CUQueue or None :return: A future for an instance of CScopeUQueue containing an expected result """ f = future() def arh(ar): # ar: an instance of CAsyncResult if f.done(): return sb = CScopeUQueue() sb.UQueue.Swap(ar.UQueue) f.set_result(sb) if not self.SendRequest(reqId, q, arh, CAsyncServiceHandler.get_aborted(f, reqId), CAsyncServiceHandler.get_se(f)): self.throw(f) return f
def getKeys(self): """ Query queue keys opened at server side :return: A future for a list of key names corresponding to a list of queue files """ f = future() def cb(aq, keys): if f.done(): return f.set_result(keys) if not self.GetKeys(cb, CAsyncQueue.get_aborted(f, CAsyncQueue.idGetKeys), CAsyncQueue.get_se(f)): self.throw(f) return f
def closeQueue(self, key, 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 permanent: true for deleting a queue file, and false for closing a queue file :return: A future object for an error code, which can be one of QUEUE_OK, QUEUE_DEQUEUING, and so on """ f = future() def cb(aq, ec): if f.done(): return f.set_result(ec) if not self.CloseQueue(key, cb, CAsyncQueue.get_aborted(f, CAsyncQueue.idClose), permanent, CAsyncQueue.get_se(f)): self.throw(f) return f
def flushQueue(self, key, option=tagOptimistic.oMemoryCached): """ 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 option: one of tagOptimistic options, oMemoryCached, oSystemMemoryCached and oDiskCommitted :return: A future for dictionary object containing messages remaining in server queue file and the queue file size in bytes """ f = future() def cb(aq, message_count, file_size): if f.done(): return f.set_result({'messages': message_count, 'fsize': file_size}) if not self.FlushQueue(key, cb, option, CAsyncQueue.get_aborted(f, CAsyncQueue.idFlush), CAsyncQueue.get_se(f)): self.throw(f) return f
def test_dequeue(aq): def cbResultReturned(idReq, q): if idReq == idMessage0 or idReq == idMessage1 or idReq == idMessage2: # parse a dequeued message which should be the same as # the above enqueued message (two unicode strings and one int) s = 'message id=' + str(idReq) + ', name=' + q.LoadString() + \ ', str=' + q.LoadString() + ', index=' + str(q.LoadInt()) print(s) return True return False # not processed aq.ResultReturned = cbResultReturned f = future() aborted = CAsyncQueue.get_aborted(f, CAsyncQueue.idDequeue) se = CAsyncQueue.get_se(f) def cbDequeue(aq, messageCount, fileSize, messages, bytes): if bytes: s = 'Total message count=' + str(messageCount) + ', queue file size=' + \ str(fileSize) + ', messages dequeued=' + str(messages) + ', bytes dequeued=' + str(bytes) print(s) if messageCount > 0: # there are more messages left at server queue, we re-send a request to dequeue aq.Dequeue(TEST_QUEUE_KEY, aq.LastDequeueCallback, 0, aborted, se) elif not f.done(): f.set_result({ 'messages': messageCount, 'fsize': fileSize, 'msgsDequeued': messages, 'bytes': bytes }) print('Going to dequeue messages ......') # optionally, add one extra to improve processing concurrency # at both client and server sides for better performance and through-output if not (aq.Dequeue(TEST_QUEUE_KEY, cbDequeue, 0, aborted, se) and aq.Dequeue(TEST_QUEUE_KEY, cbDequeue, 0, aborted, se)): aq.throw(f) return f
def dequeue(self, key, timeout=0): """ 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 timeout: A time-out number in milliseconds :return: A future for dictionary object containing messages remaining in server queue file, the queue file size in bytes, messages and bytes dequeued in this dequeue request """ f = future() def cb(aq, message_count, file_size, deq_msgs, deq_bytes): if f.done(): return f.set_result({ 'messages': message_count, 'fsize': file_size, 'msgsDequeued': deq_msgs, 'bytes': deq_bytes }) if not self.Dequeue(key, cb, timeout, CAsyncQueue.get_aborted(f, CAsyncQueue.idDequeue), CAsyncQueue.get_se(f)): self.throw(f) return f