Software / code / prosody-modules
Comparison
mod_storage_gdbm/mod_storage_gdbm.lua @ 1596:b362e6c00fd1
mod_storage_gdbm: Add archive support
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sun, 25 Jan 2015 22:18:05 +0100 |
| parent | 1595:6288591d5edf |
| child | 1602:3912a53fd4db |
comparison
equal
deleted
inserted
replaced
| 1595:6288591d5edf | 1596:b362e6c00fd1 |
|---|---|
| 7 -- http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/#lgdbm | 7 -- http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/#lgdbm |
| 8 | 8 |
| 9 local gdbm = require"gdbm"; | 9 local gdbm = require"gdbm"; |
| 10 local path = require"util.paths"; | 10 local path = require"util.paths"; |
| 11 local lfs = require"lfs"; | 11 local lfs = require"lfs"; |
| 12 local uuid = require"util.uuid".generate; | |
| 12 local serialization = require"util.serialization"; | 13 local serialization = require"util.serialization"; |
| 14 local st = require"util.stanza"; | |
| 13 local serialize = serialization.serialize; | 15 local serialize = serialization.serialize; |
| 14 local deserialize = serialization.deserialize; | 16 local deserialize = serialization.deserialize; |
| 17 | |
| 18 local function id(v) return v; end | |
| 19 | |
| 20 local function is_stanza(s) | |
| 21 return getmetatable(s) == st.stanza_mt; | |
| 22 end | |
| 23 | |
| 24 local function ifelse(cond, iftrue, iffalse) | |
| 25 if cond then return iftrue; end return iffalse; | |
| 26 end | |
| 15 | 27 |
| 16 local base_path = path.resolve_relative_path(prosody.paths.data, module.host); | 28 local base_path = path.resolve_relative_path(prosody.paths.data, module.host); |
| 17 lfs.mkdir(base_path); | 29 lfs.mkdir(base_path); |
| 18 | 30 |
| 19 local cache = {}; | 31 local cache = {}; |
| 31 local data, err = gdbm.fetch(self._db, user or "@"); | 43 local data, err = gdbm.fetch(self._db, user or "@"); |
| 32 if not data then return nil, err; end | 44 if not data then return nil, err; end |
| 33 return deserialize(data); | 45 return deserialize(data); |
| 34 end | 46 end |
| 35 | 47 |
| 48 local archive = {}; | |
| 49 local archive_mt = { __index = archive, suffix = ".adb" }; | |
| 50 | |
| 51 archive.get = keyval.get; | |
| 52 archive.set = keyval.set; | |
| 53 | |
| 54 function archive:append(username, key, when, with, value) | |
| 55 key = key or uuid(); | |
| 56 local meta = self:get(username); | |
| 57 if not meta then | |
| 58 meta = {}; | |
| 59 end | |
| 60 local i = meta[key] or #meta+1; | |
| 61 local type; | |
| 62 if is_stanza(value) then | |
| 63 type, value = "stanza", st.preserialize(value); | |
| 64 end | |
| 65 meta[i] = { key = key, when = when, with = with, type = type }; | |
| 66 meta[key] = i; | |
| 67 local ok, err = self:set(username, meta); | |
| 68 if not ok then return nil, err; end | |
| 69 ok, err = self:set(key, value); | |
| 70 if not ok then return nil, err; end | |
| 71 return key; | |
| 72 end | |
| 73 | |
| 74 local deserialize = { | |
| 75 stanza = st.deserialize; | |
| 76 }; | |
| 77 | |
| 78 function archive:find(username, query) | |
| 79 local meta = self:get(username); | |
| 80 local r = query.reverse; | |
| 81 local d = r and -1 or 1; | |
| 82 local s = meta[ifelse(r, query.before, meta.after)]; | |
| 83 if s then | |
| 84 s = s + d; | |
| 85 else | |
| 86 s = ifelse(r, #meta, 1) | |
| 87 end | |
| 88 local e = ifelse(r, 1, #meta); | |
| 89 return function () | |
| 90 local item, value; | |
| 91 for i = s, e, d do | |
| 92 item = meta[i]; | |
| 93 if (not query.with or item.with == query.with) | |
| 94 and (not query.start or item.when >= query.start) | |
| 95 and (not query["end"] or item.when >= query["end"]) then | |
| 96 s = i + d; | |
| 97 value = self:get(item.key); | |
| 98 return item.key, (deserialize[item.type] or id)(value), item.when, item.with; | |
| 99 end | |
| 100 end | |
| 101 end | |
| 102 end | |
| 103 | |
| 36 local drivers = { | 104 local drivers = { |
| 37 keyval = keyval_mt; | 105 keyval = keyval_mt; |
| 106 archive = archive_mt; | |
| 38 } | 107 } |
| 39 | 108 |
| 40 function open(_, store, typ) | 109 function open(_, store, typ) |
| 41 typ = typ or "keyval"; | 110 typ = typ or "keyval"; |
| 42 local driver_mt = drivers[typ]; | 111 local driver_mt = drivers[typ]; |