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
用户登录
还没有账号?立即注册
用户注册
投稿取消
| 文章分类: |
|
还能输入300字
上传中....
奔跑的宅猪