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
Source
# 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 pg_auto_constraint_validations_cache = {} 137 @pg_auto_constraint_validations_cache.sort.each do |k, v| 138 pg_auto_constraint_validations_cache[k] = v 139 end 140 File.open(file, 'wb'){|f| f.write(Marshal.dump(pg_auto_constraint_validations_cache))} 141 nil 142 end
Dump the in-memory cached metadata to the cache file.
Source
# File lib/sequel/plugins/pg_auto_constraint_validations.rb 145 def pg_auto_constraint_validation_override(constraint, columns, message) 146 pgacv = Hash[@pg_auto_constraint_validations] 147 overrides = pgacv[:overrides] = Hash[pgacv[:overrides]] 148 overrides[constraint] = [Array(columns), message].freeze 149 overrides.freeze 150 @pg_auto_constraint_validations = pgacv.freeze 151 nil 152 end
Override the constraint validation columns and message for a given constraint
Private Instance Methods
Source
# File lib/sequel/plugins/pg_auto_constraint_validations.rb 163 def setup_pg_auto_constraint_validations 164 return unless @dataset 165 166 case @dataset.first_source_table 167 when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier 168 convert_errors = db.respond_to?(:error_info) 169 end 170 171 unless convert_errors 172 # Might be a table returning function or subquery, skip handling those. 173 # Might have db not support error_info, skip handling that. 174 @pg_auto_constraint_validations = nil 175 return 176 end 177 178 cache = @pg_auto_constraint_validations_cache 179 literal_table_name = dataset.literal(table_name) 180 unless cache && (metadata = cache[literal_table_name]) 181 checks = {} 182 indexes = {} 183 foreign_keys = {} 184 referenced_by = {} 185 186 db.check_constraints(table_name).each do |k, v| 187 checks[k] = v[:columns].dup.freeze unless v[:columns].empty? 188 end 189 db.indexes(table_name, :include_partial=>true).each do |k, v| 190 if v[:unique] 191 indexes[k] = v[:columns].dup.freeze 192 end 193 end 194 db.foreign_key_list(table_name, :schema=>false).each do |fk| 195 foreign_keys[fk[:name]] = fk[:columns].dup.freeze 196 end 197 db.foreign_key_list(table_name, :reverse=>true, :schema=>false).each do |fk| 198 referenced_by[[fk[:schema], fk[:table], fk[:name]].freeze] = fk[:key].dup.freeze 199 end 200 201 schema, table = db[:pg_class]. 202 join(:pg_namespace, :oid=>:relnamespace, db.send(:regclass_oid, table_name)=>:oid). 203 get([:nspname, :relname]) 204 205 metadata = { 206 :schema=>schema, 207 :table=>table, 208 :check=>checks, 209 :unique=>indexes, 210 :foreign_key=>foreign_keys, 211 :referenced_by=>referenced_by, 212 :overrides=>OPTS 213 }.freeze 214 metadata.each_value(&:freeze) 215 216 if cache 217 cache[literal_table_name] = metadata 218 end 219 end 220 221 @pg_auto_constraint_validations = metadata 222 nil 223 end
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.