Fix quizzes affected by CNVS-19292
rails console DataFixup::FixCorruptAssessmentQuestionsFromCnvs19292.run( Date.parse('2015/3/14').beginning_of_day, Date.parse('2015/3/18').end_of_day ) Fixes CNVS-19365 - Increments AssessmentQuestion version numbers so quizzes will pull new data on next quiz take Test plan - Effected quizzes should be fixed Change-Id: Ie1471f1920d8e59f4081732b26c48ed649054dfc Reviewed-on: https://gerrit.instructure.com/50611 Reviewed-by: Cody Cutrer <cody@instructure.com> Reviewed-by: Ryan Taylor <rtaylor@instructure.com> Tested-by: Jenkins Product-Review: Brian Finney <bfinney@instructure.com> QA-Review: Robert Lamb <rlamb@instructure.com>
This commit is contained in:
parent
f5276f7a78
commit
3b18cd0912
|
@ -0,0 +1,7 @@
|
|||
class FixCorruptAssessmentQuestionsFromCnvs19292 < ActiveRecord::Migration
|
||||
tag :postdeploy
|
||||
|
||||
def up
|
||||
DataFixup::FixCorruptAssessmentQuestionsFromCnvs19292.send_later_if_production_enqueue_args(:run, :priority => Delayed::LOW_PRIORITY, :max_attempts => 1)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,115 @@
|
|||
DataFixup::FixCorruptAssessmentQuestionsFromCnvs19292 = Struct.new(:bug_start_date, :bug_end_date) do
|
||||
LOG_PREFIX = "FIX_19292_CORRUPTION - "
|
||||
|
||||
def self.run(bug_start_date = false, bug_end_date = false, noop = false)
|
||||
if noop
|
||||
# Dangerous, but noop should only be executed in isolation.
|
||||
connection = ActiveRecord::Base.connection
|
||||
def connection.exec_no_cache(sql, *args)
|
||||
if sql =~ /INSERT|UPDATE/
|
||||
warn '#NOOP'
|
||||
return Struct.new(:cmd_tuples, :fields, :nfields, :values, :clear).new(0, [], [], [], true)
|
||||
else
|
||||
super(sql, *args)
|
||||
end
|
||||
end
|
||||
|
||||
def connection.exec_cache(sql, *args)
|
||||
if sql =~ /INSERT|UPDATE/
|
||||
warn '#NOOP'
|
||||
return Struct.new(:fields, :nfields, :clear).new([], 0, true)
|
||||
else
|
||||
super(sql, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
runner = self.new(bug_start_date, bug_end_date)
|
||||
|
||||
result = runner.fix_assessment_questions
|
||||
|
||||
if noop
|
||||
# Just in case we weren't in isolation
|
||||
def connection.exec_no_cache(*args)
|
||||
super(*args)
|
||||
end
|
||||
|
||||
def connection.exec_cache(*args)
|
||||
super(*args)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
# SQL
|
||||
# SELECT
|
||||
# "assessment_questions".*
|
||||
# FROM
|
||||
# "assessment_questions"
|
||||
# INNER JOIN
|
||||
# "assessment_question_banks"
|
||||
# ON
|
||||
# "assessment_question_banks"."id" = "assessment_questions"."assessment_question_bank_id"
|
||||
# INNER JOIN
|
||||
# "quiz_groups"
|
||||
# ON
|
||||
# "quiz_groups"."assessment_question_bank_id" = "assessment_question_banks"."id"
|
||||
# INNER JOIN
|
||||
# "quizzes"
|
||||
# ON
|
||||
# "quizzes"."id" = "quiz_groups"."quiz_id"
|
||||
# WHERE (
|
||||
# "quizzes"."updated_at" BETWEEN '2015-03-14 00:00:00.000000' AND '2015-03-18 23:59:59.999999'
|
||||
# ) AND (
|
||||
# assessment_questions.updated_at < '2015-03-18 23:59:59.999999'
|
||||
# ) AND (
|
||||
# assessment_questions.question_data LIKE '%calculated_question%' or
|
||||
# assessment_questions.question_data LIKE '%numerical_question%' or
|
||||
# assessment_questions.question_data LIKE '%matching_question%'
|
||||
# );
|
||||
#
|
||||
# Explain
|
||||
# Nested Loop (cost=10.95..368.36 rows=1 width=1604)
|
||||
# -> Nested Loop (cost=10.95..79.50 rows=5 width=16)
|
||||
# -> Hash Join (cost=10.95..72.84 rows=15 width=8)
|
||||
# Hash Cond: (quizzes.id = quiz_groups.quiz_id)
|
||||
# -> Seq Scan on quizzes (cost=0.00..60.52 rows=35 width=8)
|
||||
# Filter: ((updated_at >= '2015-03-14 00:00:00'::timestamp without time zone) AND (updated_at <= '2015-03-18 23:59:59.999999'::timestamp without time zone))
|
||||
# -> Hash (cost=8.20..8.20 rows=220 width=16)
|
||||
# -> Seq Scan on quiz_groups (cost=0.00..8.20 rows=220 width=16)
|
||||
# -> Index Scan using assessment_question_banks_pkey on assessment_question_banks (cost=0.00..0.43 rows=1 width=8)
|
||||
# Index Cond: (id = quiz_groups.assessment_question_bank_id)
|
||||
# -> Index Scan using question_bank_id_and_position on assessment_questions (cost=0.00..57.76 rows=1 width=1604)
|
||||
# Index Cond: (assessment_question_bank_id = assessment_question_banks.id)
|
||||
# Filter: ((updated_at < '2015-03-18 23:59:59.999999'::timestamp without time zone) AND ((question_data ~~ '%calculated_question%'::text) OR (question_data ~~ '%numerical_question%'::text) OR (question_data ~~ '%matching_question%'::text)))
|
||||
|
||||
# Update each AssessmentQuestion to increment version_number, this will
|
||||
# cause associated QuizQuestions to update on next Quiz take
|
||||
def fix_assessment_questions
|
||||
query = AssessmentQuestion
|
||||
.joins(:assessment_question_bank => {:quiz_groups => :quiz})
|
||||
.where("
|
||||
assessment_questions.question_data LIKE '%calculated_question%' or
|
||||
assessment_questions.question_data LIKE '%numerical_question%' or
|
||||
assessment_questions.question_data LIKE '%matching_question%'
|
||||
")
|
||||
|
||||
if bug_start_date && bug_end_date
|
||||
query = query
|
||||
.where(quizzes: {updated_at: bug_start_date..bug_end_date})
|
||||
.where('assessment_questions.updated_at < ?', bug_end_date)
|
||||
end
|
||||
|
||||
Shackles.activate(:slave) do
|
||||
query.readonly(false).find_each do |aq|
|
||||
Shackles.activate(:master) do
|
||||
Rails.logger.info "#{LOG_PREFIX} incrementing version for assessment question #{aq.global_id} from #{aq.version_number}"
|
||||
aq.with_versioning(true, &:save!)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue