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
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
|