mirror of
https://github.com/d0zingcat/rime_wanxiang.git
synced 2026-05-13 15:10:03 +00:00
117 lines
2.8 KiB
Lua
117 lines
2.8 KiB
Lua
local META_KEY_PREFIX = "\001" .. "/"
|
|
|
|
-- UserDb 缓存,使用弱引用表,不阻止垃圾回收并能自动清理
|
|
local db_pool = setmetatable({}, { __mode = "v" })
|
|
|
|
---@class WrappedUserDb: UserDb
|
|
---@field meta_query fun(self: self, prefix: string): DbAccessor
|
|
---@field meta_fetch fun(self: self, key: string): string|nil
|
|
---@field meta_update fun(self: self, key: string, value: string): boolean
|
|
---@field meta_erase fun(self: self, key: string): boolean
|
|
---@field query_with fun(self: self, prefix: string, handler: fun(key: string, value: string))
|
|
---@field empty fun(self: self, include_metafield?: boolean) -- 清空数据库
|
|
|
|
-- 用于存放包装器对象的自定义方法
|
|
local extends = {}
|
|
|
|
--- @param key string
|
|
--- @return string|nil
|
|
function extends:meta_fetch(key)
|
|
return self._db:fetch(META_KEY_PREFIX .. key)
|
|
end
|
|
|
|
--- @param key string
|
|
--- @param value string
|
|
--- @return boolean
|
|
function extends:meta_update(key, value)
|
|
return self._db:update(META_KEY_PREFIX .. key, value)
|
|
end
|
|
|
|
--- @param key string
|
|
--- @return boolean
|
|
function extends:meta_erase(key)
|
|
return self._db:erase(META_KEY_PREFIX .. key)
|
|
end
|
|
|
|
--- @param prefix string
|
|
--- @return DbAccessor
|
|
function extends:meta_query(prefix)
|
|
return self._db:query(META_KEY_PREFIX .. prefix)
|
|
end
|
|
|
|
function extends:query_with(prefix, handler)
|
|
local da = self._db:query(prefix)
|
|
if da then
|
|
for key, value in da:iter() do
|
|
handler(key, value)
|
|
end
|
|
end
|
|
da = nil
|
|
collectgarbage()
|
|
end
|
|
|
|
--- @param include_metafield boolean 是否也清理元数据。
|
|
function extends:empty(include_metafield)
|
|
self:query_with("", function(key, _)
|
|
local is_metafield = key:find(META_KEY_PREFIX, 1, true) == 1
|
|
if include_metafield or not is_metafield then
|
|
self._db:erase(key)
|
|
end
|
|
end)
|
|
end
|
|
|
|
local mt = {
|
|
__index = function(wrapper, key)
|
|
-- 优先使用自定义方法
|
|
if extends[key] then
|
|
return extends[key]
|
|
end
|
|
|
|
-- 不是自定义方法,委托给真实的 UserDb 对象
|
|
local real_db = wrapper._db
|
|
local value = real_db[key]
|
|
|
|
if type(value) == "function" then
|
|
return function(_, ...)
|
|
return value(real_db, ...)
|
|
end
|
|
end
|
|
|
|
return value
|
|
end,
|
|
}
|
|
|
|
local userdb = {}
|
|
|
|
--- @param db_name string
|
|
--- @param db_class "userdb" | "plain_userdb" | nil
|
|
--- @return WrappedUserDb
|
|
function userdb.UserDb(db_name, db_class)
|
|
db_class = db_class or "userdb"
|
|
local key = db_name .. "." .. db_class
|
|
|
|
---@type UserDb
|
|
local db = db_pool[key]
|
|
if not db then
|
|
db = UserDb(db_name, db_class)
|
|
db_pool[key] = db
|
|
end
|
|
|
|
local wrapper = {
|
|
_db = db,
|
|
_pool_key = key,
|
|
}
|
|
|
|
return setmetatable(wrapper, mt)
|
|
end
|
|
|
|
function userdb.LevelDb(db_name)
|
|
return userdb.UserDb(db_name, "userdb")
|
|
end
|
|
|
|
function userdb.TableDb(db_name)
|
|
return userdb.UserDb(db_name, "plain_userdb")
|
|
end
|
|
|
|
return userdb
|