2 local ipairs, pairs = ipairs, pairs;
3 local setmetatable = setmetatable;
4 local tostring = tostring;
6 local t_remove = table.remove;
7 local os_remove = os.remove;
8 local io_open = io.open;
10 local st = require "util.stanza";
11 local parse_xml_real = require "util.xml".parse;
13 local function getXml(user, host)
14 local jid = user.."@"..host;
15 local path = "data/"..jid..".xml";
16 local f = io_open(path);
17 if not f then return; end
18 local s = f:read("*a");
19 return parse_xml_real(s);
21 local function setXml(user, host, xml)
22 local jid = user.."@"..host;
23 local path = "data/"..jid..".xml";
25 local f = io_open(path, "w");
26 if not f then return; end
27 local s = tostring(xml);
32 return os_remove(path);
35 local function getUserElement(xml)
36 if xml and xml.name == "server-data" then
37 local host = xml.tags[1];
38 if host and host.name == "host" then
39 local user = host.tags[1];
40 if user and user.name == "user" then
46 local function createOuterXml(user, host)
47 return st.stanza("server-data", {xmlns='http://www.xmpp.org/extensions/xep-0227.html#ns'})
48 :tag("host", {jid=host})
49 :tag("user", {name = user});
51 local function removeFromArray(array, value)
52 for i,item in ipairs(array) do
59 local function removeStanzaChild(s, child)
60 removeFromArray(s.tags, child);
61 removeFromArray(s, child);
67 get = function(self, user)
68 local user = getUserElement(getXml(user, self.host));
69 if user and user.attr.password then
70 return { password = user.attr.password };
73 set = function(self, user, data)
74 if data and data.password then
75 local xml = getXml(user, self.host);
76 if not xml then xml = createOuterXml(user, self.host); end
77 local usere = getUserElement(xml);
78 usere.attr.password = data.password;
79 return setXml(user, self.host, xml);
81 return setXml(user, self.host, nil);
86 get = function(self, user)
87 local user = getUserElement(getXml(user, self.host));
89 local vcard = user:get_child("vCard", 'vcard-temp');
91 return st.preserialize(vcard);
95 set = function(self, user, data)
96 local xml = getXml(user, self.host);
97 local usere = xml and getUserElement(xml);
99 local vcard = usere:get_child("vCard", 'vcard-temp');
101 removeStanzaChild(usere, vcard);
106 vcard = st.deserialize(data);
107 usere:add_child(vcard);
109 return setXml(user, self.host, xml);
115 get = function(self, user)
116 local user = getUserElement(getXml(user, self.host));
118 local private = user:get_child("query", "jabber:iq:private");
121 for _, tag in ipairs(private.tags) do
122 r[tag.name..":"..tag.attr.xmlns] = st.preserialize(tag);
128 set = function(self, user, data)
129 local xml = getXml(user, self.host);
130 local usere = xml and getUserElement(xml);
132 local private = usere:get_child("query", 'jabber:iq:private');
133 if private then removeStanzaChild(usere, private); end
134 if data and next(data) ~= nil then
135 private = st.stanza("query", {xmlns='jabber:iq:private'});
136 for _,tag in pairs(data) do
137 private:add_child(st.deserialize(tag));
139 usere:add_child(private);
141 return setXml(user, self.host, xml);
147 -----------------------------
150 function driver:open(host, datastore, typ)
151 local instance = setmetatable({}, self);
152 instance.host = host;
153 instance.datastore = datastore;
154 local handler = handlers[datastore];
155 if not handler then return nil; end
156 for key,val in pairs(handler) do
159 if instance.init then instance:init(); end
163 module:provides("storage", driver);