in kong/kong/db/schema/init.lua [1606:1823]
function Schema:process_auto_fields(data, context, nulls, opts)
yield(true)
local check_immutable_fields = false
local is_select = context == "select"
if not is_select then
data = tablex.deepcopy(data)
end
local shorthand_fields = self.shorthand_fields
if shorthand_fields then
local errs = {}
local has_errs
for i = 1, #shorthand_fields do
local sname, sdata = next(shorthand_fields[i])
local value = data[sname]
if value ~= nil then
local _, err = self:validate_field(sdata, value)
if err then
errs[sname] = err
has_errs = true
else
data[sname] = nil
local new_values = sdata.func(value)
if new_values then
for k, v in pairs(new_values) do
data[k] = v
end
end
end
end
end
if has_errs then
return nil, errs
end
end
local now_s
local now_ms
local kong = kong
local resolve_references
if is_select and not nulls then
if kong and kong.configuration then
resolve_references = kong.configuration.role ~= "control_plane"
else
resolve_references = true
end
end
local refs
local prev_refs = resolve_references and data["$refs"]
for key, field in self:each_field(data) do
local ftype = field.type
local value = data[key]
if not is_select and field.auto then
local is_insert_or_upsert = context == "insert" or context == "upsert"
if field.uuid then
if is_insert_or_upsert and value == nil then
value = uuid()
end
elseif ftype == "string" then
if is_insert_or_upsert and value == nil then
value = random_string()
end
elseif (key == "created_at" and is_insert_or_upsert and (value == null or
value == nil))
or
(key == "updated_at" and (is_insert_or_upsert or context == "update"))
then
if ftype == "number" then
if not now_ms then
update_time()
now_ms = ngx_now()
end
value = now_ms
elseif ftype == "integer" then
if not now_s then
update_time()
now_s = ngx_time()
end
value = now_s
end
end
end
value = adjust_field_for_context(field, value, context, nulls, opts)
if is_select then
local vtype = type(value)
if value == null and not nulls then
value = nil
elseif ftype == "integer" and vtype == "number" then
value = floor(value)
end
if resolve_references then
if ftype == "string" and field.referenceable then
if is_reference(value) then
if refs then
refs[key] = value
else
refs = { [key] = value }
end
local deref, err = kong.vault.get(value)
if deref then
value = deref
else
if err then
kong.log.warn("unable to resolve reference ", value, " (", err, ")")
else
kong.log.warn("unable to resolve reference ", value)
end
value = nil
end
elseif prev_refs and prev_refs[key] then
if refs then
refs[key] = prev_refs[key]
else
refs = { [key] = prev_refs[key] }
end
end
elseif vtype == "table" and (ftype == "array" or ftype == "set") then
local subfield = field.elements
if subfield.type == "string" and subfield.referenceable then
local count = #value
if count > 0 then
for i = 1, count do
if is_reference(value[i]) then
if not refs then
refs = {}
end
if not refs[key] then
refs[key] = new_tab(count, 0)
end
refs[key][i] = value[i]
local deref, err = kong.vault.get(value[i])
if deref then
value[i] = deref
else
if err then
kong.log.warn("unable to resolve reference ", value[i], " (", err, ")")
else
kong.log.warn("unable to resolve reference ", value[i])
end
value[i] = nil
end
end
end
end
if prev_refs and prev_refs[key] then
if refs then
if not refs[key] then
refs[key] = prev_refs[key]
end
else
refs = { [key] = prev_refs[key] }
end
end
end
end
end
elseif context == "update" and field.immutable then
check_immutable_fields = true
end
data[key] = value
end
if not is_select then
return data, nil, check_immutable_fields
end
if self.ttl and data.ttl == null and not nulls then
data.ttl = nil
end
local show_ws = opts and opts.show_ws_id
for key in pairs(data) do
local field = self.fields[key]
if field then
if field.type == "string" and (field.len_min or 1) > 0 and data[key] == ""
then
data[key] = nulls and null or nil
end
elseif not ((key == "ttl" and self.ttl) or
(key == "ws_id" and show_ws)) then
data[key] = nil
end
end
data["$refs"] = refs
return data
end