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
132 def dump_pg_auto_constraint_validations_cache
133   raise Error, "No pg_auto_constraint_validations setup" unless file = @pg_auto_constraint_validations_cache_file
134   File.open(file, 'wb'){|f| f.write(Marshal.dump(@pg_auto_constraint_validations_cache))}
135   nil
136 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
139 def pg_auto_constraint_validation_override(constraint, columns, message)
140   pgacv = Hash[@pg_auto_constraint_validations]
141   overrides = pgacv[:overrides] = Hash[pgacv[:overrides]]
142   overrides[constraint] = [Array(columns), message].freeze
143   overrides.freeze
144   @pg_auto_constraint_validations = pgacv.freeze
145   nil
146 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
157 def setup_pg_auto_constraint_validations
158   return unless @dataset
159 
160   case @dataset.first_source_table
161   when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
162    convert_errors = db.respond_to?(:error_info)
163   end
164 
165   unless convert_errors
166     # Might be a table returning function or subquery, skip handling those.
167     # Might have db not support error_info, skip handling that.
168     @pg_auto_constraint_validations = nil
169     return
170   end
171 
172   cache = @pg_auto_constraint_validations_cache
173   literal_table_name = dataset.literal(table_name)
174   unless cache && (metadata = cache[literal_table_name])
175     checks = {}
176     indexes = {}
177     foreign_keys = {}
178     referenced_by = {}
179 
180     db.check_constraints(table_name).each do |k, v|
181       checks[k] = v[:columns].dup.freeze unless v[:columns].empty?
182     end
183     db.indexes(table_name, :include_partial=>true).each do |k, v|
184       if v[:unique]
185         indexes[k] = v[:columns].dup.freeze
186       end
187     end
188     db.foreign_key_list(table_name, :schema=>false).each do |fk|
189       foreign_keys[fk[:name]] = fk[:columns].dup.freeze
190     end
191     db.foreign_key_list(table_name, :reverse=>true, :schema=>false).each do |fk|
192       referenced_by[[fk[:schema], fk[:table], fk[:name]].freeze] = fk[:key].dup.freeze
193     end
194 
195     schema, table = db[:pg_class].
196       join(:pg_namespace, :oid=>:relnamespace, db.send(:regclass_oid, table_name)=>:oid).
197       get([:nspname, :relname])
198 
199     metadata = {
200       :schema=>schema,
201       :table=>table,
202       :check=>checks,
203       :unique=>indexes,
204       :foreign_key=>foreign_keys,
205       :referenced_by=>referenced_by,
206       :overrides=>OPTS
207     }.freeze
208     metadata.each_value(&:freeze)
209 
210     if cache
211       cache[literal_table_name] = metadata
212     end
213   end
214 
215   @pg_auto_constraint_validations = metadata
216   nil
217 end