module Sequel::Plugins::PgAutoConstraintValidations::ClassMethods

Attributes

pg_auto_constraint_validations[R]

Hash of metadata checked when an instance attempts to convert a constraint violation into a validation failure.

pg_auto_constraint_validations_messages[R]

Hash of error messages keyed by constraint type symbol to use in the generated validation failures.

Public Instance Methods

dump_pg_auto_constraint_validations_cache() click to toggle source

Dump the in-memory cached metadata to the cache file.

    # File lib/sequel/plugins/pg_auto_constraint_validations.rb
134 def dump_pg_auto_constraint_validations_cache
135   raise Error, "No pg_auto_constraint_validations setup" unless file = @pg_auto_constraint_validations_cache_file
136   File.open(file, 'wb'){|f| f.write(Marshal.dump(@pg_auto_constraint_validations_cache))}
137   nil
138 end
pg_auto_constraint_validation_override(constraint, columns, message) click to toggle source

Override the constraint validation columns and message for a given constraint

    # File lib/sequel/plugins/pg_auto_constraint_validations.rb
141 def pg_auto_constraint_validation_override(constraint, columns, message)
142   pgacv = Hash[@pg_auto_constraint_validations]
143   overrides = pgacv[:overrides] = Hash[pgacv[:overrides]]
144   overrides[constraint] = [Array(columns), message].freeze
145   overrides.freeze
146   @pg_auto_constraint_validations = pgacv.freeze
147   nil
148 end

Private Instance Methods

setup_pg_auto_constraint_validations() click to toggle source

Get the list of constraints, unique indexes, foreign keys in the current table, and keys in the current table referenced by foreign keys in other tables. Store this information so that if a constraint violation occurs, all necessary metadata is already available in the model, so a query is not required at runtime. This is both for performance and because in general after the constraint violation failure you will be inside a failed transaction and not able to execute queries.

    # File lib/sequel/plugins/pg_auto_constraint_validations.rb
159 def setup_pg_auto_constraint_validations
160   return unless @dataset
161 
162   case @dataset.first_source_table
163   when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
164    convert_errors = db.respond_to?(:error_info)
165   end
166 
167   unless convert_errors
168     # Might be a table returning function or subquery, skip handling those.
169     # Might have db not support error_info, skip handling that.
170     @pg_auto_constraint_validations = nil
171     return
172   end
173 
174   cache = @pg_auto_constraint_validations_cache
175   literal_table_name = dataset.literal(table_name)
176   unless cache && (metadata = cache[literal_table_name])
177     checks = {}
178     indexes = {}
179     foreign_keys = {}
180     referenced_by = {}
181 
182     db.check_constraints(table_name).each do |k, v|
183       checks[k] = v[:columns].dup.freeze unless v[:columns].empty?
184     end
185     db.indexes(table_name, :include_partial=>true).each do |k, v|
186       if v[:unique]
187         indexes[k] = v[:columns].dup.freeze
188       end
189     end
190     db.foreign_key_list(table_name, :schema=>false).each do |fk|
191       foreign_keys[fk[:name]] = fk[:columns].dup.freeze
192     end
193     db.foreign_key_list(table_name, :reverse=>true, :schema=>false).each do |fk|
194       referenced_by[[fk[:schema], fk[:table], fk[:name]].freeze] = fk[:key].dup.freeze
195     end
196 
197     schema, table = db[:pg_class].
198       join(:pg_namespace, :oid=>:relnamespace, db.send(:regclass_oid, table_name)=>:oid).
199       get([:nspname, :relname])
200 
201     metadata = {
202       :schema=>schema,
203       :table=>table,
204       :check=>checks,
205       :unique=>indexes,
206       :foreign_key=>foreign_keys,
207       :referenced_by=>referenced_by,
208       :overrides=>OPTS
209     }.freeze
210     metadata.each_value(&:freeze)
211 
212     if cache
213       cache[literal_table_name] = metadata
214     end
215   end
216 
217   @pg_auto_constraint_validations = metadata
218   nil
219 end