function handle() if action == "delete" then -- record was deleted -- TODO: how do we drop the table? log("deleted " .. uri) elseif action == "create" then -- record was created -- TODO: if components get updated later, what do we do about that? local resp = http.get("https://slingshot.microcosm.blue/xrpc/blue.microcosm.identity.resolveMiniDoc?identifier=" .. did) local hdl = json.decode(resp.body).handle local tname = makeTableName(hdl, rkey) local query = "CREATE TABLE IF NOT EXISTS '" .. tname .. "' (uri TEXT PRIMARY KEY, did TEXT, chart TEXT, judgments TEXT, version TEXT, " if record.modes then query = query .. "mode TEXT, " end if record.inputMethods then query = query .. "inputMethod TEXT," end for k, v in pairs(record.scoreComponents) do -- SAFETY: until maps are a real legal thing in Lexicon, we technically do not have any validation/sanitization on names! -- This should be fixed URGENTLY! query = query .. "'" .. k .. "' " if v["$type"] == "dev.tsunagite.game#points" then -- store points as an int query = query .. "INTEGER" elseif v["$type"] == "dev.tsunagite.game#percentage" then -- store percentages as a float even though they're strings in-record query = query .. "REAL" elseif v["$type"] == "dev.tsunagite.game#enum" then -- store enums as their index query = query .. "INTEGER" else -- store arbitrary text as strings query = query .. "TEXT" end query = query .. ", " end query = query .. "timestamp TEXT);" db.raw(query) log("creating table " .. tname) log(action .. " " .. uri) end return true end function makeTableName(handle, key) local splitHandle = {} for str in string.gmatch(handle, "([^.]+)") do table.insert(splitHandle, str) end local result = "" for i=0, #splitHandle-1 do result = result .. splitHandle[#splitHandle-i] .. "." end result = result .. key return result end