module Sequel::Plugins::ConstraintValidations::ClassMethods

Attributes

constraint_validation_reflections[R]

A hash of reflections of constraint validations. Keys are type name symbols. Each value is an array of pairs, with the first element being the validation type symbol (e.g. :presence) and the second element being options for the validation. If the validation takes an argument, it appears as the :argument entry in the validation option hash.

constraint_validations[R]

An array of validation method call arrays. Each array is an array that is splatted to send to perform a validation via validation_helpers.

constraint_validations_table[R]

The name of the table containing the constraint validations metadata.

Public Instance Methods

freeze() click to toggle source

Freeze constraint validations data when freezing model class.

Calls superclass method
    # File lib/sequel/plugins/constraint_validations.rb
 94 def freeze
 95   @constraint_validations.freeze.each(&:freeze)
 96   @constraint_validation_reflections.freeze.each_value do |v|
 97     v.freeze
 98     v.each(&:freeze)
 99   end
100   @constraint_validation_options.freeze.each_value(&:freeze)
101 
102   super
103 end

Private Instance Methods

constraint_validation_array(r, reflections, allow_missing_columns=EMPTY_ARRAY) click to toggle source

Given a specific database constraint validation metadata row hash, transform it in an validation method call array suitable for splatting to send.

    # File lib/sequel/plugins/constraint_validations.rb
129 def constraint_validation_array(r, reflections, allow_missing_columns=EMPTY_ARRAY)
130   opts = {}
131   opts[:message] = r[:message] if r[:message]
132   opts[:allow_nil] = true if db.typecast_value(:boolean, r[:allow_nil])
133   type = r[:validation_type].to_sym
134   arg = r[:argument]
135   column = r[:column]
136 
137   case type
138   when :like, :ilike
139     arg = constraint_validation_like_to_regexp(arg, type == :ilike)
140     type = :format
141   when :exact_length, :min_length, :max_length
142     arg = arg.to_i
143   when :length_range
144     arg = constraint_validation_int_range(arg)
145   when :format
146     arg = Regexp.new(arg)
147   when :iformat
148     arg = Regexp.new(arg, Regexp::IGNORECASE)
149     type = :format
150   when :includes_str_array
151     arg = arg.split(',')
152     type = :includes
153   when :includes_int_array
154     arg = arg.split(',').map(&:to_i)
155     type = :includes
156   when :includes_int_range
157     arg = constraint_validation_int_range(arg)
158     type = :includes
159   when *OPERATOR_MAP.keys
160     arg = arg.to_i if type.to_s.start_with?('int_')
161     operator = OPERATOR_MAP[type]
162     type = :operator
163   end
164 
165   column = if type == :unique
166     column.split(',').map(&:to_sym)
167   else
168     column.to_sym
169   end
170 
171   if type_opts = @constraint_validation_options[type]
172     opts.merge!(type_opts)
173   end
174 
175   reflection_opts = opts.dup
176   a = [:"validates_#{type}"]
177 
178   if operator
179     a << operator
180     reflection_opts[:operator] = operator
181   end
182 
183   if arg
184     a << arg
185     reflection_opts[:argument] = arg
186   end 
187 
188   opts[:from] = :values
189   if column.is_a?(Symbol) && allow_missing_columns.include?(column)
190     opts[:allow_missing] = true
191   end
192 
193   a << column << opts
194 
195   if column.is_a?(Array) && column.length == 1
196     column = column.first
197   end
198   (reflections[column] ||= []) << [type, reflection_opts]
199 
200   a
201 end
constraint_validation_int_range(arg) click to toggle source

Return a range of integers assuming the argument is in 1..2 or 1…2 format.

    # File lib/sequel/plugins/constraint_validations.rb
205 def constraint_validation_int_range(arg)
206   arg =~ /(\d+)\.\.(\.)?(\d+)/
207   Range.new($1.to_i, $3.to_i, $2 == '.')
208 end
constraint_validation_like_to_regexp(arg, case_insensitive) click to toggle source

Transform the LIKE pattern string argument into a Regexp argument suitable for use with validates_format.

    # File lib/sequel/plugins/constraint_validations.rb
212 def constraint_validation_like_to_regexp(arg, case_insensitive)
213   arg = Regexp.escape(arg).gsub(/%%|%|_/) do |s|
214     case s
215     when '%%'
216       '%'
217     when '%'
218       '.*'
219     else
220     #when '_'
221       '.'
222     end
223   end
224   arg = "\\A#{arg}\\z"
225 
226   if case_insensitive
227     Regexp.new(arg, Regexp::IGNORECASE)
228   else
229     Regexp.new(arg)
230   end
231 end
parse_constraint_validations() click to toggle source

If the database has not already parsed constraint validation metadata, then run a query to get the metadata data and transform it into arrays of validation method calls.

If this model has associated dataset, use the model’s table name to get the validations for just this model.

    # File lib/sequel/plugins/constraint_validations.rb
113 def parse_constraint_validations
114   db.extension(:_model_constraint_validations)
115 
116   unless Sequel.synchronize{db.constraint_validations}
117     hash = {}
118     db.from(constraint_validations_table).each do |r|
119       (hash[r[:table]] ||= []) << r
120     end
121     Sequel.synchronize{db.constraint_validations = hash}
122   end
123 
124   parse_constraint_validations_dataset if @dataset
125 end
parse_constraint_validations_dataset() click to toggle source

If this model has associated dataset, use the model’s table name to get the validations for just this model.

    # File lib/sequel/plugins/constraint_validations.rb
235 def parse_constraint_validations_dataset
236   ds = @dataset.with_quote_identifiers(false)
237   table_name = ds.literal(ds.first_source_table)
238   reflections = {}
239   allow_missing_columns = db_schema.select{|col, sch| sch[:allow_null] == false && nil != sch[:default]}.map(&:first)
240   hash = Sequel.synchronize{db.constraint_validations}
241   @constraint_validations = (Sequel.synchronize{hash[table_name]} || []).map{|r| constraint_validation_array(r, reflections, allow_missing_columns)}
242   @constraint_validation_reflections = reflections
243 end