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 243 def _insert_raw(ds) 244 check_pg_constraint_error(ds){super} 245 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 248 def _insert_select_raw(ds) 249 check_pg_constraint_error(ds){super} 250 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 253 def _update_without_checking(_) 254 check_pg_constraint_error(_update_dataset){super} 255 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 237 def add_pg_constraint_validation_error(column, message) 238 column = column.first if column.length == 1 239 errors.add(column, message) 240 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 148 def check_pg_constraint_error(ds) 149 yield 150 rescue Sequel::ConstraintViolation => e 151 begin 152 unless cv_info = model.pg_auto_constraint_validations 153 # Necessary metadata does not exist, just reraise the exception. 154 raise e 155 end 156 157 info = ds.db.error_info(e) 158 m = ds.method(:output_identifier) 159 schema = info[:schema] 160 table = info[:table] 161 if constraint = info[:constraint] 162 constraint = m.call(constraint) 163 end 164 messages = model.pg_auto_constraint_validations_messages 165 166 case e 167 when Sequel::NotNullConstraintViolation 168 if column = info[:column] 169 add_pg_constraint_validation_error([m.call(column)], messages[:not_null]) 170 end 171 when Sequel::CheckConstraintViolation 172 if columns = cv_info[:check][constraint] 173 add_pg_constraint_validation_error(columns, messages[:check]) 174 end 175 when Sequel::UniqueConstraintViolation 176 if columns = cv_info[:unique][constraint] 177 add_pg_constraint_validation_error(columns, messages[:unique]) 178 end 179 when Sequel::ForeignKeyConstraintViolation 180 message_primary = info[:message_primary] 181 if message_primary.start_with?('update') 182 # This constraint violation is different from the others, because the constraint 183 # referenced is a constraint for a different table, not for this table. This 184 # happens when another table references the current table, and the referenced 185 # column in the current update is modified such that referential integrity 186 # would be broken. Use the reverse foreign key information to figure out 187 # which column is affected in that case. 188 skip_schema_table_check = true 189 if columns = cv_info[:referenced_by][[m.call(schema), m.call(table), constraint]] 190 add_pg_constraint_validation_error(columns, messages[:referenced_by]) 191 end 192 elsif message_primary.start_with?('insert') 193 if columns = cv_info[:foreign_key][constraint] 194 add_pg_constraint_validation_error(columns, messages[:foreign_key]) 195 end 196 end 197 end 198 rescue 199 # If there is an error trying to conver the constraint violation 200 # into a validation failure, it's best to just raise the constraint 201 # violation. This can make debugging the above block of code more 202 # difficult. 203 raise e 204 else 205 unless skip_schema_table_check 206 # The constraint violation could be caused by a trigger modifying 207 # a different table. Check that the error schema and table 208 # match the model's schema and table, or clear the validation error 209 # that was set above. 210 if schema != cv_info[:schema] || table != cv_info[:table] 211 errors.clear 212 end 213 end 214 215 if errors.empty? 216 # If we weren't able to parse the constraint violation metadata and 217 # convert it to an appropriate validation failure, or the schema/table 218 # didn't match, then raise the constraint violation. 219 raise e 220 end 221 222 # Integrate with error_splitter plugin to split any multi-column errors 223 # and add them as separate single column errors 224 if respond_to?(:split_validation_errors, true) 225 split_validation_errors(errors) 226 end 227 228 vf = ValidationFailed.new(self) 229 vf.set_backtrace(e.backtrace) 230 vf.wrapped_exception = e 231 raise vf 232 end 233 end