资讯专栏INFORMATION COLUMN

resty-mongol3的简单封装

SimpleTriangle / 2084人阅读

摘要:的简单封装近期项目中需要用到来操作数据库,在上面找了给开源的发现支持不了的认证,后来发现对其改进了一下,能够支持认证,因为业务中经常用到来进行操作,所以参照的方式对其进行了一下简单的封装,方便以后使用。

resty-mongol3的简单封装

近期项目中需要用到 openresty 来操作 mongodb 数据库,在 github 上面找了给开源的 resty-mongol 发现支持不了 mongo3.0 的认证,后来发现 resty-mongol3 对其改进了一下,能够支持 mongo3.0 认证,因为业务中经常用到 mongo 来进行操作,所以参照 mongo shell 的方式对其进行了一下简单的封装,方便以后使用。(因为业务需要,有的方法不要被支持,固没有封装)如有 bug ,望大家批评指正。

local mongo = require("resty.mongol")
local object_id = require("resty.mongol.object_id")
local _M = {
    _VERSION = "0.0.1"
}

local metatable = { __index = _M }

-- 创建objectId
_M.objectId = function(str)
    local buf = (str:gsub("..", function (cc)
        return string.char(tonumber(cc, 16))
        end))
    return object_id.new(buf)
end

--[[
    @desc
        Creates a MongoClient instance. 
    @params
        opts            @type     table
    @return
        table             @type     table     A MongoClient instance
 ]]
function _M.new(self, opts)
    opts = opts or {}
    local timeout     = opts.timeout or 3000
    local host         = opts.host or "localhost"
    local port         = opts.port or 27017
    local passwd    = opts.passwd or ""
    local user    =  opts.user or ""
    local database  = opts.database or "admin"
    local keepalive = (opts.keepalive and opts.keepalive * 1000) or 60000
    local poolSize  = opts.poolSize or 1000
  
    return setmetatable({
            timeout      = timeout,
            host          = host,
            port         = tostring(port),
            user          = user,
            passwd         = passwd,
            database     = database,
            keepalive     = keepalive,
            poolSize     = poolSize,
            _db            = database,
            _user        = user,
            _passwd     = passwd,
            _sort       = {},
            _limit      = 100,
            _skip       = 0,
            }, metatable)
end

--[[
    @desc
        get mongodb"s connection objects. 
 ]]
local function getMgoConn(mgoConfig)
    -- 获取连接对象
    local mgoConn = mongo:new()
    if not mgoConn then
        return nil, "get mongo connection occur error"
    end
    
    -- 设置链接超时
    mgoConn:set_timeout(mgoConfig.timeout)
    
    --获取连接客户端
    local ok, err =mgoConn:connect(mgoConfig.host, mgoConfig.port)
    if not ok then 
        return nil, err
    end 
    return mgoConn, nil
end

--[[
    @desc
        pack connection commands. 
 ]]
local function packConnCmd(self, mgoConn, cmd, ... )    
    local result, err = mgoConn[cmd](mgoConn, ... )

    mgoConn:set_keepalive(self.keepalive, self.poolSize)
    
    return result, err
end

--[[
    @desc
        this is a map of mongol.conn"s command. 
 ]]
local connCmd = {
    isMaster         = "ismaster",
    getPrimary         = "getprimary",
    getReusedTime     = "get_reused_times",
    dbs             = "databases",           
}
for k,v in pairs(connCmd) do
    
    _M[k] =
            function (self, ...)
                   --获取连接客户端
                local mgoConn, err = getMgoConn(self)
                if not mgoConn then 
                    return nil, err
                end 
                return packConnCmd(self, mgoConn, v, ...)
            end
end


--[[
    @desc
        switch db by dbName and auth your id 
    @params

    @return
        Returns a database object, or nil.
 ]]
function _M.useDatabase(self, dbName, user, passwd)
       --获取连接客户端
       self._db = dbName
       self._user = user or self._user
       self._passwd = passwd or self._psswd
       return string.format("%s %s","current database is", dbName)
end

function _M.ping( self )
       --获取连接客户端
    local mgoConn, err = getMgoConn(self)
    if not mgoConn then 
        return nil, err
    end    
        
    local db = mgoConn:new_db_handle(self._db)
    if not db then
        return nil, "get database occur error"
    end

    --用户授权
    local count, err = mgoConn:get_reused_times()

    if (count == 0) or err then
        if self._user and self._passwd then
            local ok, err = db:auth_scram_sha1(self._user, self._passwd)
            if not ok then 
                return nil, err
            end 
        end
    end
    return "ok", nil
end

--[[
    @desc
        switch db by self.dbName and auth your id 
    @params
        dbName            @type     table     @default    self.database
        user             @type     string     @default    self.user
        passwd             @type     string  @default     self.passwd
    @return
        Returns a database object, or nil.
 ]]
local function getDB(self)
       --获取连接客户端
    local mgoConn, err = getMgoConn(self)
    if not mgoConn then 
        return nil, nil, err
    end    

    local db = mgoConn:new_db_handle(self._db)
    if not db then
        return nil, nil, "get database occur error"
    end

    --用户授权
    local count, err = mgoConn:get_reused_times()

    if (count == 0) or err then
        if self._user and self._passwd then
            local ok, err = db:auth_scram_sha1(self._user, self._passwd)
            if not ok then 
                return nil, nil, err
            end 
        end
    end
    return db, mgoConn, nil
end

local dbCmd = {
    addUser         = "add_user",
    -- getColl         = "get_col",
    -- getGrid         = "get_grid", 
    dropDatabase     = "dropDatabase", 
}

