squash old migrations, p27 (through 2015)

Change-Id: I861eb26bb73e59dd489578b2f66ae26b08679287
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/234270
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
QA-Review: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Ethan Vizitei <evizitei@instructure.com>
This commit is contained in:
Simon Williams 2020-04-15 20:11:36 -05:00
parent 1b48c98140
commit 2348f8525c
31 changed files with 51 additions and 1150 deletions

View File

@ -28,7 +28,7 @@ class ValidateMigrationIntegrity < ActiveRecord::Migration[4.2]
def self.up
initial_migration_version = "20101210192618"
last_squashed_migration_version = "20150914171551"
last_squashed_migration_version = "20151221185407"
initial_migration_has_run = ActiveRecord::SchemaMigration.where(version: initial_migration_version).exists?
last_squashed_migration_has_run = ActiveRecord::SchemaMigration.where(version: last_squashed_migration_version).exists?

View File

@ -89,7 +89,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.string "identifier_format"
t.text "certificate_fingerprint"
t.string "entity_id"
t.string "auth_filter"
t.text "auth_filter"
t.string "requested_authn_context"
t.datetime "last_timeout_failure"
t.text "login_attribute"
@ -97,6 +97,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.integer "position"
t.boolean "parent_registration", default: false, null: false
t.string "workflow_state", default: "active", null: false
t.boolean "jit_provisioning", default: false, null: false
end
add_index "account_authorization_configs", ["account_id"], :name => "index_account_authorization_configs_on_account_id"
@ -480,6 +481,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
add_index "assignments", ["context_id", "context_type"], :name => "index_assignments_on_context_id_and_context_type"
add_index "assignments", ["due_at", "context_code"], :name => "index_assignments_on_due_at_and_context_code"
add_index "assignments", ["grading_standard_id"], :name => "index_assignments_on_grading_standard_id"
add_index :assignments, :turnitin_id, unique: true, where: "turnitin_id IS NOT NULL"
create_table "attachment_associations", :force => true do |t|
t.integer "attachment_id", :limit => 8
@ -541,6 +543,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
add_index :attachments, :need_notify, :where => "need_notify"
add_index :attachments, :replacement_attachment_id, where: "replacement_attachment_id IS NOT NULL"
add_index :attachments, :namespace
add_index :attachments, [:folder_id, :position], where: 'folder_id IS NOT NULL'
create_table "authorization_codes", :force => true do |t|
t.string "authorization_code"
@ -628,9 +631,15 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.integer :submission_id, limit: 8, null: false
end
add_index :canvadocs_submissions, :canvadoc_id, where: "canvadoc_id IS NOT NULL"
add_index :canvadocs_submissions, :crocodoc_document_id, where: "crocodoc_document_id IS NOT NULL"
add_index :canvadocs_submissions, :submission_id
add_index :canvadocs_submissions, [:submission_id, :canvadoc_id],
where: "canvadoc_id IS NOT NULL",
name: "unique_submissions_and_canvadocs",
unique: true
add_index :canvadocs_submissions, [:submission_id, :crocodoc_document_id],
where: "crocodoc_document_id IS NOT NULL",
name: "unique_submissions_and_crocodocs",
unique: true
create_table "cloned_items", :force => true do |t|
t.integer "original_item_id", :limit => 8
@ -705,6 +714,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
end
add_index :communication_channels, :confirmation_code
connection.execute("CREATE UNIQUE INDEX index_communication_channels_on_user_id_and_path_and_path_type ON #{CommunicationChannel.quoted_table_name} (user_id, LOWER(path), path_type)")
add_index :communication_channels, :last_bounce_at, where: 'bounce_count > 0'
create_table :content_exports do |t|
t.integer :user_id, :limit => 8
@ -975,19 +985,6 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
add_index :course_account_associations, [:course_id, :course_section_id, :account_id], :unique => true, :name => 'index_caa_on_course_id_and_section_id_and_account_id'
add_index :course_account_associations, :course_section_id
create_table "course_imports", :force => true do |t|
t.integer "course_id", :limit => 8
t.integer "source_id", :limit => 8
t.text "added_item_codes"
t.text "log"
t.string "workflow_state"
t.string "import_type"
t.integer "progress"
t.text "parameters"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "course_sections", :force => true do |t|
t.string "sis_source_id"
t.integer "sis_batch_id", :limit => 8
@ -1192,6 +1189,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.boolean "force_token_reuse"
t.string "workflow_state", default: "active", null: false
t.boolean "replace_tokens"
t.boolean "auto_expire_tokens"
end
add_index :developer_keys, [:tool_id], :unique => true
@ -1480,15 +1478,15 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.text "title"
t.text "message"
t.string "source_name"
t.string "source_url"
t.text "source_url"
t.datetime "posted_at"
t.datetime "start_at"
t.datetime "end_at"
t.string "workflow_state", :null => false
t.string "url", :limit => 4.kilobytes
t.text "url"
t.string "author_name"
t.string "author_email"
t.string "author_url"
t.text "author_url"
t.integer "asset_id", :limit => 8
t.string "asset_type"
t.string "uuid"
@ -1656,7 +1654,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id", :limit => 8, :null => false
t.string "uuid"
t.string "uuid", null: false
t.integer "sis_batch_id", :limit => 8
t.boolean "moderator"
end
@ -1665,6 +1663,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
add_index "group_memberships", ["user_id"], :name => "index_group_memberships_on_user_id"
add_index "group_memberships", ["workflow_state"], :name => "index_group_memberships_on_workflow_state"
add_index :group_memberships, :sis_batch_id, where: "sis_batch_id IS NOT NULL"
add_index :group_memberships, :uuid, unique: true
create_table "groups", :force => true do |t|
t.string "name"
@ -1684,7 +1683,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.string "default_view", :default => "feed"
t.string "migration_id"
t.integer "storage_quota", :limit => 8
t.string "uuid"
t.string "uuid", null: false
t.integer "root_account_id", :limit => 8, :null => false
t.string "sis_source_id"
t.integer "sis_batch_id", :limit => 8
@ -1701,6 +1700,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
add_index :groups, [:sis_source_id, :root_account_id], where: "sis_source_id IS NOT NULL", unique: true
add_index :groups, :wiki_id, where: "wiki_id IS NOT NULL"
add_index :groups, :sis_batch_id, where: "sis_batch_id IS NOT NULL"
add_index :groups, :uuid, unique: true
create_table :group_categories do |t|
t.integer :context_id, :limit => 8
@ -1711,6 +1711,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.string :self_signup
t.integer :group_limit
t.string :auto_leader
t.timestamps null: true
end
add_index :group_categories, [:context_id, :context_type], :name => "index_group_categories_on_context"
add_index :group_categories, :role, :name => "index_group_categories_on_role"
@ -1937,6 +1938,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.string :context_type, null: false, default: 'Account'
t.string :name
t.string :description
t.text :update_payload
end
add_index :lti_tool_proxies, [:guid]
@ -2058,6 +2060,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.timestamps null: true
t.boolean :final, null: false, default: false
t.integer :source_provisional_grade_id, limit: 8
end
add_index :moderated_grading_provisional_grades, :submission_id
add_index :moderated_grading_provisional_grades,
@ -2797,6 +2800,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
t.boolean "has_admin_comment", :default => false, :null => false
t.datetime "cached_due_date"
t.boolean "excused"
t.boolean "graded_anonymously"
end
add_index "submissions", ["assignment_id", "submission_type"], :name => "index_submissions_on_assignment_id_and_submission_type"
@ -2872,7 +2876,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
create_table "user_services", :force => true do |t|
t.integer "user_id", :limit => 8, :null => false
t.string "token"
t.text "token"
t.string "secret"
t.string "protocol"
t.string "service", :null => false
@ -2953,6 +2957,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
add_index :users, "LOWER(short_name) #{trgm}.gist_trgm_ops", name: "index_trgm_users_short_name", using: :gist
end
add_index :users, :lti_context_id, :unique => true
add_index :users, :turnitin_id, unique: true, where: "turnitin_id IS NOT NULL"
create_table :user_profiles do |t|
t.text :bio
@ -3100,6 +3105,16 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
ON cs.course_id = c.id
AND e.course_section_id = cs.id
LEFT JOIN #{GroupMembership.quoted_table_name} gm
ON gm.user_id = e.user_id
AND gm.workflow_state = 'accepted'
LEFT JOIN #{Group.quoted_table_name} g
ON g.context_type = 'Course'
AND g.context_id = c.id
AND g.workflow_state = 'available'
AND gm.group_id = g.id
LEFT JOIN #{AssignmentOverrideStudent.quoted_table_name} aos
ON aos.assignment_id = a.id
AND aos.user_id = e.user_id
@ -3110,6 +3125,7 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
AND (
(ao.set_type = 'CourseSection' AND ao.set_id = cs.id)
OR (ao.set_type = 'ADHOC' AND ao.set_id IS NULL AND ao.id = aos.assignment_override_id)
OR (ao.set_type = 'Group' AND ao.set_id = g.id)
)
LEFT JOIN #{Submission.quoted_table_name} s
@ -3347,6 +3363,8 @@ class InitCanvasDb < ActiveRecord::Migration[4.2]
add_foreign_key :media_objects, :accounts, :column => :root_account_id
add_foreign_key :media_objects, :users
add_foreign_key :migration_issues, :content_migrations
add_foreign_key :moderated_grading_provisional_grades, :moderated_grading_provisional_grades,
:column => :source_provisional_grade_id, :name => 'provisional_grades_source_provisional_grade_fk'
add_foreign_key :moderated_grading_provisional_grades, :submissions
add_foreign_key :moderated_grading_provisional_grades, :users, column: :scorer_id
add_foreign_key :moderated_grading_selections, :assignments

