1 local next = next; |
1 local next = next; |
2 local setmetatable = setmetatable; |
2 local setmetatable = setmetatable; |
3 local set = require"util.set"; |
|
4 local it = require"util.iterators"; |
|
5 local array = require"util.array"; |
|
6 |
3 |
7 local params = assert ( module:get_option("mongodb") , "mongodb configuration not found" ); |
4 local params = assert ( module:get_option("mongodb") , "mongodb configuration not found" ); |
8 |
5 |
9 prosody.unlock_globals(); |
6 prosody.unlock_globals(); |
10 local mongo = require "mongo"; |
7 local mongo = require "mongo"; |
47 else -- delete data |
44 else -- delete data |
48 return conn:remove ( namespace , v ); |
45 return conn:remove ( namespace , v ); |
49 end; |
46 end; |
50 end |
47 end |
51 |
48 |
52 local roster_store = {}; |
|
53 roster_store.__index = roster_store; |
|
54 |
|
55 function roster_store:get(username) |
|
56 local host = module.host or "_global"; |
|
57 local store = self.store; |
|
58 |
|
59 -- The database name can't have a period in it (hence it can't be a host/ip) |
|
60 local namespace = params.dbname .. "." .. host; |
|
61 local v = { _id = { store = store ; username = username } }; |
|
62 |
|
63 local cursor , err = conn:query ( namespace , v ); |
|
64 if not cursor then return nil , err end; |
|
65 |
|
66 local r , err = cursor:next ( ); |
|
67 if not r then return nil , err end; |
|
68 local roster = { |
|
69 [false] = { |
|
70 version = r.version; |
|
71 }; |
|
72 pending = set.new( r.pending )._items; |
|
73 }; |
|
74 local items = r.items; |
|
75 for i = 1, #items do |
|
76 local item = items[i]; |
|
77 roster[item.jid] = { |
|
78 subscription = item.subscription; |
|
79 groups = set.new( item.groups )._items; |
|
80 ask = item.ask; |
|
81 name = item.name; |
|
82 } |
|
83 end |
|
84 return roster; |
|
85 end |
|
86 |
|
87 function roster_store:set(username, data) |
|
88 local host = module.host or "_global"; |
|
89 local store = self.store; |
|
90 |
|
91 -- The database name can't have a period in it (hence it can't be a host/ip) |
|
92 local namespace = params.dbname .. "." .. host; |
|
93 local v = { _id = { store = store ; username = username } }; |
|
94 |
|
95 if data == nil or next(data) == nil then -- delete data |
|
96 return conn:remove ( namespace , v ); |
|
97 end |
|
98 |
|
99 v.version = data[false].version |
|
100 if data.pending then |
|
101 v.pending = array(it.keys(v.pending)) |
|
102 end |
|
103 |
|
104 local items = {} |
|
105 for jid, item in pairs(data) do |
|
106 if jid and jid ~= "pending" then |
|
107 table.insert(items, { |
|
108 jid = jid; |
|
109 subscription = item.subscription; |
|
110 groups = array(it.keys( item.groups )); |
|
111 name = item.name; |
|
112 ask = item.ask; |
|
113 }); |
|
114 end |
|
115 end |
|
116 v.items = items; |
|
117 |
|
118 return conn:insert ( namespace , v ); |
|
119 end |
|
120 |
|
121 local driver = {}; |
49 local driver = {}; |
122 |
50 |
123 function driver:open(store, typ) |
51 function driver:open(store, typ) |
124 if not conn then |
52 if not conn then |
125 conn = assert ( mongo.Connection.New ( true ) ); |
53 conn = assert ( mongo.Connection.New ( true ) ); |
128 assert ( conn:auth ( params ) ); |
56 assert ( conn:auth ( params ) ); |
129 end |
57 end |
130 end |
58 end |
131 |
59 |
132 if not typ then -- default key-value store |
60 if not typ then -- default key-value store |
133 if store == "roster" then |
|
134 return setmetatable({ store = store }, roster_store); |
|
135 end |
|
136 return setmetatable({ store = store }, keyval_store); |
61 return setmetatable({ store = store }, keyval_store); |
137 end; |
62 end; |
138 return nil, "unsupported-store"; |
63 return nil, "unsupported-store"; |
139 end |
64 end |
140 |
65 |