Mercurial > prosody-modules
comparison mod_storage_xmlarchive/mod_storage_xmlarchive.lua @ 2398:7e922b968b44
mod_storage_xmlarchive: Find item indices for 'before' or 'after' queries and behave as if they were excluded if the items don't exist (thanks MattJ)
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 25 Nov 2016 23:17:13 +0100 |
parents | 7f9bf161f640 |
children | 913bd81a4d3c |
comparison
equal
deleted
inserted
replaced
2397:7f9bf161f640 | 2398:7e922b968b44 |
---|---|
50 end | 50 end |
51 if not ok then | 51 if not ok then |
52 return nil, err; | 52 return nil, err; |
53 end | 53 end |
54 return id; | 54 return id; |
55 end | |
56 | |
57 function archive:_get_idx(username, id, dates) | |
58 dates = dates or self:dates(username) or empty; | |
59 local date = id:sub(1, 10); | |
60 for d = 1, #dates do | |
61 if date == dates[d] then | |
62 module:log("debug", "Loading items from %s", dates[d]); | |
63 local items = dm.list_load(username .. "@" .. dates[d], module.host, self.store) or empty; | |
64 for i = 1, #items do | |
65 if items[i].id == id then | |
66 return d, i, items; | |
67 end | |
68 end | |
69 return; -- Assuming no duplicates | |
70 elseif date > dates[d] then | |
71 return; -- List is assumed to be sorted | |
72 end | |
73 end | |
55 end | 74 end |
56 | 75 |
57 function archive:find(username, query) | 76 function archive:find(username, query) |
58 username = username or "@"; | 77 username = username or "@"; |
59 query = query or empty; | 78 query = query or empty; |
79 | 98 |
80 local limit = query.limit; | 99 local limit = query.limit; |
81 local start_day, step, last_day = 1, 1, #dates; | 100 local start_day, step, last_day = 1, 1, #dates; |
82 local count = 0; | 101 local count = 0; |
83 local rev = query.reverse; | 102 local rev = query.reverse; |
84 local in_range = not (query.after or query.before); | 103 if query.start then |
85 if query.after or query.start then | 104 local d = dt.date(query.start); |
86 local d = query.after and query.after:sub(1, 10) or dt.date(query.start); | |
87 for i = 1, #dates do | 105 for i = 1, #dates do |
88 if dates[i] == d then | 106 if dates[i] == d then |
89 start_day = i; break; | 107 start_day = i; break; |
90 end | 108 end |
91 end | 109 end |
92 end | 110 end |
93 if query.before or query["end"] then | 111 if query["end"] then |
94 local d = query.before and query.before:sub(1, 10) or dt.date(query["end"]); | 112 local d = dt.date(query["end"]); |
95 for i = #dates, 1, -1 do | 113 for i = #dates, 1, -1 do |
96 if dates[i] == d then | 114 if dates[i] == d then |
97 last_day = i; break; | 115 last_day = i; break; |
98 end | 116 end |
99 end | 117 end |
100 end | 118 end |
119 local items, xmlfile; | |
120 local first_item, last_item; | |
101 if rev then | 121 if rev then |
102 start_day, step, last_day = last_day, -step, start_day; | 122 start_day, step, last_day = last_day, -step, start_day; |
103 end | 123 if query.before then |
104 local items, xmlfile; | 124 local before_day, before_item, items_ = self:_get_idx(username, query.before, dates); |
105 local first_item, last_item; | 125 if before_day and before_day <= start_day then |
126 if before_item then | |
127 first_item = before_item - 1; | |
128 else | |
129 first_item = #items_; | |
130 end | |
131 last_item = 1; | |
132 start_day = before_day; | |
133 items = items_; | |
134 end | |
135 end | |
136 elseif query.after then | |
137 local after_day, after_item, items_ = self:_get_idx(username, query.after, dates); | |
138 if after_day and after_day >= start_day then | |
139 if after_item then | |
140 first_item = after_item + 1; | |
141 else | |
142 first_item = 1; | |
143 end | |
144 last_item = #items_; | |
145 start_day = after_day; | |
146 items = items_; | |
147 end | |
148 end | |
106 | 149 |
107 return function () | 150 return function () |
108 if limit and count >= limit then if xmlfile then xmlfile:close() end return; end | 151 if limit and count >= limit then if xmlfile then xmlfile:close() end return; end |
109 local filename; | 152 local filename; |
110 | 153 |
111 for d = start_day, last_day, step do | 154 for d = start_day, last_day, step do |
112 if d ~= start_day or not items then | 155 if not items then |
113 module:log("debug", "Loading items from %s", dates[d]); | 156 module:log("debug", "Loading items from %s", dates[d]); |
114 start_day = d; | 157 start_day = d; |
115 items = dm.list_load(username .. "@" .. dates[d], module.host, self.store) or empty; | 158 items = dm.list_load(username .. "@" .. dates[d], module.host, self.store) or empty; |
116 if not rev then | 159 if not rev then |
117 first_item, last_item = 1, #items; | 160 first_item, last_item = 1, #items; |
142 if not xmlfile then | 185 if not xmlfile then |
143 module:log("error", "Error: %s", ferr); | 186 module:log("error", "Error: %s", ferr); |
144 return; | 187 return; |
145 end | 188 end |
146 end | 189 end |
147 if in_range | 190 if (not q_with or i_with == q_with) |
148 and (not q_with or i_with == q_with) | |
149 and (not q_start or i_when >= q_start) | 191 and (not q_start or i_when >= q_start) |
150 and (not q_end or i_when <= q_end) then | 192 and (not q_end or i_when <= q_end) then |
151 count = count + 1; | 193 count = count + 1; |
152 first_item = i + step; | 194 first_item = i + step; |
153 | 195 |
162 local stanza = result; | 204 local stanza = result; |
163 result = nil; | 205 result = nil; |
164 return item.id, stanza, i_when, i_with; | 206 return item.id, stanza, i_when, i_with; |
165 end | 207 end |
166 end | 208 end |
167 if (rev and item.id == query.after) or | 209 end |
168 (not rev and item.id == query.before) then | 210 items = nil; |
169 in_range = false; | |
170 limit = count; | |
171 end | |
172 if (rev and item.id == query.before) or | |
173 (not rev and item.id == query.after) then | |
174 in_range = true; | |
175 end | |
176 end | |
177 if xmlfile then | 211 if xmlfile then |
178 xmlfile:close(); | 212 xmlfile:close(); |
179 xmlfile = nil; | 213 xmlfile = nil; |
180 end | 214 end |
181 end | 215 end |