兼容python3的SSDB客户端

SSDB.py

import socket


class SSDB_Response(object):
    def __init__(self, code='', data_or_message=None):
        self.type = 'none'
        self.code = code
        self.data = None
        self.message = None
        self.set(code, data_or_message)

    def set(self, code, data_or_message=None):
        self.code = code

        if code == 'ok':
            self.data = data_or_message
        else:
            if isinstance(data_or_message, list):
                if len(data_or_message) > 0:
                    self.message = data_or_message[0]
            else:
                self.message = data_or_message

    def __repr__(self):
        return ((((str(self.code) + ' ') + str(self.message)) + ' ') + str(self.data))

    def ok(self):
        return self.code == 'ok'

    def not_found(self):
        return self.code == 'not_found'

    def str_resp(self, resp):
        self.type = 'val'

        if resp[0] == 'ok':
            if len(resp) == 2:
                self.set('ok', resp[1])
            else:
                self.set('server_error', 'Invalid response')
        else:
            self.set(resp[0], resp[1:])
        return self

    def str_resp(self, resp):
        self.type = 'val'
        if resp[0] == 'ok':
            if len(resp) == 2:
                self.set('ok', resp[1])
            else:
                self.set('server_error', 'Invalid response')
        else:
            self.set(resp[0], resp[1:])
        return self

    def int_resp(self, resp):
        self.type = 'val'

        if resp[0] == 'ok':
            if len(resp) == 2:
                try:
                    val = int(resp[1])
                    self.set('ok', val)
                except Exception as e:
                    self.set('server_error', 'Invalid response')
            else:
                self.set('server_error', 'Invalid response')
        else:
            pass
            self.set(resp[0], resp[1:])
        return self

    def float_resp(self, resp):
        self.type = 'val'
        if resp[0] == 'ok':
            if len(resp) == 2:
                try:
                    val = float(resp[1])
                    self.set('ok', val)
                except Exception as e:
                    self.set('server_error', 'Invalid response')
            else:
                self.set('server_error', 'Invalid response')
        else:
            self.set(resp[0], resp[1:])
        return self

    def list_resp(self, resp):
        self.type = 'list'
        self.set(resp[0], resp[1:])
        return self

    def int_map_resp(self, resp):
        self.type = 'map'

        if resp[0] == 'ok':
            if len(resp) % 2 == 1:
                data = {'index': [], 'items': {}, }
                i = 1

                while i < len(resp):
                    k = resp[i]
                    v = resp[(i + 1)]
                    try:
                        v = int(v)
                    except Exception as e:
                        v = - (1)
                    data['index'].append(k)
                    data['items'][k] = v
                    i += 2
                self.set('ok', data)
            else:
                self.set('server_error', 'Invalid response')
        else:
            self.set(resp[0], resp[1:])
        return self

    def str_map_resp(self, resp):
        self.type = 'map'

        if resp[0] == 'ok':

            if len(resp) % 2 == 1:
                data = {'index': [], 'items': {}, }
                i = 1

                while i < len(resp):
                    k = resp[i]
                    v = resp[(i + 1)]
                    data['index'].append(k)
                    data['items'][k] = v
                    i += 2
                self.set('ok', data)
            else:
                self.set('server_error', 'Invalid response')
        else:
            self.set(resp[0], resp[1:])
        return self


