techage/basis/numbers_sqlite.lua

143 lines
3.4 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 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);
2022-01-03 23:40:31 +03:00
CREATE UNIQUE INDEX idx ON numbers(number);
2020-05-23 15:11:35 +03:00
]]
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)
2022-01-03 23:40:31 +03:00
set:step()
2020-05-23 15:11:35 +03:00
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
2020-05-23 15:11:35 +03:00
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
2022-01-03 23:40:31 +03:00
elseif Version == 4 then
2020-05-23 15:11:35 +03:00
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)
2022-01-03 23:40:31 +03:00
end
2020-05-23 15:11:35 +03:00
function api.set_nodepos(number, pos)
set_block(number, pos)
2022-01-03 23:40:31 +03:00
end
2020-05-23 15:11:35 +03:00
function api.add_nodepos(pos)
local num = tostring(NextNumber)
NextNumber = NextNumber + 1
storage:set_int("NextNumber", NextNumber)
set_block(num, pos)
return num
2022-01-03 23:40:31 +03:00
end
2020-05-23 15:11:35 +03:00
function api.del_nodepos(number)
del_block(number)
2022-01-03 23:40:31 +03:00
end
2020-05-23 15:11:35 +03:00
-- delete invalid entries
function api.delete_invalid_entries(node_def)
minetest.log("info", "[TechAge] Data maintenance started")
2022-01-03 23:40:31 +03:00
for id, num, x, y, z in db:urows('SELECT * FROM numbers') do
2020-05-23 15:11:35 +03:00
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")
2022-01-03 23:40:31 +03:00
end
2020-05-23 15:11:35 +03:00
return api