You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
3.3 KiB
Lua

-- module("resty.mongol", package.seeall)
local _M={}
local mt = { __index = _M }
local mod_name = (...)
local assert , pcall = assert , pcall
local ipairs , pairs = ipairs , pairs
local setmetatable = setmetatable
local socket = ngx.socket.tcp
local connmethods = { }
local connmt = { __index = connmethods }
local dbmt = require ( mod_name .. ".dbmt" )
function connmethods:ismaster()
local db = self:new_db_handle("admin")
local r, err = db:cmd({ismaster = true})
if not r then
return nil, err
end
return r.ismaster, r.hosts
end
local function parse_host ( str )
local host , port = str:match ( "([^:]+):?(%d*)" )
port = port or 27017
return host , port
end
function connmethods:getprimary ( searched )
searched = searched or { [ self.host .. ":" .. self.port ] = true }
local db = self:new_db_handle("admin")
local r, err = db:cmd({ ismaster = true })
if not r then
return nil, "query admin failed: "..err
elseif r.ismaster then return self
else
for i , v in ipairs ( r.hosts ) do
if not searched[v] then
searched[v] = true
local host, port = parse_host(v)
local conn = new()
local ok, err = conn:connect(host, port)
if not ok then
return nil, "connect failed: "..err..v
end
local found = conn:getprimary(searched)
if found then
return found
end
end
end
end
return nil , "No master server found"
end
function connmethods:databases()
local db = self:new_db_handle("admin")
local r = assert ( db:cmd({ listDatabases = true } ))
return r.databases
end
function connmethods:shutdown()
local db = self:new_db_handle("admin")
db:cmd({ shutdown = true } )
end
function connmethods:new_db_handle ( db )
if not db then
return nil
end
return setmetatable ( {
conn = self ;
db = db ;
} , dbmt )
end
function connmethods:set_timeout(timeout)
local sock = self.sock
if not sock then
return nil, "not initialized"
end
return sock:settimeout(timeout)
end
function connmethods:set_keepalive(...)
local sock = self.sock
if not sock then
return nil, "not initialized"
end
return sock:setkeepalive(...)
end
function connmethods:get_reused_times()
local sock = self.sock
if not sock then
return nil, "not initialized"
end
return sock:getreusedtimes()
end
function connmethods:connect(host, port)
self.host = host or self.host
self.port = port or self.port
local sock = self.sock
return sock:connect(self.host, self.port)
end
function connmethods:close()
local sock = self.sock
if not sock then
return nil, "not initialized"
end
return sock:close()
end
connmt.__call = connmethods.new_db_handle
function _M.new(self)
return setmetatable({
sock = socket(),
host = "localhost",
port = 27017
},
{
__call = connmethods.new_db_handle,
__index = connmethods
})
end
-- to prevent use of casual module global variables
-- getmetatable(_M).__newindex = function (table, key, val)
-- error('attempt to write to undeclared variable "' .. key .. '": '
-- .. debug.traceback())
-- end
return _M