skynet的ssdb驱动

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

local skynet = require "skynet"
local socket = require "socket"
local socketchannel = require "socketchannel"
local int64 = require "int64"

local ssdb = {}
local command = {}
local meta = {
    __index = command,
    -- DO NOT close channel in __gc
}

local function read_block( fd )
    local result = fd:readline "\n"
    -- print('read_block result',result,string.len(result))
    local len = tonumber(result)
    -- print('read_block result len',len)
    if not len  then
        return false
    elseif len == 0 then 
        local result = fd:readline "\n\n"
        return false
    end

    local value = fd:read(len+1)
    -- print('read_block value',value)
    local data = string.sub(value,1,-2)
    -- print('read_block data',data)
    -- print('data',data)
    return true,data
end


local function read_response(fd)
    local ok,result = read_block(fd)
    -- print('read_response read_block result',ok,result)
    if ok then
        if result~='ok' then
            read_block(fd)
            
            -- print('read_response')
            return true
        end
    end
    
    local bulk = {}
    local ok,d = read_block(fd)
    while ok do

        table.insert(bulk,d)

        ok,d = read_block(fd)
        if not ok then
            break
        end
    end
    
    if #bulk<=1 then
        -- print('read_response')
        return true,bulk[1]
    end
    -- print('read_response')
    return true,bulk
end

local function pack_value(lines, v)
    if v == nil then
        return
    end

    local t = type(v)
    if t == "number" then
        v = tostring(v)
    elseif t == "userdata" then
        v = int64.tostring(int64.new(v),10)
    end
    table.insert(lines,#v)
    table.insert(lines,v)
end

local function compose_message(cmd, msg)
    local t = type(msg)

    local lines = {}
    pack_value(lines,cmd)

    if t == "table" then
        for _,v in ipairs(msg) do
            pack_value(lines, v)
        end
    else
        pack_value(lines, msg)
    end

    local chunk =  table.concat(lines,"\n")..'\n\n'
    -- print("chunk",chunk)
    return chunk
end

setmetatable(command, { __index = function(t,k)
    local cmd = string.lower(k)
    local f = function (self, v, ...)
        if type(v) == "table" then
            return self[1]:request(compose_message(cmd, v), read_response)
        else
            local s = compose_message(cmd, {v, ...})
            return self[1]:request(s, read_response)
        end
    end
    t[k] = f
    return f
end})


function ssdb.connect(db_conf)
    local channel = socketchannel.channel {
        host = db_conf.host,
        port = db_conf.port or 8888,
    }
    -- try connect first only once
    channel:connect(true)
    return setmetatable( { channel }, meta )
end


return ssdb