diff --git a/db/migrate/20140826073318_sorcery_core.rb b/db/migrate/20140826073318_sorcery_core.rb index ce978f4f..8fc602dd 100644 --- a/db/migrate/20140826073318_sorcery_core.rb +++ b/db/migrate/20140826073318_sorcery_core.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class SorceryCore < ActiveRecord::Migration[4.2] + class InternalUser < ApplicationRecord + end + def change InternalUser.delete_all add_column :internal_users, :crypted_password, :string, null: false diff --git a/db/migrate/20140918063522_add_hashed_content_to_files.rb b/db/migrate/20140918063522_add_hashed_content_to_files.rb index 8b5393d4..b338b3bc 100644 --- a/db/migrate/20140918063522_add_hashed_content_to_files.rb +++ b/db/migrate/20140918063522_add_hashed_content_to_files.rb @@ -1,6 +1,20 @@ # frozen_string_literal: true class AddHashedContentToFiles < ActiveRecord::Migration[4.2] + class CodeOcean::File < ApplicationRecord + before_validation :hash_content, if: :content_present? + + private + + def content_present? + content? || native_file? + end + + def hash_content + self.hashed_content = Digest::MD5.new.hexdigest(read || '') + end + end + def change add_column :files, :hashed_content, :string diff --git a/db/migrate/20150204080832_add_pool_size_to_execution_environments.rb b/db/migrate/20150204080832_add_pool_size_to_execution_environments.rb index 11b7dc79..0df5f661 100644 --- a/db/migrate/20150204080832_add_pool_size_to_execution_environments.rb +++ b/db/migrate/20150204080832_add_pool_size_to_execution_environments.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class AddPoolSizeToExecutionEnvironments < ActiveRecord::Migration[4.2] + class ExecutionEnvironment < ApplicationRecord + end + def change add_column :execution_environments, :pool_size, :integer diff --git a/db/migrate/20150317083739_add_memory_limit_to_execution_environments.rb b/db/migrate/20150317083739_add_memory_limit_to_execution_environments.rb index 05d4a7b7..9d67506a 100644 --- a/db/migrate/20150317083739_add_memory_limit_to_execution_environments.rb +++ b/db/migrate/20150317083739_add_memory_limit_to_execution_environments.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true class AddMemoryLimitToExecutionEnvironments < ActiveRecord::Migration[4.2] + class ExecutionEnvironment < ApplicationRecord + DEFAULT_MEMORY_LIMIT = 256 + end + def change add_column :execution_environments, :memory_limit, :integer diff --git a/db/migrate/20150317115338_add_network_enabled_to_execution_environments.rb b/db/migrate/20150317115338_add_network_enabled_to_execution_environments.rb index 182cc66e..30406871 100644 --- a/db/migrate/20150317115338_add_network_enabled_to_execution_environments.rb +++ b/db/migrate/20150317115338_add_network_enabled_to_execution_environments.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class AddNetworkEnabledToExecutionEnvironments < ActiveRecord::Migration[4.2] + class ExecutionEnvironment < ApplicationRecord + end + def change add_column :execution_environments, :network_enabled, :boolean diff --git a/db/migrate/20160630154310_add_submission_to_request_for_comments.rb b/db/migrate/20160630154310_add_submission_to_request_for_comments.rb index 65dac9f1..3396f4c2 100644 --- a/db/migrate/20160630154310_add_submission_to_request_for_comments.rb +++ b/db/migrate/20160630154310_add_submission_to_request_for_comments.rb @@ -3,31 +3,32 @@ class AddSubmissionToRequestForComments < ActiveRecord::Migration[4.2] def change add_reference :request_for_comments, :submission + + up_only do + execute <<-SQL.squish + UPDATE request_for_comments + SET submission_id = sub.submission_id_external + FROM + (SELECT s.id AS submission_id_external, + rfc.id AS rfc_id, + s.created_at AS submission_created_at, + rfc.created_at AS rfc_crea + FROM submissions s, + request_for_comments rfc + WHERE s.user_id = rfc.user_id + AND s.exercise_id = rfc.exercise_id + AND rfc.created_at + interval '2 hours' > s.created_at + AND s.created_at = + (SELECT MAX(created_at) + FROM submissions + WHERE exercise_id = s.exercise_id + AND user_id = s.user_id + AND rfc.created_at + interval '2 hours' > created_at + GROUP BY s.exercise_id, + s.user_id)) as sub + WHERE id = sub.rfc_id + AND submission_id IS NULL; + SQL + end end end - -# We issued the following on the database to add the submission_ids for existing entries -# -# UPDATE request_for_comments -# SET submission_id = sub.submission_id_external -# FROM -# (SELECT s.id AS submission_id_external, -# rfc.id AS rfc_id, -# s.created_at AS submission_created_at, -# rfc.created_at AS rfc_created_at -# FROM submissions s, -# request_for_comments rfc -# WHERE s.user_id = rfc.user_id -# AND s.exercise_id = rfc.exercise_id -# AND rfc.created_at + interval '2 hours' > s.created_at -# AND s.created_at = -# (SELECT MAX(created_at) -# FROM submissions -# WHERE exercise_id = s.exercise_id -# AND user_id = s.user_id -# AND rfc.created_at + interval '2 hours' > created_at -# GROUP BY s.exercise_id, -# s.user_id)) as sub -# WHERE id = sub.rfc_id -# AND submission_id IS NULL; -# diff --git a/db/migrate/20170403162848_set_default_for_request_for_comment_solved.rb b/db/migrate/20170403162848_set_default_for_request_for_comment_solved.rb index bc120c46..81583f44 100644 --- a/db/migrate/20170403162848_set_default_for_request_for_comment_solved.rb +++ b/db/migrate/20170403162848_set_default_for_request_for_comment_solved.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class SetDefaultForRequestForCommentSolved < ActiveRecord::Migration[4.2] + class RequestForComment < ApplicationRecord + end + def change change_column_default :request_for_comments, :solved, false RequestForComment.where(solved: nil).update(solved: false) diff --git a/db/migrate/20170830083601_add_cause_to_testruns.rb b/db/migrate/20170830083601_add_cause_to_testruns.rb index 73de7e9c..291b572d 100644 --- a/db/migrate/20170830083601_add_cause_to_testruns.rb +++ b/db/migrate/20170830083601_add_cause_to_testruns.rb @@ -1,6 +1,13 @@ # frozen_string_literal: true class AddCauseToTestruns < ActiveRecord::Migration[4.2] + class Testrun < ApplicationRecord + belongs_to :submission, optional: true + end + + class Submission < ApplicationRecord + end + def up add_column :testruns, :cause, :string Testrun.reset_column_information diff --git a/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb b/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb index 79ecc350..decda30d 100644 --- a/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb +++ b/db/migrate/20180130172021_add_reached_full_score_to_request_for_comment.rb @@ -1,6 +1,57 @@ # frozen_string_literal: true class AddReachedFullScoreToRequestForComment < ActiveRecord::Migration[4.2] + class RequestForComment < ApplicationRecord + belongs_to :submission, optional: true + belongs_to :user, optional: true + end + + class Submission < ApplicationRecord + belongs_to :exercise + belongs_to :user, polymorphic: true + end + + class Exercise < ApplicationRecord + has_many :files, as: :context, class_name: 'CodeOcean::File' + has_many :submissions + + def solved_by?(user) + maximum_score(user).to_i == maximum_score.to_i + end + + def maximum_score(user) + if user + submissions + .where(user:, cause: %w[submit assess]) + .where.not(score: nil) + .order(score: :desc) + .first&.score || 0 + else + @maximum_score ||= if files.loaded? + files.filter(&:teacher_defined_assessment?).pluck(:weight).sum + else + files.teacher_defined_assessments.sum(:weight) + end + end + end + end + + class CodeOcean::File < ApplicationRecord + belongs_to :context, polymorphic: true + scope :teacher_defined_assessments, -> { where(role: %w[teacher_defined_test teacher_defined_linter]) } + + ROLES = %w[regular_file main_file reference_implementation executable_file teacher_defined_test user_defined_file + user_defined_test teacher_defined_linter].freeze + + def teacher_defined_assessment? + teacher_defined_test? || teacher_defined_linter? + end + + ROLES.each do |role| + define_method(:"#{role}?") { self.role == role } + end + end + def up add_column :request_for_comments, :full_score_reached, :boolean, default: false RequestForComment.find_each do |rfc| diff --git a/db/migrate/20181119161514_add_user_to_proxy_exercise.rb b/db/migrate/20181119161514_add_user_to_proxy_exercise.rb index 59380ea3..3fa3f5f3 100644 --- a/db/migrate/20181119161514_add_user_to_proxy_exercise.rb +++ b/db/migrate/20181119161514_add_user_to_proxy_exercise.rb @@ -1,6 +1,13 @@ # frozen_string_literal: true class AddUserToProxyExercise < ActiveRecord::Migration[5.2] + class Internaluser < ApplicationRecord + end + + class ProxyExercise < ApplicationRecord + belongs_to :user, polymorphic: true + end + def change add_reference :proxy_exercises, :user, polymorphic: true, index: true add_column :proxy_exercises, :public, :boolean, null: false, default: false diff --git a/db/migrate/20181126163428_add_user_type_to_remote_evaluation_mappings.rb b/db/migrate/20181126163428_add_user_type_to_remote_evaluation_mappings.rb index a3ab1a69..785cca3e 100644 --- a/db/migrate/20181126163428_add_user_type_to_remote_evaluation_mappings.rb +++ b/db/migrate/20181126163428_add_user_type_to_remote_evaluation_mappings.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true class AddUserTypeToRemoteEvaluationMappings < ActiveRecord::Migration[5.2] + class RemoteEvaluationMapping < ApplicationRecord + belongs_to :user, polymorphic: true + end + def change add_column :remote_evaluation_mappings, :user_type, :string # Update all existing records and set user_type to `ExternalUser` (safe way to prevent any function loss). diff --git a/db/migrate/20201019090123_add_normalized_score_and_submission_to_user_exercise_feedback.rb b/db/migrate/20201019090123_add_normalized_score_and_submission_to_user_exercise_feedback.rb index 04a55e3c..061966a0 100644 --- a/db/migrate/20201019090123_add_normalized_score_and_submission_to_user_exercise_feedback.rb +++ b/db/migrate/20201019090123_add_normalized_score_and_submission_to_user_exercise_feedback.rb @@ -1,6 +1,18 @@ # frozen_string_literal: true class AddNormalizedScoreAndSubmissionToUserExerciseFeedback < ActiveRecord::Migration[5.2] + class UserExerciseFeedback < ApplicationRecord + belongs_to :submission + belongs_to :exercise + end + + class Submission < ApplicationRecord + belongs_to :user, polymorphic: true + end + + class Exercise < ApplicationRecord + end + def change add_column :user_exercise_feedbacks, :normalized_score, :float add_reference :user_exercise_feedbacks, :submission, foreign_key: true @@ -9,7 +21,7 @@ class AddNormalizedScoreAndSubmissionToUserExerciseFeedback < ActiveRecord::Migr ActiveRecord::Base.record_timestamps = false UserExerciseFeedback.find_each do |uef| latest_submission = Submission - .where(user_id: uef.user_id, user_type: uef.user_type, exercise_id: uef.exercise_id) + .where(user: uef.user, exercise: uef.exercise) .where(created_at: ...uef.updated_at) .order(created_at: :desc).first diff --git a/db/migrate/20210602071834_change_type_of_exposed_ports_in_execution_environment.rb b/db/migrate/20210602071834_change_type_of_exposed_ports_in_execution_environment.rb index 6715c59a..d88ab604 100644 --- a/db/migrate/20210602071834_change_type_of_exposed_ports_in_execution_environment.rb +++ b/db/migrate/20210602071834_change_type_of_exposed_ports_in_execution_environment.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class ChangeTypeOfExposedPortsInExecutionEnvironment < ActiveRecord::Migration[6.1] + class ExecutionEnvironment < ApplicationRecord + end + # rubocop:disable Rails/SkipsModelValidations: def up rename_column :execution_environments, :exposed_ports, :exposed_ports_migration diff --git a/db/migrate/20211114145024_create_tips_intervention.rb b/db/migrate/20211114145024_create_tips_intervention.rb index b5938e34..d7d22d41 100644 --- a/db/migrate/20211114145024_create_tips_intervention.rb +++ b/db/migrate/20211114145024_create_tips_intervention.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class CreateTipsIntervention < ActiveRecord::Migration[6.1] + class Intervention < ApplicationRecord + end + def change Intervention.find_or_create_by(name: 'TipsIntervention') end diff --git a/db/migrate/20220415215112_migrate_testruns.rb b/db/migrate/20220415215112_migrate_testruns.rb index 050d628b..218f5526 100644 --- a/db/migrate/20220415215112_migrate_testruns.rb +++ b/db/migrate/20220415215112_migrate_testruns.rb @@ -1,6 +1,19 @@ # frozen_string_literal: true class MigrateTestruns < ActiveRecord::Migration[6.1] + class Testrun < ApplicationRecord + belongs_to :submission, optional: true + has_many :testrun_messages + end + + class Submission < ApplicationRecord + has_many :testruns + end + + class TestrunMessage < ApplicationRecord + belongs_to :testrun + end + # We are not changing any tables but only backfilling data. disable_ddl_transaction! diff --git a/db/migrate/20220906142550_migrate_permissions_to_study_group.rb b/db/migrate/20220906142550_migrate_permissions_to_study_group.rb index f35d13df..aed1846a 100644 --- a/db/migrate/20220906142550_migrate_permissions_to_study_group.rb +++ b/db/migrate/20220906142550_migrate_permissions_to_study_group.rb @@ -1,6 +1,32 @@ # frozen_string_literal: true class MigratePermissionsToStudyGroup < ActiveRecord::Migration[6.1] + class Consumer < ApplicationRecord + has_many :study_groups + has_many :internal_users + has_many :external_users + end + + class StudyGroup < ApplicationRecord + belongs_to :consumer + has_many :study_group_memberships + end + + class InternalUser < ApplicationRecord + belongs_to :consumer + has_many :study_group_memberships, as: :user + end + + class ExternalUser < ApplicationRecord + belongs_to :consumer + has_many :study_group_memberships, as: :user + end + + class StudyGroupMembership < ApplicationRecord + belongs_to :study_group + belongs_to :user, polymorphic: true + end + # rubocop:disable Rails/SkipsModelValidations def up create_default_groups diff --git a/db/migrate/20230206203117_migrate_filetype_extensions_not_nil.rb b/db/migrate/20230206203117_migrate_filetype_extensions_not_nil.rb index 485d5542..b326de4f 100644 --- a/db/migrate/20230206203117_migrate_filetype_extensions_not_nil.rb +++ b/db/migrate/20230206203117_migrate_filetype_extensions_not_nil.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class MigrateFiletypeExtensionsNotNil < ActiveRecord::Migration[7.0] + class FileType < ApplicationRecord + end + def change FileType.all.find_all {|file_type| file_type.file_extension.nil? }.each do |file_type| file_type.update file_extension: '' diff --git a/db/migrate/20230819084917_unify_lti_parameters.rb b/db/migrate/20230819084917_unify_lti_parameters.rb index ce8ec6b1..5def508b 100644 --- a/db/migrate/20230819084917_unify_lti_parameters.rb +++ b/db/migrate/20230819084917_unify_lti_parameters.rb @@ -1,6 +1,19 @@ # frozen_string_literal: true class UnifyLtiParameters < ActiveRecord::Migration[7.0] + class LtiParameter < ApplicationRecord + belongs_to :external_user + belongs_to :exercise + end + + class ExternalUser < ApplicationRecord + has_many :lti_parameters + end + + class Exercise < ApplicationRecord + has_many :lti_parameters + end + def change reversible do |dir| dir.up do @@ -35,10 +48,4 @@ class UnifyLtiParameters < ActiveRecord::Migration[7.0] add_index :lti_parameters, %i[external_user_id study_group_id exercise_id], unique: true, name: 'index_lti_params_on_external_user_and_study_group_and_exercise' end - - class LtiParameter < ActiveRecord::Base; end - - class ExternalUser < ActiveRecord::Base; end - - class Exercise < ActiveRecord::Base; end end diff --git a/db/migrate/20230821062901_add_foreign_keys_to_anomaly_notifications.rb b/db/migrate/20230821062901_add_foreign_keys_to_anomaly_notifications.rb index b81f8824..eb8eef8c 100644 --- a/db/migrate/20230821062901_add_foreign_keys_to_anomaly_notifications.rb +++ b/db/migrate/20230821062901_add_foreign_keys_to_anomaly_notifications.rb @@ -1,6 +1,14 @@ # frozen_string_literal: true class AddForeignKeysToAnomalyNotifications < ActiveRecord::Migration[7.0] + class AnomalyNotification < ApplicationRecord + belongs_to :exercise + end + + class Exercise < ApplicationRecord + has_many :anomaly_notifications + end + def change up_only do # We cannot add a foreign key to a table that has rows that violate the constraint. @@ -16,8 +24,4 @@ class AddForeignKeysToAnomalyNotifications < ActiveRecord::Migration[7.0] change_column_null :anomaly_notifications, :exercise_collection_id, false add_foreign_key :anomaly_notifications, :exercise_collections end - - class AnomalyNotification < ActiveRecord::Base; end - class Exercise < ActiveRecord::Base; end - class ExerciseCollection < ActiveRecord::Base; end end diff --git a/db/migrate/20230821063101_convert_reason_to_json_in_anomaly_notifications.rb b/db/migrate/20230821063101_convert_reason_to_json_in_anomaly_notifications.rb index 7718ef82..85e6e2cd 100644 --- a/db/migrate/20230821063101_convert_reason_to_json_in_anomaly_notifications.rb +++ b/db/migrate/20230821063101_convert_reason_to_json_in_anomaly_notifications.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class ConvertReasonToJsonInAnomalyNotifications < ActiveRecord::Migration[7.0] + class AnomalyNotification < ApplicationRecord + end + def up AnomalyNotification.where("reason LIKE '%value:%'").find_each do |anomaly_notification| reason = anomaly_notification.reason @@ -14,6 +17,4 @@ class ConvertReasonToJsonInAnomalyNotifications < ActiveRecord::Migration[7.0] def down change_column :anomaly_notifications, :reason, :string end - - class AnomalyNotification < ActiveRecord::Base; end end