View File

@ -54,6 +54,7 @@ class CreateDelayedJobs < ActiveRecord::Migration[4.2]
table.integer :shard_id, :limit => 8
table.string :source
table.integer :max_concurrent, :default => 1, :null => false
table.datetime :expires_at
end
connection.execute("CREATE INDEX get_delayed_jobs_index ON #{Delayed::Backend::ActiveRecord::Job.quoted_table_name} (priority, run_at) WHERE locked_at IS NULL AND queue = 'canvas_queue' AND next_in_strand = 't'")
@ -84,7 +85,7 @@ class CreateDelayedJobs < ActiveRecord::Migration[4.2]
(get_byte(strand_md5, 6) << 8) +
get_byte(strand_md5, 7);
END;
$$ LANGUAGE plpgsql;
$$ LANGUAGE plpgsql SET search_path TO #{search_path};
CODE
# create the insert trigger
@ -106,13 +107,16 @@ class CreateDelayedJobs < ActiveRecord::Migration[4.2]
# create the delete trigger
execute(<<-CODE)
CREATE FUNCTION #{connection.quote_table_name('delayed_jobs_after_delete_row_tr_fn')} () RETURNS trigger AS $$
DECLARE
running_count integer;
BEGIN
IF OLD.strand IS NOT NULL THEN
PERFORM pg_advisory_xact_lock(half_md5_as_bigint(OLD.strand));
IF (SELECT COUNT(*) FROM delayed_jobs WHERE strand = OLD.strand AND next_in_strand = 't') < OLD.max_concurrent THEN
running_count := (SELECT COUNT(*) FROM delayed_jobs WHERE strand = OLD.strand AND next_in_strand = 't');
IF running_count < OLD.max_concurrent THEN
UPDATE delayed_jobs SET next_in_strand = 't' WHERE id = (
SELECT id FROM delayed_jobs j2 WHERE next_in_strand = 'f' AND
j2.strand = OLD.strand ORDER BY j2.id ASC LIMIT 1 FOR UPDATE
j2.strand = OLD.strand ORDER BY j2.id ASC LIMIT (OLD.max_concurrent - running_count) FOR UPDATE
);
END IF;
END IF;
@ -140,6 +144,7 @@ class CreateDelayedJobs < ActiveRecord::Migration[4.2]
t.integer "shard_id", :limit => 8
t.integer "original_job_id", :limit => 8
t.string "source"
t.datetime "expires_at"
end
end

