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