module Sequel::Plugins::PgAutoConstraintValidations::InstanceMethods
Private Instance Methods
_insert_raw(ds)
click to toggle source
Convert PostgreSQL constraint errors when inserting.
Calls superclass method
# File lib/sequel/plugins/pg_auto_constraint_validations.rb 333 def _insert_raw(ds) 334 check_pg_constraint_error(ds){super} 335 end
_insert_select_raw(ds)
click to toggle source
Convert PostgreSQL constraint errors when inserting.
Calls superclass method
# File lib/sequel/plugins/pg_auto_constraint_validations.rb 338 def _insert_select_raw(ds) 339 check_pg_constraint_error(ds){super} 340 end
_update_without_checking(_)
click to toggle source
Convert PostgreSQL constraint errors when updating.
Calls superclass method
# File lib/sequel/plugins/pg_auto_constraint_validations.rb 343 def _update_without_checking(_) 344 check_pg_constraint_error(_update_dataset){super} 345 end
add_pg_constraint_validation_error(column, message)
click to toggle source
If there is a single column instead of an array of columns, add the error for the column, otherwise add the error for the array of columns.
# File lib/sequel/plugins/pg_auto_constraint_validations.rb 327 def add_pg_constraint_validation_error(column, message) 328 column = column.first if column.length == 1 329 errors.add(column, message) 330 end
check_pg_constraint_error(ds) { || ... }
click to toggle source
Yield to the given block, and if a Sequel::ConstraintViolation is raised, try to convert it to a Sequel::ValidationFailed
error using the PostgreSQL error metadata.
# File lib/sequel/plugins/pg_auto_constraint_validations.rb 226 def check_pg_constraint_error(ds) 227 yield 228 rescue Sequel::ConstraintViolation => e 229 begin 230 unless cv_info = model.pg_auto_constraint_validations 231 # Necessary metadata does not exist, just reraise the exception. 232 raise e 233 end 234 235 info = ds.db.error_info(e) 236 m = ds.method(:output_identifier) 237 schema = info[:schema] 238 table = info[:table] 239 240 if constraint = info[:constraint] 241 constraint = m.call(constraint) 242 243 columns, message = cv_info[:overrides][constraint] 244 if columns 245 override = true 246 add_pg_constraint_validation_error(columns, message) 247 end 248 end 249 250 messages = model.pg_auto_constraint_validations_messages 251 252 unless override 253 # :nocov: 254 case e 255 # :nocov: 256 when Sequel::NotNullConstraintViolation 257 if column = info[:column] 258 add_pg_constraint_validation_error([m.call(column)], messages[:not_null]) 259 end 260 when Sequel::CheckConstraintViolation 261 if columns = cv_info[:check][constraint] 262 add_pg_constraint_validation_error(columns, messages[:check]) 263 end 264 when Sequel::UniqueConstraintViolation 265 if columns = cv_info[:unique][constraint] 266 add_pg_constraint_validation_error(columns, messages[:unique]) 267 end 268 when Sequel::ForeignKeyConstraintViolation 269 message_primary = info[:message_primary] 270 if message_primary.start_with?('update') 271 # This constraint violation is different from the others, because the constraint 272 # referenced is a constraint for a different table, not for this table. This 273 # happens when another table references the current table, and the referenced 274 # column in the current update is modified such that referential integrity 275 # would be broken. Use the reverse foreign key information to figure out 276 # which column is affected in that case. 277 skip_schema_table_check = true 278 if columns = cv_info[:referenced_by][[m.call(schema), m.call(table), constraint]] 279 add_pg_constraint_validation_error(columns, messages[:referenced_by]) 280 end 281 elsif message_primary.start_with?('insert') 282 if columns = cv_info[:foreign_key][constraint] 283 add_pg_constraint_validation_error(columns, messages[:foreign_key]) 284 end 285 end 286 end 287 end 288 rescue 289 # If there is an error trying to conver the constraint violation 290 # into a validation failure, it's best to just raise the constraint 291 # violation. This can make debugging the above block of code more 292 # difficult. 293 raise e 294 else 295 unless skip_schema_table_check 296 # The constraint violation could be caused by a trigger modifying 297 # a different table. Check that the error schema and table 298 # match the model's schema and table, or clear the validation error 299 # that was set above. 300 if schema != cv_info[:schema] || table != cv_info[:table] 301 errors.clear 302 end 303 end 304 305 if errors.empty? 306 # If we weren't able to parse the constraint violation metadata and 307 # convert it to an appropriate validation failure, or the schema/table 308 # didn't match, then raise the constraint violation. 309 raise e 310 end 311 312 # Integrate with error_splitter plugin to split any multi-column errors 313 # and add them as separate single column errors 314 if respond_to?(:split_validation_errors, true) 315 split_validation_errors(errors) 316 end 317 318 vf = ValidationFailed.new(self) 319 vf.set_backtrace(e.backtrace) 320 vf.wrapped_exception = e 321 raise vf 322 end 323 end