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
;
12 function driver
:open(store
, typ
)
13 local mt
= self
[typ
or "keyval"]
15 return nil, "unsupported-store";
17 return setmetatable({ store
= store
, type = typ
}, mt
);
20 function driver
:stores(username
) -- luacheck: ignore 212/self
21 return datamanager
.stores(username
, host
);
24 function driver
:purge(user
) -- luacheck: ignore 212/self
25 return datamanager
.purge(user
, host
);
29 driver
.keyval
= { __index
= keyval
};
31 function keyval
:get(user
)
32 return datamanager
.load(user
, host
, self
.store
);
35 function keyval
:set(user
, data
)
36 return datamanager
.store(user
, host
, self
.store
, data
);
39 function keyval
:users()
40 return datamanager
.users(host
, self
.store
, self
.type);
44 driver
.archive
= { __index
= archive
};
46 function archive
:append(username
, key
, value
, when
, with
)
48 if not st
.is_stanza(value
) then
49 return nil, "unsupported-datatype";
51 value
= st
.preserialize(st
.clone(value
));
54 value
.attr
.stamp
= datetime
.datetime(when
);
55 value
.attr
.stamp_legacy
= datetime
.legacy(when
);
58 local items
, err
= datamanager
.list_load(username
, host
, self
.store
);
59 if not items
and err
then return items
, err
; end
62 items
:filter(function (item
)
63 return item
.key
~= key
;
67 local ok
, err
= datamanager
.list_store(username
, host
, self
.store
, items
);
68 if not ok
then return ok
, err
; end
77 local ok
, err
= datamanager
.list_append(username
, host
, self
.store
, value
);
78 if not ok
then return ok
, err
; end
82 function archive
:find(username
, query
)
83 local items
, err
= datamanager
.list_load(username
, host
, self
.store
);
88 return function () end, 0;
96 items
:filter(function (item
)
97 return item
.key
== query
.key
;
101 items
:filter(function (item
)
102 return item
.with
== query
.with
;
106 items
:filter(function (item
)
107 return item
.when
>= query
.start
;
111 items
:filter(function (item
)
112 return item
.when
<= query
["end"];
116 if query
.reverse
then
120 if (items
[j
].key
or tostring(j
)) == query
.before
then
126 elseif query
.after
then
128 if (items
[j
].key
or tostring(j
)) == query
.after
then
134 if query
.limit
and #items
- i
> query
.limit
then
135 items
[i
+query
.limit
+1] = nil;
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
;
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
);
171 items
= array(items
);
172 local count_before
= #items
;
175 items
:filter(function (item
)
176 return item
.key
~= query
.key
;
180 items
:filter(function (item
)
181 return item
.with
~= query
.with
;
185 items
:filter(function (item
)
186 return item
.when
< query
.start
;
190 items
:filter(function (item
)
191 return item
.when
> query
["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
202 -- Before: { 1, 2, 3, 4, 5, }
203 -- After: { 3, 4, 5 }
204 local offset
= #items
- query
.truncate
;
206 items
[i
] = items
[i
+offset
];
211 local count
= count_before
- #items
;
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
220 module
:provides("storage", driver
);