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