annotate mod_storage_appendmap/mod_storage_appendmap.lua @ 2205:98354fbea63c

mod_storage_appendmap: Prevent _ENV = false
author Kim Alvefur <zash@zash.se>
date Thu, 09 Jun 2016 11:47:55 +0200
parents 8f7083b980cf
children a2625a36c092
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2061
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 local dump = require "util.serialization".serialize;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 local load = require "util.envload".envloadfile;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 local dm = require "core.storagemanager".olddm;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5 local driver = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7 local map = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8 local map_mt = { __index = map };
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 map.remove = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 function map:get(user, key)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 module:log("debug", "map:get(%s, %s)", tostring(user), tostring(key))
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13 local filename = dm.getpath(user, module.host, self.store, "map");
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 module:log("debug", "File is %s", filename);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
15 local env = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16 if _VERSION == "Lua 5.1" then -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 env._ENV = env; -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18 end -- SO MANY HACKS
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19 local chunk, err = load(filename, env);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 if not chunk then return chunk, err; end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21 local ok, err = pcall(chunk);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 if not ok then return ok, err; end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 if _VERSION == "Lua 5.1" then -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 env._ENV = nil; -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 end -- HACKS EVERYWHERE
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 if key == nil then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 return env;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 return env[key];
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 function map:set_keys(user, keyvalues)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 local keys, values = {}, {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 if _VERSION == "Lua 5.1" then
2205
98354fbea63c mod_storage_appendmap: Prevent _ENV = false
Kim Alvefur <zash@zash.se>
parents: 2062
diff changeset
35 assert(keyvalues._ENV == nil, "'_ENV' is a restricted key");
2061
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37 for key, value in pairs(keyvalues) do
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
38 module:log("debug", "user %s sets %q to %s", user, key, tostring(value))
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39 if type(key) ~= "string" or not key:find("^[%w_][%w%d_]*$") or key == "_ENV" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
40 key = "_ENV[" .. dump(key) .. "]";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
41 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
42 table.insert(keys, key);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
43 if value == self.remove then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 table.insert(values, "nil")
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45 else
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 table.insert(values, dump(value))
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
47 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
48 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 local data = table.concat(keys, ", ") .. " = " .. table.concat(values, ", ") .. ";\n";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50 return dm.append_raw(user, module.host, self.store, "map", data);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
53 function map:set(user, key, value)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 if _VERSION == "Lua 5.1" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
55 assert(key ~= "_ENV", "'_ENV' is a restricted key");
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 if key == nil then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58 local filename = dm.getpath(user, module.host, self.store, "map");
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 os.remove(filename);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 return true;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
62 if type(key) ~= "string" or not key:find("^[%w_][%w%d_]*$") or key == "_ENV" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 key = "_ENV[" .. dump(key) .. "]";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65 local data = key .. " = " .. dump(value) .. ";\n";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
66 return dm.append_raw(user, module.host, self.store, "map", data);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
67 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
68
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69 local keyval = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70 local keyval_mt = { __index = keyval };
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
71
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
72 function keyval:get(user)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
73 return map.get(self, user);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75
2062
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
76 function keyval:set(user, data)
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
77 map.set(self, user);
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
78 if data then
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
79 for k, v in pairs(data) do
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
80 map.set(self, user, k, v);
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
81 end
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
82 end
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
83 return true;
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
84 end
2061
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 -- TODO some kind of periodic compaction thing?
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
87 function map:_compact(user)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
88 local data = self:get(user);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
89 return keyval.set(self, user, data);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
91
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
92 function driver:open(store, typ)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
93 if typ == "map" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
94 return setmetatable({ store = store, }, map_mt);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
95 elseif typ == nil or typ == "keyval" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
96 return setmetatable({ store = store, }, keyval_mt);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
97 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
98 return nil, "unsupported-store";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
99 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
100
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
101 module:provides("storage", driver);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
102