5 local loadfile, setfenv, pcall = loadfile, setfenv, pcall; |
5 local loadfile, setfenv, pcall = loadfile, setfenv, pcall; |
6 local log = log; |
6 local log = log; |
7 local io_open = io.open; |
7 local io_open = io.open; |
8 local tostring = tostring; |
8 local tostring = tostring; |
9 local error = error; |
9 local error = error; |
|
10 |
|
11 local indent = function(f, i) |
|
12 for n = 1, i do |
|
13 f:write("\t"); |
|
14 end |
|
15 end |
10 |
16 |
11 module "datamanager" |
17 module "datamanager" |
12 |
18 |
13 |
19 |
14 ---- utils ----- |
20 ---- utils ----- |
27 return s and (s:gsub("%W", function (c) return format("%%%x", c:byte()); end)); |
33 return s and (s:gsub("%W", function (c) return format("%%%x", c:byte()); end)); |
28 end |
34 end |
29 end |
35 end |
30 |
36 |
31 local function basicSerialize (o) |
37 local function basicSerialize (o) |
32 if type(o) == "number" or type(o) == "boolean" then |
38 if type(o) == "number" or type(o) == "boolean" then |
33 return tostring(o) |
39 return tostring(o); |
34 else -- assume it is a string |
40 else -- assume it is a string -- FIXME make sure it's a string. throw an error otherwise. |
35 return format("%q", tostring(o)) |
41 return (format("%q", tostring(o)):gsub("\\\n", "\\n")); |
36 end |
42 end |
37 end |
43 end |
38 |
44 |
39 |
45 |
40 local function simplesave (f, o) |
46 local function simplesave (f, o, ind) |
41 if type(o) == "number" then |
47 if type(o) == "number" then |
42 f:write(o) |
48 f:write(o) |
43 elseif type(o) == "string" then |
49 elseif type(o) == "string" then |
44 f:write(format("%q", o)) |
50 f:write((format("%q", o):gsub("\\\n", "\\n"))) |
45 elseif type(o) == "table" then |
51 elseif type(o) == "table" then |
46 f:write("{\n") |
52 f:write("{\n") |
47 for k,v in pairs(o) do |
53 for k,v in pairs(o) do |
48 f:write(" [", basicSerialize(k), "] = ") |
54 indent(f, ind); |
49 simplesave(f, v) |
55 f:write("[", basicSerialize(k), "] = ") |
50 f:write(",\n") |
56 simplesave(f, v, ind+1) |
51 end |
57 f:write(",\n") |
52 f:write("}\n") |
58 end |
53 elseif type(o) == "boolean" then |
59 indent(f, ind-1); |
54 f:write(o and "true" or "false"); |
60 f:write("}") |
55 else |
61 elseif type(o) == "boolean" then |
56 error("cannot serialize a " .. type(o)) |
62 f:write(o and "true" or "false"); |
57 end |
63 else |
58 end |
64 error("cannot serialize a " .. type(o)) |
59 |
65 end |
|
66 end |
|
67 |
60 ------- API ------------- |
68 ------- API ------------- |
61 |
69 |
62 function getpath(username, host, datastore) |
70 function getpath(username, host, datastore) |
63 if username then |
71 if username then |
64 return format("data/%s/%s/%s.dat", encode(host), datastore, encode(username)); |
72 return format("data/%s/%s/%s.dat", encode(host), datastore, encode(username)); |
70 end |
78 end |
71 |
79 |
72 function load(username, host, datastore) |
80 function load(username, host, datastore) |
73 local data, ret = loadfile(getpath(username, host, datastore)); |
81 local data, ret = loadfile(getpath(username, host, datastore)); |
74 if not data then |
82 if not data then |
75 log("warn", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or nil).."@"..(host or nil)); |
83 log("warn", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil")); |
76 return nil; |
84 return nil; |
77 end |
85 end |
78 setfenv(data, {}); |
86 setfenv(data, {}); |
79 local success, ret = pcall(data); |
87 local success, ret = pcall(data); |
80 if not success then |
88 if not success then |
81 log("error", "Unable to load "..datastore.." storage ('"..ret.."') for user: "..(username or nil).."@"..(host or nil)); |
89 log("error", "Unable to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil")); |
82 return nil; |
90 return nil; |
83 end |
91 end |
84 return ret; |
92 return ret; |
85 end |
93 end |
86 |
94 |
87 function store(username, host, datastore, data) |
95 function store(username, host, datastore, data) |
88 local f, msg = io_open(getpath(username, host, datastore), "w+"); |
96 local f, msg = io_open(getpath(username, host, datastore), "w+"); |
89 if not f then |
97 if not f then |
90 log("error", "Unable to write to "..datastore.." storage ('"..msg.."') for user: "..(username or nil).."@"..(host or nil)); |
98 log("error", "Unable to write to "..datastore.." storage ('"..msg.."') for user: "..(username or "nil").."@"..(host or "nil")); |
91 return nil; |
99 return nil; |
92 end |
100 end |
93 f:write("return "); |
101 f:write("return "); |
94 simplesave(f, data); |
102 simplesave(f, data, 1); |
95 f:close(); |
103 f:close(); |
96 return true; |
104 return true; |
97 end |
105 end |
98 |
106 |
99 return _M; |
107 return _M; |