I have been playing with the idea of a Blackboard system for my characters on a mud, and wanted some durable way to store data, and possibly share it with other chars. This is my attempt at somewhat simple interface for doing so.
-- BlackBoards for shared/persistant data
require "serialize"
bb = {}
DatabaseOpen("blackboard", GetInfo (66) .. "blackboard.db", 6)
DatabaseExec("blackboard", [[
CREATE TABLE IF NOT EXISTS "board" ("key" TEXT PRIMARY KEY, "character" TEXT, "value" BLOB);
]])
local mt = {
__index = function (t,k)
local t = {}
local value = DatabaseGetField ("blackboard", string.format("SELECT value FROM board WHERE key = '%s' AND character = '%s';", k, GetInfo (3)))
setfenv (assert (loadstring (value or "")), t) ()
return t['value']
end,
__newindex = function (t,k,v)
if v == nil then
DatabaseExec ("blackboard", string.format("DELETE FROM board WHERE key = '%s' AND character = '%s';", k, GetInfo (3)))
else
local data = 'value = ' .. serialize.save_simple (v)
local return_value = DatabaseExec ("blackboard", string.format("INSERT INTO board (key, character, value) VALUES ('%s', '%s', '%s');", k, GetInfo (3), data))
if return_value ~= 0 and return_value ~= 100 and return_value ~= 101 then
return_value = DatabaseExec ("blackboard", string.format("UPDATE board SET value = '%s' WHERE key = '%s' AND character = '%s';", data, k, GetInfo (3)))
end
end
end
}
setmetatable(bb, mt)
You use it like any other table:
And since it uses serialize for the saving/loading, it will remember types and do simple nested tables (could be updated to use more complex ones if needed).
The only problem I found with it was nested tables do not work as you expect them too:
bb['test'] = {name = 'Bart'}
print(bb['test']['name']) -- shows 'Bart'
bb['test']['name'] = 'Lisa'
print(bb['test']['name']) -- still shows 'Bart'
It makes sense why this happens, as what I return is a new table every time. I think if I used a hidden table to cache/record the DB results, and update those on some timer, it could work decently, but hackish.
Can anyone else think of any other improvements this could take on? |