Fix SQLite3 persistence crashing if loaded twice

This commit is contained in:
Lars Mueller 2022-02-28 01:21:42 +01:00
parent d4d3b456b5
commit 7ef08b8a5c

@ -15,10 +15,9 @@ local sqlite3 = ...
Weak tables are of no use here, as we need to be notified when a reference is dropped
]]
local _ENV = {}
setfenv(1, _ENV)
local metatable = {__index = _ENV}
_ENV.metatable = metatable
local ptab = {} -- SQLite3-backed implementation for a persistent Lua table ("ptab")
local metatable = {__index = ptab}
ptab.metatable = metatable
-- Note: keys may not be marked as weak references: wouldn't close the database: see persistence/lua_log_file.lua
local databases = {}
@ -39,14 +38,14 @@ local function increment_highest_table_id(self)
return self.highest_table_id
end
function new(file_path, root)
function ptab.new(file_path, root)
return setmetatable({
database = sqlite3.open(file_path),
root = root
}, metatable)
end
function _ENV.setmetatable(self)
function ptab.setmetatable(self)
assert(self.database and self.root)
return setmetatable(self, metatable)
end
@ -142,7 +141,7 @@ local function exec(self, sql)
end
end
function init(self)
function ptab:init()
local database = self.database
local function prepare(sql)
local stmt = database:prepare(sql)
@ -230,7 +229,7 @@ CREATE TABLE IF NOT EXISTS table_entries (
databases[self] = true
end
function rewrite(self)
function ptab:rewrite()
exec(self, "DELETE FROM table_entries")
self.highest_table_id = 0
self.table_ids = {}
@ -238,7 +237,7 @@ function rewrite(self)
add_table(self, self.root)
end
function _ENV.set(self, table, key, value)
function ptab:set(table, key, value)
local previous_value = table[key]
if previous_value == value then
-- no change
@ -248,11 +247,11 @@ function _ENV.set(self, table, key, value)
table[key] = value
end
function set_root(self, key, value)
return _ENV.set(self, self.root, key, value)
function ptab:set_root(key, value)
return self:set(self.root, key, value)
end
function collectgarbage(self)
function ptab:collectgarbage()
local marked = {}
local function mark(table)
if type(table) ~= "table" or marked[table] then return end
@ -270,7 +269,7 @@ function collectgarbage(self)
end
end
function defragment_ids(self)
function ptab:defragment_ids()
local ids = {}
for _, id in pairs(self.table_ids) do
table_insert(ids, id)
@ -300,7 +299,7 @@ local function finalize_statements(table)
end
end
function close(self)
function ptab:close()
finalize_statements(self._prepared)
self.database:close()
databases[self] = nil
@ -314,4 +313,4 @@ if minetest then
end)
end
return _ENV
return ptab