View File

@ -81,7 +81,8 @@ class AddAuthenticationAuditorTables < ActiveRecord::Migration[4.2]
context_type text,
event_type text,
grade_before text,
grade_after text
grade_after text,
graded_anonymously boolean
) #{compression_params}}
indexes.each do |index_name|

View File

@ -1,24 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddJitProvisioningToAuthenticationProviders < ActiveRecord::Migration[4.2]
tag :predeploy
def change
add_column :account_authorization_configs, :jit_provisioning, :bool, default: false, null: false
end
end

View File

@ -1,32 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class GrandfatherSelfRegistration < ActiveRecord::Migration[4.2]
tag :predeploy
def up
Account.root_accounts.active.non_shadow.each do |account|
next unless account.settings[:self_registration]
ap = account.authentication_providers.active.where(auth_type: 'canvas').first
next unless ap
ap.self_registration = account.settings[:self_registration_type] || 'all'
ap.save!
end
end
end

View File

@ -1,24 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddGradedAnonymouslyToSubmissions < ActiveRecord::Migration[4.2]
tag :predeploy
def change
add_column :submissions, :graded_anonymously, :boolean
end
end

View File

@ -1,39 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddCassandraGradedAnonymouslyToAuditorTables < ActiveRecord::Migration[4.2]
tag :predeploy
include Canvas::Cassandra::Migration
def self.cassandra_cluster
'auditors'
end
def self.up
cassandra.execute %{
ALTER TABLE grade_changes
ADD graded_anonymously boolean
}
end
def self.down
cassandra.execute %{
ALTER TABLE grade_changes
DROP graded_anonymously
}
end
end

