25 |
25 |
26 local function id(v) return v; end |
26 local function id(v) return v; end |
27 |
27 |
28 local function is_stanza(s) |
28 local function is_stanza(s) |
29 return getmetatable(s) == st.stanza_mt; |
29 return getmetatable(s) == st.stanza_mt; |
30 end |
|
31 |
|
32 local function t(c, a, b) |
|
33 if c then return a; end return b; |
|
34 end |
30 end |
35 |
31 |
36 local base_path = path.resolve_relative_path(prosody.paths.data, module.host); |
32 local base_path = path.resolve_relative_path(prosody.paths.data, module.host); |
37 lfs.mkdir(base_path); |
33 lfs.mkdir(base_path); |
38 |
34 |
104 |
100 |
105 function archive:find(username, query) |
101 function archive:find(username, query) |
106 query = query or empty; |
102 query = query or empty; |
107 local meta = self:get(username) or empty; |
103 local meta = self:get(username) or empty; |
108 local prefix = (username or "@") .. "#"; |
104 local prefix = (username or "@") .. "#"; |
109 local r = query.reverse; |
105 local reverse = query.reverse; |
110 local d = t(r, -1, 1); |
106 local step = reverse and -1 or 1; |
111 local s = meta[t(r, query.before, query.after)]; |
107 local first = meta[query.after]; |
|
108 local last = meta[query.before]; |
|
109 -- we don't want to include the actual 'after' or 'before' item |
|
110 if first then first = first + 1; end |
|
111 if last then last = last - 1; end |
|
112 first, last = first or 1, last or #meta; |
|
113 if reverse then first, last = last, first; end |
112 local limit = query.limit; |
114 local limit = query.limit; |
113 if s then |
115 local count = 0; |
114 s = s + d; |
|
115 else |
|
116 s = t(r, #meta, 1) |
|
117 end |
|
118 local e = t(r, 1, #meta); |
|
119 local c = 0; |
|
120 return function () |
116 return function () |
121 if limit and c >= limit then return end |
117 if limit and count >= limit then return end |
122 local item, value; |
118 local item, value; |
123 for i = s, e, d do |
119 for i = first, last, step do |
124 item = meta[i]; |
120 item = meta[i]; |
125 if (not query.with or item.with == query.with) |
121 if (not query.with or item.with == query.with) |
126 and (not query.start or item.when >= query.start) |
122 and (not query.start or item.when >= query.start) |
127 and (not query["end"] or item.when <= query["end"]) then |
123 and (not query["end"] or item.when <= query["end"]) then |
128 s = i + d; c = c + 1; |
124 first = i + step; count = count + 1; |
129 value = self:get(prefix..item.key); |
125 value = self:get(prefix..item.key); |
130 return item.key, (deserialize_map[item.type] or id)(value), item.when, item.with; |
126 return item.key, (deserialize_map[item.type] or id)(value), item.when, item.with; |
131 end |
127 end |
132 end |
128 end |
133 end |
129 end |