Module: DynamicMigrations::Postgres::Generator::Validation

Included in:
DynamicMigrations::Postgres::Generator
Defined in:
lib/dynamic_migrations/postgres/generator/validation.rb

Defined Under Namespace

Classes: TemplateAlreadyExistsError, UnexpectedTemplateError

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.add_template(name, template_class) ⇒ Object

install a template into the migration generator, this can be used from outside this library to clean up common migrations (replace common migrations with syntatic sugar)



21
22
23
24
25
# File 'lib/dynamic_migrations/postgres/generator/validation.rb', line 21

def self.add_template name, template_class
  @templates ||= {}
  raise TemplateAlreadyExistsError, name if @templates.key?(name)
  @templates[name] = template_class
end

.has_template?(template_name) ⇒ Boolean

Returns:

  • (Boolean)


15
16
17
# File 'lib/dynamic_migrations/postgres/generator/validation.rb', line 15

def self.has_template? template_name
  @templates&.key?(template_name) || false
end

.template(template_name) ⇒ Object



11
12
13
# File 'lib/dynamic_migrations/postgres/generator/validation.rb', line 11

def self.template template_name
  @templates && @templates[template_name]
end

Instance Method Details

#add_validation(validation, code_comment = nil) ⇒ Object



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
# File 'lib/dynamic_migrations/postgres/generator/validation.rb', line 27

def add_validation validation, code_comment = nil
  # if we have a corresponding template, then use it
  if validation.template
    unless (template_class = Validation.template(validation.template))
      raise UnexpectedTemplateError, "Unrecognised template #{validation.template}"
    end

    arguments = template_class.new(validation, code_comment).fragment_arguments
    add_fragment(**arguments)

  # no template, process this as a default validation (takes all options)
  else

    options = {
      name: ":#{validation.name}",
      deferrable: validation.deferrable,
      initially_deferred: validation.initially_deferred
    }

    if validation.description.nil?
      comment_sql = ""
    else
      comment_sql = <<~RUBY
        #{validation.name}_comment = <<~COMMENT
          #{indent validation.description || ""}
        COMMENT
      RUBY
      options[:comment] = "#{validation.name}_comment"
    end

    options_syntax = options.map { |k, v| "#{k}: #{v}" }.join(", ")

    validation_sql = validation.check_clause.strip

    add_fragment schema: validation.table.schema,
      table: validation.table,
      migration_method: :add_validation,
      object: validation,
      code_comment: code_comment,
      migration: comment_sql + <<~RUBY
        add_validation :#{validation.table.name}, #{options_syntax} do
          <<~SQL
            #{indent validation_sql}
          SQL
        end
      RUBY
  end
end

#recreate_validation(original_validation, updated_validation) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/dynamic_migrations/postgres/generator/validation.rb', line 87

def recreate_validation original_validation, updated_validation
  # remove the original validation
  removal_fragment = remove_validation original_validation, <<~CODE_COMMENT
    Removing original validation because it has changed (it is recreated below)
    Changes:
      #{indent original_validation.differences_descriptions(updated_validation).join("\n")}
  CODE_COMMENT

  # recrete the validation with the new options
  recreation_fragment = add_validation updated_validation, <<~CODE_COMMENT
    Recreating this validation
  CODE_COMMENT

  # return the new fragments (the main reason to return them here is for the specs)
  [removal_fragment, recreation_fragment]
end

#remove_validation(validation, code_comment = nil) ⇒ Object



76
77
78
79
80
81
82
83
84
85
# File 'lib/dynamic_migrations/postgres/generator/validation.rb', line 76

def remove_validation validation, code_comment = nil
  add_fragment schema: validation.table.schema,
    table: validation.table,
    migration_method: :remove_validation,
    object: validation,
    code_comment: code_comment,
    migration: <<~RUBY
      remove_validation :#{validation.table.name}, :#{validation.name}
    RUBY
end

#remove_validation_comment(validation, code_comment = nil) ⇒ Object

remove the comment from a validation



125
126
127
128
129
130
131
132
133
134
# File 'lib/dynamic_migrations/postgres/generator/validation.rb', line 125

def remove_validation_comment validation, code_comment = nil
  add_fragment schema: validation.table.schema,
    table: validation.table,
    migration_method: :remove_validation_comment,
    object: validation,
    code_comment: code_comment,
    migration: <<~RUBY
      remove_validation_comment :#{validation.table.name}, :#{validation.name}
    RUBY
end

#set_validation_comment(validation, code_comment = nil) ⇒ Object

add a comment to a validation



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/dynamic_migrations/postgres/generator/validation.rb', line 105

def set_validation_comment validation, code_comment = nil
  description = validation.description

  if description.nil?
    raise MissingDescriptionError, "Missing required description for validation `#{validation.name}` in table `#{validation.table.schema.name}.#{validation.table.name}`"
  end

  add_fragment schema: validation.table.schema,
    table: validation.table,
    migration_method: :set_validation_comment,
    object: validation,
    code_comment: code_comment,
    migration: <<~RUBY
      set_validation_comment :#{validation.table.name}, :#{validation.name}, <<~COMMENT
        #{indent description}
      COMMENT
    RUBY
end