mod_storage_mongodb/mod_storage_mongodb.lua
changeset 1325 b21236b6b8d8
parent 1324 853a382c9bd6
child 1593 3e4d15ae2133
equal deleted inserted replaced
1324:853a382c9bd6 1325:b21236b6b8d8
     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