mod_storage_appendmap/mod_storage_appendmap.lua
author Kim Alvefur <zash@zash.se>
Mon, 02 Jan 2017 21:03:56 +0100
changeset 2434 a2625a36c092
parent 2209 98354fbea63c
child 2435 623e23190c3e
permissions -rw-r--r--
mod_storage_appendmap: Fix pattern meant to match valid Lua Names so such are escaped correctly
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
local dump = require "util.serialization".serialize;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
local load = require "util.envload".envloadfile;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
local dm = require "core.storagemanager".olddm;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
local driver = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
local map = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
local map_mt = { __index = map };
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
map.remove = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
function map:get(user, key)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
	module:log("debug", "map:get(%s, %s)", tostring(user), tostring(key))
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
	local filename = dm.getpath(user, module.host, self.store, "map");
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
	module:log("debug", "File is %s", filename);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
	local env = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
	if _VERSION == "Lua 5.1" then -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
		env._ENV = env; -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
	end -- SO MANY HACKS
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
	local chunk, err = load(filename, env);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
	if not chunk then return chunk, err; end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
	local ok, err = pcall(chunk);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
	if not ok then return ok, err; end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
	if _VERSION == "Lua 5.1" then -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
		env._ENV = nil; -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
	end -- HACKS EVERYWHERE
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
	if key == nil then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
		return env;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
	return env[key];
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
function map:set_keys(user, keyvalues)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
	local keys, values = {}, {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
	if _VERSION == "Lua 5.1" then
2209
98354fbea63c mod_storage_appendmap: Prevent _ENV = false
Kim Alvefur <zash@zash.se>
parents: 2066
diff changeset
    35
		assert(keyvalues._ENV == nil, "'_ENV' is a restricted key");
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
	for key, value in pairs(keyvalues) do
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
		module:log("debug", "user %s sets %q to %s", user, key, tostring(value))
2434
a2625a36c092 mod_storage_appendmap: Fix pattern meant to match valid Lua Names so such are escaped correctly
Kim Alvefur <zash@zash.se>
parents: 2209
diff changeset
    39
		if type(key) ~= "string" or not key:find("^[%a_][%w_]*$") or key == "_ENV" then
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
			key = "_ENV[" .. dump(key) .. "]";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
		end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
		table.insert(keys, key);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
		if value == self.remove then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
			table.insert(values, "nil")
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
		else
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
			table.insert(values, dump(value))
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
		end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
	local data = table.concat(keys, ", ") .. " = " .. table.concat(values, ", ") .. ";\n";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
	return dm.append_raw(user, module.host, self.store, "map", data);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
function map:set(user, key, value)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
	if _VERSION == "Lua 5.1" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
		assert(key ~= "_ENV", "'_ENV' is a restricted key");
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
	if key == nil then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
		local filename = dm.getpath(user, module.host, self.store, "map");
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
		os.remove(filename);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
		return true;
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
	if type(key) ~= "string" or not key:find("^[%w_][%w%d_]*$") or key == "_ENV" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
		key = "_ENV[" .. dump(key) .. "]";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
	local data = key .. " = " .. dump(value) .. ";\n";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
	return dm.append_raw(user, module.host, self.store, "map", data);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
local keyval = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
local keyval_mt = { __index = keyval };
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
function keyval:get(user)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
	return map.get(self, user);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
2066
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    76
function keyval:set(user, data)
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    77
	map.set(self, user);
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    78
	if data then
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    79
		for k, v in pairs(data) do
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    80
			map.set(self, user, k, v);
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    81
		end
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    82
	end
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    83
	return true;
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
    84
end
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
-- TODO some kind of periodic compaction thing?
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
function map:_compact(user)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
	local data = self:get(user);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
	return keyval.set(self, user, data);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
function driver:open(store, typ)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
	if typ == "map" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
		return setmetatable({ store = store, }, map_mt);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
	elseif typ == nil or typ == "keyval" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
		return setmetatable({ store = store, }, keyval_mt);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
	return nil, "unsupported-store";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
module:provides("storage", driver);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102