comp-tg/etc/db/init.lua

74 lines
1.7 KiB
Lua

local mp = require 'etc.db.mp'
local tools = {
isFile = function(path)
local f = io.open(path, 'r')
if not f then return false end
f:close()
return true
end,
isDir = function(path)
path = (path .. '/'):gsub('//', '/')
local o, _, c = os.rename(path, path)
return o or c == 13
end,
loadPg = function(db, k)
local f = io.open(db._path .. '/' .. k, 'rb')
if not f then return end
local res = mp.unpack(f:read '*a')
f:close()
return res
end,
savePg = function(db, k, page)
if type(k) == 'string' and k:sub(1, 1) == '_' then return '_' end
local f = io.open(db._path .. '/' .. k, 'wb')
if type(page) ~= 'table' or not f then return false end
f:write(mp.pack(page))
f:close()
return true
end,
}
local dbInt = {
save = function(db, p)
if p then
if type(p) ~= 'string' or type(db[p]) ~= 'table' then return false end
return tools.savePg(db, p, db[p])
end
for p, con in pairs(db) do
if not tools.savePg(db, p, con) then return false end
end
return true
end,
}
local _db = {
__index = function(db, k)
if dbInt[k] then return dbInt[k] end
if tools.isFile(db._path .. '/' .. k) then
db[k] = tools.loadPg(db, k)
end
return rawget(db, k)
end,
__newindex = function(db, k, v)
if type(k) ~= 'string' or type(v) == 'function' then return end
if k:sub(1, 1) == '_' then return end
return rawset(db, k, v)
end
}
return setmetatable({}, {
__mode = 'kv',
__call = function(self, path)
assert(tools.isDir(path), path .. ' is not a directory')
if self[path] then return self[path] end
local db = setmetatable({_path = path}, _db)
self[path] = db
return db
end
})