2018-11-06 03:05:04 +01:00
|
|
|
colddb = {}
|
|
|
|
|
2019-01-15 01:17:45 +01:00
|
|
|
function colddb.Colddb(dir)
|
|
|
|
if not minetest.mkdir(dir) then
|
|
|
|
error(string.format("%s is not a directory.", dir))
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
|
|
|
|
local self = {}
|
|
|
|
|
2019-01-15 01:17:45 +01:00
|
|
|
local directory = dir
|
|
|
|
local mem_pool = {}
|
|
|
|
local mem_pool_del = {}
|
|
|
|
local add_to_mem_pool = true
|
2019-05-13 21:32:42 +02:00
|
|
|
local async = async.Async()
|
2019-05-20 05:19:20 +02:00
|
|
|
local use_async = true
|
2019-01-15 01:17:45 +01:00
|
|
|
|
|
|
|
async.priority(150, 250)
|
2019-01-08 07:32:34 +01:00
|
|
|
|
2018-11-08 23:15:35 +01:00
|
|
|
-- make tables weak so the garbage-collector will remove unused data
|
2019-01-15 01:17:45 +01:00
|
|
|
setmetatable(mem_pool, {__mode = "kv"})
|
|
|
|
setmetatable(mem_pool_del, {__mode = "kv"})
|
2019-03-16 03:14:30 +01:00
|
|
|
|
|
|
|
self.get_directory = function()
|
|
|
|
return directory
|
|
|
|
end
|
|
|
|
|
|
|
|
self.set_directory = function(new_directory)
|
|
|
|
directory = new_directory
|
|
|
|
if not minetest.mkdir(directory) then
|
|
|
|
error(string.format("%s is not a directory.", dir))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
self.get_memory_pool = function()
|
|
|
|
return mem_pool
|
|
|
|
end
|
|
|
|
|
|
|
|
self.set_memory_pool = function(pool)
|
|
|
|
mem_pool = pool
|
|
|
|
end
|
|
|
|
|
|
|
|
self.get_async = function()
|
|
|
|
return async
|
|
|
|
end
|
|
|
|
|
|
|
|
self.set_async = function(new_async)
|
|
|
|
async = new_async
|
|
|
|
end
|
|
|
|
|
|
|
|
self.add_to_memory_pool = function(value)
|
|
|
|
if value then
|
|
|
|
add_to_mem_pool = value
|
|
|
|
end
|
|
|
|
return add_to_mem_pool
|
|
|
|
end
|
2019-05-20 05:19:20 +02:00
|
|
|
|
|
|
|
self.use_async = function(value)
|
|
|
|
use_async = value
|
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
local function file_exists(name)
|
2019-03-16 05:55:57 +01:00
|
|
|
local f = io.open(string.format("%s/%s.cold", directory, name), "r")
|
2019-01-08 07:32:34 +01:00
|
|
|
if f ~= nil then
|
|
|
|
io.close(f)
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
return false
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
local function load_into_mem(name, _table)
|
2019-01-15 01:17:45 +01:00
|
|
|
if add_to_mem_pool then
|
2019-03-16 03:02:31 +01:00
|
|
|
mem_pool[name] = {mem = _table}
|
2019-01-08 07:32:34 +01:00
|
|
|
end
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
self.exists = function(name)
|
|
|
|
return file_exists(name)
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
local function delete_file(name)
|
2019-03-16 05:55:57 +01:00
|
|
|
local text = string.format("%s/%s.cold", directory, name)
|
2019-01-08 07:32:34 +01:00
|
|
|
|
|
|
|
local err, msg = os.remove(text)
|
|
|
|
if err == nil then
|
2019-05-20 05:19:20 +02:00
|
|
|
minetest.log(string.format("error removing db data %s error message: %s", text, msg))
|
2019-01-08 07:32:34 +01:00
|
|
|
end
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
local function load_table(name)
|
2019-03-16 05:55:57 +01:00
|
|
|
local f = io.open(string.format("%s/%s.cold", directory, name), "r")
|
2018-11-06 03:05:04 +01:00
|
|
|
if f then
|
2019-01-08 07:32:34 +01:00
|
|
|
local data = minetest.deserialize(f:read("*a"))
|
2018-11-06 03:05:04 +01:00
|
|
|
f:close()
|
2019-01-08 07:32:34 +01:00
|
|
|
return data
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
return nil
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
local function save_table(name, _table)
|
2019-03-16 05:55:57 +01:00
|
|
|
minetest.log(string.format("%s/%s.cold", directory, name))
|
2019-05-20 05:21:21 +02:00
|
|
|
if save_table == nil or name == nil then
|
|
|
|
return false
|
|
|
|
end
|
2019-03-16 05:55:57 +01:00
|
|
|
return minetest.safe_file_write(string.format("%s/%s.cold", directory, name), minetest.serialize(_table))
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
local function save_key(name)
|
2019-03-16 05:55:57 +01:00
|
|
|
return minetest.safe_file_write(string.format("%s/%s.cold", directory, name), "")
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
local function load_key(name)
|
2019-03-16 05:55:57 +01:00
|
|
|
local f = io.open(string.format("%s/%s.cold", directory, name), "r")
|
2018-11-06 03:05:04 +01:00
|
|
|
if f then
|
2019-01-08 07:32:34 +01:00
|
|
|
f:close()
|
|
|
|
return true
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
return false
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-02-03 01:28:55 +01:00
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
self.set_mem = function(name, _table)
|
|
|
|
load_into_mem(name, _table)
|
|
|
|
mem_pool_del[name] = nil
|
2019-02-03 01:28:55 +01:00
|
|
|
end
|
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
self.save_mem = function(name)
|
2019-05-20 05:19:20 +02:00
|
|
|
if use_async then
|
|
|
|
async.queue_task(function()
|
|
|
|
if mem_pool[name] ~= nil then
|
|
|
|
save_table(name, mem_pool[name].mem)
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
if mem_pool[name] ~= nil then
|
|
|
|
save_table(name, mem_pool[name].mem)
|
2019-02-03 01:28:55 +01:00
|
|
|
end
|
2019-05-20 05:19:20 +02:00
|
|
|
end
|
2019-02-03 01:28:55 +01:00
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
mem_pool_del[name] = nil
|
|
|
|
end
|
|
|
|
|
2019-03-16 05:55:57 +01:00
|
|
|
self.clear_mem = function(name)
|
2019-03-16 03:02:31 +01:00
|
|
|
mem_pool[name] = nil
|
|
|
|
mem_pool_del[name] = nil
|
2019-02-03 01:28:55 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
self.set = function(name, _table)
|
2019-05-20 05:19:20 +02:00
|
|
|
if use_async then
|
|
|
|
async.queue_task(function()
|
|
|
|
save_table(name, _table)
|
|
|
|
end)
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
save_table(name, _table)
|
2019-05-20 05:19:20 +02:00
|
|
|
end
|
|
|
|
|
2019-01-15 01:17:45 +01:00
|
|
|
if add_to_mem_pool then
|
2019-03-16 03:02:31 +01:00
|
|
|
load_into_mem(name, _table)
|
2019-01-08 07:32:34 +01:00
|
|
|
end
|
2019-03-16 03:02:31 +01:00
|
|
|
|
|
|
|
mem_pool_del[name] = nil
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
self.set_key = function(name)
|
2019-05-20 05:19:20 +02:00
|
|
|
if use_async then
|
|
|
|
async.queue_task(function()
|
|
|
|
save_key(name)
|
|
|
|
end)
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
save_key(name)
|
2019-05-20 05:19:20 +02:00
|
|
|
end
|
|
|
|
|
2019-01-15 01:17:45 +01:00
|
|
|
if add_to_mem_pool then
|
2019-03-16 03:02:31 +01:00
|
|
|
load_into_mem(name, "")
|
2019-01-08 07:32:34 +01:00
|
|
|
end
|
2019-03-16 03:02:31 +01:00
|
|
|
mem_pool_del[name] = nil
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
self.get = function(name, callback)
|
|
|
|
if mem_pool_del[name] then
|
2019-01-08 07:32:34 +01:00
|
|
|
if callback then
|
|
|
|
callback(nil)
|
2018-12-08 21:56:38 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
return nil
|
|
|
|
end
|
|
|
|
if callback then
|
2019-01-15 01:17:45 +01:00
|
|
|
async.queue_task(function()
|
2019-03-16 03:02:31 +01:00
|
|
|
local pm = mem_pool[name]
|
2019-01-08 07:32:34 +01:00
|
|
|
if pm then
|
|
|
|
return pm.mem
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
local _table = load_table(name)
|
2019-01-08 07:32:34 +01:00
|
|
|
if _table then
|
2019-03-16 03:02:31 +01:00
|
|
|
load_into_mem(name, _table)
|
2019-01-08 07:32:34 +01:00
|
|
|
return _table
|
|
|
|
end
|
|
|
|
end
|
2019-03-16 03:02:31 +01:00
|
|
|
mem_pool_del[name] = true
|
2019-01-08 07:32:34 +01:00
|
|
|
return nil
|
|
|
|
end,callback)
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
local pm = mem_pool[name]
|
2018-12-08 21:56:38 +01:00
|
|
|
if pm then
|
|
|
|
return pm.mem
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
local _table = load_table(name)
|
2018-12-08 21:56:38 +01:00
|
|
|
if _table then
|
2019-03-16 03:02:31 +01:00
|
|
|
load_into_mem(name, _table)
|
2018-12-08 21:56:38 +01:00
|
|
|
return _table
|
|
|
|
end
|
|
|
|
end
|
2019-03-16 03:02:31 +01:00
|
|
|
mem_pool_del[name] = true
|
2018-12-08 21:56:38 +01:00
|
|
|
return nil
|
2019-01-08 07:32:34 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
self.get_key = function(name, callback)
|
|
|
|
if mem_pool_del[name] then
|
2019-01-08 07:32:34 +01:00
|
|
|
if callback then
|
|
|
|
callback(false)
|
2018-11-11 04:40:49 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
return false
|
2018-11-11 04:40:49 +01:00
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
if callback then
|
2019-01-15 01:17:45 +01:00
|
|
|
async.queue_task(function()
|
2019-03-16 03:02:31 +01:00
|
|
|
local pm = mem_pool[name]
|
2019-01-08 07:32:34 +01:00
|
|
|
if pm then
|
|
|
|
return true
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
local bool = load_key(name)
|
2019-01-08 07:32:34 +01:00
|
|
|
if bool then
|
2019-03-16 03:02:31 +01:00
|
|
|
load_into_mem(name, bool)
|
2019-01-08 07:32:34 +01:00
|
|
|
return bool
|
|
|
|
end
|
|
|
|
end
|
2019-03-16 03:02:31 +01:00
|
|
|
mem_pool_del[name] = true
|
2019-01-08 07:32:34 +01:00
|
|
|
return nil
|
|
|
|
end,callback)
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
local pm = mem_pool[name]
|
2018-12-08 21:56:38 +01:00
|
|
|
if pm then
|
|
|
|
return true
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
local bool = load_key(name)
|
2018-12-08 21:56:38 +01:00
|
|
|
if bool then
|
2019-03-16 03:02:31 +01:00
|
|
|
load_into_mem(name, bool)
|
2018-12-08 21:56:38 +01:00
|
|
|
return bool
|
|
|
|
end
|
|
|
|
end
|
2019-03-16 03:02:31 +01:00
|
|
|
mem_pool_del[name] = true
|
2018-12-08 21:56:38 +01:00
|
|
|
return nil
|
2019-01-08 07:32:34 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-03-16 03:02:31 +01:00
|
|
|
self.remove = function(name)
|
|
|
|
mem_pool[name] = nil
|
|
|
|
mem_pool_del[name] = true
|
2019-05-20 05:19:20 +02:00
|
|
|
|
|
|
|
if use_async then
|
|
|
|
async.queue_task(function()
|
|
|
|
delete_file(name)
|
|
|
|
end)
|
|
|
|
else
|
2019-03-16 03:02:31 +01:00
|
|
|
delete_file(name)
|
2019-05-20 05:19:20 +02:00
|
|
|
end
|
2018-11-06 03:05:04 +01:00
|
|
|
end
|
2019-05-20 06:55:05 +02:00
|
|
|
|
|
|
|
self.sub_database = function(path)
|
|
|
|
local db = colddb.Colddb(dir .. "/" .. path)
|
|
|
|
db.set_async(async)
|
|
|
|
return db
|
|
|
|
end
|
2019-05-20 07:02:43 +02:00
|
|
|
|
|
|
|
self.to_array = function()
|
|
|
|
local entries = {}
|
|
|
|
|
2019-05-21 19:27:04 +02:00
|
|
|
for k, v in pairs(minetest.get_dir_list(directory, false)) do
|
2019-05-20 07:02:43 +02:00
|
|
|
entries[#entries + 1] = v:sub(0, v:len() - 5)
|
|
|
|
end
|
|
|
|
|
|
|
|
return entries
|
|
|
|
end
|
|
|
|
|
|
|
|
self.to_table = function()
|
|
|
|
local entries = {}
|
|
|
|
|
2019-05-21 19:27:04 +02:00
|
|
|
for k, v in pairs(minetest.get_dir_list(directory, false)) do
|
2019-05-20 07:02:43 +02:00
|
|
|
entries[v:sub(0, v:len() - 5)] = true
|
|
|
|
end
|
|
|
|
|
|
|
|
return entries
|
|
|
|
end
|
|
|
|
|
|
|
|
self.iterate = function()
|
|
|
|
local entries = {}
|
|
|
|
|
2019-05-21 19:27:04 +02:00
|
|
|
for k, v in pairs(minetest.get_dir_list(directory, false)) do
|
2019-05-20 07:02:43 +02:00
|
|
|
entries[v:sub(0, v:len() - 5)] = true
|
|
|
|
end
|
|
|
|
|
|
|
|
return pairs(entries)
|
|
|
|
end
|
2019-01-08 07:32:34 +01:00
|
|
|
|
|
|
|
return self
|
|
|
|
end
|