class SSDB(object):
    def __init__(self, host, port):
        self.recv_buf = ''
        self._closed = False
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect(tuple([host, port]))
        self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

    def close(self):
        if not (self._closed):
            self.sock.close()
            self._closed = True

    def closed(self):
        pass
        return self._closed

    def request(self, cmd, params=None):
        pass

        if params is None:
            params = []
        params = ([cmd] + params)
        self.send(params)
        resp = self.recv()

        if resp is None:
            return SSDB_Response('error', 'Unknown error')

        if len(resp) == 0:
            return SSDB_Response('disconnected', 'Connection closed')
        ret = SSDB_Response()

        # {{{ switch: cmd
        _continue_1 = False
        while True:
            if False or ((cmd) == 'ping') or ((cmd) == 'set') or ((cmd) == 'del') or ((cmd) == 'qset') or (
                (cmd) == 'zset') or ((cmd) == 'hset') or ((cmd) == 'qpush') or ((cmd) == 'qpush_front') or (
                (cmd) == 'qpush_back') or ((cmd) == 'zdel') or ((cmd) == 'hdel') or ((cmd) == 'multi_set') or (
                (cmd) == 'multi_del') or ((cmd) == 'multi_hset') or ((cmd) == 'multi_hdel') or (
                (cmd) == 'multi_zset') or ((cmd) == 'multi_zdel'):
                if len(resp) > 1:
                    return ret.int_resp(resp)
                else:
                    return SSDB_Response(resp[0], None)
                break
            if False or ((cmd) == 'version') or ((cmd) == 'substr') or ((cmd) == 'get') or ((cmd) == 'getset') or (
                (cmd) == 'hget') or ((cmd) == 'qfront') or ((cmd) == 'qback') or ((cmd) == 'qget'):
                pass
                return ret.str_resp(resp)
                break
            if False or ((cmd) == 'qpop') or ((cmd) == 'qpop_front') or ((cmd) == 'qpop_back'):
                size = 1
                try:
                    size = int(params[2])
                except Exception as e:
                    pass

                if size == 1:
                    return ret.str_resp(resp)
                else:
                    return ret.list_resp(resp)
                break
            if False or ((cmd) == 'dbsize') or ((cmd) == 'getbit') or ((cmd) == 'setbit') or ((cmd) == 'countbit') or (
                (cmd) == 'bitcount') or ((cmd) == 'strlen') or ((cmd) == 'ttl') or ((cmd) == 'expire') or (
                (cmd) == 'setnx') or ((cmd) == 'incr') or ((cmd) == 'decr') or ((cmd) == 'zincr') or (
                (cmd) == 'zdecr') or ((cmd) == 'hincr') or ((cmd) == 'hdecr') or ((cmd) == 'hsize') or (
                (cmd) == 'zsize') or ((cmd) == 'qsize') or ((cmd) == 'zget') or ((cmd) == 'zrank') or (
                (cmd) == 'zrrank') or ((cmd) == 'zsum') or ((cmd) == 'zcount') or ((cmd) == 'zremrangebyrank') or (
                (cmd) == 'zremrangebyscore') or ((cmd) == 'hclear') or ((cmd) == 'zclear') or ((cmd) == 'qclear') or (
                (cmd) == 'qpush') or ((cmd) == 'qpush_front') or ((cmd) == 'qpush_back') or (
                (cmd) == 'qtrim_front') or ((cmd) == 'qtrim_back'):
                pass
                return ret.int_resp(resp)
                break
            if False or ((cmd) == 'zavg'):
                pass
                return ret.float_resp(resp)
                break
            if False or ((cmd) == 'keys') or ((cmd) == 'rkeys') or ((cmd) == 'zkeys') or ((cmd) == 'zrkeys') or (
                (cmd) == 'hkeys') or ((cmd) == 'hrkeys') or ((cmd) == 'list') or ((cmd) == 'hlist') or (
                (cmd) == 'hrlist') or ((cmd) == 'zlist') or ((cmd) == 'zrlist'):
                pass
                return ret.list_resp(resp)
                break
            if False or ((cmd) == 'scan') or ((cmd) == 'rscan') or ((cmd) == 'hgetall') or ((cmd) == 'hscan') or (
                (cmd) == 'hrscan'):
                pass
                return ret.str_map_resp(resp)
                break
            if False or ((cmd) == 'zscan') or ((cmd) == 'zrscan') or ((cmd) == 'zrange') or ((cmd) == 'zrrange') or (
                (cmd) == 'zpop_front') or ((cmd) == 'zpop_back'):
                pass
                return ret.int_map_resp(resp)
                break
            if False or ((cmd) == 'auth') or ((cmd) == 'exists') or ((cmd) == 'hexists') or ((cmd) == 'zexists'):
                pass
                return ret.int_resp(resp)
                break
            if False or ((cmd) == 'multi_exists') or ((cmd) == 'multi_hexists') or ((cmd) == 'multi_zexists'):
                pass
                return ret.int_map_resp(resp)
                break
            if False or ((cmd) == 'multi_get') or ((cmd) == 'multi_hget'):
                pass
                return ret.str_map_resp(resp)
                break
            if False or ((cmd) == 'multi_hsize') or ((cmd) == 'multi_zsize') or ((cmd) == 'multi_zget'):
                pass
                return ret.int_map_resp(resp)
                break
            ### default
            return ret.list_resp(resp)
            break
            break
            if _continue_1:
                continue
        # }}} switch

        return SSDB_Response('error', 'Unknown error')

    def send(self, data):
        pass
        ps = []

        _cpy_r_0 = _cpy_l_1 = data
        if type(_cpy_r_0).__name__ == 'dict':
            _cpy_b_3 = True; _cpy_l_1 = _cpy_r_0.iterkeys()
        else:
            _cpy_b_3 = False;
        for _cpy_k_2 in _cpy_l_1:
            if _cpy_b_3:
                p = _cpy_r_0[_cpy_k_2]
            else:
                p = _cpy_k_2
            pass
            p = str(p)
            ps.append(str(len(p)))
            ps.append(p)
        nl = '\n'
        s = (nl.join(ps) + '\n\n')
        try:
            while True:
                ret = self.sock.send(s.encode())
                if ret == 0:
                    return - (1)
                s = s[ret:]
                if len(s) == 0:
                    break
        except socket.error as e:
            return -(1)
        return ret

    def net_read(self):
        try:
            data = self.sock.recv(1024 * 8)
        except Exception as e:
            data = ''

        if data == '':
            self.close()
            return 0
        self.recv_buf += str(data,encoding = "ascii")
        return len(data)

    def recv(self):
        while True:
            ret = self.parse()
            if ret is None:
                if self.net_read() == 0:
                    return []
            else:
                return ret

    def parse(self):
        pass
        ret = []
        spos = 0
        epos = 0

        while True:
            spos = epos
            epos = self.recv_buf.find('\n', spos)

            if epos == - (1):
                break
            epos += 1
            line = self.recv_buf[spos: epos]
            spos = epos

            if line.strip() == '':
                if len(ret) == 0:
                    continue
                else:
                    self.recv_buf = self.recv_buf[spos:]
                    return ret
            try:
                num = int(line)
            except Exception as e:
                return []
            epos = (spos + num)

            if epos > len(self.recv_buf):
                break
            data = self.recv_buf[spos: epos]
            ret.append(data)
            spos = epos
            epos = self.recv_buf.find('\n', spos)

            if epos == - (1):
                break
            epos += 1
        return None

