core/storagemanager.lua
author Kim Alvefur <zash@zash.se>
Sat, 23 Mar 2024 20:48:19 +0100
changeset 13465 c673ff1075bd
parent 13262 c8c0cfb7f5df
permissions -rw-r--r--
mod_posix: Move everything to util.startup This allows greater control over the order of events. Notably, the internal ordering between daemonization, initialization of libunbound and setup of signal handling is sensitive. libunbound starts a separate thread for processing DNS requests. If this thread is started before signal handling has been set up, it will not inherit the signal handlers and instead behave as it would have before signal handlers were set up, i.e. cause the whole process to immediately exit. libunbound is usually initialized on the first DNS request, usually triggered by an outgoing s2s connection attempt. If daemonization happens before signals have been set up, signals may not be processed at all.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     1
6555
bcb834728ee5 storagemanager: Remove unused import of error()
Matthew Wild <mwild1@gmail.com>
parents: 5776
diff changeset
     2
local type, pairs = type, pairs;
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     3
local setmetatable = setmetatable;
8673
800c648827e3 storagemanager: Remove unused variable [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8657
diff changeset
     4
local rawset = rawset;
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     5
12976
ead41e25ebc0 core: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12960
diff changeset
     6
local config = require "prosody.core.configmanager";
ead41e25ebc0 core: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12960
diff changeset
     7
local datamanager = require "prosody.util.datamanager";
ead41e25ebc0 core: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12960
diff changeset
     8
local modulemanager = require "prosody.core.modulemanager";
ead41e25ebc0 core: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12960
diff changeset
     9
local multitable = require "prosody.util.multitable";
ead41e25ebc0 core: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12960
diff changeset
    10
local log = require "prosody.util.logger".init("storagemanager");
ead41e25ebc0 core: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12960
diff changeset
    11
local async = require "prosody.util.async";
8657
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    12
local debug = debug;
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    13
3728
b1b8fe846d68 storagemanager: Hook "host-activated", to make sure we are notified about data drivers.
Waqas Hussain <waqas20@gmail.com>
parents: 3727
diff changeset
    14
local prosody = prosody;
8720
9ddd0fbbe53a core: Use prosody.hosts instead of _G.hosts for consistency
Kim Alvefur <zash@zash.se>
parents: 8694
diff changeset
    15
local hosts = prosody.hosts;
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    16
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
    17
local _ENV = nil;
8558
4f0f5b49bb03 vairious: Add annotation when an empty environment is set [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8002
diff changeset
    18
-- luacheck: std none
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    19
4085
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
    20
local olddm = {}; -- maintain old datamanager, for backwards compatibility
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
    21
for k,v in pairs(datamanager) do olddm[k] = v; end
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
    22
4010
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    23
local null_storage_method = function () return false, "no data storage active"; end
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    24
local null_storage_driver = setmetatable(
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    25
	{
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    26
		name = "null",
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    27
		open = function (self) return self; end
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    28
	}, {
6666
d3023dd07cb6 portmanager, s2smanager, sessionmanager, stanza_router, storagemanager, usermanager, util.xml: Add luacheck annotations
Matthew Wild <mwild1@gmail.com>
parents: 6555
diff changeset
    29
		__index = function (self, method) --luacheck: ignore 212
4010
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    30
			return null_storage_method;
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    31
		end
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    32
	}
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    33
);
21311bd31f6b storagemanager: Add new "null" provider to get used when loading a driver or opening a store fails, instead of falling back to the default driver
Matthew Wild <mwild1@gmail.com>
parents: 4009
diff changeset
    34
8694
564e2c63e0d4 storagemanager: Default storage_async_check to false for a while
Matthew Wild <mwild1@gmail.com>
parents: 8673
diff changeset
    35
local async_check = config.get("*", "storage_async_check") == true;
8657
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    36
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    37
local stores_available = multitable.new();
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    38
8657
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    39
local function check_async_wrapper(event)
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    40
	local store = event.store;
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    41
	event.store = setmetatable({}, {
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    42
		__index = function (t, method_name)
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    43
			local original_method = store[method_name];
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    44
			if type(original_method) ~= "function" then
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    45
				if original_method then
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    46
					rawset(t, method_name, original_method);
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    47
				end
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    48
				return original_method;
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    49
			end
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    50
			local wrapped_method = function (...)
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    51
				if not async.ready() then
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    52
					log("warn", "ASYNC-01: Attempt to access storage outside async context, "
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    53
					  .."see https://prosody.im/doc/developers/async - %s", debug.traceback());
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    54
				end
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    55
				return original_method(...);
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    56
			end
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    57
			rawset(t, method_name, wrapped_method);
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    58
			return wrapped_method;
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    59
		end;
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    60
	});
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    61
end
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    62
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
    63
local function initialize_host(host)
3727
1bbd655975ca storagemanager: Fixed a nil global access.
Waqas Hussain <waqas20@gmail.com>
parents: 3662
diff changeset
    64
	local host_session = hosts[host];
5121
b5a5643f8572 core.storagemanager, mod_storage_*: "data-driver" -> "storage-provider", to allow using module:provides().
Waqas Hussain <waqas20@gmail.com>
parents: 5111
diff changeset
    65
	host_session.events.add_handler("item-added/storage-provider", function (event)
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    66
		local item = event.item;
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    67
		stores_available:set(host, item.name, item);
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    68
	end);
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5502
diff changeset
    69
5121
b5a5643f8572 core.storagemanager, mod_storage_*: "data-driver" -> "storage-provider", to allow using module:provides().
Waqas Hussain <waqas20@gmail.com>
parents: 5111
diff changeset
    70
	host_session.events.add_handler("item-removed/storage-provider", function (event)
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    71
		local item = event.item;
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    72
		stores_available:set(host, item.name, nil);
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    73
	end);
8657
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    74
	if async_check then
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    75
		host_session.events.add_handler("store-opened", check_async_wrapper);
425de10efde4 storagemanager: Log warning on storage access outside of async contexts
Matthew Wild <mwild1@gmail.com>
parents: 8558
diff changeset
    76
	end
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    77
end
3728
b1b8fe846d68 storagemanager: Hook "host-activated", to make sure we are notified about data drivers.
Waqas Hussain <waqas20@gmail.com>
parents: 3727
diff changeset
    78
prosody.events.add_handler("host-activated", initialize_host, 101);
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    79
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
    80
local function load_driver(host, driver_name)
4085
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
    81
	if driver_name == "null" then
4758
b8b050e76ee1 storagemanager: Fix incorrect variable name
Matthew Wild <mwild1@gmail.com>
parents: 4115
diff changeset
    82
		return null_storage_driver;
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    83
	end
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    84
	local driver = stores_available:get(host, driver_name);
3734
ec59071e2a55 storagemanager: When we have a cached data driver, we are supposed to use it.
Waqas Hussain <waqas20@gmail.com>
parents: 3728
diff changeset
    85
	if driver then return driver; end
4085
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
    86
	local ok, err = modulemanager.load(host, "storage_"..driver_name);
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
    87
	if not ok then
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
    88
		log("error", "Failed to load storage driver plugin %s on %s: %s", driver_name, host, err);
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
    89
	end
4085
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
    90
	return stores_available:get(host, driver_name);
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    91
end
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    92
6952
1c2c3d913172 storagemanager: Split config retrieval into its own function
Matthew Wild <mwild1@gmail.com>
parents: 6812
diff changeset
    93
local function get_storage_config(host)
13262
c8c0cfb7f5df core.storagemanager: Remove 0.10 era sql2 driver COMPAT
Kim Alvefur <zash@zash.se>
parents: 12976
diff changeset
    94
	-- Here used to be some some compat checks
c8c0cfb7f5df core.storagemanager: Remove 0.10 era sql2 driver COMPAT
Kim Alvefur <zash@zash.se>
parents: 12976
diff changeset
    95
	return config.get(host, "storage");
6952
1c2c3d913172 storagemanager: Split config retrieval into its own function
Matthew Wild <mwild1@gmail.com>
parents: 6812
diff changeset
    96
end
1c2c3d913172 storagemanager: Split config retrieval into its own function
Matthew Wild <mwild1@gmail.com>
parents: 6812
diff changeset
    97
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
    98
local function get_driver(host, store)
6952
1c2c3d913172 storagemanager: Split config retrieval into its own function
Matthew Wild <mwild1@gmail.com>
parents: 6812
diff changeset
    99
	local storage = get_storage_config(host);
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   100
	local driver_name;
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   101
	local option_type = type(storage);
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   102
	if option_type == "string" then
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   103
		driver_name = storage;
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   104
	elseif option_type == "table" then
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   105
		driver_name = storage[store];
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   106
	end
4085
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
   107
	if not driver_name then
5131
0cd962661fa2 storagemanager: Remove usage of 'core' when calling configmanager.get()
Matthew Wild <mwild1@gmail.com>
parents: 5130
diff changeset
   108
		driver_name = config.get(host, "default_storage") or "internal";
4085
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
   109
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5502
diff changeset
   110
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   111
	local driver = load_driver(host, driver_name);
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   112
	if not driver then
4085
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
   113
		log("warn", "Falling back to null driver for %s storage on %s", store, host);
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
   114
		driver_name = "null";
7699cef04740 storagemanager, mod_storage_internal: Split out default driver to mod_storage_internal, and greatly simplify storagemanager's error handling and fallback code
Matthew Wild <mwild1@gmail.com>
parents: 4011
diff changeset
   115
		driver = null_storage_driver;
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   116
	end
5036
be33164aa97e storagemanager: Split out driver choosing from the open() method
Kim Alvefur <zash@zash.se>
parents: 4758
diff changeset
   117
	return driver, driver_name;
5110
72a7427368f8 storagemanager: Fix indentation
Kim Alvefur <zash@zash.se>
parents: 5041
diff changeset
   118
end
72a7427368f8 storagemanager: Fix indentation
Kim Alvefur <zash@zash.se>
parents: 5041
diff changeset
   119
7153
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   120
local map_shim_mt = {
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   121
	__index = {
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   122
		get = function(self, username, key)
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   123
			local ret, err = self.keyval_store:get(username);
7154
584d5229cb91 storagemanager: Fix map store shim if store is empty
Kim Alvefur <zash@zash.se>
parents: 7153
diff changeset
   124
			if ret == nil then return nil, err end
7153
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   125
			return ret[key];
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   126
		end;
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   127
		set = function(self, username, key, data)
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   128
			local current, err = self.keyval_store:get(username);
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   129
			if current == nil then
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   130
				if err then
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   131
					return nil, err;
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   132
				else
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   133
					current = {};
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   134
				end
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   135
			end
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   136
			current[key] = data;
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   137
			return self.keyval_store:set(username, current);
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   138
		end;
7155
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   139
		set_keys = function (self, username, keydatas)
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   140
			local current, err = self.keyval_store:get(username);
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   141
			if current == nil then
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   142
				if err then
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   143
					return nil, err;
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   144
				end
7247
8c6943918279 storagemanager: Fix saving data in map shim when no prior data exists
Kim Alvefur <zash@zash.se>
parents: 7155
diff changeset
   145
				current = {};
8c6943918279 storagemanager: Fix saving data in map shim when no prior data exists
Kim Alvefur <zash@zash.se>
parents: 7155
diff changeset
   146
			end
8c6943918279 storagemanager: Fix saving data in map shim when no prior data exists
Kim Alvefur <zash@zash.se>
parents: 7155
diff changeset
   147
			for k,v in pairs(keydatas) do
8c6943918279 storagemanager: Fix saving data in map shim when no prior data exists
Kim Alvefur <zash@zash.se>
parents: 7155
diff changeset
   148
				if v == self.remove then v = nil; end
8c6943918279 storagemanager: Fix saving data in map shim when no prior data exists
Kim Alvefur <zash@zash.se>
parents: 7155
diff changeset
   149
				current[k] = v;
7155
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   150
			end
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   151
			return self.keyval_store:set(username, current);
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   152
		end;
ca64255bf7cd storagemanager: Add set_keys method to map store shim
Kim Alvefur <zash@zash.se>
parents: 7154
diff changeset
   153
		remove = {};
10684
19692fc5c106 storagemanager, mod_storage_sql: Rename methods to :get_all() and :delete_all()
Matthew Wild <mwild1@gmail.com>
parents: 10683
diff changeset
   154
		get_all = function (self, key)
10683
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   155
			if type(key) ~= "string" or key == "" then
10684
19692fc5c106 storagemanager, mod_storage_sql: Rename methods to :get_all() and :delete_all()
Matthew Wild <mwild1@gmail.com>
parents: 10683
diff changeset
   156
				return nil, "get_all only supports non-empty string keys";
10683
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   157
			end
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   158
			local ret;
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   159
			for username in self.keyval_store:users() do
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   160
				local key_data = self:get(username, key);
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   161
				if key_data then
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   162
					if not ret then
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   163
						ret = {};
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   164
					end
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   165
					ret[username] = key_data;
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   166
				end
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   167
			end
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   168
			return ret;
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   169
		end;
10684
19692fc5c106 storagemanager, mod_storage_sql: Rename methods to :get_all() and :delete_all()
Matthew Wild <mwild1@gmail.com>
parents: 10683
diff changeset
   170
		delete_all = function (self, key)
10683
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   171
			if type(key) ~= "string" or key == "" then
10684
19692fc5c106 storagemanager, mod_storage_sql: Rename methods to :get_all() and :delete_all()
Matthew Wild <mwild1@gmail.com>
parents: 10683
diff changeset
   172
				return nil, "delete_all only supports non-empty string keys";
10683
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   173
			end
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   174
			local data = { [key] = self.remove };
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   175
			local last_err;
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   176
			for username in self.keyval_store:users() do
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   177
				local ok, err = self:set_keys(username, data);
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   178
				if not ok then
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   179
					last_err = err;
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   180
				end
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   181
			end
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   182
			if last_err then
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   183
				return nil, last_err;
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   184
			end
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   185
			return true;
b50b1eae711c storagemanager: Add support for :find_key() and :delete_key() to map store shim
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   186
		end;
7153
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   187
	};
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   188
}
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   189
12960
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   190
local combined_store_mt = {
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   191
	__index = {
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   192
		-- keyval
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   193
		get = function (self, name)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   194
			return self.keyval_store:get(name);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   195
		end;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   196
		set = function (self, name, data)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   197
			return self.keyval_store:set(name, data);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   198
		end;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   199
		items = function (self)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   200
			return self.keyval_store:users();
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   201
		end;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   202
		-- map
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   203
		get_key = function (self, name, key)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   204
			return self.map_store:get(name, key);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   205
		end;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   206
		set_key = function (self, name, key, value)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   207
			return self.map_store:set(name, key, value);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   208
		end;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   209
		set_keys = function (self, name, map)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   210
			return self.map_store:set_keys(name, map);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   211
		end;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   212
		get_key_from_all = function (self, key)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   213
			return self.map_store:get_all(key);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   214
		end;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   215
		delete_key_from_all = function (self, key)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   216
			return self.map_store:delete_all(key);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   217
		end;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   218
	};
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   219
};
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   220
6795
8b284787fe26 storagemanager: Add forward declaration to fix use of open() before it's defined
Kim Alvefur <zash@zash.se>
parents: 6794
diff changeset
   221
local open; -- forward declaration
7153
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   222
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   223
local function create_map_shim(host, store)
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   224
	local keyval_store, err = open(host, store, "keyval");
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   225
	if keyval_store == nil then return nil, err end
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   226
	return setmetatable({
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   227
		keyval_store = keyval_store;
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   228
	}, map_shim_mt);
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   229
end
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   230
12960
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   231
local function open_combined(host, store)
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   232
	local driver, driver_name = get_driver(host, store);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   233
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   234
	-- Open keyval
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   235
	local keyval_store, err = driver:open(store, "keyval");
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   236
	if not keyval_store then
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   237
		if err == "unsupported-store" then
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   238
			log("debug", "Storage driver %s does not support store %s (keyval), falling back to null driver",
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   239
				driver_name, store);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   240
			keyval_store, err = null_storage_driver, nil;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   241
		end
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   242
	end
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   243
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   244
	local map_store;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   245
	if keyval_store then
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   246
		-- Open map
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   247
		map_store, err = driver:open(store, "map");
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   248
		if not map_store then
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   249
			if err == "unsupported-store" then
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   250
				log("debug", "Storage driver %s does not support store %s (map), falling back to shim",
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   251
					driver_name, store);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   252
				map_store, err = setmetatable({ keyval_store = keyval_store }, map_shim_mt), nil;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   253
			end
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   254
		end
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   255
	end
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   256
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   257
	if not(keyval_store and map_store) then
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   258
		return nil, err;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   259
	end
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   260
	local combined_store = setmetatable({
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   261
		keyval_store = keyval_store;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   262
		map_store = map_store;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   263
		remove = map_store.remove;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   264
	}, combined_store_mt);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   265
	local event_data = { host = host, store_name = store, store_type = "keyval+", store = combined_store };
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   266
	hosts[host].events.fire_event("store-opened", event_data);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   267
	return event_data.store, event_data.store_err;
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   268
end
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   269
7153
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   270
function open(host, store, typ)
12960
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   271
	if typ == "keyval+" then -- TODO: default in some release?
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   272
		return open_combined(host, store);
52fcdfe710ca storagemanager: Add keyval+ (combined keyval + map) store type
Matthew Wild <mwild1@gmail.com>
parents: 10684
diff changeset
   273
	end
5036
be33164aa97e storagemanager: Split out driver choosing from the open() method
Kim Alvefur <zash@zash.se>
parents: 4758
diff changeset
   274
	local driver, driver_name = get_driver(host, store);
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   275
	local ret, err = driver:open(store, typ);
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   276
	if not ret then
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   277
		if err == "unsupported-store" then
7153
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   278
			if typ == "map" then -- Use shim on top of keyval store
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   279
				log("debug", "map storage driver unavailable, using shim on top of keyval store.");
7646
44fe2aaf817e storagemanager: Simplify function flow
Matthew Wild <mwild1@gmail.com>
parents: 7328
diff changeset
   280
				ret, err = create_map_shim(host, store);
44fe2aaf817e storagemanager: Simplify function flow
Matthew Wild <mwild1@gmail.com>
parents: 7328
diff changeset
   281
			else
44fe2aaf817e storagemanager: Simplify function flow
Matthew Wild <mwild1@gmail.com>
parents: 7328
diff changeset
   282
				log("debug", "Storage driver %s does not support store %s (%s), falling back to null driver",
44fe2aaf817e storagemanager: Simplify function flow
Matthew Wild <mwild1@gmail.com>
parents: 7328
diff changeset
   283
					driver_name, store, typ or "<nil>");
44fe2aaf817e storagemanager: Simplify function flow
Matthew Wild <mwild1@gmail.com>
parents: 7328
diff changeset
   284
				ret, err = null_storage_driver, nil;
7153
fcaaafe4062f storagemanager: When map store isn't available, fallback to keyval store [backported from trunk]
daurnimator <quae@daurnimator.com>
parents: 6954
diff changeset
   285
			end
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   286
		end
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   287
	end
7647
90a4790c2329 storagemanager: Fire event when opening a store, and allow the returned store/err to be overridden
Matthew Wild <mwild1@gmail.com>
parents: 7646
diff changeset
   288
	if ret then
90a4790c2329 storagemanager: Fire event when opening a store, and allow the returned store/err to be overridden
Matthew Wild <mwild1@gmail.com>
parents: 7646
diff changeset
   289
		local event_data = { host = host, store_name = store, store_type = typ, store = ret };
7997
3325ac397f17 storagemanager: Use the existing local reference to 'hosts'
Kim Alvefur <zash@zash.se>
parents: 7950
diff changeset
   290
		hosts[host].events.fire_event("store-opened", event_data);
7647
90a4790c2329 storagemanager: Fire event when opening a store, and allow the returned store/err to be overridden
Matthew Wild <mwild1@gmail.com>
parents: 7646
diff changeset
   291
		ret, err = event_data.store, event_data.store_err;
90a4790c2329 storagemanager: Fire event when opening a store, and allow the returned store/err to be overridden
Matthew Wild <mwild1@gmail.com>
parents: 7646
diff changeset
   292
	end
3644
22fc2063b824 storagemanager: Much refactoring and renaming of options. Untested, needs storage plugin(s) to be brought into line.
Matthew Wild <mwild1@gmail.com>
parents: 3403
diff changeset
   293
	return ret, err;
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   294
end
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   295
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   296
local function purge(user, host)
6952
1c2c3d913172 storagemanager: Split config retrieval into its own function
Matthew Wild <mwild1@gmail.com>
parents: 6812
diff changeset
   297
	local storage = get_storage_config(host);
5129
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   298
	if type(storage) == "table" then
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   299
		-- multiple storage backends in use that we need to purge
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   300
		local purged = {};
6812
dd6b21862e3b storagemanager: Check if drivers support purging, warn otherwise
Kim Alvefur <zash@zash.se>
parents: 6810
diff changeset
   301
		for store, driver_name in pairs(storage) do
dd6b21862e3b storagemanager: Check if drivers support purging, warn otherwise
Kim Alvefur <zash@zash.se>
parents: 6810
diff changeset
   302
			if not purged[driver_name] then
dd6b21862e3b storagemanager: Check if drivers support purging, warn otherwise
Kim Alvefur <zash@zash.se>
parents: 6810
diff changeset
   303
				local driver = get_driver(host, store);
dd6b21862e3b storagemanager: Check if drivers support purging, warn otherwise
Kim Alvefur <zash@zash.se>
parents: 6810
diff changeset
   304
				if driver.purge then
dd6b21862e3b storagemanager: Check if drivers support purging, warn otherwise
Kim Alvefur <zash@zash.se>
parents: 6810
diff changeset
   305
					purged[driver_name] = driver:purge(user);
dd6b21862e3b storagemanager: Check if drivers support purging, warn otherwise
Kim Alvefur <zash@zash.se>
parents: 6810
diff changeset
   306
				else
7950
24170d74b00b core: Split some very long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7648
diff changeset
   307
					log("warn", "Storage driver %s does not support removing all user data, "
24170d74b00b core: Split some very long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7648
diff changeset
   308
						.."you may need to delete it manually", driver_name);
6812
dd6b21862e3b storagemanager: Check if drivers support purging, warn otherwise
Kim Alvefur <zash@zash.se>
parents: 6810
diff changeset
   309
				end
5129
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   310
			end
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   311
		end
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   312
	end
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   313
	get_driver(host):purge(user); -- and the default driver
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   314
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   315
	olddm.purge(user, host); -- COMPAT list stores, like offline messages end up in the old datamanager
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   316
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   317
	return true;
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   318
end
e8253c931166 storagemanager: Add purge() for purging user data from all backends in use
Kim Alvefur <zash@zash.se>
parents: 5111
diff changeset
   319
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   320
function datamanager.load(username, host, datastore)
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   321
	return open(host, datastore):get(username);
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   322
end
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   323
function datamanager.store(username, host, datastore, data)
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   324
	return open(host, datastore):set(username, data);
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   325
end
5155
a207d4bff5a4 storagemanager: Support for iterating over users
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
   326
function datamanager.users(host, datastore, typ)
a207d4bff5a4 storagemanager: Support for iterating over users
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
   327
	local driver = open(host, datastore, typ);
a207d4bff5a4 storagemanager: Support for iterating over users
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
   328
	if not driver.users then
7328
7baf1b14defb storagemanager: Capitalize log message
Kim Alvefur <zash@zash.se>
parents: 7247
diff changeset
   329
		return function() log("warn", "Storage driver %s does not support listing users", driver.name) end
5155
a207d4bff5a4 storagemanager: Support for iterating over users
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
   330
	end
a207d4bff5a4 storagemanager: Support for iterating over users
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
   331
	return driver:users();
a207d4bff5a4 storagemanager: Support for iterating over users
Kim Alvefur <zash@zash.se>
parents: 5137
diff changeset
   332
end
5130
051d352ed03c storagemanager, datamanager, mod_storage_{internal,sql}: Replace list_stores() with an iterator version
Kim Alvefur <zash@zash.se>
parents: 5129
diff changeset
   333
function datamanager.stores(username, host, typ)
051d352ed03c storagemanager, datamanager, mod_storage_{internal,sql}: Replace list_stores() with an iterator version
Kim Alvefur <zash@zash.se>
parents: 5129
diff changeset
   334
	return get_driver(host):stores(username, typ);
5037
c34fdcae6d29 storagemanager: Add method for listing stores
Kim Alvefur <zash@zash.se>
parents: 5036
diff changeset
   335
end
5041
be204204cc5f storagemanager: Add method for removing all data belonging to a user
Kim Alvefur <zash@zash.se>
parents: 5037
diff changeset
   336
function datamanager.purge(username, host)
5136
77ea38607a89 storagemanager: Fix argument (Thanks Maranda)
Kim Alvefur <zash@zash.se>
parents: 5133
diff changeset
   337
	return purge(username, host);
5041
be204204cc5f storagemanager: Add method for removing all data belonging to a user
Kim Alvefur <zash@zash.se>
parents: 5037
diff changeset
   338
end
3401
2387f35db5c8 storagemanager: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   339
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   340
return {
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   341
	initialize_host = initialize_host;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   342
	load_driver = load_driver;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   343
	get_driver = get_driver;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   344
	open = open;
6810
5e3242d349f2 storagemanager: Export purge (fixes deleting users from usermanager) (thanks mt)
Kim Alvefur <zash@zash.se>
parents: 6782
diff changeset
   345
	purge = purge;
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   346
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   347
	olddm = olddm;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6666
diff changeset
   348
};