215 lines
4.4 KiB
Lua
215 lines
4.4 KiB
Lua
local blueprints = require "spec.fixtures.blueprints"
|
|
local assert = require "luassert"
|
|
local cycle_aware_deep_copy = require("kong.tools.table").cycle_aware_deep_copy
|
|
|
|
|
|
local dc_blueprints = {}
|
|
|
|
|
|
local null = ngx.null
|
|
|
|
|
|
local function new_config()
|
|
return {
|
|
_format_version = "3.0"
|
|
}
|
|
end
|
|
|
|
|
|
local function remove_nulls(tbl)
|
|
for k,v in pairs(tbl) do
|
|
if v == null then
|
|
tbl[k] = nil
|
|
elseif type(v) == "table" then
|
|
tbl[k] = remove_nulls(v)
|
|
end
|
|
end
|
|
return tbl
|
|
end
|
|
|
|
|
|
-- tparam boolean expand_foreigns expand the complete "foreign"-type fields, not
|
|
-- replacing it with "string"-type fields
|
|
local function wrap_db(db, expand_foreigns)
|
|
local dc_as_db = {}
|
|
|
|
local config = new_config()
|
|
|
|
for name, _ in pairs(db.daos) do
|
|
dc_as_db[name] = {
|
|
insert = function(_, tbl)
|
|
tbl = cycle_aware_deep_copy(tbl)
|
|
if not config[name] then
|
|
config[name] = {}
|
|
end
|
|
local schema = db.daos[name].schema
|
|
tbl = schema:process_auto_fields(tbl, "insert")
|
|
for fname, field in schema:each_field() do
|
|
if not expand_foreigns and field.type == "foreign" then
|
|
tbl[fname] = type(tbl[fname]) == "table"
|
|
and tbl[fname].id
|
|
or nil
|
|
end
|
|
end
|
|
table.insert(config[name], remove_nulls(tbl))
|
|
return cycle_aware_deep_copy(tbl)
|
|
end,
|
|
update = function(_, id, tbl)
|
|
if not config[name] then
|
|
return nil, "not found"
|
|
end
|
|
tbl = cycle_aware_deep_copy(tbl)
|
|
local element
|
|
for _, e in ipairs(config[name]) do
|
|
if e.id == id then
|
|
element = e
|
|
break
|
|
end
|
|
end
|
|
if not element then
|
|
return nil, "not found"
|
|
end
|
|
for k,v in pairs(tbl) do
|
|
element[k] = v
|
|
end
|
|
return element
|
|
end,
|
|
remove = function(_, id)
|
|
assert(id, "id is required")
|
|
if type(id) == "table" then
|
|
id = assert(type(id.id) == "string" and id.id)
|
|
end
|
|
|
|
if not config[name] then
|
|
return nil, "not found"
|
|
end
|
|
|
|
for idx, entity in ipairs(config[name]) do
|
|
if entity.id == id then
|
|
table.remove(config[name], idx)
|
|
return entity
|
|
end
|
|
end
|
|
|
|
return nil, "not found"
|
|
end,
|
|
}
|
|
end
|
|
|
|
dc_as_db.export = function()
|
|
return cycle_aware_deep_copy(config)
|
|
end
|
|
|
|
dc_as_db.import = function(input)
|
|
config = cycle_aware_deep_copy(input)
|
|
end
|
|
|
|
dc_as_db.reset = function()
|
|
config = new_config()
|
|
end
|
|
|
|
return dc_as_db
|
|
end
|
|
|
|
|
|
function dc_blueprints.new(db, expand_foreigns)
|
|
local dc_as_db = wrap_db(db, expand_foreigns)
|
|
|
|
local save_dc = new_config()
|
|
|
|
local bp = blueprints.new(dc_as_db)
|
|
|
|
bp.done = function()
|
|
local ret = dc_as_db.export()
|
|
save_dc = ret
|
|
dc_as_db.reset()
|
|
return ret
|
|
end
|
|
|
|
bp.reset_back = function()
|
|
dc_as_db.import(save_dc)
|
|
end
|
|
|
|
return bp
|
|
end
|
|
|
|
|
|
function dc_blueprints.admin_api(db, forced_port)
|
|
-- lazy import to avoid cyclical dependency
|
|
local helpers = require "spec.helpers"
|
|
|
|
db = db or helpers.db
|
|
|
|
local dc_as_db = wrap_db(db)
|
|
local api = {}
|
|
|
|
local function update_config()
|
|
local client = helpers.admin_client(nil, forced_port)
|
|
|
|
local res = client:post("/config", {
|
|
headers = {
|
|
["Content-Type"] = "application/json",
|
|
},
|
|
body = dc_as_db.export(),
|
|
})
|
|
|
|
assert.response(res).has.status(201)
|
|
client:close()
|
|
return assert.response(res).has.jsonbody()
|
|
end
|
|
|
|
for name in pairs(db.daos) do
|
|
local dao = dc_as_db[name]
|
|
|
|
api[name] = {
|
|
insert = function(_, entity)
|
|
local res, err = dao:insert(entity)
|
|
|
|
if not res then
|
|
return nil, err
|
|
end
|
|
|
|
update_config()
|
|
|
|
return res
|
|
end,
|
|
|
|
update = function(_, id, updates)
|
|
local res, err = dao:update(id, updates)
|
|
if not res then
|
|
return nil, err
|
|
end
|
|
|
|
update_config()
|
|
|
|
return res
|
|
end,
|
|
|
|
remove = function(_, id)
|
|
local res, err = dao:remove(id)
|
|
if not res then
|
|
return nil, err
|
|
end
|
|
|
|
update_config()
|
|
|
|
return res
|
|
end,
|
|
|
|
truncate = function()
|
|
local config = dc_as_db.export()
|
|
config[name] = {}
|
|
|
|
dc_as_db.import(config)
|
|
update_config()
|
|
|
|
return true
|
|
end,
|
|
}
|
|
end
|
|
|
|
return blueprints.new(api)
|
|
end
|
|
|
|
return dc_blueprints
|