Software /
code /
prosody-modules
Comparison
mod_storage_lmdb/mod_storage_lmdb.lua @ 1981:1f815f57fa57
mod_storage_lmdb: Factor out a transaction wrapper
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 18 Dec 2015 22:00:00 +0100 |
parent | 1800:669d1208221a |
child | 1982:bb0b2eae5563 |
comparison
equal
deleted
inserted
replaced
1980:5e0ee0e4d5b1 | 1981:1f815f57fa57 |
---|---|
6 -- Depends on lightningdbm | 6 -- Depends on lightningdbm |
7 -- https://github.com/shmul/lightningdbm | 7 -- https://github.com/shmul/lightningdbm |
8 -- | 8 -- |
9 -- luacheck: globals prosody open | 9 -- luacheck: globals prosody open |
10 | 10 |
11 local assert = assert; | |
12 local select = select; | |
13 local xpcall = xpcall; | |
14 local traceback = debug.traceback; | |
15 | |
11 local lmdb = require"lightningmdb"; | 16 local lmdb = require"lightningmdb"; |
12 local lfs = require"lfs"; | 17 local lfs = require"lfs"; |
13 local path = require"util.paths"; | 18 local path = require"util.paths"; |
14 local serialization = require"util.serialization"; | 19 local serialization = require"util.serialization"; |
15 local serialize = serialization.serialize; | 20 local serialize = serialization.serialize; |
16 local deserialize = serialization.deserialize; | 21 local deserialize = serialization.deserialize; |
22 | |
23 local function transaction(env, func, ...) | |
24 local args, n_args = {...}, select("#", ...); | |
25 local t = env:txn_begin(nil, 0); | |
26 local function f() return func(t, unpack(args, 1, n_args)); end | |
27 local success, a, b, c = xpcall(f, traceback); | |
28 if not success then | |
29 io.stderr:write(a, "\n\n"); | |
30 t:abort(); | |
31 os.exit() | |
32 return success, a; | |
33 end | |
34 local ok, err = t:commit(); | |
35 if not ok then | |
36 return ok, err; | |
37 end | |
38 return success, a, b, c; | |
39 end | |
40 | |
41 local function keyvalue_set(t, db, key, value) | |
42 if value ~= nil then | |
43 return assert(t:put(db, key, value, 0)); | |
44 else | |
45 return t:del(db, key, value); | |
46 end | |
47 end | |
48 | |
49 local function keyvalue_get(t, db, key) | |
50 local data, err = t:get(db, key, 0); | |
51 assert(data or not err, err); | |
52 return data; | |
53 end | |
17 | 54 |
18 local drivers = {}; | 55 local drivers = {}; |
19 local provider = {}; | 56 local provider = {}; |
20 | 57 |
21 local keyval = {}; | 58 local keyval = {}; |
22 local keyval_mt = { __index = keyval, flags = lmdb.MDB_CREATE }; | 59 local keyval_mt = { __index = keyval, flags = lmdb.MDB_CREATE }; |
23 drivers.keyval = keyval_mt; | 60 drivers.keyval = keyval_mt; |
24 | 61 |
25 function keyval:set(user, value) | 62 function keyval:set(user, value) |
26 local t = self.env:txn_begin(nil, 0); | |
27 if type(value) == "table" and next(value) == nil then | 63 if type(value) == "table" and next(value) == nil then |
28 value = nil; | 64 value = nil; |
29 end | 65 end |
30 if value ~= nil then | 66 if value ~= nil then |
31 value = serialize(value); | 67 value = serialize(value); |
32 end | 68 end |
33 local ok, err; | 69 return transaction(self.env, keyvalue_set, self.db, user, value); |
34 if value ~= nil then | |
35 ok, err = t:put(self.db, user, value, 0); | |
36 else | |
37 ok, err = t:del(self.db, user, value); | |
38 end | |
39 if not ok then | |
40 t:abort(); | |
41 return nil, err; | |
42 end | |
43 return t:commit(); | |
44 end | 70 end |
45 | 71 |
46 function keyval:get(user) | 72 function keyval:get(user) |
47 local t = self.env:txn_begin(nil, 0); | 73 local ok, data = transaction(self.env, keyvalue_get, self.db, user); |
48 local data, err = t:get(self.db, user, 0); | 74 if not ok then return ok, data; end |
49 if not data then | |
50 t:abort(); | |
51 return nil, err; | |
52 end | |
53 t:commit(); | |
54 return deserialize(data); | 75 return deserialize(data); |
55 end | 76 end |
56 | 77 |
57 function provider:init(config) | 78 function provider:init(config) |
58 if config.base_path then | 79 if config.base_path then |
93 base_path = path.resolve_relative_path(prosody.paths.data, module.host); | 114 base_path = path.resolve_relative_path(prosody.paths.data, module.host); |
94 flags = module:get_option_set("lmdb_flags", {}); | 115 flags = module:get_option_set("lmdb_flags", {}); |
95 maxdbs = module:get_option_number("lmdb_maxdbs", 20); | 116 maxdbs = module:get_option_number("lmdb_maxdbs", 20); |
96 }); | 117 }); |
97 | 118 |
98 function module.unload() | 119 function module.unload() --luacheck: ignore |
99 provider.env:sync(1); | 120 provider.env:sync(1); |
100 provider.env:close(); | 121 provider.env:close(); |
101 end | 122 end |
102 | 123 |
103 module:provides("storage", provider); | 124 module:provides("storage", provider); |