From e96eda69d7284612347a71bd9f89cf65223d6271 Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Wed, 15 Feb 2023 22:49:00 +0100 Subject: [PATCH] Bulk insert LinterCheckRuns Similar to TestrunMessages, we insert all linter check runs through a bulk operation, potentially reducing time. --- app/models/linter_check_run.rb | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/models/linter_check_run.rb b/app/models/linter_check_run.rb index b955f562..e571cf37 100644 --- a/app/models/linter_check_run.rb +++ b/app/models/linter_check_run.rb @@ -6,7 +6,12 @@ class LinterCheckRun < ApplicationRecord belongs_to :file, class_name: 'CodeOcean::File' def self.create_from(testrun, assessment) - assessment[:detailed_linter_results]&.each do |linter_result| + linter_check_runs = create_linter_check_runs(testrun, assessment) + validate_and_store!(linter_check_runs) + end + + def self.create_linter_check_runs(testrun, assessment) + assessment[:detailed_linter_results]&.map do |linter_result| check = LinterCheck.find_or_create_by!(code: linter_result[:code]) do |new_check| new_check.name = linter_result[:name] new_check.severity = linter_result[:severity] @@ -14,7 +19,7 @@ class LinterCheckRun < ApplicationRecord file = testrun.submission.file_by_name(linter_result[:file_name]) - LinterCheckRun.create!( + LinterCheckRun.new( linter_check: check, result: linter_result[:result], line: linter_result[:line], @@ -22,9 +27,22 @@ class LinterCheckRun < ApplicationRecord testrun:, file: ) + end + end + private_class_method :create_linter_check_runs + + def self.validate_and_store!(linter_check_runs) + validated_check_runs = linter_check_runs.map do |check_run| + check_run.validate! + # We serialize the message without the ID, created_at and updated_at, as they are generated by the database. + check_run.serializable_hash(except: %w[id created_at updated_at]) rescue ActiveRecord::RecordInvalid # Something bad happened. Probably, the RegEx in lib/py_lint_adapter.rb didn't work. Sentry.set_extras(testrun: testrun.inspect, linter_result:) end + + # Now, we store all check runs and skip validations (they are already done) + LinterCheckRun.insert_all!(validated_check_runs) # rubocop:disable Rails/SkipsModelValidations end + private_class_method :validate_and_store! end