Merge 0.10->trunk
[prosody.git] / core / storagemanager.lua
index 55f0800a203fe34a615ca028616f3dc2e13ccb8a..046f496a2ca8c5e85b73d8e0d4e1076744ce5c8e 100644 (file)
@@ -79,11 +79,47 @@ local function get_driver(host, store)
        return driver, driver_name;
 end
 
-local function open(host, store, typ)
+local map_shim_mt = {
+       __index = {
+               get = function(self, username, key)
+                       local ret, err = self.keyval_store:get(username);
+                       if ret == nil then return nil, err end
+                       return ret[key];
+               end;
+               set = function(self, username, key, data)
+                       local current, err = self.keyval_store:get(username);
+                       if current == nil then
+                               if err then
+                                       return nil, err;
+                               else
+                                       current = {};
+                               end
+                       end
+                       current[key] = data;
+                       return self.keyval_store:set(username, current);
+               end;
+       };
+}
+
+local open; -- forward declaration
+
+local function create_map_shim(host, store)
+       local keyval_store, err = open(host, store, "keyval");
+       if keyval_store == nil then return nil, err end
+       return setmetatable({
+               keyval_store = keyval_store;
+       }, map_shim_mt);
+end
+
+function open(host, store, typ)
        local driver, driver_name = get_driver(host, store);
        local ret, err = driver:open(store, typ);
        if not ret then
                if err == "unsupported-store" then
+                       if typ == "map" then -- Use shim on top of keyval store
+                               log("debug", "map storage driver unavailable, using shim on top of keyval store.");
+                               return create_map_shim(host, store);
+                       end
                        log("debug", "Storage driver %s does not support store %s (%s), falling back to null driver",
                                driver_name, store, typ or "<nil>");
                        ret = null_storage_driver;
@@ -98,9 +134,14 @@ local function purge(user, host)
        if type(storage) == "table" then
                -- multiple storage backends in use that we need to purge
                local purged = {};
-               for store, driver in pairs(storage) do
-                       if not purged[driver] then
-                               purged[driver] = get_driver(host, store):purge(user);
+               for store, driver_name in pairs(storage) do
+                       if not purged[driver_name] then
+                               local driver = get_driver(host, store);
+                               if driver.purge then
+                                       purged[driver_name] = driver:purge(user);
+                               else
+                                       log("warn", "Storage driver %s does not support removing all user data, you may need to delete it manually", driver_name);
+                               end
                        end
                end
        end