Module: DbSchema::Validator
- Defined in:
- lib/db_schema/validator.rb
Defined Under Namespace
Classes: Result
Class Method Summary collapse
Class Method Details
.validate(schema) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/db_schema/validator.rb', line 6 def validate(schema) table_errors = schema.tables.each_with_object([]) do |table, errors| primary_keys_count = table.indexes.select(&:primary?).count if primary_keys_count > 1 = %(Table "#{table.name}" has #{primary_keys_count} primary keys) errors << end table.fields.each do |field| if field.custom? type = schema.enums.find { |enum| enum.name == field.type } if type.nil? = %(Field "#{table.name}.#{field.name}" has unknown type "#{field.type}") errors << elsif !field.default.nil? && !type.values.include?(field.default.to_sym) errors << %(Field "#{table.name}.#{field.name}" has invalid default value "#{field.default}" (valid values are #{type.values.map(&:to_s)})) end elsif field.array? && field.custom_element_type? type = schema.enums.find { |enum| enum.name == field.element_type.type } if type.nil? = %(Array field "#{table.name}.#{field.name}" has unknown element type "#{field.element_type.type}") errors << elsif !field.default.nil? default_array = Sequel::Postgres::PGArray::Parser.new(field.default).parse.map(&:to_sym) invalid_values = default_array - type.values if invalid_values.any? = %(Array field "#{table.name}.#{field.name}" has invalid default value #{default_array.map(&:to_s)} (valid values are #{type.values.map(&:to_s)})) errors << end end end end field_names = table.fields.map(&:name) table.indexes.each do |index| index.columns.reject(&:expression?).map(&:name).each do |field_name| unless field_names.include?(field_name) = %(Index "#{index.name}" refers to a missing field "#{table.name}.#{field_name}") errors << end end end table.foreign_keys.each do |fkey| fkey.fields.each do |field_name| unless field_names.include?(field_name) = %(Foreign key "#{fkey.name}" constrains a missing field "#{table.name}.#{field_name}") errors << end end if referenced_table = schema.tables.find { |table| table.name == fkey.table } if fkey.references_primary_key? unless referenced_table.indexes.any?(&:primary?) = %(Foreign key "#{fkey.name}" refers to primary key of table "#{fkey.table}" which does not have a primary key) errors << end else referenced_table_field_names = referenced_table.fields.map(&:name) fkey.keys.each do |key| unless referenced_table_field_names.include?(key) = %(Foreign key "#{fkey.name}" refers to a missing field "#{fkey.table}.#{key}") errors << end end end else = %(Foreign key "#{fkey.name}" refers to a missing table "#{fkey.table}") errors << end end end enum_errors = schema.enums.each_with_object([]) do |enum, errors| if enum.values.empty? = %(Enum "#{enum.name}" contains no values) errors << end end Result.new(table_errors + enum_errors) end |