测试程序

from SSDB import SSDB

ssdb = SSDB('192.168.1.250', 8888)

l  =  []
l.append('person_1')
l.append('a')
l.append('1111')
l.append('b')
l.append('2222')

print(ssdb.request('multi_hset', l))

'''
print(ssdb.request('set', ['test', '123']))
print(ssdb.request('get', ['test']))
print(ssdb.request('incr', ['test', '1']))
print(ssdb.request('decr', ['test', '1']))
print(ssdb.request('scan', ['a', 'z', 10]))
print(ssdb.request('rscan', ['z', 'a', 10]))
print(ssdb.request('keys', ['a', 'z', 10]))
print(ssdb.request('del', ['test']))
print(ssdb.request('get', ['test']))
print("\n")
print(ssdb.request('zset', ['test', 'a', 20]))
print(ssdb.request('zget', ['test', 'a']))
print(ssdb.request('zincr', ['test', 'a', 20]))
print(ssdb.request('zdecr', ['test', 'a', 20]))
print(ssdb.request('zscan', ['test', 'a', 0, 100, 10]))
print(ssdb.request('zrscan', ['test', 'a', 100, 0, 10]))
print(ssdb.request('zkeys', ['test', 'a', 0, 100, 10]))
print(ssdb.request('zdel', ['test', 'a']))
print(ssdb.request('zget', ['test', 'a']))
print("\n")
print(ssdb.request('hset', ['test', 'a', 20]))
print(ssdb.request('hget', ['test', 'a']))
print(ssdb.request('hincr', ['test', 'a', 20]))
print(ssdb.request('hdecr', ['test', 'a', 20]))
print(ssdb.request('hscan', ['test', '0', 'z', 10]))
print(ssdb.request('hrscan', ['test', 'z', '0', 10]))
print(ssdb.request('hkeys', ['test', '0', 'z', 10]))
print(ssdb.request('hdel', ['test', 'a']))
print(ssdb.request('hget', ['test', 'a']))
print("\n")
'''

 pyssdb客户端的使用

import pyssdb

c = pyssdb.Client('192.168.1.250', 8888)
list = ['lastName', '', 'firstName', '']
print(c.multi_hset('person_1', *tuple(list)))
c.disconnect()

 测试多线程

import pyssdb
import threading

# 客户端默认是有连接池的
c = pyssdb.Client('192.168.1.250', 8888)

def makeCache(func):
    list = ['lastName', '', 'firstName', '']
    for i in range(10000):
        c.multi_hset('person_huanghai_'+str((func-1)*i), *tuple(list))
    print('成功完成线程:'+str(func))
# 定义五个线程

threads = []
t1 = threading.Thread(target=makeCache, args=(1,))
threads.append(t1)

t2 = threading.Thread(target=makeCache, args=(2,))
threads.append(t2)

t3 = threading.Thread(target=makeCache, args=(3,))
threads.append(t3)

t4 = threading.Thread(target=makeCache, args=(4,))
threads.append(t4)

t5 = threading.Thread(target=makeCache, args=(5,))
threads.append(t5)

for t in threads:
    t.setDaemon(True)
    t.start()
    
t1.join()
t2.join()
t3.join()
t4.join()
t5.join()

c.disconnect()
print('程序结束')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值