--[[
    @desc
        pack database commands. 
 ]]
local function packDBCmd(self, db, mgoConn, cmd, ... )    
    local result, err = db[cmd](db, ... )

    mgoConn:set_keepalive(self.keepalive, self.poolSize)
    
    return result, err
end

for k,v in pairs(dbCmd) do
    
    _M[k] =
            function (self, ...)
                   --获取连接客户端
                local db, mgoConn, err = getDB(self)
                if not db then
                    return nil, "get current database occur error " .. err
                end
                return packDBCmd(self, db, mgoConn, v, ...)
            end
end

function _M.list( self )
       --获取连接客户端
    local db, mgoConn, err = getDB(self)
    if not db then
        return nil, "get current database occur error " .. err
    end
    -- return packDBCmd(self, db, mgoConn, v, ...)
    local cursor, err = db:listcollections()
    if not cursor then
        return nil, string.format("%s %s %s", "system.namespaces", "find occur error", err)
    end
    local results = {}
    for index, item in cursor:pairs() do
        table.insert(results, item)
    end
    
    mgoConn:set_keepalive(self.keepalive, self.poolSize)
    
    return result, err
end

function _M.getCollection( self, collName )
    self.collName = collName
    return self
end

local collCmd = {
    count     = "count",
    drop     = "drop",
    update     = "update",    
    insert  = "insert",  
    delete     = "delete", 
}

--[[
    @desc
        pack collection"s commands. 
 ]]
local function packCollCmd(self, db, mgoConn, cmd, ... )    
    --获取集合
    local coll = db:get_col(self.collName)
    if not coll then
        return nil, "get collection occur error"
    end

    local result, err = coll[cmd](coll, ... )

    mgoConn:set_keepalive(self.keepalive, self.poolSize)
    
    return result, err
end

for k,v in pairs(collCmd) do
    
    _M[k] =
            function (self, ...)
                   --获取连接客户端
                local db, mgoConn, err = getDB(self)
                if not db then
                    return nil, "get current database occur error " .. err
                end
                return packCollCmd(self, db, mgoConn, v, ...)
            end
end

function _M.sort( self, fields )
    self._sort = fields
    return self
end

function _M.limit( self, num )
    self._limit = num 
    return self
end

function _M.skip( self, num )
    self._skip = num
    return self
end

--[[
find 方法要在用户每次操作后直接帮他关闭链接,所以没有返回游标给用户,而是自己内部遍历了下,直接返回结果
]] 
function _M.find( self, ... )
       --获取连接客户端
    local db, mgoConn, err = getDB(self)
    if not db then
        return nil, "get current database occur error " .. err
    end
    --获取集合
    local coll, err = db:get_col(self.collName)
    
    if not coll then
        return nil, "get collection occur error"
    end

    local cursor, err = coll["find"](coll, ... )
    if not cursor then
        return nil, string.format("%s %s %s", self.collName, "find occur error", err)
    end

    cursor:limit(self._limit)
    cursor:skip(self._skip)
    cursor = cursor:sort(self._sort)
    local results = {}
    for index, item in cursor:pairs() do
        table.insert(results, item)
    end
    mgoConn:set_keepalive(self.keepalive, self.poolSize)
    return results, err    
end

return _M

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/18988.html

相关文章

  • 前端基础进阶(八):深入详解函数柯里化

    摘要:函数被转化之后得到柯里化函数,能够处理的所有剩余参数。因此柯里化也被称为部分求值。那么函数的柯里化函数则可以如下因此下面的运算方式是等价的。而这里对于函数参数的自由处理,正是柯里化的核心所在。额外知识补充无限参数的柯里化。 showImg(https://segmentfault.com/img/remote/1460000008493346); 柯里化是函数的一个比较高级的应用,想要...

    kk_miles 评论0 收藏0
  • ajax简单封装

    摘要:工作之余简单封装了的请求,但是工作中还是用,,内部封装好了模块笑。代码解析参数创建高级浏览器和以上连接发送请求头发送接收完成清除定时器成功超时超时了终止转 工作之余简单封装了ajax的请求,但是工作中还是用jquery,axios,angular内部封装好了http模块(笑)。 ajax一般分为简单的四部: 创建ajax对象(这里兼容ie的话要做一下处理) 连接,即请求对象的open...

    caoym 评论0 收藏0
  • node.js对mysql数据库封装库node-transform-mysql库 链式调用、使用简单

    摘要:最近我准备写一个这样的库,基于前期自己对的封装是我使用过的一个框架,对它的模型模块调用的方式很喜欢因此决定参考其,用实现一次。 在我自己的平常开发中很少有见到javascript对sql的封装比较好的库(找了一圈也没找到、应该是暂时我没发现),因此前期的项目中根据自己的项目情况实现了一套封装方法。 最近我准备写一个这样的库,基于前期自己对mysql的封装(ThinkPHP是我使用过的一...

    Tikitoo 评论0 收藏0
  • js异步从入门到放弃(四)- Generator 封装异步任务

    摘要:总结本文简要介绍了函数的一些特性,重点在于说明如何使用函数对异步任务进行封装,从而能够让异步代码编写的更加清晰。 在之前的文章介绍了传统异步的实现方案,本文将介绍ES6中的一种全新的异步方案--Generator函数。 generator简介 简单介绍一下generator的原理和语法,(更详细内容请看ECMAScript 6 入门,本文只介绍和异步相关的核心内容) 基本语法 通过一个...

    jimhs 评论0 收藏0

发表评论

0条评论

SimpleTriangle

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<