mod_csi_simple: Consider messages encrypted payload as important (fixes part of ...
[prosody.git] / plugins / mod_storage_internal.lua
blob42b451bd3c0a436ba5f6ad408bcf1918a613e2a4
1 local datamanager = require "core.storagemanager".olddm;
2 local array = require "util.array";
3 local datetime = require "util.datetime";
4 local st = require "util.stanza";
5 local now = require "util.time".now;
6 local id = require "util.id".medium;
8 local host = module.host;
10 local driver = {};
12 function driver:open(store, typ)
13 local mt = self[typ or "keyval"]
14 if not mt then
15 return nil, "unsupported-store";
16 end
17 return setmetatable({ store = store, type = typ }, mt);
18 end
20 function driver:stores(username) -- luacheck: ignore 212/self
21 return datamanager.stores(username, host);
22 end
24 function driver:purge(user) -- luacheck: ignore 212/self
25 return datamanager.purge(user, host);
26 end
28 local keyval = { };
29 driver.keyval = { __index = keyval };
31 function keyval:get(user)
32 return datamanager.load(user, host, self.store);
33 end
35 function keyval:set(user, data)
36 return datamanager.store(user, host, self.store, data);
37 end
39 function keyval:users()
40 return datamanager.users(host, self.store, self.type);
41 end
43 local archive = {};
44 driver.archive = { __index = archive };
46 function archive:append(username, key, value, when, with)
47 when = when or now();
48 if not st.is_stanza(value) then
49 return nil, "unsupported-datatype";
50 end
51 value = st.preserialize(st.clone(value));
52 value.when = when;
53 value.with = with;
54 value.attr.stamp = datetime.datetime(when);
55 value.attr.stamp_legacy = datetime.legacy(when);
57 if key then
58 local items, err = datamanager.list_load(username, host, self.store);
59 if not items and err then return items, err; end
60 if items then
61 items = array(items);
62 items:filter(function (item)
63 return item.key ~= key;
64 end);
65 value.key = key;
66 items:push(value);
67 local ok, err = datamanager.list_store(username, host, self.store, items);
68 if not ok then return ok, err; end
69 return key;
70 end
71 else
72 key = id();
73 end
75 value.key = key;
77 local ok, err = datamanager.list_append(username, host, self.store, value);
78 if not ok then return ok, err; end
79 return key;
80 end
82 function archive:find(username, query)
83 local items, err = datamanager.list_load(username, host, self.store);
84 if not items then
85 if err then
86 return items, err;
87 else
88 return function () end, 0;
89 end
90 end
91 local count = #items;
92 local i = 0;
93 if query then
94 items = array(items);
95 if query.key then
96 items:filter(function (item)
97 return item.key == query.key;
98 end);
99 end
100 if query.with then
101 items:filter(function (item)
102 return item.with == query.with;
103 end);
105 if query.start then
106 items:filter(function (item)
107 return item.when >= query.start;
108 end);
110 if query["end"] then
111 items:filter(function (item)
112 return item.when <= query["end"];
113 end);
115 count = #items;
116 if query.reverse then
117 items:reverse();
118 if query.before then
119 for j = 1, count do
120 if (items[j].key or tostring(j)) == query.before then
121 i = j;
122 break;
126 elseif query.after then
127 for j = 1, count do
128 if (items[j].key or tostring(j)) == query.after then
129 i = j;
130 break;
134 if query.limit and #items - i > query.limit then
135 items[i+query.limit+1] = nil;
138 return function ()
139 i = i + 1;
140 local item = items[i];
141 if not item then return; end
142 local key = item.key or tostring(i);
143 local when = item.when or datetime.parse(item.attr.stamp);
144 local with = item.with;
145 item.key, item.when, item.with = nil, nil, nil;
146 item.attr.stamp = nil;
147 item.attr.stamp_legacy = nil;
148 item = st.deserialize(item);
149 return key, item, when, with;
150 end, count;
153 function archive:dates(username)
154 local items, err = datamanager.list_load(username, host, self.store);
155 if not items then return items, err; end
156 return array(items):pluck("when"):map(datetime.date):unique();
159 function archive:delete(username, query)
160 if not query or next(query) == nil then
161 return datamanager.list_store(username, host, self.store, nil);
163 local items, err = datamanager.list_load(username, host, self.store);
164 if not items then
165 if err then
166 return items, err;
168 -- Store is empty
169 return 0;
171 items = array(items);
172 local count_before = #items;
173 if query then
174 if query.key then
175 items:filter(function (item)
176 return item.key ~= query.key;
177 end);
179 if query.with then
180 items:filter(function (item)
181 return item.with ~= query.with;
182 end);
184 if query.start then
185 items:filter(function (item)
186 return item.when < query.start;
187 end);
189 if query["end"] then
190 items:filter(function (item)
191 return item.when > query["end"];
192 end);
194 if query.truncate and #items > query.truncate then
195 if query.reverse then
196 -- Before: { 1, 2, 3, 4, 5, }
197 -- After: { 1, 2, 3 }
198 for i = #items, query.truncate + 1, -1 do
199 items[i] = nil;
201 else
202 -- Before: { 1, 2, 3, 4, 5, }
203 -- After: { 3, 4, 5 }
204 local offset = #items - query.truncate;
205 for i = 1, #items do
206 items[i] = items[i+offset];
211 local count = count_before - #items;
212 if count == 0 then
213 return 0; -- No changes, skip write
215 local ok, err = datamanager.list_store(username, host, self.store, items);
216 if not ok then return ok, err; end
217 return count;
220 module:provides("storage", driver);