in kong/kong/db/schema/init.lua [849:993]
function Schema:validate_field(field, value)
yield(true)
if value == null then
if field.ne == null then
return nil, field.err or validation_errors.NE:format("null")
end
if field.eq ~= nil and field.eq ~= null then
return nil, validation_errors.EQ:format(tostring(field.eq))
end
if field.required then
return nil, validation_errors.REQUIRED
end
return true
end
if field.eq == null then
return nil, field.err or validation_errors.EQ:format("null")
end
if field.abstract then
return nil, validation_errors.SUBSCHEMA_ABSTRACT_FIELD
end
if field.type == "array" then
if not is_sequence(value) then
return nil, validation_errors.ARRAY
end
local ok, err = validate_elements(self, field, value)
if not ok then
return nil, err
end
elseif field.type == "set" then
if not is_sequence(value) then
return nil, validation_errors.SET
end
field.elements.required = true
local ok, err = validate_elements(self, field, value)
if not ok then
return nil, err
end
elseif field.type == "map" then
if type(value) ~= "table" then
return nil, validation_errors.MAP
end
field.keys.required = true
field.values.required = true
for k, v in pairs(value) do
local ok, err
ok, err = self:validate_field(field.keys, k)
if not ok then
return nil, err
end
ok, err = self:validate_field(field.values, v)
if not ok then
return nil, err
end
end
elseif field.type == "record" then
if type(value) ~= "table" then
return nil, validation_errors.RECORD
end
local field_schema = get_field_schema(field)
local copy = field_schema:process_auto_fields(value, "insert")
local ok, err = field_schema:validate(copy)
if not ok then
return nil, err
end
elseif field.type == "foreign" then
if field.schema and field.schema.validate_primary_key then
local ok, errs = field.schema:validate_primary_key(value, true)
if not ok then
if type(value) == "table" and field.schema.validate then
local foreign_ok, foreign_errs = field.schema:validate(value, false)
if not foreign_ok then
return nil, foreign_errs
end
end
return ok, errs
end
end
elseif field.type == "integer" then
if not (type(value) == "number"
and value == floor(value)
and value ~= 1/0
and value ~= -1/0) then
return nil, validation_errors.INTEGER
end
elseif field.type == "string" then
if type(value) ~= "string" then
return nil, validation_errors.STRING
end
if not field.len_min then
field.len_min = 1
end
if field.referenceable and is_reference(value) then
return true
end
elseif field.type == "function" then
if type(value) ~= "function" then
return nil, validation_errors.FUNCTION
end
elseif self.valid_types[field.type] then
if type(value) ~= field.type then
return nil, validation_errors[field.type:upper()]
end
elseif field.type ~= "any" then
return nil, validation_errors.SCHEMA_TYPE:format(field.type)
end
local validators = Schema.validators_order
for i = 1, #validators do
local k = validators[i]
if field[k] ~= nil then
local ok, err = self.validators[k](value, field[k], field)
if not ok then
if not err then
err = (validation_errors[k:upper()]
or validation_errors.VALIDATION):format(value)
end
return nil, field.err or err
end
end
end
return true
end