annotate mod_storage_appendmap/mod_storage_appendmap.lua @ 2506:5941aac79f06

mod_mam: Add support for XEP-0313 v0.5
author Kim Alvefur <zash@zash.se>
date Mon, 20 Feb 2017 00:41:13 +0100
parents 623e23190c3e
children 4548c3d685b4
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
2431
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
32 local keywords = {
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
33 ["do"] = true; ["and"] = true; ["else"] = true; ["break"] = true;
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
34 ["if"] = true; ["end"] = true; ["goto"] = true; ["false"] = true;
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
35 ["in"] = true; ["for"] = true; ["then"] = true; ["local"] = true;
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
36 ["or"] = true; ["nil"] = true; ["true"] = true; ["until"] = true;
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
37 ["elseif"] = true; ["function"] = true; ["not"] = true;
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
38 ["repeat"] = true; ["return"] = true; ["while"] = true;
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
39
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
40 -- _ENV is not technically a keyword but we need to treat it as such
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
41 ["_ENV"] = true;
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
42 };
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
43
2061
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 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
45 local keys, values = {}, {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 if _VERSION == "Lua 5.1" then
2205
98354fbea63c mod_storage_appendmap: Prevent _ENV = false
Kim Alvefur <zash@zash.se>
parents: 2062
diff changeset
47 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
48 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 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
50 module:log("debug", "user %s sets %q to %s", user, key, tostring(value))
2431
623e23190c3e mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents: 2430
diff changeset
51 if type(key) ~= "string" or not key:find("^[%a_][%w_]*$") or keywords[key] then
2061
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52 key = "_ENV[" .. dump(key) .. "]";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
53 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 table.insert(keys, key);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
55 if value == self.remove then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56 table.insert(values, "nil")
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 else
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58 table.insert(values, dump(value))
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 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
62 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
63 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65 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
66 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
67 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
68 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69 if key == nil then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70 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
71 os.remove(filename);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
72 return true;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
73 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 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
75 key = "_ENV[" .. dump(key) .. "]";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
76 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
77 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
78 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
79 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 local keyval = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 local keyval_mt = { __index = keyval };
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 function keyval:get(user)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85 return map.get(self, user);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
87
2062
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
88 function keyval:set(user, data)
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
89 map.set(self, user);
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
90 if data then
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
91 for k, v in pairs(data) do
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
92 map.set(self, user, k, v);
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
93 end
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
94 end
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
95 return true;
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2061
diff changeset
96 end
2061
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
97
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
98 -- 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
99 function map:_compact(user)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
100 local data = self:get(user);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
101 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
102 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
103
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
104 function driver:open(store, typ)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
105 if typ == "map" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
106 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
107 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
108 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
109 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
110 return nil, "unsupported-store";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
111 end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
112
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
113 module:provides("storage", driver);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
114