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