View File

@ -1,27 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class FixImportedQuestionMediaComments < ActiveRecord::Migration[4.2]
tag :postdeploy
def up
DataFixup::FixImportedQuestionMediaComments.send_later_if_production_enqueue_args(:run,
:priority => Delayed::LOW_PRIORITY, :n_strand => 'long_datafixups')
end
def down
end
end

View File

@ -1,30 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class ChangeAuthFilterToText < ActiveRecord::Migration[4.2]
tag :postdeploy
def self.up
AuthenticationProvider.maybe_recreate_view do
change_column :account_authorization_configs, :auth_filter, :text
end
end
def self.down
change_column :account_authorization_configs, :auth_filter, :string
end
end

View File

@ -1,32 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class ExpandExternalFeedUrlColumns < ActiveRecord::Migration[4.2]
tag :postdeploy
def self.up
change_column :external_feed_entries, :url, :text
change_column :external_feed_entries, :source_url, :text
change_column :external_feed_entries, :author_url, :text
end
def self.down
change_column :external_feed_entries, :url, :string
change_column :external_feed_entries, :source_url, :string
change_column :external_feed_entries, :author_url, :string
end
end

View File

@ -1,26 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddTimestampsToGroupCategories < ActiveRecord::Migration[4.2]
tag :predeploy
def change
change_table(:group_categories) do |t|
t.timestamps null: true
end
end
end

View File

@ -1,49 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class FixGroupsWithDuplicateWikiAndUuid < ActiveRecord::Migration[4.2]
tag :postdeploy
disable_ddl_transaction!
def up
DataFixup::FixGroupsWithDuplicateWikiAndUuid.run
# There are a very small number of groups with no uuid
[Group, GroupMembership].each do |klass|
klass.where(uuid: nil).find_each do |item|
klass.where(id: item).update_all(
uuid: CanvasSlug.generate_securish_uuid,
updated_at: Time.now.utc
)
end
end
change_column_null :groups, :uuid, false
change_column_null :group_memberships, :uuid, false
add_index :groups, :uuid, unique: true, algorithm: :concurrently
add_index :group_memberships, :uuid, unique: true, algorithm: :concurrently
end
def down
change_column_null :groups, :uuid, true
change_column_null :group_memberships, :uuid, true
remove_index :groups, :uuid
remove_index :group_memberships, :uuid
end
end

View File

@ -1,28 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class LengthenUserServicesToken < ActiveRecord::Migration[4.2]
tag :predeploy
def up
change_column :user_services, :token, :text
end
def down
change_column :user_services, :token, :string, :limit => 255
end
end

View File

@ -1,25 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddAutoExpireTokensToDeveloperKey < ActiveRecord::Migration[4.2]
tag :predeploy
def change
add_column :developer_keys, :auto_expire_tokens, :boolean
end
end

View File

@ -1,26 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddSourceProvisionalGradeIdToProvisionalGrades < ActiveRecord::Migration[4.2]
tag :predeploy
def change
add_column :moderated_grading_provisional_grades, :source_provisional_grade_id, :integer, :limit => 8
add_foreign_key :moderated_grading_provisional_grades, :moderated_grading_provisional_grades,
:column => :source_provisional_grade_id, :name => 'provisional_grades_source_provisional_grade_fk'
end
end

View File

@ -1,26 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddUniqueIndexToTurnitinColumns < ActiveRecord::Migration[4.2]
tag :predeploy
disable_ddl_transaction!
def change
add_index :assignments, :turnitin_id, unique: true, algorithm: :concurrently, where: "turnitin_id IS NOT NULL"
add_index :users, :turnitin_id, unique: true, algorithm: :concurrently, where: "turnitin_id IS NOT NULL"
end
end

View File

@ -1,36 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class SetSearchPathsOnFunctions < ActiveRecord::Migration[4.2]
tag :predeploy
def self.connection
Delayed::Backend::ActiveRecord::Job.connection
end
def up
set_search_path("delayed_jobs_after_delete_row_tr_fn", "()")
set_search_path("delayed_jobs_before_insert_row_tr_fn", "()")
set_search_path("half_md5_as_bigint", "(varchar)")
end
def down
set_search_path("delayed_jobs_after_delete_row_tr_fn", "()", "DEFAULT")
set_search_path("delayed_jobs_before_insert_row_tr_fn", "()", "DEFAULT")
set_search_path("half_md5_as_bigint", "(varchar)", "DEFAULT")
end
end

View File

@ -1,24 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddUpdatePayloadToLtiToolProxy < ActiveRecord::Migration[4.2]
tag :predeploy
def change
add_column :lti_tool_proxies, :update_payload, :text
end
end

View File

@ -1,34 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddExpiresAtToJobs < ActiveRecord::Migration[4.2]
tag :predeploy
def connection
Delayed::Backend::ActiveRecord::Job.connection
end
def up
add_column :delayed_jobs, :expires_at, :datetime
add_column :failed_jobs, :expires_at, :datetime
end
def down
remove_column :delayed_jobs, :expires_at
remove_column :failed_jobs, :expires_at
end
end

View File

@ -1,29 +0,0 @@
#
# Copyright (C) 2013 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddPermissionsForModeratedGrading < ActiveRecord::Migration[4.2]
tag :postdeploy
def self.up
DataFixup::CopyRoleOverrides.send_later_if_production_enqueue_args(:run,
{:priority => Delayed::LOW_PRIORITY, :max_attempts => 1},
:manage_account_settings, :moderate_grades)
end
def self.down
end
end

View File

@ -1,26 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddLastBounceAtIndexToCommunicationChannels < ActiveRecord::Migration[4.2]
tag :predeploy
disable_ddl_transaction!
def change
add_index :communication_channels, :last_bounce_at, algorithm: :concurrently, where: 'bounce_count > 0'
end
end

View File

@ -1,73 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class ImproveMaxConcurrent < ActiveRecord::Migration[4.2]
tag :predeploy
def connection
Delayed::Backend::ActiveRecord::Job.connection
end
def up
if connection.adapter_name == 'PostgreSQL'
search_path = Shard.current.name
execute(<<-CODE)
CREATE OR REPLACE FUNCTION #{connection.quote_table_name('delayed_jobs_after_delete_row_tr_fn')} () RETURNS trigger AS $$
DECLARE
running_count integer;
BEGIN
IF OLD.strand IS NOT NULL THEN
PERFORM pg_advisory_xact_lock(half_md5_as_bigint(OLD.strand));
running_count := (SELECT COUNT(*) FROM delayed_jobs WHERE strand = OLD.strand AND next_in_strand = 't');
IF running_count < OLD.max_concurrent THEN
UPDATE delayed_jobs SET next_in_strand = 't' WHERE id = (
SELECT id FROM delayed_jobs j2 WHERE next_in_strand = 'f' AND
j2.strand = OLD.strand ORDER BY j2.id ASC LIMIT (OLD.max_concurrent - running_count) FOR UPDATE
);
END IF;
END IF;
RETURN OLD;
END;
$$ LANGUAGE plpgsql SET search_path TO #{search_path};
CODE
end
end
def down
if connection.adapter_name == 'PostgreSQL'
search_path = Shard.current.name
execute(<<-CODE)
CREATE OR REPLACE FUNCTION #{connection.quote_table_name('delayed_jobs_after_delete_row_tr_fn')} () RETURNS trigger AS $$
BEGIN
IF OLD.strand IS NOT NULL THEN
PERFORM pg_advisory_xact_lock(half_md5_as_bigint(OLD.strand));
IF (SELECT COUNT(*) FROM delayed_jobs WHERE strand = OLD.strand AND next_in_strand = 't') < OLD.max_concurrent THEN
UPDATE delayed_jobs SET next_in_strand = 't' WHERE id = (
SELECT id FROM delayed_jobs j2 WHERE next_in_strand = 'f' AND
j2.strand = OLD.strand ORDER BY j2.id ASC LIMIT 1 FOR UPDATE
);
END IF;
END IF;
RETURN OLD;
END;
$$ LANGUAGE plpgsql SET search_path TO #{search_path};
CODE
end
end
end

View File

@ -1,38 +0,0 @@
#
# Copyright (C) 2016 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class DropCourseImports < ActiveRecord::Migration[4.2]
tag :postdeploy
def up
drop_table :course_imports
end
def down
create_table "course_imports" do |t|
t.integer "course_id", :limit => 8
t.integer "source_id", :limit => 8
t.text "added_item_codes"
t.text "log"
t.string "workflow_state"
t.string "import_type"
t.integer "progress"
t.datetime "created_at"
t.datetime "updated_at"
end
end
end

View File

@ -1,25 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddFolderAndPositionIndexToAttachments < ActiveRecord::Migration[4.2]
tag :postdeploy
disable_ddl_transaction!
def change
add_index :attachments, [:folder_id, :position], algorithm: :concurrently, where: 'folder_id IS NOT NULL'
end
end

View File

@ -1,125 +0,0 @@
#
# Copyright (C) 2014 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class AddGroupsToAssignmentVisibilityView < ActiveRecord::Migration[4.2]
tag :predeploy
def up
self.connection.execute "DROP VIEW #{connection.quote_table_name('assignment_student_visibilities')};"
self.connection.execute %Q(CREATE VIEW #{connection.quote_table_name('assignment_student_visibilities')} AS
SELECT DISTINCT a.id as assignment_id,
e.user_id as user_id,
c.id as course_id
FROM #{Assignment.quoted_table_name} a
JOIN #{Course.quoted_table_name} c
ON a.context_id = c.id
AND a.context_type = 'Course'
JOIN #{Enrollment.quoted_table_name} e
ON e.course_id = c.id
AND e.type IN ('StudentEnrollment', 'StudentViewEnrollment')
AND e.workflow_state != 'deleted'
JOIN #{CourseSection.quoted_table_name} cs
ON cs.course_id = c.id
AND e.course_section_id = cs.id
LEFT JOIN #{GroupMembership.quoted_table_name} gm
ON gm.user_id = e.user_id
AND gm.workflow_state = 'accepted'
LEFT JOIN #{Group.quoted_table_name} g
ON g.context_type = 'Course'
AND g.context_id = c.id
AND g.workflow_state = 'available'
AND gm.group_id = g.id
LEFT JOIN #{AssignmentOverrideStudent.quoted_table_name} aos
ON aos.assignment_id = a.id
AND aos.user_id = e.user_id
LEFT JOIN #{AssignmentOverride.quoted_table_name} ao
ON ao.assignment_id = a.id
AND ao.workflow_state = 'active'
AND (
(ao.set_type = 'CourseSection' AND ao.set_id = cs.id)
OR (ao.set_type = 'ADHOC' AND ao.set_id IS NULL AND ao.id = aos.assignment_override_id)
OR (ao.set_type = 'Group' AND ao.set_id = g.id)
)
LEFT JOIN #{Submission.quoted_table_name} s
ON s.user_id = e.user_id
AND s.assignment_id = a.id
AND s.score IS NOT NULL
WHERE a.workflow_state NOT IN ('deleted','unpublished')
AND(
( a.only_visible_to_overrides = 'true' AND (ao.id IS NOT NULL OR s.id IS NOT NULL))
OR (COALESCE(a.only_visible_to_overrides, 'false') = 'false')
)
)
end
def down
self.connection.execute "DROP VIEW #{connection.quote_table_name('assignment_student_visibilities')};"
self.connection.execute %Q(CREATE VIEW #{connection.quote_table_name('assignment_student_visibilities')} AS
SELECT DISTINCT a.id as assignment_id,
e.user_id as user_id,
c.id as course_id
FROM #{Assignment.quoted_table_name} a
JOIN #{Course.quoted_table_name} c
ON a.context_id = c.id
AND a.context_type = 'Course'
JOIN #{Enrollment.quoted_table_name} e
ON e.course_id = c.id
AND e.type IN ('StudentEnrollment', 'StudentViewEnrollment')
AND e.workflow_state != 'deleted'
JOIN #{CourseSection.quoted_table_name} cs
ON cs.course_id = c.id
AND e.course_section_id = cs.id
LEFT JOIN #{AssignmentOverrideStudent.quoted_table_name} aos
ON aos.assignment_id = a.id
AND aos.user_id = e.user_id
LEFT JOIN #{AssignmentOverride.quoted_table_name} ao
ON ao.assignment_id = a.id
AND ao.workflow_state = 'active'
AND (
(ao.set_type = 'CourseSection' AND ao.set_id = cs.id)
OR (ao.set_type = 'ADHOC' AND ao.set_id IS NULL AND ao.id = aos.assignment_override_id)
)
LEFT JOIN #{Submission.quoted_table_name} s
ON s.user_id = e.user_id
AND s.assignment_id = a.id
AND s.score IS NOT NULL
WHERE a.workflow_state NOT IN ('deleted','unpublished')
AND(
( a.only_visible_to_overrides = 'true' AND (ao.id IS NOT NULL OR s.id IS NOT NULL))
OR (COALESCE(a.only_visible_to_overrides, 'false') = 'false')
)
)
end
end

View File

