Repository navigation
Expand file tree
/
Copy pathdb.lua
More file actions
224 lines (186 loc) · 6.31 KB
/
Copy pathdb.lua
File metadata and controls
224 lines (186 loc) · 6.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
--[[
Database connection functionality via PostgreSQL.
`luarocks install luasql-postgres`
]]--
local ie = ...
local driver_exists, driver = pcall(ie.require, "luasql.postgres")
if not driver_exists then
error("[Citadella] Lua PostgreSQL driver not found. "
.."Please install it (try 'luarocks install luasql-postgres').")
end
local db = nil
local env = nil
local sourcename = minetest.settings:get("citadella_db_sourcename")
local username = minetest.settings:get("citadella_db_username")
local password = minetest.settings:get("citadella_db_password")
local u = pmutils
local function prep_db()
env = assert (driver.postgres())
-- connect to data source
db = assert (env:connect(sourcename, username, password))
-- create reinforcements table
local res = assert(u.prepare(db, [[
CREATE TABLE IF NOT EXISTS reinforcement (
x INTEGER NOT NULL,
y INTEGER NOT NULL,
z INTEGER NOT NULL,
value INTEGER NOT NULL,
material VARCHAR(50) NOT NULL,
ctgroup_id VARCHAR(32) REFERENCES ctgroup(id),
creation_date TIMESTAMP,
last_update TIMESTAMP,
last_stacked TIMESTAMP,
PRIMARY KEY (x, y, z)
)]]))
local luatime = os.time(os.date("!*t"))
-- 2020-04-20: since I have to care about other people now :-)
assert(u.prepare(db, [[
ALTER TABLE reinforcement ADD COLUMN IF NOT EXISTS
creation_date TIMESTAMP;
UPDATE reinforcement
SET creation_date = (TO_TIMESTAMP(?) AT TIME ZONE 'UTC')
WHERE (SELECT TRUE FROM reinforcement
WHERE creation_date IS NULL LIMIT 1)
AND creation_date IS NULL;
]], luatime))
assert(u.prepare(db, [[
ALTER TABLE reinforcement ADD COLUMN IF NOT EXISTS
last_update TIMESTAMP;
UPDATE reinforcement
SET last_update = (TO_TIMESTAMP(?) AT TIME ZONE 'UTC')
WHERE (SELECT TRUE FROM reinforcement
WHERE last_update IS NULL LIMIT 1)
AND last_update IS NULL;
]], luatime))
assert(u.prepare(db, [[
ALTER TABLE reinforcement ADD COLUMN IF NOT EXISTS
last_stacked TIMESTAMP;
UPDATE reinforcement
SET last_stacked = (TO_TIMESTAMP(?) AT TIME ZONE 'UTC')
WHERE (SELECT TRUE FROM reinforcement
WHERE last_stacked IS NULL LIMIT 1)
AND last_stacked IS NULL;
]], luatime))
end
prep_db()
minetest.register_on_shutdown(function()
ct.force_flush_cache()
db:close()
env:close()
end)
local QUERY_REGISTER_REINFORCEMENT = [[
INSERT INTO reinforcement
(x, y, z, value, material, ctgroup_id, creation_date, last_update, last_stacked)
VALUES (
?, ?, ?,
?, ?, ?,
TO_TIMESTAMP(?) AT TIME ZONE 'UTC',
TO_TIMESTAMP(?) AT TIME ZONE 'UTC',
TO_TIMESTAMP(?) AT TIME ZONE 'UTC'
)
]]
function ctdb.register_reinforcement(pos, ctgroup_id, item_name,
last_update, creation_date)
local value = ct.reinforcement_types[item_name].value
assert(u.prepare(db, QUERY_REGISTER_REINFORCEMENT,
pos.x, pos.y, pos.z,
value, item_name, ctgroup_id,
last_update, creation_date, creation_date))
end
local QUERY_UPDATE_REINFORCEMENT_GROUP = [[
UPDATE reinforcement
SET ctgroup_id = ?
WHERE ctgroup_id = ?
AND reinforcement.x = ?
AND reinforcement.y = ?
AND reinforcement.z = ?
]]
function ctdb.update_reinforcement_group(pos, old_ctgroup_id, new_ctgroup_id)
assert(u.prepare(db, QUERY_UPDATE_REINFORCEMENT_GROUP,
new_ctgroup_id, old_ctgroup_id,
pos.x, pos.y, pos.z))
end
local QUERY_REMOVE_REINFORCEMENT = [[
DELETE FROM reinforcement
WHERE reinforcement.x = ?
AND reinforcement.y = ?
AND reinforcement.z = ?
]]
function ctdb.remove_reinforcement(pos)
assert(u.prepare(db, QUERY_REMOVE_REINFORCEMENT,
pos.x, pos.y, pos.z))
end
local QUERY_GET_REINFORCEMENT = [[
SELECT * FROM reinforcement
WHERE reinforcement.x = ?
AND reinforcement.y = ?
AND reinforcement.z = ?
]]
function ctdb.get_reinforcement(pos)
local cur = u.prepare(db, QUERY_GET_REINFORCEMENT,
pos.x, pos.y, pos.z)
if cur then
return cur:fetch({}, "a")
else
return nil
end
end
local QUERY_GET_REINFORCEMENTS = [[
SELECT *,
FLOOR(EXTRACT(epoch FROM reinforcement.last_update)) AS last_update_unix,
FLOOR(EXTRACT(epoch FROM reinforcement.creation_date)) AS creation_date_unix,
FLOOR(EXTRACT(epoch FROM reinforcement.last_stacked)) AS last_stacked_unix
FROM reinforcement
WHERE reinforcement.x BETWEEN ? AND ?
AND reinforcement.y BETWEEN ? AND ?
AND reinforcement.z BETWEEN ? AND ?
]]
function ctdb.get_reinforcements_for_cache(cache, pos1, pos2)
local cur = u.prepare(db, QUERY_GET_REINFORCEMENTS,
pos1.x, pos2.x,
pos1.y, pos2.y,
pos1.z, pos2.z)
local reinfs = {}
local row = cur:fetch({}, "a")
while row do
local x, y, z = tonumber(row.x), tonumber(row.y), tonumber(row.z)
reinfs[ptos(x, y, z)] = {
x = x, y = y, z = z,
value = tonumber(row.value),
material = row.material,
ctgroup_id = row.ctgroup_id,
new = false,
last_update = tonumber(row.last_update_unix),
creation_date = tonumber(row.creation_date_unix),
last_stacked = tonumber(row.last_stacked_unix),
}
row = cur:fetch(row, "a")
end
cache[vtos(pos1)] = {
reinforcements = reinfs,
time_added = os.time(os.date("!*t"))
}
end
local QUERY_UPDATE_REINFORCEMENT = [[
UPDATE reinforcement
SET value = ?,
last_update = TO_TIMESTAMP(?) AT TIME ZONE 'UTC',
creation_date = TO_TIMESTAMP(?) AT TIME ZONE 'UTC',
last_stacked = TO_TIMESTAMP(?) AT TIME ZONE 'UTC'
WHERE reinforcement.x = ?
AND reinforcement.y = ?
AND reinforcement.z = ?
]]
function ctdb.update_reinforcement(pos, new_value, last_update,
creation_date, last_stacked)
assert(u.prepare(db, QUERY_UPDATE_REINFORCEMENT, new_value,
last_update, creation_date, last_stacked,
pos.x, pos.y, pos.z))
end
function ctdb.begin_transaction()
u.prepare(db, [[ BEGIN; ]])
end
function ctdb.end_transaction()
u.prepare(db, [[ COMMIT; ]])
end
return db