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.

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
 92 def setup_pg_auto_constraint_validations
 93   return unless @dataset
 94 
 95   case @dataset.first_source_table
 96   when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
 97    convert_errors = db.respond_to?(:error_info)
 98   end
 99 
100   unless convert_errors
101     # Might be a table returning function or subquery, skip handling those.
102     # Might have db not support error_info, skip handling that.
103     @pg_auto_constraint_validations = nil
104     return
105   end
106 
107   checks = {}
108   indexes = {}
109   foreign_keys = {}
110   referenced_by = {}
111 
112   db.check_constraints(table_name).each do |k, v|
113     checks[k] = v[:columns].dup.freeze
114   end
115   db.indexes(table_name, :include_partial=>true).each do |k, v|
116     if v[:unique]
117       indexes[k] = v[:columns].dup.freeze
118     end
119   end
120   db.foreign_key_list(table_name, :schema=>false).each do |fk|
121     foreign_keys[fk[:name]] = fk[:columns].dup.freeze
122   end
123   db.foreign_key_list(table_name, :reverse=>true, :schema=>false).each do |fk|
124     referenced_by[[fk[:schema], fk[:table], fk[:name]].freeze] = fk[:key].dup.freeze
125   end
126 
127   schema, table = db[:pg_class].
128     join(:pg_namespace, :oid=>:relnamespace, db.send(:regclass_oid, table_name)=>:oid).
129     get([:nspname, :relname])
130 
131   (@pg_auto_constraint_validations = {
132     :schema=>schema,
133     :table=>table,
134     :check=>checks,
135     :unique=>indexes,
136     :foreign_key=>foreign_keys,
137     :referenced_by=>referenced_by
138   }.freeze).each_value(&:freeze)
139 end