@ -1,47 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class EnsureUniquenessOnCanvadocsSubmissions < ActiveRecord::Migration[4.2]
tag :postdeploy
disable_ddl_transaction!
def up
DataFixup::RemoveDuplicateCanvadocsSubmissions.run
remove_index :canvadocs_submissions, :canvadoc_id
remove_index :canvadocs_submissions, :crocodoc_document_id
add_index :canvadocs_submissions, [:submission_id, :canvadoc_id],
where: "canvadoc_id IS NOT NULL",
name: "unique_submissions_and_canvadocs",
unique: true, algorithm: :concurrently
add_index :canvadocs_submissions, [:submission_id, :crocodoc_document_id],
where: "crocodoc_document_id IS NOT NULL",
name: "unique_submissions_and_crocodocs",
unique: true, algorithm: :concurrently
end
def down
remove_index "canvadocs_submissions", name: "unique_submissions_and_canvadocs"
remove_index "canvadocs_submissions", name: "unique_submissions_and_crocodocs"
add_index :canvadocs_submissions, :canvadoc_id,
where: "canvadoc_id IS NOT NULL"
add_index :canvadocs_submissions, :crocodoc_document_id,
where: "crocodoc_document_id IS NOT NULL"
end
end

View File

@ -1,54 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
module DataFixup::FixGroupsWithDuplicateWikiAndUuid
def self.reset_dups(dup_scope, attrs)
keeper = dup_scope.first
dup_scope = dup_scope.where.not(:id => keeper)
attrs.each do |attr|
dup_scope.where(attr => keeper[attr]).update_all(attr => nil, updated_at: Time.now.utc)
end
end
def self.run
run_groups(:wiki_id)
run_groups(:uuid)
run_uuid_group_memberships
end
def self.run_groups(attr)
Group.where.not(attr => nil).group(attr, :context_id, :context_type).having("COUNT(*) > 1").
pluck(attr, :context_id, :context_type).each do |value, context_id, context_type|
scope = Group.where(
attr => value,
context_id: context_id,
context_type: context_type
).order(:created_at)
reset_dups(scope, [:sis_batch_id, :sis_source_id, :wiki_id, :uuid])
end
end
def self.run_uuid_group_memberships
GroupMembership.group(:uuid).having("COUNT(*) > 1").pluck(:uuid).each do |uuid|
scope = GroupMembership.where(uuid: uuid).order(:created_at)
reset_dups(scope, [:sis_batch_id, :uuid])
end
end
end

View File

@ -1,99 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
module DataFixup
module FixImportedQuestionMediaComments
def self.get_fixed_hash(bad_yaml)
return unless bad_yaml
placeholders = []
# tl;dr - search for the imported media comment links and re-substitute them in the right way so the yaml still works
# so first make a placeholder without quotes so we deserialize the yaml again
bad_yaml.gsub!(/\<a.*?\<\/a\>/m) do |link_str|
placeholder = "somuchsadness_#{Digest::MD5.hexdigest(link_str)}"
placeholders << {:placeholder => placeholder, :new_value => link_str}
placeholder
end
bad_yaml.gsub!(/\<a.*?\>/m) do |link_str| # for empty/unmatched tags
placeholder = "somuchsadness_#{Digest::MD5.hexdigest(link_str)}"
placeholders << {:placeholder => placeholder, :new_value => link_str}
placeholder
end
return unless hash = (YAML.load(bad_yaml) rescue nil)
# now make the substitutions correctly and return the serialized yaml
Importers::LinkReplacer.new(nil).recursively_sub_placeholders!(hash, placeholders)
hash
end
def self.run
quiz_ids_to_fix = []
still_broken_aq_ids = []
still_broken_qq_ids = []
still_broken_quiz_ids = []
date_of_sadness = DateTime.parse("2015-07-17") # day before the borked link refactoring was released
AssessmentQuestion.find_ids_in_ranges(:batch_size => 10000) do |min_id, max_id|
AssessmentQuestion.where(id: min_id..max_id).where("migration_id IS NOT NULL").
where("updated_at > ?", date_of_sadness).where("question_data LIKE ?", "%media_comment%").each do |aq|
next unless (aq['question_data'] rescue nil).nil? # deserializing the attribute will fail silently in Rails 3 but not Rails 4
unless hash = get_fixed_hash(aq.attributes_before_type_cast['question_data'])
still_broken_aq_ids << aq.id
next
end
AssessmentQuestion.where(:id => aq).update_all(:question_data => hash)
end
end
Quizzes::QuizQuestion.find_ids_in_ranges(:batch_size => 10000) do |min_id, max_id|
Quizzes::QuizQuestion.where(id: min_id..max_id).where("migration_id IS NOT NULL").
where("updated_at > ?", date_of_sadness).where("question_data LIKE ?", "%media_comment%").each do |qq|
next unless (qq['question_data'] rescue nil).nil?
unless hash = get_fixed_hash(qq.attributes_before_type_cast['question_data'])
still_broken_qq_ids << qq.id
next
end
quiz_ids_to_fix << qq.quiz_id
Quizzes::QuizQuestion.where(:id => qq).update_all(:question_data => hash)
end
end
quiz_ids_to_fix.uniq.each_slice(100) do |quiz_ids|
Quizzes::Quiz.where("quiz_data IS NOT NULL").where(:id => quiz_ids).each do |quiz|
next unless (quiz['quiz_data'] rescue nil).nil?
unless hash = get_fixed_hash(quiz.attributes_before_type_cast['quiz_data'])
still_broken_quiz_ids << quiz.id
next
end
Quizzes::Quiz.where(:id => quiz).update_all(:quiz_data => hash)
end
end
Rails.logger.error("Problem running FixImportedQuestionMediaComments: could not fix quiz questions #{still_broken_qq_ids}") if still_broken_qq_ids.any?
Rails.logger.error("Problem running FixImportedQuestionMediaComments: could not fix assessment questions #{still_broken_aq_ids}") if still_broken_aq_ids.any?
Rails.logger.error("Problem running FixImportedQuestionMediaComments: could not fix quizzes #{still_broken_quiz_ids}") if still_broken_quiz_ids.any?
end
end
end

