module Sequel::Plugins::PgAutoConstraintValidations::ClassMethods
Attributes
Hash of metadata checked when an instance attempts to convert a constraint violation into a validation failure.
Hash of error messages keyed by constraint type symbol to use in the generated validation failures.
Public Instance Methods
Dump the in-memory cached metadata to the cache file.
# File lib/sequel/plugins/pg_auto_constraint_validations.rb, line 133 def dump_pg_auto_constraint_validations_cache raise Error, "No pg_auto_constraint_validations setup" unless file = @pg_auto_constraint_validations_cache_file pg_auto_constraint_validations_cache = {} @pg_auto_constraint_validations_cache.sort.each do |k, v| pg_auto_constraint_validations_cache[k] = v end File.open(file, 'wb'){|f| f.write(Marshal.dump(pg_auto_constraint_validations_cache))} nil end
Override the constraint validation columns and message for a given constraint
# File lib/sequel/plugins/pg_auto_constraint_validations.rb, line 144 def pg_auto_constraint_validation_override(constraint, columns, message) pgacv = Hash[@pg_auto_constraint_validations] overrides = pgacv[:overrides] = Hash[pgacv[:overrides]] overrides[constraint] = [Array(columns), message].freeze overrides.freeze @pg_auto_constraint_validations = pgacv.freeze nil end
Private Instance Methods
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, line 162 def setup_pg_auto_constraint_validations return unless @dataset case @dataset.first_source_table when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier convert_errors = db.respond_to?(:error_info) end unless convert_errors # Might be a table returning function or subquery, skip handling those. # Might have db not support error_info, skip handling that. @pg_auto_constraint_validations = nil return end cache = @pg_auto_constraint_validations_cache literal_table_name = dataset.literal(table_name) unless cache && (metadata = cache[literal_table_name]) checks = {} indexes = {} foreign_keys = {} referenced_by = {} db.check_constraints(table_name).each do |k, v| checks[k] = v[:columns].dup.freeze unless v[:columns].empty? end db.indexes(table_name, :include_partial=>true).each do |k, v| if v[:unique] indexes[k] = v[:columns].dup.freeze end end db.foreign_key_list(table_name, :schema=>false).each do |fk| foreign_keys[fk[:name]] = fk[:columns].dup.freeze end db.foreign_key_list(table_name, :reverse=>true, :schema=>false).each do |fk| referenced_by[[fk[:schema], fk[:table], fk[:name]].freeze] = fk[:key].dup.freeze end schema, table = db[:pg_class]. join(:pg_namespace, :oid=>:relnamespace, db.send(:regclass_oid, table_name)=>:oid). get([:nspname, :relname]) metadata = { :schema=>schema, :table=>table, :check=>checks, :unique=>indexes, :foreign_key=>foreign_keys, :referenced_by=>referenced_by, :overrides=>OPTS }.freeze metadata.each_value(&:freeze) if cache cache[literal_table_name] = metadata end end @pg_auto_constraint_validations = metadata nil end