core/storagemanager.lua
author Kim Alvefur <zash@zash.se>
Sun, 24 Mar 2024 21:32:00 +0100
changeset 13468 2dbc169aae6a
parent 13262 c8c0cfb7f5df
permissions -rw-r--r--
util.startup: Abort before initialization of logging when started as root Prevents creation of log files owned by the root user which could be inaccessible once started correctly.
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
};