util/datamanager.lua
changeset 0 3e3171b59028
child 82 cbf387f29d56
child 84 d0a0bac6815e
equal deleted inserted replaced
-1:000000000000 0:3e3171b59028
       
     1 local format = string.format;
       
     2 local setmetatable, type = setmetatable, type;
       
     3 local pairs = pairs;
       
     4 local char = string.char;
       
     5 local loadfile, setfenv, pcall = loadfile, setfenv, pcall;
       
     6 local log = log;
       
     7 local io_open = io.open;
       
     8 
       
     9 module "datamanager"
       
    10 
       
    11 
       
    12 ---- utils -----
       
    13 local encode, decode;
       
    14 
       
    15 local log = function (type, msg) return log(type, "datamanager", msg); end
       
    16 
       
    17 do 
       
    18 	local urlcodes = setmetatable({}, { __index = function (t, k) t[k] = char(tonumber("0x"..k)); return t[k]; end });
       
    19 
       
    20 	decode = function (s)
       
    21 		return s and (s:gsub("+", " "):gsub("%%([a-fA-F0-9][a-fA-F0-9])", urlcodes));
       
    22 	end
       
    23 
       
    24 	encode = function (s)
       
    25 		return s and (s:gsub("%W", function (c) return format("%%%x", c:byte()); end));
       
    26 	end
       
    27 end
       
    28 
       
    29 local function basicSerialize (o)
       
    30   if type(o) == "number" or type(o) == "boolean" then
       
    31     return tostring(o)
       
    32   else -- assume it is a string
       
    33     return string.format("%q", tostring(o))
       
    34   end
       
    35 end
       
    36 
       
    37 
       
    38 local function simplesave (f, o)
       
    39       if type(o) == "number" then
       
    40         f:write(o)
       
    41       elseif type(o) == "string" then
       
    42         f:write(format("%q", o))
       
    43       elseif type(o) == "table" then
       
    44         f:write("{\n")
       
    45         for k,v in pairs(o) do
       
    46           f:write(" [", format("%q", k), "] = ")
       
    47           simplesave(f, v)
       
    48           f:write(",\n")
       
    49         end
       
    50         f:write("}\n")
       
    51       else
       
    52         error("cannot serialize a " .. type(o))
       
    53       end
       
    54     end
       
    55   
       
    56 ------- API -------------
       
    57 
       
    58 function getpath(username, host, datastore)
       
    59 	return format("data/%s/%s/%s.dat", encode(host), datastore, encode(username));
       
    60 end
       
    61 
       
    62 function load(username, host, datastore)
       
    63 	local data, ret = loadfile(getpath(username, host, datastore));
       
    64 	if not data then log("warn", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..username.."@"..host); return nil; end
       
    65 	setfenv(data, {});
       
    66 	local success, ret = pcall(data);
       
    67 	if not success then log("error", "Unable to load "..datastore.." storage ('"..ret.."') for user: "..username.."@"..host); return nil; end
       
    68 	return ret;
       
    69 end
       
    70 
       
    71 function store(username, host, datastore, data)
       
    72 	local f, msg = io_open(getpath(username, host, datastore), "w+");
       
    73 	if not f then log("error", "Unable to write to "..datastore.." storage ('"..msg.."') for user: "..username.."@"..host); return nil; end
       
    74 	f:write("return ");
       
    75 	simplesave(f, data);
       
    76 	f:close();
       
    77 	return true;
       
    78 end
       
    79