UNPKG

dogmaql.driver.redis

Version:

Redis driver for DogmaQL (Dogma Query Language).

78 lines (76 loc) 7.1 kB
"use strict"; var _dogmalang = require("dogmalang"); const LuaTrans = _dogmalang.dogma.use(require("./LuaTrans")); const luaTrans = LuaTrans(); const $UpdateTrans = class UpdateTrans { constructor() { {} } }; const UpdateTrans = new Proxy($UpdateTrans, { apply(receiver, self, args) { return new $UpdateTrans(...args); } });module.exports = exports = UpdateTrans; UpdateTrans.prototype.transAlterTable = function (stmt) { _dogmalang.dogma.paramExpected("stmt", stmt, null);{ return [["eval", "local tab = \"db.tables:\" .. ARGV[1]\nlocal ttl = ARGV[2]\nlocal meta = redis.call(\"json.get\", tab)\n\nif meta then\n meta = cjson.decode(meta)\n meta.ttl = (ttl == \"true\")\n redis.call(\"json.set\", tab, \".\", cjson.encode(meta), \"XX\")\nend", 0, stmt.table, _dogmalang.dogma.getItem(stmt.set, 0).root.right.value]]; } }; UpdateTrans.prototype.transUpdateItem = function (stmt) { _dogmalang.dogma.paramExpected("stmt", stmt, null);{ return stmt.where ? transOneItemUpdate(stmt) : transMultipleItemsUpdate(stmt); } }; function transOneItemUpdate(stmt) { _dogmalang.dogma.paramExpected("stmt", stmt, null);{ return stmt.ifc ? transConditionalItemUpdate(stmt) : transUnconditionalItemUpdate(stmt); } } function transUnconditionalItemUpdate(stmt) { _dogmalang.dogma.paramExpected("stmt", stmt, null);{ return [["eval", (0, _dogmalang.fmt)("--unconditional one\nlocal tab = ARGV[1]\nlocal key = tab .. \":\" .. KEYS[1]\nlocal item = redis.call(\"json.get\", key)\nlocal old, new\n\nlocal function update()\n local type = type\n setfenv(1, item)\n %s\nend\n\nif item then\n old = item\n item = cjson.decode(item)\n update()\n item = cjson.encode(item)\n redis.call(\"json.set\", key, \".\", item, \"XX\")\nelse\n old = \"null\"\n item = \"null\"\nend\n\n%s", (exps => { let code = "";_dogmalang.dogma.paramExpected("exps", exps, null);{ for (let exp of exps) { code += luaTrans.transformSet(exp) + "\n"; } }return code; })(stmt.set), stmt.returnOld && stmt.returnNew ? "return cjson.encode({old=cjson.decode(old), new=cjson.decode(item)})" : stmt.returnOld ? "return old" : stmt.returnNew ? "return item" : ""), 1, _dogmalang.dogma.getItem(stmt.where, 0).value, stmt.table]]; } } function transConditionalItemUpdate(stmt) { _dogmalang.dogma.paramExpected("stmt", stmt, null);{ return [["eval", (0, _dogmalang.fmt)("--conditional one\nlocal tab = ARGV[1]\nlocal key = tab .. \":\" .. KEYS[1]\nlocal item = redis.call(\"json.get\", key)\nlocal old, new\n\nlocal function checkCond()\n local type = type\n setfenv(1, item)\n return %s\nend\n\nlocal function update()\n local type = type\n setfenv(1, item)\n %s\nend\n\nif item then\n old = item\n item = cjson.decode(item)\n\n if checkCond() then\n update()\n item = cjson.encode(item)\n redis.call(\"json.set\", key, \".\", item, \"XX\")\n else\n old = \"null\"\n item = \"null\"\n end\nelse\n old = \"null\"\n item = \"null\"\nend\n\n%s", luaTrans.transform(stmt.ifc), (exps => { let code = "";_dogmalang.dogma.paramExpected("exps", exps, null);{ for (let exp of exps) { code += luaTrans.transformSet(exp) + "\n"; } }return code; })(stmt.set), stmt.returnOld && stmt.returnNew ? "return cjson.encode({old=cjson.decode(old), new=cjson.decode(item)})" : stmt.returnOld ? "return old" : stmt.returnNew ? "return item" : ""), 1, _dogmalang.dogma.getItem(stmt.where, 0).value, stmt.table]]; } } function transMultipleItemsUpdate(stmt) { _dogmalang.dogma.paramExpected("stmt", stmt, null);{ return stmt.ifc ? transConditionalMultipleItemsUpdate(stmt) : transUnconditionalMultipleItemsUpdate(stmt); } } function transUnconditionalMultipleItemsUpdate(stmt) { _dogmalang.dogma.paramExpected("stmt", stmt, null);{ return [["eval", (0, _dogmalang.fmt)("--unconditional multi\nlocal tab = ARGV[1]\nlocal olds, news, item\n\nlocal function update()\n local type = type\n item.setfenv = setfenv\n setfenv(1, item)\n %s\nend\n\n--(1) init olds and news if needed\nif ARGV[2] == \"true\" then olds = {} end\nif ARGV[3] == \"true\" then news = {} end\n\n--(2) update\nlocal env, setfenv\n\nfor _, key in ipairs(redis.call(\"keys\", tab .. \":*\")) do\n --get current/old value\n local old = redis.call(\"json.get\", key)\n if olds ~= nil then table.insert(olds, cjson.decode(old)) end\n\n --update item\n item = cjson.decode(old)\n update()\n\n --save update, saving env for next update() call\n env = item\n setfenv = item.setfenv\n item.setfenv = nil\n\n local value = cjson.encode(item)\n redis.call(\"json.set\", key, \".\", value, \"XX\")\n if news ~= nil then table.insert(news, cjson.decode(value)) end\n\n env.setfenv = setfenv\nend\n\n--(3) return\nlocal rslt\n\nif olds ~= nil then\n if news ~= nil then\n rslt = {old=olds, new=news}\n else\n rslt = olds\n end\nelseif news ~= nil then\n rslt = news\nend\n\nif rslt ~= nil then return cjson.encode(rslt) end", (exps => { let code = "";_dogmalang.dogma.paramExpected("exps", exps, null);{ for (let exp of exps) { code += luaTrans.transformSet(exp) + "\n"; } }return code; })(stmt.set)), 0, stmt.table, (0, _dogmalang.bool)(stmt.returnOld), (0, _dogmalang.bool)(stmt.returnNew)]]; } } function transConditionalMultipleItemsUpdate(stmt) { _dogmalang.dogma.paramExpected("stmt", stmt, null);{ return [["eval", (0, _dogmalang.fmt)("--conditional multi\nlocal tab = ARGV[1]\nlocal olds, news, item\n\nlocal function checkCond()\n local type = type\n item.setfenv = setfenv\n setfenv(1, item)\n return %s\nend\n\nlocal function update()\n local type = type\n item.setfenv = setfenv\n setfenv(1, item)\n %s\nend\n\n--(1) init olds and news if needed\nif ARGV[2] == \"true\" then olds = {} end\nif ARGV[3] == \"true\" then news = {} end\n\n--(2) update\nlocal env, setfenv\n\nfor _, key in ipairs(redis.call(\"keys\", tab .. \":*\")) do\n local old = redis.call(\"json.get\", key)\n item = cjson.decode(old)\n\n local cond = checkCond()\n env = item\n setfenv = item.setfenv\n\n if cond then\n if olds ~= nil then table.insert(olds, cjson.decode(old)) end\n\n update()\n env = item\n setfenv = item.setfenv\n item.setfenv = nil\n\n local value = cjson.encode(item)\n redis.call(\"json.set\", key, \".\", value, \"XX\")\n if news ~= nil then table.insert(news, cjson.decode(value)) end\n\n env.setfenv = setfenv\n end\nend\n\n--(3) return\nlocal rslt\n\nif olds ~= nil then\n if news ~= nil then\n rslt = {old=olds, new=news}\n else\n rslt = olds\n end\nelseif news ~= nil then\n rslt = news\nend\n\nif rslt ~= nil then return cjson.encode(rslt) end", luaTrans.transform(stmt.ifc), (exps => { let code = "";_dogmalang.dogma.paramExpected("exps", exps, null);{ for (let exp of exps) { code += luaTrans.transformSet(exp) + "\n"; } }return code; })(stmt.set)), 0, stmt.table, (0, _dogmalang.bool)(stmt.returnOld), (0, _dogmalang.bool)(stmt.returnNew)]]; } }