163 lines
3.9 KiB
Lua
163 lines
3.9 KiB
Lua
--
|
|
-- Licensed to the Apache Software Foundation (ASF) under one or more
|
|
-- contributor license agreements. See the NOTICE file distributed with
|
|
-- this work for additional information regarding copyright ownership.
|
|
-- The ASF licenses this file to You under the Apache License, Version 2.0
|
|
-- (the "License"); you may not use this file except in compliance with
|
|
-- the License. You may obtain a copy of the License at
|
|
--
|
|
-- http://www.apache.org/licenses/LICENSE-2.0
|
|
--
|
|
-- Unless required by applicable law or agreed to in writing, software
|
|
-- distributed under the License is distributed on an "AS IS" BASIS,
|
|
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
-- See the License for the specific language governing permissions and
|
|
-- limitations under the License.
|
|
--
|
|
local newproxy = newproxy
|
|
local getmetatable = getmetatable
|
|
local setmetatable = setmetatable
|
|
local select = select
|
|
local new_tab = require("table.new")
|
|
local pairs = pairs
|
|
local type = type
|
|
local string = string
|
|
|
|
|
|
local _M = {
|
|
version = 0.2,
|
|
new = new_tab,
|
|
clear = require("table.clear"),
|
|
insert = table.insert,
|
|
concat = table.concat,
|
|
sort = table.sort,
|
|
}
|
|
|
|
|
|
setmetatable(_M, {__index = table})
|
|
|
|
|
|
local nkeys
|
|
do
|
|
local ok, table_nkeys = pcall(require, 'table.nkeys')
|
|
if ok then
|
|
nkeys = table_nkeys
|
|
else
|
|
nkeys = function(t)
|
|
local count = 0
|
|
for _, _ in pairs(t) do
|
|
count = count + 1
|
|
end
|
|
return count
|
|
end
|
|
end
|
|
end
|
|
_M.nkeys = nkeys
|
|
|
|
|
|
function _M.insert_tail(tab, ...)
|
|
local idx = #tab
|
|
for i = 1, select('#', ...) do
|
|
idx = idx + 1
|
|
tab[idx] = select(i, ...)
|
|
end
|
|
|
|
return idx
|
|
end
|
|
|
|
|
|
function _M.set(tab, ...)
|
|
for i = 1, select('#', ...) do
|
|
tab[i] = select(i, ...)
|
|
end
|
|
end
|
|
|
|
|
|
-- only work under lua51 or luajit
|
|
function _M.setmt__gc(t, mt)
|
|
local prox = newproxy(true)
|
|
getmetatable(prox).__gc = function() mt.__gc(t) end
|
|
t[prox] = true
|
|
return setmetatable(t, mt)
|
|
end
|
|
|
|
|
|
local function deepcopy(orig)
|
|
local orig_type = type(orig)
|
|
if orig_type ~= 'table' then
|
|
return orig
|
|
end
|
|
|
|
-- If the array-like table contains nil in the middle,
|
|
-- the len might be smaller than the expected.
|
|
-- But it doesn't affect the correctness.
|
|
local len = #orig
|
|
local copy = new_tab(len, nkeys(orig) - len)
|
|
for orig_key, orig_value in pairs(orig) do
|
|
copy[orig_key] = deepcopy(orig_value)
|
|
end
|
|
|
|
return copy
|
|
end
|
|
_M.deepcopy = deepcopy
|
|
|
|
local ngx_null = nil
|
|
local function merge(origin, extend)
|
|
for k,v in pairs(extend) do
|
|
if type(v) == "table" then
|
|
if type(origin[k] or false) == "table" then
|
|
if _M.nkeys(origin[k]) ~= #origin[k] then
|
|
merge(origin[k] or {}, extend[k] or {})
|
|
else
|
|
origin[k] = v
|
|
end
|
|
else
|
|
origin[k] = v
|
|
end
|
|
elseif v == ngx_null then
|
|
origin[k] = nil
|
|
else
|
|
origin[k] = v
|
|
end
|
|
end
|
|
|
|
return origin
|
|
end
|
|
_M.merge = merge
|
|
|
|
|
|
local function patch(node_value, sub_path, conf)
|
|
local sub_value = node_value
|
|
local sub_paths = string.split(sub_path, "/")
|
|
for i = 1, #sub_paths - 1 do
|
|
local sub_name = sub_paths[i]
|
|
if sub_value[sub_name] == nil then
|
|
sub_value[sub_name] = {}
|
|
end
|
|
|
|
sub_value = sub_value[sub_name]
|
|
|
|
if type(sub_value) ~= "table" then
|
|
return 400, "invalid sub-path: /"
|
|
.. _M.concat(sub_paths, 1, i)
|
|
end
|
|
end
|
|
|
|
if type(sub_value) ~= "table" then
|
|
return 400, "invalid sub-path: /" .. sub_path
|
|
end
|
|
|
|
local sub_name = sub_paths[#sub_paths]
|
|
if sub_name and sub_name ~= "" then
|
|
sub_value[sub_name] = conf
|
|
else
|
|
node_value = conf
|
|
end
|
|
|
|
return nil, nil, node_value
|
|
end
|
|
_M.patch = patch
|
|
|
|
|
|
return _M
|