1 local dump
= require
"util.serialization".serialize
;
2 local load
= require
"util.envload".envloadfile
;
3 local dm
= require
"core.storagemanager".olddm
;
5 local REMOVE
= {}; -- Special value for removing keys
11 ["do"] = true; ["and"] = true; ["else"] = true; ["break"] = true;
12 ["if"] = true; ["end"] = true; ["goto"] = true; ["false"] = true;
13 ["in"] = true; ["for"] = true; ["then"] = true; ["local"] = true;
14 ["or"] = true; ["nil"] = true; ["true"] = true; ["until"] = true;
15 ["elseif"] = true; ["function"] = true; ["not"] = true;
16 ["repeat"] = true; ["return"] = true; ["while"] = true;
18 -- _ENV is not technically a keyword but we need to treat it as such
22 local function is_usable_identifier(s
)
23 return type(s
) == "string" and not keywords
[s
] and s
:find("^[%a_][%w_]*$");
26 local function serialize_key(key
)
27 if is_usable_identifier(key
) then
30 return "_ENV[" .. dump(key
) .. "]";
34 local function serialize_value(value
)
35 if value
== REMOVE
then
42 local function serialize_pair(key
, value
)
43 key
= serialize_key(key
);
44 value
= serialize_value(value
);
45 return key
.. " = " .. value
.. ";\n";
48 local function serialize_map(keyvalues
)
49 local keys
, values
= {}, {};
50 for key
, value
in pairs(keyvalues
) do
51 key
= serialize_key(key
);
52 value
= serialize_value(value
);
53 table.insert(keys
, key
);
54 table.insert(values
, value
);
56 return table.concat(keys
, ", ") .. " = " .. table.concat(values
, ", ") .. ";\n";
59 local map
= { remove = REMOVE
};
60 local map_mt
= { __index
= map
};
62 function map
:get(user
, key
)
63 module
:log("debug", "map:get(%s, %s)", tostring(user
), tostring(key
))
64 local filename
= dm
.getpath(user
, module
.host
, self
.store
, "map");
65 module
:log("debug", "File is %s", filename
);
67 if _VERSION
== "Lua 5.1" then -- HACK
68 env
._ENV
= env
; -- HACK
70 local chunk
, err
, errno
= load(filename
, env
);
71 if not chunk
then if errno
== 2 then return end return chunk
, err
; end
72 local ok
, err
= pcall(chunk
);
73 if not ok
then return ok
, err
; end
74 if _VERSION
== "Lua 5.1" then -- HACK
75 env
._ENV
= nil; -- HACK
76 end -- HACKS EVERYWHERE
83 function map
:set_keys(user
, keyvalues
)
84 local data
= serialize_map(keyvalues
);
85 return dm
.append_raw(user
, module
.host
, self
.store
, "map", data
);
88 function map
:set(user
, key
, value
)
89 if _VERSION
== "Lua 5.1" then
90 assert(key
~= "_ENV", "'_ENV' is a restricted key");
93 local filename
= dm
.getpath(user
, module
.host
, self
.store
, "map");
94 return os
.remove(filename
);
96 local data
= serialize_pair(key
, value
);
97 return dm
.append_raw(user
, module
.host
, self
.store
, "map", data
);
100 local keyval
= { remove = REMOVE
};
101 local keyval_mt
= { __index
= keyval
};
103 function keyval
:get(user
)
104 return map
.get(self
, user
, nil);
107 function keyval
:set(user
, keyvalues
)
108 local data
= serialize_map(keyvalues
);
109 return dm
.store_raw(user
, module
.host
, self
.store
, "map", data
);
112 -- TODO some kind of periodic compaction thing?
113 function map
:_compact(user
)
114 local data
= self
:get(user
);
115 return keyval
.set(self
, user
, data
);
118 function driver
:open(store
, typ
)
120 return setmetatable({ store
= store
, }, map_mt
);
121 elseif typ
== nil or typ
== "keyval" then
122 return setmetatable({ store
= store
, }, keyval_mt
);
124 return nil, "unsupported-store";
127 module
:provides("storage", driver
);