techage/basis/nodedata_sqlite.lua

124 lines
2.7 KiB
Lua
Raw Normal View History

2020-05-23 15:11:35 +03:00
--[[
TechAge
=======
Copyright (C) 2020 Joachim Stolberg
2020-10-19 20:09:17 +03:00
AGPL v3
2020-05-23 15:11:35 +03:00
See LICENSE.txt for more information
2022-01-03 23:40:31 +03:00
2020-05-23 15:11:35 +03:00
Storage backend for node related data via sqlite database
]]--
-- for lazy programmers
local M = minetest.get_meta
-------------------------------------------------------------------
-- Database
-------------------------------------------------------------------
local MN = minetest.get_current_modname()
local WP = minetest.get_worldpath()
2022-08-03 23:19:46 +03:00
local use_marshal = minetest.settings:get_bool('techage_use_marshal', false)
2020-05-23 15:11:35 +03:00
local MAR_MAGIC = 0x8e
if not techage.IE then
error("Please add 'secure.trusted_mods = techage' to minetest.conf!")
end
local sqlite3 = techage.IE.require("lsqlite3")
local marshal = techage.IE.require("marshal")
if not sqlite3 then
error("Please install sqlite3 via 'luarocks install lsqlite3'")
end
if not marshal then
error("Please install marshal via 'luarocks install lua-marshal'")
end
local db = sqlite3.open(WP.."/techage_nodedata.sqlite")
local ROW = sqlite3.ROW
-- Prevent use of this db instance.
if sqlite3 then sqlite3 = nil end
db:exec[[
CREATE TABLE mapblocks(id INTEGER PRIMARY KEY, key INTEGER, data BLOB);
2022-01-03 23:40:31 +03:00
CREATE UNIQUE INDEX idx ON mapblocks(key);
2020-05-23 15:11:35 +03:00
]]
local set = db:prepare("INSERT or REPLACE INTO mapblocks VALUES(NULL, ?, ?);")
local get = db:prepare("SELECT * FROM mapblocks WHERE key=?;")
local function set_block(key, data)
set:reset()
set:bind(1, key)
set:bind_blob(2, data)
2022-01-03 23:40:31 +03:00
set:step()
2020-05-23 15:11:35 +03:00
end
local function get_block(key)
get:reset()
get:bind(1, key)
if get:step() == ROW then
return get:get_value(2)
end
end
-------------------------------------------------------------------
-- API functions
-------------------------------------------------------------------
local api = {}
function api.store_mapblock_data(key, mapblock_data)
2022-10-18 15:11:25 +03:00
if use_marshal and mapblock_data then
local data = marshal.encode(mapblock_data)
if data then
set_block(key, data)
end
2022-08-03 23:19:46 +03:00
else
set_block(key, minetest.serialize(mapblock_data))
end
2022-01-03 23:40:31 +03:00
end
2020-05-23 15:11:35 +03:00
function api.get_mapblock_data(key)
local s = get_block(key)
if s then
if s:byte(1) == MAR_MAGIC then
return marshal.decode(s)
else
return minetest.deserialize(s)
end
2020-05-23 15:11:35 +03:00
end
api.store_mapblock_data(key, {})
return {}
2022-01-03 23:40:31 +03:00
end
2020-05-23 15:11:35 +03:00
function api.get_node_data(pos)
-- legacy data available?
local s = M(pos):get_string("ta_data")
if s ~= "" then
M(pos):set_string("ta_data", "")
if s:byte(1) == MAR_MAGIC then
return marshal.decode(s)
else
return minetest.deserialize(s)
end
end
return {}
end
function api.freeze_at_shutdown(data)
for key, item in pairs(data) do
api.store_mapblock_data(key, item)
end
end
function api.restore_at_startup()
-- nothing to restore
return {}
end
return api