1 local format = string.format; |
1 local format = string.format; |
2 local setmetatable, type = setmetatable, type; |
2 local setmetatable, type = setmetatable, type; |
3 local pairs = pairs; |
3 local pairs, ipairs = pairs, ipairs; |
4 local char = string.char; |
4 local char = string.char; |
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 os_remove = os.remove; |
8 local os_remove = os.remove; |
9 local tostring = tostring; |
9 local tostring, tonumber = tostring, tonumber; |
10 local error = error; |
10 local error = error; |
11 local next = next; |
11 local next = next; |
|
12 local t_insert = table.insert; |
12 |
13 |
13 local indent = function(f, i) |
14 local indent = function(f, i) |
14 for n = 1, i do |
15 for n = 1, i do |
15 f:write("\t"); |
16 f:write("\t"); |
16 end |
17 end |
67 end |
68 end |
68 end |
69 end |
69 |
70 |
70 ------- API ------------- |
71 ------- API ------------- |
71 |
72 |
72 function getpath(username, host, datastore) |
73 function getpath(username, host, datastore, ext) |
|
74 ext = ext or "dat"; |
73 if username then |
75 if username then |
74 return format("data/%s/%s/%s.dat", encode(host), datastore, encode(username)); |
76 return format("data/%s/%s/%s.%s", encode(host), datastore, encode(username), ext); |
75 elseif host then |
77 elseif host then |
76 return format("data/%s/%s.dat", encode(host), datastore); |
78 return format("data/%s/%s.%s", encode(host), datastore, ext); |
77 else |
79 else |
78 return format("data/%s.dat", datastore); |
80 return format("data/%s.%s", datastore, ext); |
79 end |
81 end |
80 end |
82 end |
81 |
83 |
82 function load(username, host, datastore) |
84 function load(username, host, datastore) |
83 local data, ret = loadfile(getpath(username, host, datastore)); |
85 local data, ret = loadfile(getpath(username, host, datastore)); |
113 -- we write data even when we are deleting because lua doesn't have a |
115 -- we write data even when we are deleting because lua doesn't have a |
114 -- platform independent way of checking for non-exisitng files |
116 -- platform independent way of checking for non-exisitng files |
115 return true; |
117 return true; |
116 end |
118 end |
117 |
119 |
|
120 function list_append(username, host, datastore, data) |
|
121 if not data then return; end |
|
122 -- save the datastore |
|
123 local f, msg = io_open(getpath(username, host, datastore, "list"), "a+"); |
|
124 if not f then |
|
125 log("error", "Unable to write to "..datastore.." storage ('"..msg.."') for user: "..(username or "nil").."@"..(host or "nil")); |
|
126 return; |
|
127 end |
|
128 f:write("item("); |
|
129 simplesave(f, data, 1); |
|
130 f:write(");\n"); |
|
131 f:close(); |
|
132 return true; |
|
133 end |
|
134 |
|
135 function list_store(username, host, datastore, data) |
|
136 if not data then |
|
137 data = {}; |
|
138 end |
|
139 -- save the datastore |
|
140 local f, msg = io_open(getpath(username, host, datastore, "list"), "w+"); |
|
141 if not f then |
|
142 log("error", "Unable to write to "..datastore.." storage ('"..msg.."') for user: "..(username or "nil").."@"..(host or "nil")); |
|
143 return; |
|
144 end |
|
145 for _, d in ipairs(data) do |
|
146 f:write("item("); |
|
147 simplesave(f, d, 1); |
|
148 f:write(");\n"); |
|
149 end |
|
150 f:close(); |
|
151 if not next(data) then -- try to delete empty datastore |
|
152 os_remove(getpath(username, host, datastore, "list")); |
|
153 end |
|
154 -- we write data even when we are deleting because lua doesn't have a |
|
155 -- platform independent way of checking for non-exisitng files |
|
156 return true; |
|
157 end |
|
158 |
|
159 function list_load(username, host, datastore) |
|
160 local data, ret = loadfile(getpath(username, host, datastore, "list")); |
|
161 if not data then |
|
162 log("warn", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil")); |
|
163 return nil; |
|
164 end |
|
165 local items = {}; |
|
166 setfenv(data, {item = function(i) t_insert(items, i); end}); |
|
167 local success, ret = pcall(data); |
|
168 if not success then |
|
169 log("error", "Unable to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil")); |
|
170 return nil; |
|
171 end |
|
172 return items; |
|
173 end |
|
174 |
118 return _M; |
175 return _M; |