143 lines
3.4 KiB
Lua
143 lines
3.4 KiB
Lua
--[[
|
|
|
|
TechAge
|
|
=======
|
|
|
|
Copyright (C) 2020 Joachim Stolberg
|
|
|
|
AGPL v3
|
|
See LICENSE.txt for more information
|
|
|
|
Storage backend for node number mapping via sqlite database
|
|
|
|
]]--
|
|
|
|
-- for lazy programmers
|
|
local M = minetest.get_meta
|
|
|
|
local storage = techage.storage
|
|
|
|
-------------------------------------------------------------------
|
|
-- Database
|
|
-------------------------------------------------------------------
|
|
local MN = minetest.get_current_modname()
|
|
local WP = minetest.get_worldpath()
|
|
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_numbers.sqlite")
|
|
local ROW = sqlite3.ROW
|
|
|
|
-- Prevent use of this db instance.
|
|
if sqlite3 then sqlite3 = nil end
|
|
|
|
db:exec[[
|
|
CREATE TABLE numbers(id INTEGER PRIMARY KEY, number INTEGER, x INTEGER, y INTEGER, z INTEGER);
|
|
CREATE UNIQUE INDEX idx ON numbers(number);
|
|
]]
|
|
|
|
local set = db:prepare("INSERT or REPLACE INTO numbers VALUES(NULL, ?, ?, ?, ?);")
|
|
local get = db:prepare("SELECT * FROM numbers WHERE number=?;")
|
|
|
|
local function set_block(number, pos)
|
|
set:reset()
|
|
set:bind(1, number)
|
|
set:bind(2, pos.x)
|
|
set:bind(3, pos.y)
|
|
set:bind(4, pos.z)
|
|
set:step()
|
|
return true
|
|
end
|
|
|
|
local function get_block(number)
|
|
get:reset()
|
|
get:bind(1, number)
|
|
if get:step() == ROW then
|
|
return {x = get:get_value(2), y = get:get_value(3), z = get:get_value(4)}
|
|
end
|
|
end
|
|
|
|
local function del_block(number)
|
|
db:exec("DELETE FROM numbers WHERE number="..number..";")
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
-- Migration from mod storage
|
|
-------------------------------------------------------------------
|
|
local Version = storage:get_int("Version") or 0
|
|
local NextNumber = 0
|
|
|
|
if Version == 0 then
|
|
Version = 4
|
|
end
|
|
if Version == 3 then
|
|
Version = 4
|
|
NextNumber = storage:get_int("NextNumber")
|
|
for i = 1, NextNumber do
|
|
local number = tostring(i)
|
|
if storage:contains(number) then
|
|
local pos = minetest.string_to_pos(storage:get_string(number))
|
|
set_block(number, pos)
|
|
storage:set_string(number, "")
|
|
end
|
|
end
|
|
elseif Version == 4 then
|
|
NextNumber = storage:get_int("NextNumber")
|
|
else
|
|
error("[] Invalid version number for 'number to pos mapping' table!")
|
|
end
|
|
|
|
|
|
-------------------------------------------------------------------
|
|
-- API functions
|
|
-------------------------------------------------------------------
|
|
local api = {}
|
|
|
|
function api.get_nodepos(number)
|
|
return get_block(number)
|
|
end
|
|
|
|
function api.set_nodepos(number, pos)
|
|
set_block(number, pos)
|
|
end
|
|
|
|
function api.add_nodepos(pos)
|
|
local num = tostring(NextNumber)
|
|
NextNumber = NextNumber + 1
|
|
storage:set_int("NextNumber", NextNumber)
|
|
set_block(num, pos)
|
|
return num
|
|
end
|
|
|
|
function api.del_nodepos(number)
|
|
del_block(number)
|
|
end
|
|
|
|
-- delete invalid entries
|
|
function api.delete_invalid_entries(node_def)
|
|
minetest.log("info", "[TechAge] Data maintenance started")
|
|
for id, num, x, y, z in db:urows('SELECT * FROM numbers') do
|
|
local pos = {x = x, y = y, z = z}
|
|
local name = techage.get_node_lvm(pos).name
|
|
if not node_def[name] then
|
|
del_block(num)
|
|
end
|
|
end
|
|
minetest.log("info", "[TechAge] Data maintenance finished")
|
|
end
|
|
|
|
return api
|