View File

@ -1,36 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
module DataFixup::RemoveDuplicateCanvadocsSubmissions
def self.run
%w[crocodoc_document_id canvadoc_id].each do |column|
duplicates = CanvadocsSubmission.
select("#{column}, submission_id").
group("#{column}, submission_id").
having("count(*) > 1")
duplicates.find_each do |dup|
scope = CanvadocsSubmission.where(
column => dup[column],
submission_id: dup.submission_id
)
keeper = scope.first
scope.where("id <> ?", keeper.id).delete_all
end
end
end
end

View File

@ -1,89 +0,0 @@
#
# Copyright (C) 2015 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require 'spec_helper'
require 'db/migrate/20151006222126_fix_groups_with_duplicate_wiki_and_uuid'
describe 'FixGroupsWithDuplicateWikiAndUuid' do
before do
FixGroupsWithDuplicateWikiAndUuid.new.down
end
it "properly resets groups with duplicate data" do
course_with_student
@group_category = @course.group_categories.create!(name: 'Hi')
@group = @group_category.groups.create!(name: 'Hi 1', context: @course)
@membership = @group.group_memberships.create!(user: @student, workflow_state: 'invited')
@group.wiki # this creates the wiki
@new_group_category = @course.group_categories.create!(name: 'Hi Dup')
@dup_group = @new_group_category.groups.create!(name: 'Hi Dup 1', context: @course)
@dup_membership = @dup_group.group_memberships.create!(user: @student, workflow_state: 'invited')
Group.where(id: @dup_group).update_all(wiki_id: @group.wiki_id, uuid: @group.uuid)
GroupMembership.where(id: @dup_membership).update_all(uuid: @membership.uuid)
@dup_uuid_only_group = @new_group_category.groups.create!(name: 'Hi Dup 2', context: @course)
@dup_uuid_only_group.wiki
Group.where(id: @dup_uuid_only_group).update_all(uuid: @group.uuid)
@other_group_category = @course.group_categories.create!(name: 'Hi Other')
@other_group = @other_group_category.groups.create!(name: 'Hi Other 1', context: @course)
@other_membership = @other_group.group_memberships.create!(user: @student, workflow_state: 'invited')
@other_group.wiki
other_group_wiki_id = @other_group.wiki_id
other_group_uuid = @other_group.uuid
other_membership_uuid = @other_membership.uuid
dup_uuid_only_group_wiki_id = @dup_uuid_only_group.wiki_id
FixGroupsWithDuplicateWikiAndUuid.new.up
@group.reload
@dup_group.reload
@dup_uuid_only_group.reload
@other_group.reload
@membership.reload
@dup_membership.reload
@other_membership.reload
expect(@dup_group.wiki_id).not_to eq @group.wiki_id
expect(@dup_group.uuid).not_to eq @group.uuid
expect(@dup_uuid_only_group.wiki_id).to eq dup_uuid_only_group_wiki_id
expect(@dup_uuid_only_group.uuid).not_to eq @group.uuid
expect(@dup_membership.uuid).not_to eq @membership.uuid
expect(@other_group.wiki_id).to eq other_group_wiki_id
expect(@other_group.uuid).to eq other_group_uuid
expect(@other_membership.uuid).to eq other_membership_uuid
end
it "sets a uuid for groups without one" do
course_model
@group_category = @course.group_categories.create!(name: 'Hi')
@group = @group_category.groups.create!(name: 'Hi 1', context: @course)
Group.where(id: @group).update_all(uuid: nil)
FixGroupsWithDuplicateWikiAndUuid.new.up
@group.reload
expect(@group.uuid).not_to be nil
end
end