storagemanager, datamanager, mod_storage_{internal,sql}: Replace list_stores() with an iterator version
authorKim Alvefur <zash@zash.se>
Mon, 17 Sep 2012 05:42:10 +0200
changeset 5130 051d352ed03c
parent 5129 e8253c931166
child 5131 0cd962661fa2
storagemanager, datamanager, mod_storage_{internal,sql}: Replace list_stores() with an iterator version
core/storagemanager.lua
plugins/mod_storage_internal.lua
plugins/mod_storage_sql.lua
util/datamanager.lua
--- a/core/storagemanager.lua	Sun Sep 16 02:18:07 2012 +0200
+++ b/core/storagemanager.lua	Mon Sep 17 05:42:10 2012 +0200
@@ -119,8 +119,8 @@
 function datamanager.store(username, host, datastore, data)
 	return open(host, datastore):set(username, data);
 end
-function datamanager.list_stores(username, host)
-	return get_driver(host):list_stores(username);
+function datamanager.stores(username, host, typ)
+	return get_driver(host):stores(username, typ);
 end
 function datamanager.purge(username, host)
 	return purge(username);
--- a/plugins/mod_storage_internal.lua	Sun Sep 16 02:18:07 2012 +0200
+++ b/plugins/mod_storage_internal.lua	Mon Sep 17 05:42:10 2012 +0200
@@ -16,8 +16,8 @@
 	return datamanager.store(user, host, self.store, data);
 end
 
-function driver:list_stores(username)
-	return datamanager.list_stores(username, host);
+function driver:stores(username)
+	return datamanager.stores(username, host);
 end
 
 function driver:purge(user)
--- a/plugins/mod_storage_sql.lua	Sun Sep 16 02:18:07 2012 +0200
+++ b/plugins/mod_storage_sql.lua	Mon Sep 17 05:42:10 2012 +0200
@@ -374,10 +374,9 @@
 	return nil, "unsupported-store";
 end
 
-function driver:list_stores(username) -- Not to be confused with the list store type
-	local sql = (username == true
-		and "SELECT DISTINCT `store` FROM `prosody` WHERE `host`=? AND `user`!=?"
-		or  "SELECT DISTINCT `store` FROM `prosody` WHERE `host`=? AND `user`=?");
+function driver:stores(username) -- Not to be confused with the list store type
+	local sql = "SELECT DISTINCT `store` FROM `prosody` WHERE `host`=? AND `user`" ..
+		(username == true and "!=?" or "=?");
 	if username == true or not username then
 		username = "";
 	end
@@ -385,11 +384,11 @@
 	if not stmt then
 		return rollback(nil, err);
 	end
-	local stores = {};
-	for row in stmt:rows() do
-		stores[#stores+1] = row[1];
-	end
-	return commit(stores);
+	local next = stmt:rows();
+	return commit(function()
+		local row = next();
+		return row and row[1];
+	end);
 end
 
 function driver:purge(username)
--- a/util/datamanager.lua	Sun Sep 16 02:18:07 2012 +0200
+++ b/util/datamanager.lua	Mon Sep 17 05:42:10 2012 +0200
@@ -277,31 +277,41 @@
 	return items;
 end
 
-function list_stores(username, host)
-	if not host then
-		return nil, "bad argument #2 to 'list_stores' (string expected, got nothing)";
+local type_map = {
+	keyval = "dat";
+	list = "list";
+}
+
+function stores(username, host, typ)
+	typ = type_map[typ or "keyval"];
+	local store_dir = format("%s/%s/", data_path, encode(host));
+
+	local mode, err = lfs.attributes(store_dir, "mode");
+	if not mode then
+		return function() log("debug", err or (store_dir .. " does not exist")) end
 	end
-	local list = {};
-	local host_dir = format("%s/%s/", data_path, encode(host));
-	for node in lfs.dir(host_dir) do
-		if not node:match"^%." then -- dots should be encoded, this is probably . or ..
-			local store = decode(node);
-			local path = host_dir..node;
-			if username == true then
-				if lfs.attributes(path, "mode") == "directory" then
-					list[#list+1] = store;
+	local next, state = lfs.dir(store_dir);
+	return function(state)
+		for node in next, state do
+			if not node:match"^%." then
+				if username == true then
+					if lfs.attributes(store_dir..node, "mode") == "directory" then
+						return decode(node);
+					end
+				elseif username then
+					local store = decode(node)
+					if lfs.attributes(getpath(username, host, store, typ), "mode") then
+						return store;
+					end
+				elseif lfs.attributes(node, "mode") == "file" then
+					local file, ext = node:match("^(.*)%.([dalist]+)$");
+					if ext == typ then
+						return decode(file)
+					end
 				end
-			elseif username then
-				if lfs.attributes(getpath(username, host, store), "mode")
-					or lfs.attributes(getpath(username, host, store, "list"), "mode") then
-					list[#list+1] = store;
-				end
-			elseif lfs.attributes(path, "mode") == "file" then
-				list[#list+1] = store:gsub("%.[dalist]+$","");
 			end
 		end
-	end
-	return list;
+	end, state;
 end
 
 local function do_remove(path)