Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2019-06-17 19:24:10 +0300
committerRobert Speicher <rspeicher@gmail.com>2019-06-17 19:24:10 +0300
commit0ca3c672c739b118258cd12d3f5de954bded6895 (patch)
tree0da6f44a940aea75fd2f4b45acf3fd523016f6b8 /db
parent982d62a0452b2e806e363aa7be1f1a169227fc7f (diff)
parentd5baece038d043881279ef1182cc977ddec60294 (diff)
Merge branch 'backport-schema-changes' into 'master'
Backport the EE schema to CE Closes gitlab-ee#9686 See merge request gitlab-org/gitlab-ce!26940
Diffstat (limited to 'db')
-rw-r--r--db/migrate/20161007073613_create_user_activities.rb25
-rw-r--r--db/migrate/20161117114805_remove_undeleted_groups.rb105
-rw-r--r--db/migrate/20171121135738_clean_up_from_merge_request_diffs_and_commits.rb36
-rw-r--r--db/migrate/20171216111734_clean_up_for_members.rb31
-rw-r--r--db/migrate/20180502122856_create_project_mirror_data.rb24
-rw-r--r--db/migrate/20180503131624_create_remote_mirrors.rb2
-rw-r--r--db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb2
-rw-r--r--db/migrate/20180503193542_add_indexes_to_remote_mirror.rb1
-rw-r--r--db/migrate/20180503193953_add_mirror_available_to_application_settings.rb2
-rw-r--r--db/migrate/20190402150158_backport_enterprise_schema.rb2144
-rw-r--r--db/migrate/20190403161806_update_designs_index.rb21
-rw-r--r--db/migrate/20190409224933_add_name_to_geo_nodes.rb26
-rw-r--r--db/migrate/20190410173409_add_name_index_to_geo_nodes.rb21
-rw-r--r--db/migrate/20190412183653_remove_url_index_from_geo_nodes.rb21
-rw-r--r--db/migrate/20190414185432_add_comment_to_vulnerability_feedback.rb17
-rw-r--r--db/migrate/20190415172035_update_insights_foreign_keys.rb25
-rw-r--r--db/migrate/20190418132750_add_foreign_key_from_vulnerability_feedback_to_users.rb19
-rw-r--r--db/migrate/20190419121952_add_bridged_pipeline_id_to_bridges.rb15
-rw-r--r--db/migrate/20190419123057_add_bridged_pipeline_id_foreign_key.rb23
-rw-r--r--db/migrate/20190423124640_add_index_to_projects_mirror_user_id.rb17
-rw-r--r--db/migrate/20190520200123_add_rule_type_to_approval_merge_request_approval_rules.rb21
-rw-r--r--db/migrate/20190528173628_add_index_for_code_owner_rule_type_on_approval_merge_request_rules.rb55
-rw-r--r--db/migrate/20190603124955_add_index_to_count_pending_mirror_updates.rb17
-rw-r--r--db/post_migrate/20161128170531_drop_user_activities_table.rb28
-rw-r--r--db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb47
-rw-r--r--db/post_migrate/20170703130158_schedule_merge_request_diff_migrations.rb33
-rw-r--r--db/post_migrate/20170926150348_schedule_merge_request_diff_migrations_take_two.rb32
-rw-r--r--db/post_migrate/20171005130944_schedule_create_gpg_key_subkeys_from_gpg_keys.rb28
-rw-r--r--db/post_migrate/20171128214150_schedule_populate_merge_request_metrics_with_events_data.rb37
-rw-r--r--db/post_migrate/20171207150343_remove_soft_removed_objects.rb208
-rw-r--r--db/post_migrate/20180502134117_migrate_import_attributes_data_from_projects_to_project_mirror_data.rb37
-rw-r--r--db/post_migrate/20180521162137_migrate_remaining_mr_metrics_populating_background_migration.rb44
-rw-r--r--db/post_migrate/20180619121030_enqueue_delete_diff_files_workers.rb26
-rw-r--r--db/post_migrate/20180723130817_delete_inconsistent_internal_id_records.rb47
-rw-r--r--db/post_migrate/20180906051323_remove_orphaned_label_links.rb43
-rw-r--r--db/post_migrate/20180913051323_consume_remaining_diff_files_deletion_jobs.rb23
-rw-r--r--db/post_migrate/20180916014356_populate_external_pipeline_source.rb33
-rw-r--r--db/post_migrate/20181014121030_enqueue_redact_links.rb65
-rw-r--r--db/post_migrate/20181204154019_populate_mr_metrics_with_events_data.rb38
-rw-r--r--db/post_migrate/20190402224749_schedule_merge_request_assignees_migration_progress_check.rb18
-rw-r--r--db/post_migrate/20190404143330_add_unique_constraint_to_approvals_user_id_and_merge_request_id.rb55
-rw-r--r--db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb21
-rw-r--r--db/post_migrate/20190418132125_populate_project_statistics_packages_size.rb46
-rw-r--r--db/post_migrate/20190511144331_remove_users_support_type.rb27
-rw-r--r--db/post_migrate/20190520201748_populate_rule_type_on_approval_merge_request_rules.rb34
-rw-r--r--db/schema.rb1200
46 files changed, 3907 insertions, 933 deletions
diff --git a/db/migrate/20161007073613_create_user_activities.rb b/db/migrate/20161007073613_create_user_activities.rb
index be3ecb17eef..dc972bf4664 100644
--- a/db/migrate/20161007073613_create_user_activities.rb
+++ b/db/migrate/20161007073613_create_user_activities.rb
@@ -1,7 +1,28 @@
+
class CreateUserActivities < ActiveRecord::Migration[4.2]
- DOWNTIME = false
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = true
+
+ # When a migration requires downtime you **must** uncomment the following
+ # constant and define a short and easy to understand explanation as to why the
+ # migration requires downtime.
+ DOWNTIME_REASON = 'Adding foreign key'.freeze
+
+ # When using the methods "add_concurrent_index" or "add_column_with_default"
+ # you must disable the use of transactions as these methods can not run in an
+ # existing transaction. When using "add_concurrent_index" make sure that this
+ # method is the _only_ method called in the migration, any other changes
+ # should go in a separate migration. This ensures that upon failure _only_ the
+ # index creation fails and can be retried or reverted easily.
+ #
+ # To disable transactions uncomment the following line and remove these
+ # comments:
+ # disable_ddl_transaction!
- # This migration is a no-op. It just exists to match EE.
def change
+ create_table :user_activities do |t|
+ t.belongs_to :user, index: { unique: true }, foreign_key: { on_delete: :cascade }
+ t.datetime :last_activity_at, null: false
+ end
end
end
diff --git a/db/migrate/20161117114805_remove_undeleted_groups.rb b/db/migrate/20161117114805_remove_undeleted_groups.rb
deleted file mode 100644
index 0a4fe1c05b7..00000000000
--- a/db/migrate/20161117114805_remove_undeleted_groups.rb
+++ /dev/null
@@ -1,105 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RemoveUndeletedGroups < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def up
- is_ee = defined?(Gitlab::License)
-
- if is_ee
- execute <<-EOF.strip_heredoc
- DELETE FROM path_locks
- WHERE project_id IN (
- SELECT project_id
- FROM projects
- WHERE namespace_id IN (#{namespaces_pending_removal})
- );
- EOF
-
- execute <<-EOF.strip_heredoc
- DELETE FROM remote_mirrors
- WHERE project_id IN (
- SELECT project_id
- FROM projects
- WHERE namespace_id IN (#{namespaces_pending_removal})
- );
- EOF
- end
-
- execute <<-EOF.strip_heredoc
- DELETE FROM lists
- WHERE label_id IN (
- SELECT id
- FROM labels
- WHERE group_id IN (#{namespaces_pending_removal})
- );
- EOF
-
- execute <<-EOF.strip_heredoc
- DELETE FROM lists
- WHERE board_id IN (
- SELECT id
- FROM boards
- WHERE project_id IN (
- SELECT project_id
- FROM projects
- WHERE namespace_id IN (#{namespaces_pending_removal})
- )
- );
- EOF
-
- execute <<-EOF.strip_heredoc
- DELETE FROM labels
- WHERE group_id IN (#{namespaces_pending_removal});
- EOF
-
- execute <<-EOF.strip_heredoc
- DELETE FROM boards
- WHERE project_id IN (
- SELECT project_id
- FROM projects
- WHERE namespace_id IN (#{namespaces_pending_removal})
- )
- EOF
-
- execute <<-EOF.strip_heredoc
- DELETE FROM projects
- WHERE namespace_id IN (#{namespaces_pending_removal});
- EOF
-
- if is_ee
- # EE adds these columns but we have to make sure this data is cleaned up
- # here before we run the DELETE below. An alternative would be patching
- # this migration in EE but this will only result in a mess and confusing
- # migrations.
- execute <<-EOF.strip_heredoc
- DELETE FROM protected_branch_push_access_levels
- WHERE group_id IN (#{namespaces_pending_removal});
- EOF
-
- execute <<-EOF.strip_heredoc
- DELETE FROM protected_branch_merge_access_levels
- WHERE group_id IN (#{namespaces_pending_removal});
- EOF
- end
-
- # This removes namespaces that were supposed to be deleted but still reside
- # in the database.
- execute "DELETE FROM namespaces WHERE deleted_at IS NOT NULL;"
- end
-
- def down
- # This is an irreversible migration;
- # If someone is trying to rollback for other reasons, we should not throw an Exception.
- # raise ActiveRecord::IrreversibleMigration
- end
-
- def namespaces_pending_removal
- "SELECT id FROM (
- SELECT id
- FROM namespaces
- WHERE deleted_at IS NOT NULL
- ) namespace_ids"
- end
-end
diff --git a/db/migrate/20171121135738_clean_up_from_merge_request_diffs_and_commits.rb b/db/migrate/20171121135738_clean_up_from_merge_request_diffs_and_commits.rb
deleted file mode 100644
index 6be7b75492d..00000000000
--- a/db/migrate/20171121135738_clean_up_from_merge_request_diffs_and_commits.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-class CleanUpFromMergeRequestDiffsAndCommits < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- class MergeRequestDiff < ActiveRecord::Base
- self.table_name = 'merge_request_diffs'
-
- include ::EachBatch
- end
-
- disable_ddl_transaction!
-
- def up
- Gitlab::BackgroundMigration.steal('DeserializeMergeRequestDiffsAndCommits')
-
- # The literal '--- []\n' value is created by the import process and treated
- # as null by the application, so we can ignore those - even if we were
- # migrating, it wouldn't create any rows.
- literal_prefix = Gitlab::Database.postgresql? ? 'E' : ''
- non_empty = "
- (st_commits IS NOT NULL AND st_commits != #{literal_prefix}'--- []\n')
- OR
- (st_diffs IS NOT NULL AND st_diffs != #{literal_prefix}'--- []\n')
- ".squish
-
- MergeRequestDiff.where(non_empty).each_batch(of: 500) do |relation, index|
- range = relation.pluck('MIN(id)', 'MAX(id)').first
-
- Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits.new.perform(*range)
- end
- end
-
- def down
- end
-end
diff --git a/db/migrate/20171216111734_clean_up_for_members.rb b/db/migrate/20171216111734_clean_up_for_members.rb
deleted file mode 100644
index 2fefc6c7fd1..00000000000
--- a/db/migrate/20171216111734_clean_up_for_members.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class CleanUpForMembers < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class Member < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'members'
- end
-
- def up
- condition = <<~EOF.squish
- invite_token IS NULL AND
- NOT EXISTS (SELECT 1 FROM users WHERE users.id = members.user_id)
- EOF
-
- Member.each_batch(of: 10_000) do |batch|
- batch.where(condition).delete_all
- end
- end
-
- def down
- end
-end
diff --git a/db/migrate/20180502122856_create_project_mirror_data.rb b/db/migrate/20180502122856_create_project_mirror_data.rb
index 8bc114afc0c..9781815a97b 100644
--- a/db/migrate/20180502122856_create_project_mirror_data.rb
+++ b/db/migrate/20180502122856_create_project_mirror_data.rb
@@ -4,17 +4,25 @@ class CreateProjectMirrorData < ActiveRecord::Migration[4.2]
DOWNTIME = false
def up
- return if table_exists?(:project_mirror_data)
-
- create_table :project_mirror_data do |t|
- t.references :project, index: true, foreign_key: { on_delete: :cascade }
- t.string :status
- t.string :jid
- t.text :last_error
+ if table_exists?(:project_mirror_data)
+ add_column :project_mirror_data, :status, :string unless column_exists?(:project_mirror_data, :status)
+ add_column :project_mirror_data, :jid, :string unless column_exists?(:project_mirror_data, :jid)
+ add_column :project_mirror_data, :last_error, :text unless column_exists?(:project_mirror_data, :last_error)
+ else
+ create_table :project_mirror_data do |t|
+ t.references :project, index: true, foreign_key: { on_delete: :cascade }
+ t.string :status
+ t.string :jid
+ t.text :last_error
+ end
end
end
def down
- drop_table(:project_mirror_data) if table_exists?(:project_mirror_data)
+ remove_column :project_mirror_data, :status
+ remove_column :project_mirror_data, :jid
+ remove_column :project_mirror_data, :last_error
+
+ # ee/db/migrate/20170509153720_create_project_mirror_data_ee.rb will remove the table.
end
end
diff --git a/db/migrate/20180503131624_create_remote_mirrors.rb b/db/migrate/20180503131624_create_remote_mirrors.rb
index 9f4bd463e66..288ae365f0f 100644
--- a/db/migrate/20180503131624_create_remote_mirrors.rb
+++ b/db/migrate/20180503131624_create_remote_mirrors.rb
@@ -29,6 +29,6 @@ class CreateRemoteMirrors < ActiveRecord::Migration[4.2]
end
def down
- drop_table(:remote_mirrors) if table_exists?(:remote_mirrors)
+ # ee/db/migrate/20160321161032_create_remote_mirrors_ee.rb will remove the table
end
end
diff --git a/db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb b/db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb
index 5e2ef5706ee..1d99d46b7d6 100644
--- a/db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb
+++ b/db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb
@@ -10,6 +10,6 @@ class AddRemoteMirrorAvailableOverriddenToProjects < ActiveRecord::Migration[4.2
end
def down
- remove_column(:projects, :remote_mirror_available_overridden) if column_exists?(:projects, :remote_mirror_available_overridden)
+ # ee/db/migrate/20171017130239_add_remote_mirror_available_overridden_to_projects_ee.rb will remove the column.
end
end
diff --git a/db/migrate/20180503193542_add_indexes_to_remote_mirror.rb b/db/migrate/20180503193542_add_indexes_to_remote_mirror.rb
index bdf05c4e69b..19bed8d0500 100644
--- a/db/migrate/20180503193542_add_indexes_to_remote_mirror.rb
+++ b/db/migrate/20180503193542_add_indexes_to_remote_mirror.rb
@@ -10,6 +10,7 @@ class AddIndexesToRemoteMirror < ActiveRecord::Migration[4.2]
end
def down
+ # ee/db/migrate/20170208144550_add_index_to_mirrors_last_update_at_fields.rb will remove the index.
# rubocop:disable Migration/RemoveIndex
remove_index :remote_mirrors, :last_successful_update_at if index_exists? :remote_mirrors, :last_successful_update_at
end
diff --git a/db/migrate/20180503193953_add_mirror_available_to_application_settings.rb b/db/migrate/20180503193953_add_mirror_available_to_application_settings.rb
index 64f65cd23be..d6a04035d48 100644
--- a/db/migrate/20180503193953_add_mirror_available_to_application_settings.rb
+++ b/db/migrate/20180503193953_add_mirror_available_to_application_settings.rb
@@ -10,6 +10,6 @@ class AddMirrorAvailableToApplicationSettings < ActiveRecord::Migration[4.2]
end
def down
- remove_column(:application_settings, :mirror_available) if column_exists?(:application_settings, :mirror_available)
+ # ee/db/migrate/20171017125928_add_remote_mirror_available_to_application_settings.rb will remove the column.
end
end
diff --git a/db/migrate/20190402150158_backport_enterprise_schema.rb b/db/migrate/20190402150158_backport_enterprise_schema.rb
new file mode 100644
index 00000000000..610a8808383
--- /dev/null
+++ b/db/migrate/20190402150158_backport_enterprise_schema.rb
@@ -0,0 +1,2144 @@
+# frozen_string_literal: true
+
+# rubocop: disable Metrics/AbcSize
+# rubocop: disable Migration/Datetime
+class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ APPLICATION_SETTINGS_COLUMNS = [
+ { type: :boolean, name: :elasticsearch_indexing, default: false, null: false },
+ { type: :boolean, name: :elasticsearch_search, default: false, null: false },
+ { type: :integer, name: :shared_runners_minutes, default: 0, null: false },
+ { type: :bigint, name: :repository_size_limit, default: 0, null: true },
+ { type: :string, name: :elasticsearch_url, default: "http://localhost:9200" },
+ { type: :boolean, name: :elasticsearch_aws, default: false, null: false },
+ { type: :string, name: :elasticsearch_aws_region, default: "us-east-1", null: true },
+ { type: :string, name: :elasticsearch_aws_access_key, default: nil, null: true },
+ { type: :string, name: :elasticsearch_aws_secret_access_key, default: nil, null: true },
+ { type: :integer, name: :geo_status_timeout, default: 10, null: true },
+ { type: :boolean, name: :elasticsearch_experimental_indexer, default: nil, null: true },
+ { type: :boolean, name: :check_namespace_plan, default: false, null: false },
+ { type: :integer, name: :mirror_max_delay, default: 300, null: false },
+ { type: :integer, name: :mirror_max_capacity, default: 100, null: false },
+ { type: :integer, name: :mirror_capacity_threshold, default: 50, null: false },
+ { type: :boolean, name: :slack_app_enabled, default: false },
+ { type: :string, name: :slack_app_id },
+ { type: :string, name: :slack_app_secret },
+ { type: :string, name: :slack_app_verification_token },
+ { type: :boolean, name: :allow_group_owners_to_manage_ldap, default: true, null: false },
+ { type: :integer, name: :default_project_creation, default: 2, null: false },
+ { type: :string, name: :email_additional_text },
+ { type: :integer, name: :file_template_project_id },
+ { type: :boolean, name: :pseudonymizer_enabled, default: false, null: false },
+ { type: :boolean, name: :snowplow_enabled, default: false, null: false },
+ { type: :string, name: :snowplow_collector_uri },
+ { type: :string, name: :snowplow_site_id },
+ { type: :string, name: :snowplow_cookie_domain },
+ { type: :integer, name: :custom_project_templates_group_id },
+ { type: :boolean, name: :elasticsearch_limit_indexing, default: false, null: false },
+ { type: :string, name: :geo_node_allowed_ips, default: '0.0.0.0/0, ::/0' }
+ ].freeze
+
+ NAMESPACE_COLUMNS = [
+ { type: :integer, name: :custom_project_templates_group_id },
+ { type: :integer, name: :file_template_project_id },
+ { type: :string, name: :ldap_sync_error },
+ { type: :datetime, name: :ldap_sync_last_successful_update_at },
+ { type: :datetime, name: :ldap_sync_last_sync_at },
+ { type: :datetime, name: :ldap_sync_last_update_at },
+ { type: :integer, name: :plan_id },
+ { type: :integer, name: :project_creation_level },
+ { type: :bigint, name: :repository_size_limit },
+ { type: :string, name: :saml_discovery_token },
+ { type: :integer, name: :shared_runners_minutes_limit },
+ { type: :datetime_with_timezone, name: :trial_ends_on },
+ { type: :integer, name: :extra_shared_runners_minutes_limit }
+ ].freeze
+
+ PROJECT_MIRROR_DATA_COLUMNS = [
+ { type: :datetime_with_timezone, name: :last_successful_update_at },
+ { type: :datetime_with_timezone, name: :last_update_at },
+ { type: :datetime, name: :last_update_scheduled_at },
+ { type: :datetime, name: :last_update_started_at },
+ { type: :datetime, name: :next_execution_timestamp }
+ ].freeze
+
+ PROJECTS_COLUMNS = [
+ { type: :boolean, name: :disable_overriding_approvers_per_merge_request },
+ { type: :string, name: :external_webhook_token },
+ { type: :text, name: :issues_template },
+ { type: :boolean, name: :merge_requests_author_approval },
+ { type: :boolean, name: :merge_requests_disable_committers_approval },
+ { type: :boolean, name: :merge_requests_require_code_owner_approval },
+ { type: :text, name: :merge_requests_template },
+ { type: :datetime, name: :mirror_last_successful_update_at },
+ { type: :datetime, name: :mirror_last_update_at },
+ { type: :boolean, name: :mirror_overwrites_diverged_branches },
+ { type: :integer, name: :mirror_user_id },
+ { type: :boolean, name: :only_mirror_protected_branches },
+ { type: :boolean, name: :packages_enabled },
+ { type: :boolean, name: :pull_mirror_available_overridden },
+ { type: :bigint, name: :repository_size_limit },
+ { type: :boolean, name: :require_password_to_approve }
+ ].freeze
+
+ USERS_COLUMNS = [
+ { type: :datetime, name: :admin_email_unsubscribed_at },
+ { type: :boolean, name: :email_opted_in },
+ { type: :datetime, name: :email_opted_in_at },
+ { type: :string, name: :email_opted_in_ip },
+ { type: :integer, name: :email_opted_in_source_id },
+ { type: :integer, name: :group_view },
+ { type: :integer, name: :managing_group_id },
+ { type: :text, name: :note },
+ { type: :integer, name: :roadmap_layout, limit: 2 },
+ { type: :boolean, name: :support_bot },
+ { type: :integer, name: :bot_type, limit: 2 }
+ ].freeze
+
+ class ApplicationSetting < ActiveRecord::Base
+ self.table_name = 'application_settings'
+ end
+
+ class ProtectedBranchMergeAccessLevels < ActiveRecord::Base
+ self.table_name = 'protected_branch_merge_access_levels'
+ end
+
+ class ProtectedBranchPushAccessLevels < ActiveRecord::Base
+ self.table_name = 'protected_branch_push_access_levels'
+ end
+
+ class Project < ActiveRecord::Base
+ self.table_name = 'projects'
+ end
+
+ def up
+ create_missing_tables
+
+ update_appearances
+ update_application_settings
+ update_boards_table
+ update_clusters_applications_prometheus
+ update_identities
+ update_issues
+ update_lists
+ update_members
+ update_merge_requests
+ update_notes
+ update_ci_builds
+ update_environments
+ update_namespaces
+ update_notification_settings
+ update_project_mirror_data
+ update_project_statistics
+ update_projects
+ update_protected_branch_merge_access_levels
+ update_protected_branch_push_access_levels
+ update_resource_label_events
+ update_user_preferences
+ update_users
+ update_web_hooks
+ update_geo_nodes
+
+ add_missing_foreign_keys
+ end
+
+ def down
+ # This migration can not be reverted in a production environment, as doing
+ # so would lead to data loss for existing EE installations.
+ return if !Rails.env.test? && !Rails.env.development?
+
+ remove_foreign_keys
+ remove_tables
+
+ revert_appearances
+ revert_application_settings
+ revert_boards_table
+ revert_clusters_applications_prometheus
+ revert_identities
+ revert_issues
+ revert_lists
+ revert_members
+ revert_merge_requests
+ revert_notes
+ revert_ci_builds
+ revert_environments
+ revert_namespaces
+ revert_notification_settings
+ revert_project_mirror_data
+ revert_project_statistics
+ revert_projects
+ revert_protected_branch_merge_access_levels
+ revert_protected_branch_push_access_levels
+ revert_resource_label_events
+ revert_user_preferences
+ revert_users
+ revert_web_hooks
+ end
+
+ def add_column_if_not_exists(table, name, *args)
+ add_column(table, name, *args) unless column_exists?(table, name)
+ end
+
+ def remove_column_if_exists(table, column)
+ remove_column(table, column) if column_exists?(table, column)
+ end
+
+ def drop_table_if_exists(table)
+ drop_table(table) if table_exists?(table)
+ end
+
+ def add_column_with_default_if_not_exists(table, name, *args)
+ unless column_exists?(table, name)
+ add_column_with_default(table, name, *args)
+ end
+ end
+
+ def add_missing_columns(table, columns)
+ columns.each do |column|
+ next if table.column_exists?(column[:name])
+
+ # We can't use (public_)send here as this doesn't work with
+ # `datetime_with_timezone` for some reason.
+ table.column(
+ column[:name],
+ column[:type],
+ default: column[:default],
+ null: column.fetch(:null, true),
+ limit: column[:limit]
+ )
+ end
+ end
+
+ def remove_columns(table, columns)
+ columns.each do |column|
+ remove_column_if_exists(table, column[:name])
+ end
+ end
+
+ def create_table_if_not_exists(name, *args, &block)
+ return if table_exists?(name)
+
+ create_table(name, *args, &block)
+ end
+
+ def add_concurrent_foreign_key(source, target, column:, on_delete: nil, name: nil)
+ # We don't want redundant VALIDATE CONSTRAINT statements to run for existing
+ # foreign keys, as this can take a long time on large installations such as
+ # GitLab.com.
+ return if foreign_key_exists?(source, target, column: column)
+
+ super
+ end
+
+ def update_appearances
+ add_column_if_not_exists(:appearances, :updated_by, :integer)
+ end
+
+ def revert_appearances
+ remove_column_if_exists(:namespaces, :updated_by)
+ end
+
+ def update_application_settings
+ # In the CE schema this column allows NULL values even though there is a
+ # default value. In EE this column is not allowed to be NULL. This means
+ # that if we want to add a NOT NULL clause below, we must ensure no existing
+ # data would violate this clause.
+ ApplicationSetting
+ .where(password_authentication_enabled_for_git: nil)
+ .update_all(password_authentication_enabled_for_git: true)
+
+ change_column_null(
+ :application_settings,
+ :password_authentication_enabled_for_git,
+ false
+ )
+
+ # This table will only have a single row, and all operations here will be
+ # very fast. As such we merge all of this into a single ALTER TABLE
+ # statement.
+ change_table(:application_settings) do |t|
+ t.text(:help_text) unless t.column_exists?(:help_text)
+
+ add_missing_columns(t, APPLICATION_SETTINGS_COLUMNS)
+ end
+
+ add_concurrent_index(
+ :application_settings,
+ :custom_project_templates_group_id
+ )
+
+ add_concurrent_index(
+ :application_settings,
+ :file_template_project_id
+ )
+ end
+
+ def revert_application_settings
+ change_column_null(
+ :application_settings,
+ :password_authentication_enabled_for_git,
+ true
+ )
+
+ remove_concurrent_index(
+ :application_settings,
+ :custom_project_templates_group_id
+ )
+
+ remove_concurrent_index(
+ :application_settings,
+ :file_template_project_id
+ )
+
+ remove_columns(:application_settings, APPLICATION_SETTINGS_COLUMNS)
+ end
+
+ def update_boards_table
+ add_column_if_not_exists(:boards, :milestone_id, :integer)
+ add_column_if_not_exists(:boards, :weight, :integer)
+
+ add_column_with_default_if_not_exists(
+ :boards,
+ :name,
+ :string,
+ default: 'Development'
+ )
+
+ add_concurrent_index(:boards, :milestone_id)
+ end
+
+ def revert_boards_table
+ remove_concurrent_index(:boards, :milestone_id)
+ remove_column_if_exists(:boards, :name)
+ remove_column_if_exists(:boards, :weight)
+ remove_column_if_exists(:boards, :milestone_id)
+ end
+
+ def update_clusters_applications_prometheus
+ add_column_if_not_exists(
+ :clusters_applications_prometheus,
+ :encrypted_alert_manager_token,
+ :string
+ )
+
+ add_column_if_not_exists(
+ :clusters_applications_prometheus,
+ :encrypted_alert_manager_token_iv,
+ :string
+ )
+
+ add_column_if_not_exists(
+ :clusters_applications_prometheus,
+ :last_update_started_at,
+ :datetime_with_timezone
+ )
+ end
+
+ def revert_clusters_applications_prometheus
+ remove_column_if_exists(
+ :clusters_applications_prometheus,
+ :encrypted_alert_manager_token
+ )
+
+ remove_column_if_exists(
+ :clusters_applications_prometheus,
+ :encrypted_alert_manager_token_iv
+ )
+
+ remove_column_if_exists(
+ :clusters_applications_prometheus,
+ :last_update_started_at
+ )
+ end
+
+ def update_identities
+ add_column_if_not_exists(:identities, :saml_provider_id, :integer)
+ add_column_if_not_exists(:identities, :secondary_extern_uid, :string)
+
+ add_concurrent_index(
+ :identities,
+ :saml_provider_id,
+ where: 'saml_provider_id IS NOT NULL'
+ )
+ end
+
+ def revert_identities
+ remove_column_if_exists(:identities, :saml_provider_id)
+ remove_column_if_exists(:identities, :secondary_extern_uid)
+ end
+
+ def update_issues
+ add_column_if_not_exists(:issues, :service_desk_reply_to, :string)
+ add_column_if_not_exists(:issues, :weight, :integer)
+ end
+
+ def revert_issues
+ remove_column_if_exists(:issues, :service_desk_reply_to)
+ remove_column_if_exists(:issues, :weight)
+ end
+
+ def update_lists
+ add_column_if_not_exists(:lists, :milestone_id, :integer)
+ add_column_if_not_exists(:lists, :user_id, :integer)
+
+ add_concurrent_index(:lists, :milestone_id)
+ add_concurrent_index(:lists, :user_id)
+ end
+
+ def revert_lists
+ remove_column_if_exists(:lists, :milestone_id)
+ remove_column_if_exists(:lists, :user_id)
+ end
+
+ def update_members
+ add_column_with_default_if_not_exists(
+ :members,
+ :ldap,
+ :boolean,
+ default: false
+ )
+
+ add_column_with_default_if_not_exists(
+ :members,
+ :override,
+ :boolean,
+ default: false
+ )
+ end
+
+ def revert_members
+ remove_column_if_exists(:members, :ldap)
+ remove_column_if_exists(:members, :override)
+ end
+
+ def update_merge_requests
+ add_column_if_not_exists(:merge_requests, :approvals_before_merge, :integer)
+ end
+
+ def revert_merge_requests
+ remove_column_if_exists(:merge_requests, :approvals_before_merge)
+ end
+
+ def update_notes
+ add_column_if_not_exists(:notes, :review_id, :bigint)
+ add_concurrent_index(:notes, :review_id)
+ end
+
+ def revert_notes
+ remove_column_if_exists(:notes, :review_id)
+ end
+
+ def update_ci_builds
+ add_concurrent_index(
+ :ci_builds,
+ [:name],
+ name: 'index_ci_builds_on_name_for_security_products_values',
+ where: "
+ (
+ (name)::text = ANY (
+ ARRAY[
+ ('container_scanning'::character varying)::text,
+ ('dast'::character varying)::text,
+ ('dependency_scanning'::character varying)::text,
+ ('license_management'::character varying)::text,
+ ('sast'::character varying)::text
+ ]
+ )
+ )"
+ )
+ end
+
+ def revert_ci_builds
+ remove_concurrent_index_by_name(
+ :ci_builds,
+ 'index_ci_builds_on_name_for_security_products_values'
+ )
+ end
+
+ def update_environments
+ return unless Gitlab::Database.postgresql?
+ return if index_exists?(:environments, :name, name: 'index_environments_on_name_varchar_pattern_ops')
+
+ execute('CREATE INDEX CONCURRENTLY index_environments_on_name_varchar_pattern_ops ON environments (name varchar_pattern_ops);')
+ end
+
+ def revert_environments
+ return unless Gitlab::Database.postgresql?
+
+ remove_concurrent_index_by_name(
+ :environments,
+ 'index_environments_on_name_varchar_pattern_ops'
+ )
+ end
+
+ def update_namespaces
+ change_table(:namespaces) do |t|
+ add_missing_columns(t, NAMESPACE_COLUMNS)
+ end
+
+ add_column_with_default_if_not_exists(
+ :namespaces,
+ :ldap_sync_status,
+ :string,
+ default: 'ready'
+ )
+
+ add_column_with_default_if_not_exists(
+ :namespaces,
+ :membership_lock,
+ :boolean,
+ default: false,
+ allow_null: true
+ )
+
+ # When `add_concurrent_index` runs, it for some reason incorrectly
+ # determines this index does not exist when it does. To work around this, we
+ # check the existence by name ourselves.
+ unless index_exists_by_name?(:namespaces, 'index_namespaces_on_custom_project_templates_group_id_and_type')
+ add_concurrent_index(
+ :namespaces,
+ %i[custom_project_templates_group_id type],
+ where: "(custom_project_templates_group_id IS NOT NULL)"
+ )
+ end
+
+ add_concurrent_index(:namespaces, :file_template_project_id)
+ add_concurrent_index(:namespaces, :ldap_sync_last_successful_update_at)
+ add_concurrent_index(:namespaces, :ldap_sync_last_update_at)
+ add_concurrent_index(:namespaces, :plan_id)
+ add_concurrent_index(
+ :namespaces,
+ :trial_ends_on,
+ where: "(trial_ends_on IS NOT NULL)"
+ )
+
+ unless index_exists_by_name?(:namespaces, 'index_namespaces_on_shared_and_extra_runners_minutes_limit')
+ add_concurrent_index(
+ :namespaces,
+ %i[shared_runners_minutes_limit extra_shared_runners_minutes_limit],
+ name: 'index_namespaces_on_shared_and_extra_runners_minutes_limit'
+ )
+ end
+ end
+
+ def revert_namespaces
+ remove_columns(:namespaces, NAMESPACE_COLUMNS)
+ remove_column_if_exists(:namespaces, :ldap_sync_status)
+ remove_column_if_exists(:namespaces, :membership_lock)
+
+ remove_concurrent_index_by_name(
+ :namespaces,
+ 'index_namespaces_on_shared_and_extra_runners_minutes_limit'
+ )
+ end
+
+ def update_notification_settings
+ add_column_if_not_exists(:notification_settings, :new_epic, :boolean)
+ end
+
+ def revert_notification_settings
+ remove_column_if_exists(:notification_settings, :new_epic)
+ end
+
+ def update_project_mirror_data
+ change_table(:project_mirror_data) do |t|
+ add_missing_columns(t, PROJECT_MIRROR_DATA_COLUMNS)
+ end
+
+ add_column_with_default_if_not_exists(
+ :project_mirror_data,
+ :retry_count,
+ :integer,
+ default: 0
+ )
+
+ add_concurrent_index(:project_mirror_data, :last_successful_update_at)
+
+ add_concurrent_index(
+ :project_mirror_data,
+ %i[next_execution_timestamp retry_count],
+ name: 'index_mirror_data_on_next_execution_and_retry_count'
+ )
+ end
+
+ def revert_project_mirror_data
+ remove_columns(:project_mirror_data, PROJECT_MIRROR_DATA_COLUMNS)
+
+ remove_concurrent_index_by_name(
+ :project_mirror_data,
+ 'index_mirror_data_on_next_execution_and_retry_count'
+ )
+
+ remove_column_if_exists(:project_statistics, :retry_count)
+ end
+
+ def update_project_statistics
+ add_column_with_default_if_not_exists(
+ :project_statistics,
+ :shared_runners_seconds,
+ :bigint,
+ default: 0
+ )
+
+ add_column_if_not_exists(
+ :project_statistics,
+ :shared_runners_seconds_last_reset,
+ :datetime
+ )
+ end
+
+ def revert_project_statistics
+ remove_column_if_exists(:project_statistics, :shared_runners_seconds)
+
+ remove_column_if_exists(
+ :project_statistics,
+ :shared_runners_seconds_last_reset
+ )
+ end
+
+ def update_projects
+ change_table(:projects) do |t|
+ add_missing_columns(t, PROJECTS_COLUMNS)
+ end
+
+ change_column_null(:projects, :merge_requests_rebase_enabled, true)
+
+ add_column_with_default_if_not_exists(
+ :projects,
+ :mirror,
+ :boolean,
+ default: false
+ )
+
+ add_column_with_default_if_not_exists(
+ :projects,
+ :mirror_trigger_builds,
+ :boolean,
+ default: false
+ )
+
+ add_column_with_default_if_not_exists(
+ :projects,
+ :reset_approvals_on_push,
+ :boolean,
+ default: true,
+ allow_null: true
+ )
+
+ add_column_with_default_if_not_exists(
+ :projects,
+ :service_desk_enabled,
+ :boolean,
+ default: true,
+ allow_null: true
+ )
+
+ add_column_with_default_if_not_exists(
+ :projects,
+ :approvals_before_merge,
+ :integer,
+ default: 0
+ )
+
+ add_concurrent_index(
+ :projects,
+ %i[archived pending_delete merge_requests_require_code_owner_approval],
+ name: 'projects_requiring_code_owner_approval',
+ where: '((pending_delete = false) AND (archived = false) AND (merge_requests_require_code_owner_approval = true))'
+ )
+
+ add_concurrent_index(
+ :projects,
+ %i[id repository_storage last_repository_updated_at],
+ name: 'idx_projects_on_repository_storage_last_repository_updated_at'
+ )
+
+ add_concurrent_index(
+ :projects,
+ :id,
+ name: 'index_projects_on_mirror_and_mirror_trigger_builds_both_true',
+ where: '((mirror IS TRUE) AND (mirror_trigger_builds IS TRUE))'
+ )
+
+ add_concurrent_index(:projects, :mirror_last_successful_update_at)
+ end
+
+ def revert_projects
+ remove_columns(:projects, PROJECTS_COLUMNS)
+
+ Project
+ .where(merge_requests_rebase_enabled: nil)
+ .update_all(merge_requests_rebase_enabled: false)
+
+ change_column_null(:projects, :merge_requests_rebase_enabled, false)
+
+ remove_column_if_exists(:projects, :mirror)
+ remove_column_if_exists(:projects, :mirror_trigger_builds)
+ remove_column_if_exists(:projects, :reset_approvals_on_push)
+ remove_column_if_exists(:projects, :service_desk_enabled)
+ remove_column_if_exists(:projects, :approvals_before_merge)
+
+ remove_concurrent_index_by_name(
+ :projects,
+ 'projects_requiring_code_owner_approval'
+ )
+
+ remove_concurrent_index_by_name(
+ :projects,
+ 'idx_projects_on_repository_storage_last_repository_updated_at'
+ )
+
+ remove_concurrent_index_by_name(
+ :projects,
+ 'index_projects_on_mirror_and_mirror_trigger_builds_both_true'
+ )
+ end
+
+ def update_protected_branch_merge_access_levels
+ change_column_null(:protected_branch_merge_access_levels, :access_level, true)
+
+ add_column_if_not_exists(
+ :protected_branch_merge_access_levels,
+ :group_id,
+ :integer
+ )
+
+ add_column_if_not_exists(
+ :protected_branch_merge_access_levels,
+ :user_id,
+ :integer
+ )
+
+ add_concurrent_index(:protected_branch_merge_access_levels, :group_id)
+ add_concurrent_index(:protected_branch_merge_access_levels, :user_id)
+ end
+
+ def revert_protected_branch_merge_access_levels
+ ProtectedBranchMergeAccessLevels
+ .where(access_level: nil)
+ .update_all(access_level: false)
+
+ change_column_null(
+ :protected_branch_merge_access_levels,
+ :access_level,
+ false
+ )
+
+ remove_column_if_exists(:protected_branch_merge_access_levels, :group_id)
+ remove_column_if_exists(:protected_branch_merge_access_levels, :user_id)
+ end
+
+ def update_protected_branch_push_access_levels
+ change_column_null(
+ :protected_branch_push_access_levels,
+ :access_level,
+ true
+ )
+
+ add_column_if_not_exists(
+ :protected_branch_push_access_levels,
+ :group_id,
+ :integer
+ )
+
+ add_column_if_not_exists(
+ :protected_branch_push_access_levels,
+ :user_id,
+ :integer
+ )
+
+ add_concurrent_index(:protected_branch_push_access_levels, :group_id)
+ add_concurrent_index(:protected_branch_push_access_levels, :user_id)
+ end
+
+ def revert_protected_branch_push_access_levels
+ ProtectedBranchPushAccessLevels
+ .where(access_level: nil)
+ .update_all(access_level: false)
+
+ change_column_null(
+ :protected_branch_push_access_levels,
+ :access_level,
+ false
+ )
+
+ remove_column_if_exists(:protected_branch_push_access_levels, :group_id)
+ remove_column_if_exists(:protected_branch_push_access_levels, :user_id)
+ end
+
+ def update_resource_label_events
+ add_column_if_not_exists(:resource_label_events, :epic_id, :integer)
+ add_concurrent_index(:resource_label_events, :epic_id)
+ end
+
+ def revert_resource_label_events
+ remove_column_if_exists(:resource_label_events, :epic_id)
+ end
+
+ def update_user_preferences
+ add_column_with_default_if_not_exists(
+ :user_preferences,
+ :epic_notes_filter,
+ :integer,
+ default: 0,
+ limit: 2
+ )
+
+ add_column_if_not_exists(:user_preferences, :epics_sort, :string)
+ add_column_if_not_exists(:user_preferences, :roadmap_epics_state, :integer)
+ add_column_if_not_exists(:user_preferences, :roadmaps_sort, :string)
+ end
+
+ def revert_user_preferences
+ remove_column_if_exists(:user_preferences, :epic_notes_filter)
+ remove_column_if_exists(:user_preferences, :epics_sort)
+ remove_column_if_exists(:user_preferences, :roadmap_epics_state)
+ remove_column_if_exists(:user_preferences, :roadmaps_sort)
+ end
+
+ def update_users
+ add_column_with_default_if_not_exists(
+ :users,
+ :auditor,
+ :boolean,
+ default: false
+ )
+
+ change_table(:users) do |t|
+ add_missing_columns(t, USERS_COLUMNS)
+ end
+
+ add_concurrent_index(:users, :group_view)
+ add_concurrent_index(:users, :managing_group_id)
+ add_concurrent_index(:users, :support_bot)
+ add_concurrent_index(:users, :bot_type)
+
+ add_concurrent_index(
+ :users,
+ :state,
+ name: 'index_users_on_state_and_internal_attrs',
+ where: '((ghost <> true) AND (support_bot <> true))'
+ )
+
+ internal_index = 'index_users_on_state_and_internal'
+
+ remove_concurrent_index(:users, :state, name: internal_index)
+
+ add_concurrent_index(
+ :users,
+ :state,
+ name: internal_index,
+ where: '((ghost <> true) AND (bot_type IS NULL))'
+ )
+ end
+
+ def revert_users
+ remove_column_if_exists(:users, :auditor)
+ remove_columns(:users, USERS_COLUMNS)
+
+ remove_concurrent_index_by_name(
+ :users,
+ 'index_users_on_state_and_internal_attrs'
+ )
+
+ internal_index = 'index_users_on_state_and_internal'
+
+ remove_concurrent_index(:users, :state, name: internal_index)
+ add_concurrent_index(:users, :state, name: internal_index)
+ end
+
+ def update_web_hooks
+ add_column_if_not_exists(:web_hooks, :group_id, :integer)
+ end
+
+ def revert_web_hooks
+ remove_column_if_exists(:web_hooks, :group_id)
+ end
+
+ def update_geo_nodes
+ add_column_if_not_exists(:geo_nodes, :internal_url, :string)
+ end
+
+ def revert_geo_nodes
+ remove_column_if_exists(:geo_nodes, :internal_url)
+ end
+
+ def create_missing_tables
+ create_table_if_not_exists "approval_merge_request_rule_sources", id: :bigserial do |t|
+ t.bigint "approval_merge_request_rule_id", null: false
+ t.bigint "approval_project_rule_id", null: false
+ t.index %w[approval_merge_request_rule_id], name: "index_approval_merge_request_rule_sources_1", unique: true, using: :btree
+ t.index %w[approval_project_rule_id], name: "index_approval_merge_request_rule_sources_2", using: :btree
+ end
+
+ create_table_if_not_exists "approval_merge_request_rules", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "merge_request_id", null: false
+ t.integer "approvals_required", limit: 2, default: 0, null: false
+ t.boolean "code_owner", default: false, null: false
+ t.string "name", null: false
+ t.index %w[merge_request_id code_owner name], name: "approval_rule_name_index_for_code_owners", unique: true, where: "(code_owner = true)", using: :btree
+ t.index %w[merge_request_id code_owner], name: "index_approval_merge_request_rules_1", using: :btree
+ end
+
+ create_table_if_not_exists "approval_merge_request_rules_approved_approvers", id: :bigserial do |t|
+ t.bigint "approval_merge_request_rule_id", null: false
+ t.integer "user_id", null: false
+ t.index %w[approval_merge_request_rule_id user_id], name: "index_approval_merge_request_rules_approved_approvers_1", unique: true, using: :btree
+ t.index %w[user_id], name: "index_approval_merge_request_rules_approved_approvers_2", using: :btree
+ end
+
+ create_table_if_not_exists "approval_merge_request_rules_groups", id: :bigserial do |t|
+ t.bigint "approval_merge_request_rule_id", null: false
+ t.integer "group_id", null: false
+ t.index %w[approval_merge_request_rule_id group_id], name: "index_approval_merge_request_rules_groups_1", unique: true, using: :btree
+ t.index %w[group_id], name: "index_approval_merge_request_rules_groups_2", using: :btree
+ end
+
+ create_table_if_not_exists "approval_merge_request_rules_users", id: :bigserial do |t|
+ t.bigint "approval_merge_request_rule_id", null: false
+ t.integer "user_id", null: false
+ t.index %w[approval_merge_request_rule_id user_id], name: "index_approval_merge_request_rules_users_1", unique: true, using: :btree
+ t.index %w[user_id], name: "index_approval_merge_request_rules_users_2", using: :btree
+ end
+
+ create_table_if_not_exists "approval_project_rules", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.integer "approvals_required", limit: 2, default: 0, null: false
+ t.string "name", null: false
+ t.index %w[project_id], name: "index_approval_project_rules_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "approval_project_rules_groups", id: :bigserial do |t|
+ t.bigint "approval_project_rule_id", null: false
+ t.integer "group_id", null: false
+ t.index %w[approval_project_rule_id group_id], name: "index_approval_project_rules_groups_1", unique: true, using: :btree
+ t.index %w[group_id], name: "index_approval_project_rules_groups_2", using: :btree
+ end
+
+ create_table_if_not_exists "approval_project_rules_users", id: :bigserial do |t|
+ t.bigint "approval_project_rule_id", null: false
+ t.integer "user_id", null: false
+ t.index %w[approval_project_rule_id user_id], name: "index_approval_project_rules_users_1", unique: true, using: :btree
+ t.index %w[user_id], name: "index_approval_project_rules_users_2", using: :btree
+ end
+
+ create_table_if_not_exists "approvals" do |t|
+ t.integer "merge_request_id", null: false
+ t.integer "user_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index %w[merge_request_id], name: "index_approvals_on_merge_request_id", using: :btree
+ end
+
+ create_table_if_not_exists "approver_groups" do |t|
+ t.integer "target_id", null: false
+ t.string "target_type", null: false
+ t.integer "group_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index %w[group_id], name: "index_approver_groups_on_group_id", using: :btree
+ t.index %w[target_id target_type], name: "index_approver_groups_on_target_id_and_target_type", using: :btree
+ end
+
+ create_table_if_not_exists "approvers" do |t|
+ t.integer "target_id", null: false
+ t.string "target_type"
+ t.integer "user_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index %w[target_id target_type], name: "index_approvers_on_target_id_and_target_type", using: :btree
+ t.index %w[user_id], name: "index_approvers_on_user_id", using: :btree
+ end
+
+ create_table_if_not_exists "board_assignees" do |t|
+ t.integer "board_id", null: false
+ t.integer "assignee_id", null: false
+ t.index %w[assignee_id], name: "index_board_assignees_on_assignee_id", using: :btree
+ t.index %w[board_id assignee_id], name: "index_board_assignees_on_board_id_and_assignee_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "board_labels" do |t|
+ t.integer "board_id", null: false
+ t.integer "label_id", null: false
+ t.index %w[board_id label_id], name: "index_board_labels_on_board_id_and_label_id", unique: true, using: :btree
+ t.index %w[label_id], name: "index_board_labels_on_label_id", using: :btree
+ end
+
+ create_table_if_not_exists "ci_sources_pipelines" do |t|
+ t.integer "project_id"
+ t.integer "pipeline_id"
+ t.integer "source_project_id"
+ t.integer "source_job_id"
+ t.integer "source_pipeline_id"
+ t.index ["pipeline_id"], name: "index_ci_sources_pipelines_on_pipeline_id", using: :btree
+ t.index ["project_id"], name: "index_ci_sources_pipelines_on_project_id", using: :btree
+ t.index ["source_job_id"], name: "index_ci_sources_pipelines_on_source_job_id", using: :btree
+ t.index ["source_pipeline_id"], name: "index_ci_sources_pipelines_on_source_pipeline_id", using: :btree
+ t.index ["source_project_id"], name: "index_ci_sources_pipelines_on_source_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "design_management_designs", id: :bigserial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "issue_id", null: false
+ t.string "filename", null: false
+ t.index %w[issue_id filename], name: "index_design_management_designs_on_issue_id_and_filename", unique: true, using: :btree
+ t.index ["project_id"], name: "index_design_management_designs_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "design_management_designs_versions", id: false, force: :cascade do |t|
+ t.bigint "design_id", null: false
+ t.bigint "version_id", null: false
+ t.index %w[design_id version_id], name: "design_management_designs_versions_uniqueness", unique: true, using: :btree
+ t.index ["design_id"], name: "index_design_management_designs_versions_on_design_id", using: :btree
+ t.index ["version_id"], name: "index_design_management_designs_versions_on_version_id", using: :btree
+ end
+
+ create_table_if_not_exists "design_management_versions", id: :bigserial, force: :cascade do |t|
+ t.binary "sha", null: false
+ t.index ["sha"], name: "index_design_management_versions_on_sha", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "draft_notes", id: :bigserial do |t|
+ t.integer "merge_request_id", null: false
+ t.integer "author_id", null: false
+ t.boolean "resolve_discussion", default: false, null: false
+ t.string "discussion_id"
+ t.text "note", null: false
+ t.text "position"
+ t.text "original_position"
+ t.text "change_position"
+ t.index ["author_id"], name: "index_draft_notes_on_author_id", using: :btree
+ t.index ["discussion_id"], name: "index_draft_notes_on_discussion_id", using: :btree
+ t.index ["merge_request_id"], name: "index_draft_notes_on_merge_request_id", using: :btree
+ end
+
+ create_table_if_not_exists "elasticsearch_indexed_namespaces", id: false do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "namespace_id"
+ t.index ["namespace_id"], name: "index_elasticsearch_indexed_namespaces_on_namespace_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "elasticsearch_indexed_projects", id: false do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id"
+ t.index ["project_id"], name: "index_elasticsearch_indexed_projects_on_project_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "epic_issues" do |t|
+ t.integer "epic_id", null: false
+ t.integer "issue_id", null: false
+ t.integer "relative_position", default: 1073741823, null: false
+ t.index ["epic_id"], name: "index_epic_issues_on_epic_id", using: :btree
+ t.index ["issue_id"], name: "index_epic_issues_on_issue_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "epic_metrics" do |t|
+ t.integer "epic_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["epic_id"], name: "index_epic_metrics", using: :btree
+ end
+
+ create_table_if_not_exists "epics" do |t|
+ t.integer "milestone_id"
+ t.integer "group_id", null: false
+ t.integer "author_id", null: false
+ t.integer "assignee_id"
+ t.integer "iid", null: false
+ t.integer "cached_markdown_version"
+ t.integer "updated_by_id"
+ t.integer "last_edited_by_id"
+ t.integer "lock_version"
+ t.date "start_date"
+ t.date "end_date"
+ t.datetime "last_edited_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "title", null: false
+ t.string "title_html", null: false
+ t.text "description"
+ t.text "description_html"
+ t.integer "start_date_sourcing_milestone_id"
+ t.integer "due_date_sourcing_milestone_id"
+ t.date "start_date_fixed"
+ t.date "due_date_fixed"
+ t.boolean "start_date_is_fixed"
+ t.boolean "due_date_is_fixed"
+ t.integer "state", limit: 2, default: 1, null: false
+ t.integer "closed_by_id"
+ t.datetime "closed_at"
+ t.integer "parent_id"
+ t.integer "relative_position"
+ t.index ["assignee_id"], name: "index_epics_on_assignee_id", using: :btree
+ t.index ["author_id"], name: "index_epics_on_author_id", using: :btree
+ t.index ["closed_by_id"], name: "index_epics_on_closed_by_id", using: :btree
+ t.index ["end_date"], name: "index_epics_on_end_date", using: :btree
+ t.index ["group_id"], name: "index_epics_on_group_id", using: :btree
+ t.index ["iid"], name: "index_epics_on_iid", using: :btree
+ t.index ["milestone_id"], name: "index_milestone", using: :btree
+ t.index ["parent_id"], name: "index_epics_on_parent_id", using: :btree
+ t.index ["start_date"], name: "index_epics_on_start_date", using: :btree
+ end
+
+ create_table_if_not_exists "geo_cache_invalidation_events", id: :bigserial do |t|
+ t.string "key", null: false
+ end
+
+ create_table_if_not_exists "geo_event_log", id: :bigserial do |t|
+ t.datetime "created_at", null: false
+ t.bigint "repository_updated_event_id"
+ t.bigint "repository_deleted_event_id"
+ t.bigint "repository_renamed_event_id"
+ t.bigint "repositories_changed_event_id"
+ t.bigint "repository_created_event_id"
+ t.bigint "hashed_storage_migrated_event_id"
+ t.bigint "lfs_object_deleted_event_id"
+ t.bigint "hashed_storage_attachments_event_id"
+ t.bigint "upload_deleted_event_id"
+ t.bigint "job_artifact_deleted_event_id"
+ t.bigint "reset_checksum_event_id"
+ t.bigint "cache_invalidation_event_id"
+ t.index ["cache_invalidation_event_id"], name: "index_geo_event_log_on_cache_invalidation_event_id", where: "(cache_invalidation_event_id IS NOT NULL)", using: :btree
+ t.index ["hashed_storage_attachments_event_id"], name: "index_geo_event_log_on_hashed_storage_attachments_event_id", where: "(hashed_storage_attachments_event_id IS NOT NULL)", using: :btree
+ t.index ["hashed_storage_migrated_event_id"], name: "index_geo_event_log_on_hashed_storage_migrated_event_id", where: "(hashed_storage_migrated_event_id IS NOT NULL)", using: :btree
+ t.index ["job_artifact_deleted_event_id"], name: "index_geo_event_log_on_job_artifact_deleted_event_id", where: "(job_artifact_deleted_event_id IS NOT NULL)", using: :btree
+ t.index ["lfs_object_deleted_event_id"], name: "index_geo_event_log_on_lfs_object_deleted_event_id", where: "(lfs_object_deleted_event_id IS NOT NULL)", using: :btree
+ t.index ["repositories_changed_event_id"], name: "index_geo_event_log_on_repositories_changed_event_id", where: "(repositories_changed_event_id IS NOT NULL)", using: :btree
+ t.index ["repository_created_event_id"], name: "index_geo_event_log_on_repository_created_event_id", where: "(repository_created_event_id IS NOT NULL)", using: :btree
+ t.index ["repository_deleted_event_id"], name: "index_geo_event_log_on_repository_deleted_event_id", where: "(repository_deleted_event_id IS NOT NULL)", using: :btree
+ t.index ["repository_renamed_event_id"], name: "index_geo_event_log_on_repository_renamed_event_id", where: "(repository_renamed_event_id IS NOT NULL)", using: :btree
+ t.index ["repository_updated_event_id"], name: "index_geo_event_log_on_repository_updated_event_id", where: "(repository_updated_event_id IS NOT NULL)", using: :btree
+ t.index ["reset_checksum_event_id"], name: "index_geo_event_log_on_reset_checksum_event_id", where: "(reset_checksum_event_id IS NOT NULL)", using: :btree
+ t.index ["upload_deleted_event_id"], name: "index_geo_event_log_on_upload_deleted_event_id", where: "(upload_deleted_event_id IS NOT NULL)", using: :btree
+ end
+
+ create_table_if_not_exists "geo_hashed_storage_attachments_events", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.text "old_attachments_path", null: false
+ t.text "new_attachments_path", null: false
+ t.index ["project_id"], name: "index_geo_hashed_storage_attachments_events_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_hashed_storage_migrated_events", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.text "repository_storage_name", null: false
+ t.text "old_disk_path", null: false
+ t.text "new_disk_path", null: false
+ t.text "old_wiki_disk_path", null: false
+ t.text "new_wiki_disk_path", null: false
+ t.integer "old_storage_version", limit: 2
+ t.integer "new_storage_version", limit: 2, null: false
+ t.index ["project_id"], name: "index_geo_hashed_storage_migrated_events_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_job_artifact_deleted_events", id: :bigserial do |t|
+ t.integer "job_artifact_id", null: false
+ t.string "file_path", null: false
+ t.index ["job_artifact_id"], name: "index_geo_job_artifact_deleted_events_on_job_artifact_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_lfs_object_deleted_events", id: :bigserial do |t|
+ t.integer "lfs_object_id", null: false
+ t.string "oid", null: false
+ t.string "file_path", null: false
+ t.index ["lfs_object_id"], name: "index_geo_lfs_object_deleted_events_on_lfs_object_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_node_namespace_links" do |t|
+ t.integer "geo_node_id", null: false
+ t.integer "namespace_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index %w[geo_node_id namespace_id], name: "index_geo_node_namespace_links_on_geo_node_id_and_namespace_id", unique: true, using: :btree
+ t.index ["geo_node_id"], name: "index_geo_node_namespace_links_on_geo_node_id", using: :btree
+ t.index ["namespace_id"], name: "index_geo_node_namespace_links_on_namespace_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_node_statuses" do |t|
+ t.integer "geo_node_id", null: false
+ t.integer "db_replication_lag_seconds"
+ t.integer "repositories_synced_count"
+ t.integer "repositories_failed_count"
+ t.integer "lfs_objects_count"
+ t.integer "lfs_objects_synced_count"
+ t.integer "lfs_objects_failed_count"
+ t.integer "attachments_count"
+ t.integer "attachments_synced_count"
+ t.integer "attachments_failed_count"
+ t.integer "last_event_id"
+ t.datetime "last_event_date"
+ t.integer "cursor_last_event_id"
+ t.datetime "cursor_last_event_date"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.datetime "last_successful_status_check_at"
+ t.string "status_message"
+ t.integer "replication_slots_count"
+ t.integer "replication_slots_used_count"
+ t.bigint "replication_slots_max_retained_wal_bytes"
+ t.integer "wikis_synced_count"
+ t.integer "wikis_failed_count"
+ t.integer "job_artifacts_count"
+ t.integer "job_artifacts_synced_count"
+ t.integer "job_artifacts_failed_count"
+ t.string "version"
+ t.string "revision"
+ t.integer "repositories_verified_count"
+ t.integer "repositories_verification_failed_count"
+ t.integer "wikis_verified_count"
+ t.integer "wikis_verification_failed_count"
+ t.integer "lfs_objects_synced_missing_on_primary_count"
+ t.integer "job_artifacts_synced_missing_on_primary_count"
+ t.integer "attachments_synced_missing_on_primary_count"
+ t.integer "repositories_checksummed_count"
+ t.integer "repositories_checksum_failed_count"
+ t.integer "repositories_checksum_mismatch_count"
+ t.integer "wikis_checksummed_count"
+ t.integer "wikis_checksum_failed_count"
+ t.integer "wikis_checksum_mismatch_count"
+ t.binary "storage_configuration_digest"
+ t.integer "repositories_retrying_verification_count"
+ t.integer "wikis_retrying_verification_count"
+ t.integer "projects_count"
+ t.index ["geo_node_id"], name: "index_geo_node_statuses_on_geo_node_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "geo_nodes" do |t|
+ t.boolean "primary"
+ t.integer "oauth_application_id"
+ t.boolean "enabled", default: true, null: false
+ t.string "access_key"
+ t.string "encrypted_secret_access_key"
+ t.string "encrypted_secret_access_key_iv"
+ t.string "clone_url_prefix"
+ t.integer "files_max_capacity", default: 10, null: false
+ t.integer "repos_max_capacity", default: 25, null: false
+ t.string "url", null: false
+ t.string "selective_sync_type"
+ t.text "selective_sync_shards"
+ t.integer "verification_max_capacity", default: 100, null: false
+ t.integer "minimum_reverification_interval", default: 7, null: false
+ t.string "alternate_url"
+ t.index ["access_key"], name: "index_geo_nodes_on_access_key", using: :btree
+ t.index ["primary"], name: "index_geo_nodes_on_primary", using: :btree
+ t.index ["url"], name: "index_geo_nodes_on_url", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "geo_repositories_changed_events", id: :bigserial do |t|
+ t.integer "geo_node_id", null: false
+ t.index ["geo_node_id"], name: "index_geo_repositories_changed_events_on_geo_node_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_repository_created_events", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.text "repository_storage_name", null: false
+ t.text "repo_path", null: false
+ t.text "wiki_path"
+ t.text "project_name", null: false
+ t.index ["project_id"], name: "index_geo_repository_created_events_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_repository_deleted_events", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.text "repository_storage_name", null: false
+ t.text "deleted_path", null: false
+ t.text "deleted_wiki_path"
+ t.text "deleted_project_name", null: false
+ t.index ["project_id"], name: "index_geo_repository_deleted_events_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_repository_renamed_events", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.text "repository_storage_name", null: false
+ t.text "old_path_with_namespace", null: false
+ t.text "new_path_with_namespace", null: false
+ t.text "old_wiki_path_with_namespace", null: false
+ t.text "new_wiki_path_with_namespace", null: false
+ t.text "old_path", null: false
+ t.text "new_path", null: false
+ t.index ["project_id"], name: "index_geo_repository_renamed_events_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_repository_updated_events", id: :bigserial do |t|
+ t.integer "branches_affected", null: false
+ t.integer "tags_affected", null: false
+ t.integer "project_id", null: false
+ t.integer "source", limit: 2, null: false
+ t.boolean "new_branch", default: false, null: false
+ t.boolean "remove_branch", default: false, null: false
+ t.text "ref"
+ t.index ["project_id"], name: "index_geo_repository_updated_events_on_project_id", using: :btree
+ t.index ["source"], name: "index_geo_repository_updated_events_on_source", using: :btree
+ end
+
+ create_table_if_not_exists "geo_reset_checksum_events", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.index ["project_id"], name: "index_geo_reset_checksum_events_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "geo_upload_deleted_events", id: :bigserial do |t|
+ t.integer "upload_id", null: false
+ t.string "file_path", null: false
+ t.integer "model_id", null: false
+ t.string "model_type", null: false
+ t.string "uploader", null: false
+ t.index ["upload_id"], name: "index_geo_upload_deleted_events_on_upload_id", using: :btree
+ end
+
+ create_table_if_not_exists "gitlab_subscriptions", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.date "start_date"
+ t.date "end_date"
+ t.date "trial_ends_on"
+ t.integer "namespace_id"
+ t.integer "hosted_plan_id"
+ t.integer "max_seats_used", default: 0
+ t.integer "seats", default: 0
+ t.boolean "trial", default: false
+ t.index ["hosted_plan_id"], name: "index_gitlab_subscriptions_on_hosted_plan_id", using: :btree
+ t.index ["namespace_id"], name: "index_gitlab_subscriptions_on_namespace_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "historical_data" do |t|
+ t.date "date", null: false
+ t.integer "active_user_count"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ create_table_if_not_exists "index_statuses" do |t|
+ t.integer "project_id", null: false
+ t.datetime "indexed_at"
+ t.text "note"
+ t.string "last_commit"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["project_id"], name: "index_index_statuses_on_project_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "insights" do |t|
+ t.integer "namespace_id", null: false
+ t.integer "project_id", null: false
+ t.index ["namespace_id"], name: "index_insights_on_namespace_id", using: :btree
+ t.index ["project_id"], name: "index_insights_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "issue_links" do |t|
+ t.integer "source_id", null: false
+ t.integer "target_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index %w[source_id target_id], name: "index_issue_links_on_source_id_and_target_id", unique: true, using: :btree
+ t.index ["source_id"], name: "index_issue_links_on_source_id", using: :btree
+ t.index ["target_id"], name: "index_issue_links_on_target_id", using: :btree
+ end
+
+ create_table_if_not_exists "jira_connect_installations", id: :bigserial do |t|
+ t.string "client_key"
+ t.string "encrypted_shared_secret"
+ t.string "encrypted_shared_secret_iv"
+ t.string "base_url"
+ t.index ["client_key"], name: "index_jira_connect_installations_on_client_key", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "jira_connect_subscriptions", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.bigint "jira_connect_installation_id", null: false
+ t.integer "namespace_id", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index %w[jira_connect_installation_id namespace_id], name: "idx_jira_connect_subscriptions_on_installation_id_namespace_id", unique: true, using: :btree
+ t.index ["jira_connect_installation_id"], name: "idx_jira_connect_subscriptions_on_installation_id", using: :btree
+ t.index ["namespace_id"], name: "index_jira_connect_subscriptions_on_namespace_id", using: :btree
+ end
+
+ create_table_if_not_exists "ldap_group_links" do |t|
+ t.string "cn"
+ t.integer "group_access", null: false
+ t.integer "group_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "provider"
+ t.string "filter"
+ end
+
+ create_table_if_not_exists "licenses" do |t|
+ t.text "data", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ create_table_if_not_exists "namespace_statistics" do |t|
+ t.integer "namespace_id", null: false
+ t.integer "shared_runners_seconds", default: 0, null: false
+ t.datetime "shared_runners_seconds_last_reset"
+ t.index ["namespace_id"], name: "index_namespace_statistics_on_namespace_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "operations_feature_flag_scopes", id: :bigserial do |t|
+ t.bigint "feature_flag_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.boolean "active", null: false
+ t.string "environment_scope", default: "*", null: false
+ t.index %w[feature_flag_id environment_scope], name: "index_feature_flag_scopes_on_flag_id_and_environment_scope", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "operations_feature_flags", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.boolean "active", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "name", null: false
+ t.text "description"
+ t.index %w[project_id name], name: "index_operations_feature_flags_on_project_id_and_name", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "operations_feature_flags_clients", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.string "token", null: false
+ t.index %w[project_id token], name: "index_operations_feature_flags_clients_on_project_id_and_token", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "packages_maven_metadata", id: :bigserial do |t|
+ t.bigint "package_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "app_group", null: false
+ t.string "app_name", null: false
+ t.string "app_version"
+ t.string "path", limit: 512, null: false
+ t.index %w[package_id path], name: "index_packages_maven_metadata_on_package_id_and_path", using: :btree
+ end
+
+ create_table_if_not_exists "packages_package_files", id: :bigserial do |t|
+ t.bigint "package_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "size"
+ t.integer "file_type"
+ t.integer "file_store"
+ t.binary "file_md5"
+ t.binary "file_sha1"
+ t.string "file_name", null: false
+ t.text "file", null: false
+ t.index %w[package_id file_name], name: "index_packages_package_files_on_package_id_and_file_name", using: :btree
+ end
+
+ create_table_if_not_exists "packages_packages", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "name", null: false
+ t.string "version"
+ t.integer "package_type", limit: 2, null: false
+ t.index ["project_id"], name: "index_packages_packages_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "path_locks" do |t|
+ t.string "path", null: false
+ t.integer "project_id"
+ t.integer "user_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["path"], name: "index_path_locks_on_path", using: :btree
+ t.index ["project_id"], name: "index_path_locks_on_project_id", using: :btree
+ t.index ["user_id"], name: "index_path_locks_on_user_id", using: :btree
+ end
+
+ create_table_if_not_exists "plans" do |t|
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "name"
+ t.string "title"
+ t.integer "active_pipelines_limit"
+ t.integer "pipeline_size_limit"
+ t.index ["name"], name: "index_plans_on_name", using: :btree
+ end
+
+ create_table_if_not_exists "project_alerting_settings", primary_key: "project_id", id: :integer do |t|
+ t.string "encrypted_token", null: false
+ t.string "encrypted_token_iv", null: false
+ end
+
+ create_table_if_not_exists "project_feature_usages", primary_key: "project_id", id: :integer do |t|
+ t.datetime "jira_dvcs_cloud_last_sync_at"
+ t.datetime "jira_dvcs_server_last_sync_at"
+ t.index %w[jira_dvcs_cloud_last_sync_at project_id], name: "idx_proj_feat_usg_on_jira_dvcs_cloud_last_sync_at_and_proj_id", where: "(jira_dvcs_cloud_last_sync_at IS NOT NULL)", using: :btree
+ t.index %w[jira_dvcs_server_last_sync_at project_id], name: "idx_proj_feat_usg_on_jira_dvcs_server_last_sync_at_and_proj_id", where: "(jira_dvcs_server_last_sync_at IS NOT NULL)", using: :btree
+ t.index ["project_id"], name: "index_project_feature_usages_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "project_incident_management_settings", primary_key: "project_id", id: :integer do |t|
+ t.boolean "create_issue", default: false, null: false
+ t.boolean "send_email", default: true, null: false
+ t.text "issue_template_key"
+ end
+
+ create_table_if_not_exists "project_repository_states" do |t|
+ t.integer "project_id", null: false
+ t.binary "repository_verification_checksum"
+ t.binary "wiki_verification_checksum"
+ t.string "last_repository_verification_failure"
+ t.string "last_wiki_verification_failure"
+ t.datetime_with_timezone "repository_retry_at"
+ t.datetime_with_timezone "wiki_retry_at"
+ t.integer "repository_retry_count"
+ t.integer "wiki_retry_count"
+ t.datetime_with_timezone "last_repository_verification_ran_at"
+ t.datetime_with_timezone "last_wiki_verification_ran_at"
+ t.index ["last_repository_verification_failure"], name: "idx_repository_states_on_repository_failure_partial", where: "(last_repository_verification_failure IS NOT NULL)", using: :btree
+ t.index ["last_wiki_verification_failure"], name: "idx_repository_states_on_wiki_failure_partial", where: "(last_wiki_verification_failure IS NOT NULL)", using: :btree
+ t.index %w[project_id last_repository_verification_ran_at], name: "idx_repository_states_on_last_repository_verification_ran_at", where: "((repository_verification_checksum IS NOT NULL) AND (last_repository_verification_failure IS NULL))", using: :btree
+ t.index %w[project_id last_wiki_verification_ran_at], name: "idx_repository_states_on_last_wiki_verification_ran_at", where: "((wiki_verification_checksum IS NOT NULL) AND (last_wiki_verification_failure IS NULL))", using: :btree
+ t.index ["project_id"], name: "idx_repository_states_outdated_checksums", where: "(((repository_verification_checksum IS NULL) AND (last_repository_verification_failure IS NULL)) OR ((wiki_verification_checksum IS NULL) AND (last_wiki_verification_failure IS NULL)))", using: :btree
+ t.index ["project_id"], name: "index_project_repository_states_on_project_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "project_tracing_settings", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.string "external_url", null: false
+ t.index ["project_id"], name: "index_project_tracing_settings_on_project_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "prometheus_alert_events", id: :bigserial do |t|
+ t.integer "project_id", null: false
+ t.integer "prometheus_alert_id", null: false
+ t.datetime_with_timezone "started_at", null: false
+ t.datetime_with_timezone "ended_at"
+ t.integer "status", limit: 2
+ t.string "payload_key"
+ t.index %w[project_id status], name: "index_prometheus_alert_events_on_project_id_and_status", using: :btree
+ t.index %w[prometheus_alert_id payload_key], name: "index_prometheus_alert_event_scoped_payload_key", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "prometheus_alerts" do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.float "threshold", null: false
+ t.integer "operator", null: false
+ t.integer "environment_id", null: false
+ t.integer "project_id", null: false
+ t.integer "prometheus_metric_id", null: false
+ t.index ["environment_id"], name: "index_prometheus_alerts_on_environment_id", using: :btree
+ t.index %w[project_id prometheus_metric_id environment_id], name: "index_prometheus_alerts_metric_environment", unique: true, using: :btree
+ t.index ["prometheus_metric_id"], name: "index_prometheus_alerts_on_prometheus_metric_id", using: :btree
+ end
+
+ create_table_if_not_exists "protected_branch_unprotect_access_levels" do |t|
+ t.integer "protected_branch_id", null: false
+ t.integer "access_level", default: 40
+ t.integer "user_id"
+ t.integer "group_id"
+ t.index ["group_id"], name: "index_protected_branch_unprotect_access_levels_on_group_id", using: :btree
+ t.index ["protected_branch_id"], name: "index_protected_branch_unprotect_access", using: :btree
+ t.index ["user_id"], name: "index_protected_branch_unprotect_access_levels_on_user_id", using: :btree
+ end
+
+ create_table_if_not_exists "protected_environment_deploy_access_levels" do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "access_level", default: 40
+ t.integer "protected_environment_id", null: false
+ t.integer "user_id"
+ t.integer "group_id"
+ t.index ["group_id"], name: "index_protected_environment_deploy_access_levels_on_group_id", using: :btree
+ t.index ["protected_environment_id"], name: "index_protected_environment_deploy_access", using: :btree
+ t.index ["user_id"], name: "index_protected_environment_deploy_access_levels_on_user_id", using: :btree
+ end
+
+ create_table_if_not_exists "protected_environments" do |t|
+ t.integer "project_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "name", null: false
+ t.index %w[project_id name], name: "index_protected_environments_on_project_id_and_name", unique: true, using: :btree
+ t.index ["project_id"], name: "index_protected_environments_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "push_rules" do |t|
+ t.string "force_push_regex"
+ t.string "delete_branch_regex"
+ t.string "commit_message_regex"
+ t.boolean "deny_delete_tag"
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "author_email_regex"
+ t.boolean "member_check", default: false, null: false
+ t.string "file_name_regex"
+ t.boolean "is_sample", default: false
+ t.integer "max_file_size", default: 0, null: false
+ t.boolean "prevent_secrets", default: false, null: false
+ t.string "branch_name_regex"
+ t.boolean "reject_unsigned_commits"
+ t.boolean "commit_committer_check"
+ t.boolean "regexp_uses_re2", default: true
+ t.string "commit_message_negative_regex"
+ t.index ["is_sample"], name: "index_push_rules_on_is_sample", where: "is_sample", using: :btree
+ t.index ["project_id"], name: "index_push_rules_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "reviews", id: :bigserial do |t|
+ t.integer "author_id"
+ t.integer "merge_request_id", null: false
+ t.integer "project_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.index ["author_id"], name: "index_reviews_on_author_id", using: :btree
+ t.index ["merge_request_id"], name: "index_reviews_on_merge_request_id", using: :btree
+ t.index ["project_id"], name: "index_reviews_on_project_id", using: :btree
+ end
+
+ create_table_if_not_exists "saml_providers" do |t|
+ t.integer "group_id", null: false
+ t.boolean "enabled", null: false
+ t.string "certificate_fingerprint", null: false
+ t.string "sso_url", null: false
+ t.boolean "enforced_sso", default: false, null: false
+ t.boolean "enforced_group_managed_accounts", default: false, null: false
+ t.index ["group_id"], name: "index_saml_providers_on_group_id", using: :btree
+ end
+
+ create_table_if_not_exists "scim_oauth_access_tokens" do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "group_id", null: false
+ t.string "token_encrypted", null: false
+ t.index %w[group_id token_encrypted], name: "index_scim_oauth_access_tokens_on_group_id_and_token_encrypted", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "slack_integrations" do |t|
+ t.integer "service_id", null: false
+ t.string "team_id", null: false
+ t.string "team_name", null: false
+ t.string "alias", null: false
+ t.string "user_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["service_id"], name: "index_slack_integrations_on_service_id", using: :btree
+ t.index %w[team_id alias], name: "index_slack_integrations_on_team_id_and_alias", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "smartcard_identities", id: :bigserial do |t|
+ t.integer "user_id", null: false
+ t.string "subject", null: false
+ t.string "issuer", null: false
+ t.index %w[subject issuer], name: "index_smartcard_identities_on_subject_and_issuer", unique: true, using: :btree
+ t.index ["user_id"], name: "index_smartcard_identities_on_user_id", using: :btree
+ end
+
+ create_table_if_not_exists "software_license_policies" do |t|
+ t.integer "project_id", null: false
+ t.integer "software_license_id", null: false
+ t.integer "approval_status", default: 0, null: false
+ t.index %w[project_id software_license_id], name: "index_software_license_policies_unique_per_project", unique: true, using: :btree
+ t.index ["software_license_id"], name: "index_software_license_policies_on_software_license_id", using: :btree
+ end
+
+ create_table_if_not_exists "software_licenses" do |t|
+ t.string "name", null: false
+ t.index ["name"], name: "index_software_licenses_on_name", using: :btree
+ end
+
+ create_table_if_not_exists "users_ops_dashboard_projects", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "user_id", null: false
+ t.integer "project_id", null: false
+ t.index ["project_id"], name: "index_users_ops_dashboard_projects_on_project_id", using: :btree
+ t.index %w[user_id project_id], name: "index_users_ops_dashboard_projects_on_user_id_and_project_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "vulnerability_feedback" do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "feedback_type", limit: 2, null: false
+ t.integer "category", limit: 2, null: false
+ t.integer "project_id", null: false
+ t.integer "author_id", null: false
+ t.integer "pipeline_id"
+ t.integer "issue_id"
+ t.string "project_fingerprint", limit: 40, null: false
+ t.integer "merge_request_id"
+ t.index ["author_id"], name: "index_vulnerability_feedback_on_author_id", using: :btree
+ t.index ["issue_id"], name: "index_vulnerability_feedback_on_issue_id", using: :btree
+ t.index ["merge_request_id"], name: "index_vulnerability_feedback_on_merge_request_id", using: :btree
+ t.index ["pipeline_id"], name: "index_vulnerability_feedback_on_pipeline_id", using: :btree
+ t.index %w[project_id category feedback_type project_fingerprint], name: "vulnerability_feedback_unique_idx", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "vulnerability_identifiers", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.binary "fingerprint", null: false
+ t.string "external_type", null: false
+ t.string "external_id", null: false
+ t.string "name", null: false
+ t.text "url"
+ t.index %w[project_id fingerprint], name: "index_vulnerability_identifiers_on_project_id_and_fingerprint", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "vulnerability_occurrence_identifiers", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "occurrence_id", null: false
+ t.bigint "identifier_id", null: false
+ t.index ["identifier_id"], name: "index_vulnerability_occurrence_identifiers_on_identifier_id", using: :btree
+ t.index %w[occurrence_id identifier_id], name: "index_vulnerability_occurrence_identifiers_on_unique_keys", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "vulnerability_occurrence_pipelines", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "occurrence_id", null: false
+ t.integer "pipeline_id", null: false
+ t.index %w[occurrence_id pipeline_id], name: "vulnerability_occurrence_pipelines_on_unique_keys", unique: true, using: :btree
+ t.index ["pipeline_id"], name: "index_vulnerability_occurrence_pipelines_on_pipeline_id", using: :btree
+ end
+
+ create_table_if_not_exists "vulnerability_occurrences", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "severity", limit: 2, null: false
+ t.integer "confidence", limit: 2, null: false
+ t.integer "report_type", limit: 2, null: false
+ t.integer "project_id", null: false
+ t.bigint "scanner_id", null: false
+ t.bigint "primary_identifier_id", null: false
+ t.binary "project_fingerprint", null: false
+ t.binary "location_fingerprint", null: false
+ t.string "uuid", limit: 36, null: false
+ t.string "name", null: false
+ t.string "metadata_version", null: false
+ t.text "raw_metadata", null: false
+ t.index ["primary_identifier_id"], name: "index_vulnerability_occurrences_on_primary_identifier_id", using: :btree
+ t.index %w[project_id primary_identifier_id location_fingerprint scanner_id], name: "index_vulnerability_occurrences_on_unique_keys", unique: true, using: :btree
+ t.index ["scanner_id"], name: "index_vulnerability_occurrences_on_scanner_id", using: :btree
+ t.index ["uuid"], name: "index_vulnerability_occurrences_on_uuid", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "vulnerability_scanners", id: :bigserial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.string "external_id", null: false
+ t.string "name", null: false
+ t.index %w[project_id external_id], name: "index_vulnerability_scanners_on_project_id_and_external_id", unique: true, using: :btree
+ end
+
+ create_table_if_not_exists "dependency_proxy_blobs", id: :serial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.text "file", null: false
+ t.string "file_name", null: false
+ t.integer "file_store"
+ t.integer "group_id", null: false
+ t.bigint "size"
+ t.datetime_with_timezone "updated_at", null: false
+ t.index %w[group_id file_name], name: "index_dependency_proxy_blobs_on_group_id_and_file_name", using: :btree
+ end
+
+ create_table_if_not_exists "dependency_proxy_group_settings", id: :serial do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.boolean "enabled", default: false, null: false
+ t.integer "group_id", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["group_id"], name: "index_dependency_proxy_group_settings_on_group_id", using: :btree
+ end
+ end
+
+ def remove_tables
+ drop_table_if_exists "approval_merge_request_rule_sources"
+ drop_table_if_exists "approval_merge_request_rules"
+ drop_table_if_exists "approval_merge_request_rules_approved_approvers"
+ drop_table_if_exists "approval_merge_request_rules_groups"
+ drop_table_if_exists "approval_merge_request_rules_users"
+ drop_table_if_exists "approval_project_rules"
+ drop_table_if_exists "approval_project_rules_groups"
+ drop_table_if_exists "approval_project_rules_users"
+ drop_table_if_exists "approvals"
+ drop_table_if_exists "approver_groups"
+ drop_table_if_exists "approvers"
+ drop_table_if_exists "board_assignees"
+ drop_table_if_exists "board_labels"
+ drop_table_if_exists "ci_sources_pipelines"
+ drop_table_if_exists "design_management_designs_versions"
+ drop_table_if_exists "design_management_versions"
+ drop_table_if_exists "design_management_designs"
+ drop_table_if_exists "draft_notes"
+ drop_table_if_exists "elasticsearch_indexed_namespaces"
+ drop_table_if_exists "elasticsearch_indexed_projects"
+ drop_table_if_exists "epic_issues"
+ drop_table_if_exists "epic_metrics"
+ drop_table_if_exists "epics"
+ drop_table_if_exists "geo_cache_invalidation_events"
+ drop_table_if_exists "geo_event_log"
+ drop_table_if_exists "geo_hashed_storage_attachments_events"
+ drop_table_if_exists "geo_hashed_storage_migrated_events"
+ drop_table_if_exists "geo_job_artifact_deleted_events"
+ drop_table_if_exists "geo_lfs_object_deleted_events"
+ drop_table_if_exists "geo_node_namespace_links"
+ drop_table_if_exists "geo_node_statuses"
+ drop_table_if_exists "geo_nodes"
+ drop_table_if_exists "geo_repositories_changed_events"
+ drop_table_if_exists "geo_repository_created_events"
+ drop_table_if_exists "geo_repository_deleted_events"
+ drop_table_if_exists "geo_repository_renamed_events"
+ drop_table_if_exists "geo_repository_updated_events"
+ drop_table_if_exists "geo_reset_checksum_events"
+ drop_table_if_exists "geo_upload_deleted_events"
+ drop_table_if_exists "gitlab_subscriptions"
+ drop_table_if_exists "historical_data"
+ drop_table_if_exists "index_statuses"
+ drop_table_if_exists "insights"
+ drop_table_if_exists "issue_links"
+ drop_table_if_exists "jira_connect_subscriptions"
+ drop_table_if_exists "jira_connect_installations"
+ drop_table_if_exists "ldap_group_links"
+ drop_table_if_exists "licenses"
+ drop_table_if_exists "namespace_statistics"
+ drop_table_if_exists "operations_feature_flag_scopes"
+ drop_table_if_exists "operations_feature_flags"
+ drop_table_if_exists "operations_feature_flags_clients"
+ drop_table_if_exists "packages_maven_metadata"
+ drop_table_if_exists "packages_package_files"
+ drop_table_if_exists "packages_packages"
+ drop_table_if_exists "path_locks"
+ drop_table_if_exists "plans"
+ drop_table_if_exists "project_alerting_settings"
+ drop_table_if_exists "project_feature_usages"
+ drop_table_if_exists "project_incident_management_settings"
+ drop_table_if_exists "project_repository_states"
+ drop_table_if_exists "project_tracing_settings"
+ drop_table_if_exists "prometheus_alert_events"
+ drop_table_if_exists "prometheus_alerts"
+ drop_table_if_exists "protected_branch_unprotect_access_levels"
+ drop_table_if_exists "protected_environment_deploy_access_levels"
+ drop_table_if_exists "protected_environments"
+ drop_table_if_exists "push_rules"
+ drop_table_if_exists "reviews"
+ drop_table_if_exists "saml_providers"
+ drop_table_if_exists "scim_oauth_access_tokens"
+ drop_table_if_exists "slack_integrations"
+ drop_table_if_exists "smartcard_identities"
+ drop_table_if_exists "software_license_policies"
+ drop_table_if_exists "software_licenses"
+ drop_table_if_exists "users_ops_dashboard_projects"
+ drop_table_if_exists "vulnerability_feedback"
+ drop_table_if_exists "vulnerability_identifiers"
+ drop_table_if_exists "vulnerability_occurrence_identifiers"
+ drop_table_if_exists "vulnerability_occurrence_pipelines"
+ drop_table_if_exists "vulnerability_occurrences"
+ drop_table_if_exists "vulnerability_scanners"
+ drop_table_if_exists "dependency_proxy_blobs"
+ drop_table_if_exists "dependency_proxy_group_settings"
+ end
+
+ def add_missing_foreign_keys
+ add_concurrent_foreign_key("application_settings", "namespaces", column: "custom_project_templates_group_id", name: "fk_rails_b53e481273", on_delete: :nullify)
+ add_concurrent_foreign_key("application_settings", "projects", column: "file_template_project_id", name: "fk_ec757bd087", on_delete: :nullify)
+ add_concurrent_foreign_key("approval_merge_request_rule_sources", "approval_merge_request_rules", column: "approval_merge_request_rule_id", name: "fk_rails_e605a04f76", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_merge_request_rule_sources", "approval_project_rules", column: "approval_project_rule_id", name: "fk_rails_64e8ed3c7e", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_merge_request_rules", "merge_requests", column: "merge_request_id", name: "fk_rails_004ce82224", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_merge_request_rules_approved_approvers", "approval_merge_request_rules", column: "approval_merge_request_rule_id", name: "fk_rails_6577725edb", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_merge_request_rules_approved_approvers", "users", column: "user_id", name: "fk_rails_8dc94cff4d", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_merge_request_rules_groups", "approval_merge_request_rules", column: "approval_merge_request_rule_id", name: "fk_rails_5b2ecf6139", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_merge_request_rules_groups", "namespaces", column: "group_id", name: "fk_rails_2020a7124a", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_merge_request_rules_users", "approval_merge_request_rules", column: "approval_merge_request_rule_id", name: "fk_rails_80e6801803", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_merge_request_rules_users", "users", column: "user_id", name: "fk_rails_bc8972fa55", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_project_rules", "projects", column: "project_id", name: "fk_rails_5fb4dd100b", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_project_rules_groups", "approval_project_rules", column: "approval_project_rule_id", name: "fk_rails_9071e863d1", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_project_rules_groups", "namespaces", column: "group_id", name: "fk_rails_396841e79e", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_project_rules_users", "approval_project_rules", column: "approval_project_rule_id", name: "fk_rails_b9e9394efb", on_delete: :cascade)
+ add_concurrent_foreign_key("approval_project_rules_users", "users", column: "user_id", name: "fk_rails_f365da8250", on_delete: :cascade)
+ add_concurrent_foreign_key("approvals", "merge_requests", column: "merge_request_id", name: "fk_310d714958", on_delete: :cascade)
+ add_concurrent_foreign_key("approver_groups", "namespaces", column: "group_id", name: "fk_rails_1cdcbd7723", on_delete: :cascade)
+ add_concurrent_foreign_key("board_assignees", "boards", column: "board_id", name: "fk_rails_3f6f926bd5", on_delete: :cascade)
+ add_concurrent_foreign_key("board_assignees", "users", column: "assignee_id", name: "fk_rails_1c0ff59e82", on_delete: :cascade)
+ add_concurrent_foreign_key("board_labels", "boards", column: "board_id", name: "fk_rails_9374a16edd", on_delete: :cascade)
+ add_concurrent_foreign_key("board_labels", "labels", column: "label_id", name: "fk_rails_362b0600a3", on_delete: :cascade)
+ add_concurrent_foreign_key("ci_sources_pipelines", "ci_builds", column: "source_job_id", name: "fk_be5624bf37", on_delete: :cascade)
+ add_concurrent_foreign_key("ci_sources_pipelines", "ci_pipelines", column: "pipeline_id", name: "fk_e1bad85861", on_delete: :cascade)
+ add_concurrent_foreign_key("ci_sources_pipelines", "ci_pipelines", column: "source_pipeline_id", name: "fk_d4e29af7d7", on_delete: :cascade)
+ add_concurrent_foreign_key("ci_sources_pipelines", "projects", column: "source_project_id", name: "fk_acd9737679", on_delete: :cascade)
+ add_concurrent_foreign_key("ci_sources_pipelines", "projects", column: "project_id", name: "fk_1e53c97c0a", on_delete: :cascade)
+ add_concurrent_foreign_key("design_management_designs", "issues", column: "issue_id", name: "fk_rails_bfe283ec3c", on_delete: :cascade)
+ add_concurrent_foreign_key("design_management_designs", "projects", column: "project_id", name: "fk_rails_4bb1073360", on_delete: :cascade)
+ add_concurrent_foreign_key("design_management_designs_versions", "design_management_designs", column: "design_id", on_delete: :cascade)
+ add_concurrent_foreign_key("design_management_designs_versions", "design_management_versions", column: "version_id", on_delete: :cascade)
+ add_concurrent_foreign_key("draft_notes", "merge_requests", column: "merge_request_id", name: "fk_rails_e753681674", on_delete: :cascade)
+ add_concurrent_foreign_key("draft_notes", "users", column: "author_id", name: "fk_rails_2a8dac9901", on_delete: :cascade)
+ add_concurrent_foreign_key("elasticsearch_indexed_namespaces", "namespaces", column: "namespace_id", name: "fk_rails_bdcf044f37", on_delete: :cascade)
+ add_concurrent_foreign_key("elasticsearch_indexed_projects", "projects", column: "project_id", name: "fk_rails_bd13bbdc3d", on_delete: :cascade)
+ add_concurrent_foreign_key("epic_issues", "epics", column: "epic_id", name: "fk_rails_5d942936b4", on_delete: :cascade)
+ add_concurrent_foreign_key("epic_issues", "issues", column: "issue_id", name: "fk_rails_4209981af6", on_delete: :cascade)
+ add_concurrent_foreign_key("epic_metrics", "epics", column: "epic_id", name: "fk_rails_d071904753", on_delete: :cascade)
+ add_concurrent_foreign_key("epics", "epics", column: "parent_id", name: "fk_25b99c1be3", on_delete: :cascade)
+ add_concurrent_foreign_key("epics", "milestones", column: "milestone_id", name: "fk_rails_1bf671ebb7", on_delete: :nullify)
+ add_concurrent_foreign_key("epics", "namespaces", column: "group_id", name: "fk_f081aa4489", on_delete: :cascade)
+ add_concurrent_foreign_key("epics", "users", column: "assignee_id", name: "fk_dccd3f98fc", on_delete: :nullify)
+ add_concurrent_foreign_key("epics", "users", column: "author_id", name: "fk_3654b61b03", on_delete: :cascade)
+ add_concurrent_foreign_key("epics", "users", column: "closed_by_id", name: "fk_aa5798e761", on_delete: :nullify)
+ add_concurrent_foreign_key("geo_event_log", "geo_cache_invalidation_events", column: "cache_invalidation_event_id", name: "fk_42c3b54bed", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_hashed_storage_migrated_events", column: "hashed_storage_migrated_event_id", name: "fk_27548c6db3", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_job_artifact_deleted_events", column: "job_artifact_deleted_event_id", name: "fk_176d3fbb5d", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_lfs_object_deleted_events", column: "lfs_object_deleted_event_id", name: "fk_d5af95fcd9", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_repositories_changed_events", column: "repositories_changed_event_id", name: "fk_4a99ebfd60", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_repository_created_events", column: "repository_created_event_id", name: "fk_9b9afb1916", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_repository_deleted_events", column: "repository_deleted_event_id", name: "fk_c4b1c1f66e", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_repository_renamed_events", column: "repository_renamed_event_id", name: "fk_86c84214ec", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_repository_updated_events", column: "repository_updated_event_id", name: "fk_78a6492f68", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_reset_checksum_events", column: "reset_checksum_event_id", name: "fk_cff7185ad2", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_event_log", "geo_upload_deleted_events", column: "upload_deleted_event_id", name: "fk_c1f241c70d", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_hashed_storage_attachments_events", "projects", column: "project_id", name: "fk_rails_d496b088e9", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_hashed_storage_migrated_events", "projects", column: "project_id", name: "fk_rails_687ed7d7c5", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_node_namespace_links", "geo_nodes", column: "geo_node_id", name: "fk_rails_546bf08d3e", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_node_namespace_links", "namespaces", column: "namespace_id", name: "fk_rails_41ff5fb854", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_node_statuses", "geo_nodes", column: "geo_node_id", name: "fk_rails_0ecc699c2a", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_repositories_changed_events", "geo_nodes", column: "geo_node_id", name: "fk_rails_75ec0fefcc", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_repository_created_events", "projects", column: "project_id", name: "fk_rails_1f49e46a61", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_repository_renamed_events", "projects", column: "project_id", name: "fk_rails_4e6524febb", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_repository_updated_events", "projects", column: "project_id", name: "fk_rails_2b70854c08", on_delete: :cascade)
+ add_concurrent_foreign_key("geo_reset_checksum_events", "projects", column: "project_id", name: "fk_rails_910a06f12b", on_delete: :cascade)
+ add_concurrent_foreign_key("gitlab_subscriptions", "namespaces", column: "namespace_id", name: "fk_e2595d00a1", on_delete: :cascade)
+ add_concurrent_foreign_key("gitlab_subscriptions", "plans", column: "hosted_plan_id", name: "fk_bd0c4019c3", on_delete: :cascade)
+ add_concurrent_foreign_key("identities", "saml_providers", column: "saml_provider_id", name: "fk_aade90f0fc", on_delete: :cascade)
+ add_concurrent_foreign_key("index_statuses", "projects", column: "project_id", name: "fk_74b2492545", on_delete: :cascade)
+ add_concurrent_foreign_key("insights", "namespaces", column: "namespace_id", name: "fk_rails_5c4391f60a", on_delete: nil)
+ add_concurrent_foreign_key("insights", "projects", column: "project_id", name: "fk_rails_f36fda3932", on_delete: nil)
+ add_concurrent_foreign_key("issue_links", "issues", column: "source_id", name: "fk_c900194ff2", on_delete: :cascade)
+ add_concurrent_foreign_key("issue_links", "issues", column: "target_id", name: "fk_e71bb44f1f", on_delete: :cascade)
+ add_concurrent_foreign_key("lists", "milestones", column: "milestone_id", name: "fk_rails_baed5f39b7", on_delete: :cascade)
+ add_concurrent_foreign_key("lists", "users", column: "user_id", name: "fk_d6cf4279f7", on_delete: :cascade)
+ add_concurrent_foreign_key("namespace_statistics", "namespaces", column: "namespace_id", name: "fk_rails_0062050394", on_delete: :cascade)
+ add_concurrent_foreign_key("namespaces", "namespaces", column: "custom_project_templates_group_id", name: "fk_e7a0b20a6b", on_delete: :nullify)
+ add_concurrent_foreign_key("namespaces", "plans", column: "plan_id", name: "fk_fdd12e5b80", on_delete: :nullify)
+ add_concurrent_foreign_key("namespaces", "projects", column: "file_template_project_id", name: "fk_319256d87a", on_delete: :nullify)
+ add_concurrent_foreign_key("notes", "reviews", column: "review_id", name: "fk_2e82291620", on_delete: :nullify)
+ add_concurrent_foreign_key("operations_feature_flag_scopes", "operations_feature_flags", column: "feature_flag_id", name: "fk_rails_a50a04d0a4", on_delete: :cascade)
+ add_concurrent_foreign_key("operations_feature_flags", "projects", column: "project_id", name: "fk_rails_648e241be7", on_delete: :cascade)
+ add_concurrent_foreign_key("operations_feature_flags_clients", "projects", column: "project_id", name: "fk_rails_6650ed902c", on_delete: :cascade)
+ add_concurrent_foreign_key("packages_maven_metadata", "packages_packages", column: "package_id", name: "fk_be88aed360", on_delete: :cascade)
+ add_concurrent_foreign_key("packages_package_files", "packages_packages", column: "package_id", name: "fk_86f0f182f8", on_delete: :cascade)
+ add_concurrent_foreign_key("packages_packages", "projects", column: "project_id", name: "fk_rails_e1ac527425", on_delete: :cascade)
+ add_concurrent_foreign_key("path_locks", "projects", column: "project_id", name: "fk_5265c98f24", on_delete: :cascade)
+ add_concurrent_foreign_key("path_locks", "users", column: "user_id", name: "fk_rails_762cdcf942", on_delete: nil)
+ add_concurrent_foreign_key("project_alerting_settings", "projects", column: "project_id", name: "fk_rails_27a84b407d", on_delete: :cascade)
+ add_concurrent_foreign_key("project_feature_usages", "projects", column: "project_id", name: "fk_rails_c22a50024b", on_delete: :cascade)
+ add_concurrent_foreign_key("project_incident_management_settings", "projects", column: "project_id", name: "fk_rails_9c2ea1b7dd", on_delete: :cascade)
+ add_concurrent_foreign_key("project_repository_states", "projects", column: "project_id", name: "fk_rails_0f2298ca8a", on_delete: :cascade)
+ add_concurrent_foreign_key("project_tracing_settings", "projects", column: "project_id", name: "fk_rails_fe56f57fc6", on_delete: :cascade)
+ add_concurrent_foreign_key("prometheus_alert_events", "projects", column: "project_id", name: "fk_rails_4675865839", on_delete: :cascade)
+ add_concurrent_foreign_key("prometheus_alert_events", "prometheus_alerts", column: "prometheus_alert_id", name: "fk_rails_106f901176", on_delete: :cascade)
+ add_concurrent_foreign_key("prometheus_alerts", "environments", column: "environment_id", name: "fk_rails_6d9b283465", on_delete: :cascade)
+ add_concurrent_foreign_key("prometheus_alerts", "projects", column: "project_id", name: "fk_rails_f0e8db86aa", on_delete: :cascade)
+ add_concurrent_foreign_key("prometheus_alerts", "prometheus_metrics", column: "prometheus_metric_id", name: "fk_rails_e6351447ec", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_branch_merge_access_levels", "namespaces", column: "group_id", name: "fk_98f3d044fe", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_branch_merge_access_levels", "users", column: "user_id", name: "fk_rails_5ffb4f3590", on_delete: nil)
+ add_concurrent_foreign_key("protected_branch_push_access_levels", "namespaces", column: "group_id", name: "fk_7111b68cdb", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_branch_push_access_levels", "users", column: "user_id", name: "fk_rails_8dcb712d65", on_delete: nil)
+ add_concurrent_foreign_key("protected_branch_unprotect_access_levels", "namespaces", column: "group_id", name: "fk_rails_5be1abfc25", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_branch_unprotect_access_levels", "protected_branches", column: "protected_branch_id", name: "fk_rails_e9eb8dc025", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_branch_unprotect_access_levels", "users", column: "user_id", name: "fk_rails_2d2aba21ef", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_environment_deploy_access_levels", "namespaces", column: "group_id", name: "fk_rails_45cc02a931", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_environment_deploy_access_levels", "protected_environments", column: "protected_environment_id", name: "fk_rails_898a13b650", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_environment_deploy_access_levels", "users", column: "user_id", name: "fk_rails_5b9f6970fe", on_delete: :cascade)
+ add_concurrent_foreign_key("protected_environments", "projects", column: "project_id", name: "fk_rails_a354313d11", on_delete: :cascade)
+ add_concurrent_foreign_key("push_rules", "projects", column: "project_id", name: "fk_83b29894de", on_delete: :cascade)
+ add_concurrent_foreign_key("resource_label_events", "epics", column: "epic_id", name: "fk_rails_75efb0a653", on_delete: :cascade)
+ add_concurrent_foreign_key("reviews", "merge_requests", column: "merge_request_id", name: "fk_rails_5ca11d8c31", on_delete: :cascade)
+ add_concurrent_foreign_key("reviews", "projects", column: "project_id", name: "fk_rails_64798be025", on_delete: :cascade)
+ add_concurrent_foreign_key("reviews", "users", column: "author_id", name: "fk_rails_29e6f859c4", on_delete: :nullify)
+ add_concurrent_foreign_key("saml_providers", "namespaces", column: "group_id", name: "fk_rails_306d459be7", on_delete: :cascade)
+ add_concurrent_foreign_key("scim_oauth_access_tokens", "namespaces", column: "group_id", name: "fk_rails_c84404fb6c", on_delete: :cascade)
+ add_concurrent_foreign_key("slack_integrations", "services", column: "service_id", name: "fk_rails_73db19721a", on_delete: :cascade)
+ add_concurrent_foreign_key("smartcard_identities", "users", column: "user_id", name: "fk_rails_4689f889a9", on_delete: :cascade)
+ add_concurrent_foreign_key("software_license_policies", "projects", column: "project_id", name: "fk_rails_87b2247ce5", on_delete: :cascade)
+ add_concurrent_foreign_key("software_license_policies", "software_licenses", column: "software_license_id", name: "fk_rails_7a7a2a92de", on_delete: :cascade)
+ add_concurrent_foreign_key("users", "namespaces", column: "managing_group_id", name: "fk_a4b8fefe3e", on_delete: :nullify)
+ add_concurrent_foreign_key("users_ops_dashboard_projects", "projects", column: "project_id", name: "fk_rails_9b4ebf005b", on_delete: :cascade)
+ add_concurrent_foreign_key("users_ops_dashboard_projects", "users", column: "user_id", name: "fk_rails_220a0562db", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_feedback", "ci_pipelines", column: "pipeline_id", name: "fk_rails_20976e6fd9", on_delete: :nullify)
+ add_concurrent_foreign_key("vulnerability_feedback", "issues", column: "issue_id", name: "fk_rails_8c77e5891a", on_delete: :nullify)
+ add_concurrent_foreign_key("vulnerability_feedback", "merge_requests", column: "merge_request_id", name: "fk_563ff1912e", on_delete: :nullify)
+ add_concurrent_foreign_key("vulnerability_feedback", "projects", column: "project_id", name: "fk_rails_debd54e456", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_feedback", "users", column: "author_id", name: "fk_rails_472f69b043", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_identifiers", "projects", column: "project_id", name: "fk_rails_a67a16c885", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_occurrence_identifiers", "vulnerability_identifiers", column: "identifier_id", name: "fk_rails_be2e49e1d0", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_occurrence_identifiers", "vulnerability_occurrences", column: "occurrence_id", name: "fk_rails_e4ef6d027c", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_occurrence_pipelines", "ci_pipelines", column: "pipeline_id", name: "fk_rails_6421e35d7d", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_occurrence_pipelines", "vulnerability_occurrences", column: "occurrence_id", name: "fk_rails_dc3ae04693", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_occurrences", "projects", column: "project_id", name: "fk_rails_90fed4faba", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_occurrences", "vulnerability_identifiers", column: "primary_identifier_id", name: "fk_rails_c8661a61eb", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_occurrences", "vulnerability_scanners", column: "scanner_id", name: "fk_rails_bf5b788ca7", on_delete: :cascade)
+ add_concurrent_foreign_key("vulnerability_scanners", "projects", column: "project_id", name: "fk_rails_5c9d42a221", on_delete: :cascade)
+ add_concurrent_foreign_key("dependency_proxy_blobs", "namespaces", column: "group_id", on_delete: :cascade)
+ add_concurrent_foreign_key("dependency_proxy_group_settings", "namespaces", column: "group_id", on_delete: :cascade)
+ add_concurrent_foreign_key("jira_connect_subscriptions", "jira_connect_installations", column: "jira_connect_installation_id", on_delete: :cascade)
+ add_concurrent_foreign_key("jira_connect_subscriptions", "namespaces", column: "namespace_id", on_delete: :cascade)
+
+ remove_foreign_key_without_error("protected_tag_create_access_levels", column: :group_id)
+ add_concurrent_foreign_key("protected_tag_create_access_levels", "namespaces", column: :group_id, name: "fk_b4eb82fe3c", on_delete: :cascade)
+ end
+
+ def remove_foreign_keys
+ remove_foreign_key_without_error("application_settings", column: "custom_project_templates_group_id")
+ remove_foreign_key_without_error("application_settings", column: "file_template_project_id")
+ remove_foreign_key_without_error("approval_merge_request_rule_sources", column: "approval_merge_request_rule_id")
+ remove_foreign_key_without_error("approval_merge_request_rule_sources", column: "approval_project_rule_id")
+ remove_foreign_key_without_error("approval_merge_request_rules", column: "merge_request_id")
+ remove_foreign_key_without_error("approval_merge_request_rules_approved_approvers", column: "approval_merge_request_rule_id")
+ remove_foreign_key_without_error("approval_merge_request_rules_approved_approvers", column: "user_id")
+ remove_foreign_key_without_error("approval_merge_request_rules_groups", column: "approval_merge_request_rule_id")
+ remove_foreign_key_without_error("approval_merge_request_rules_groups", column: "group_id")
+ remove_foreign_key_without_error("approval_merge_request_rules_users", column: "approval_merge_request_rule_id")
+ remove_foreign_key_without_error("approval_merge_request_rules_users", column: "user_id")
+ remove_foreign_key_without_error("approval_project_rules", column: "project_id")
+ remove_foreign_key_without_error("approval_project_rules_groups", column: "approval_project_rule_id")
+ remove_foreign_key_without_error("approval_project_rules_groups", column: "group_id")
+ remove_foreign_key_without_error("approval_project_rules_users", column: "approval_project_rule_id")
+ remove_foreign_key_without_error("approval_project_rules_users", column: "user_id")
+ remove_foreign_key_without_error("approvals", column: "merge_request_id")
+ remove_foreign_key_without_error("approver_groups", column: "group_id")
+ remove_foreign_key_without_error("board_assignees", column: "board_id")
+ remove_foreign_key_without_error("board_assignees", column: "assignee_id")
+ remove_foreign_key_without_error("board_labels", column: "board_id")
+ remove_foreign_key_without_error("board_labels", column: "label_id")
+ remove_foreign_key_without_error("ci_sources_pipelines", column: "source_job_id")
+ remove_foreign_key_without_error("ci_sources_pipelines", column: "pipeline_id")
+ remove_foreign_key_without_error("ci_sources_pipelines", column: "source_pipeline_id")
+ remove_foreign_key_without_error("ci_sources_pipelines", column: "source_project_id")
+ remove_foreign_key_without_error("ci_sources_pipelines", column: "project_id")
+ remove_foreign_key_without_error("design_management_designs", column: "issue_id")
+ remove_foreign_key_without_error("design_management_designs", column: "project_id")
+ remove_foreign_key_without_error("design_management_versions", column: "design_management_design_id")
+ remove_foreign_key_without_error("draft_notes", column: "merge_request_id")
+ remove_foreign_key_without_error("draft_notes", column: "author_id")
+ remove_foreign_key_without_error("elasticsearch_indexed_namespaces", column: "namespace_id")
+ remove_foreign_key_without_error("elasticsearch_indexed_projects", column: "project_id")
+ remove_foreign_key_without_error("epic_issues", column: "epic_id")
+ remove_foreign_key_without_error("epic_issues", column: "issue_id")
+ remove_foreign_key_without_error("epic_metrics", column: "epic_id")
+ remove_foreign_key_without_error("epics", column: "parent_id")
+ remove_foreign_key_without_error("epics", column: "milestone_id")
+ remove_foreign_key_without_error("epics", column: "group_id")
+ remove_foreign_key_without_error("epics", column: "assignee_id")
+ remove_foreign_key_without_error("epics", column: "author_id")
+ remove_foreign_key_without_error("epics", column: "closed_by_id")
+ remove_foreign_key_without_error("geo_event_log", column: "cache_invalidation_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "hashed_storage_migrated_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "job_artifact_deleted_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "lfs_object_deleted_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "repositories_changed_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "repository_created_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "repository_deleted_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "repository_renamed_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "repository_updated_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "reset_checksum_event_id")
+ remove_foreign_key_without_error("geo_event_log", column: "upload_deleted_event_id")
+ remove_foreign_key_without_error("geo_hashed_storage_attachments_events", column: "project_id")
+ remove_foreign_key_without_error("geo_hashed_storage_migrated_events", column: "project_id")
+ remove_foreign_key_without_error("geo_node_namespace_links", column: "geo_node_id")
+ remove_foreign_key_without_error("geo_node_namespace_links", column: "namespace_id")
+ remove_foreign_key_without_error("geo_node_statuses", column: "geo_node_id")
+ remove_foreign_key_without_error("geo_repositories_changed_events", column: "geo_node_id")
+ remove_foreign_key_without_error("geo_repository_created_events", column: "project_id")
+ remove_foreign_key_without_error("geo_repository_renamed_events", column: "project_id")
+ remove_foreign_key_without_error("geo_repository_updated_events", column: "project_id")
+ remove_foreign_key_without_error("geo_reset_checksum_events", column: "project_id")
+ remove_foreign_key_without_error("gitlab_subscriptions", column: "namespace_id")
+ remove_foreign_key_without_error("gitlab_subscriptions", column: "hosted_plan_id")
+ remove_foreign_key_without_error("identities", column: "saml_provider_id")
+ remove_foreign_key_without_error("index_statuses", column: "project_id")
+ remove_foreign_key_without_error("insights", column: "namespace_id", on_delete: nil)
+ remove_foreign_key_without_error("insights", column: "project_id", on_delete: nil)
+ remove_foreign_key_without_error("issue_links", column: "source_id")
+ remove_foreign_key_without_error("issue_links", column: "target_id")
+ remove_foreign_key_without_error("lists", column: "milestone_id")
+ remove_foreign_key_without_error("lists", column: "user_id")
+ remove_foreign_key_without_error("namespace_statistics", column: "namespace_id")
+ remove_foreign_key_without_error("namespaces", column: "custom_project_templates_group_id")
+ remove_foreign_key_without_error("namespaces", column: "plan_id")
+ remove_foreign_key_without_error("namespaces", column: "file_template_project_id")
+ remove_foreign_key_without_error("notes", column: "review_id")
+ remove_foreign_key_without_error("operations_feature_flag_scopes", column: "feature_flag_id")
+ remove_foreign_key_without_error("operations_feature_flags", column: "project_id")
+ remove_foreign_key_without_error("operations_feature_flags_clients", column: "project_id")
+ remove_foreign_key_without_error("packages_maven_metadata", column: "package_id")
+ remove_foreign_key_without_error("packages_package_files", column: "package_id")
+ remove_foreign_key_without_error("packages_packages", column: "project_id")
+ remove_foreign_key_without_error("path_locks", column: "project_id")
+ remove_foreign_key_without_error("path_locks", column: "user_id", on_delete: nil)
+ remove_foreign_key_without_error("project_alerting_settings", column: "project_id")
+ remove_foreign_key_without_error("project_feature_usages", column: "project_id")
+ remove_foreign_key_without_error("project_incident_management_settings", column: "project_id")
+ remove_foreign_key_without_error("project_repository_states", column: "project_id")
+ remove_foreign_key_without_error("project_tracing_settings", column: "project_id")
+ remove_foreign_key_without_error("prometheus_alert_events", column: "project_id")
+ remove_foreign_key_without_error("prometheus_alert_events", column: "prometheus_alert_id")
+ remove_foreign_key_without_error("prometheus_alerts", column: "environment_id")
+ remove_foreign_key_without_error("prometheus_alerts", column: "project_id")
+ remove_foreign_key_without_error("prometheus_alerts", column: "prometheus_metric_id")
+ remove_foreign_key_without_error("protected_branch_merge_access_levels", column: "group_id")
+ remove_foreign_key_without_error("protected_branch_merge_access_levels", column: "user_id", on_delete: nil)
+ remove_foreign_key_without_error("protected_branch_push_access_levels", column: "group_id")
+ remove_foreign_key_without_error("protected_branch_push_access_levels", column: "user_id", on_delete: nil)
+ remove_foreign_key_without_error("protected_branch_unprotect_access_levels", column: "group_id")
+ remove_foreign_key_without_error("protected_branch_unprotect_access_levels", column: "protected_branch_id")
+ remove_foreign_key_without_error("protected_branch_unprotect_access_levels", column: "user_id")
+ remove_foreign_key_without_error("protected_environment_deploy_access_levels", column: "group_id")
+ remove_foreign_key_without_error("protected_environment_deploy_access_levels", column: "protected_environment_id")
+ remove_foreign_key_without_error("protected_environment_deploy_access_levels", column: "user_id")
+ remove_foreign_key_without_error("protected_environments", column: "project_id")
+ remove_foreign_key_without_error("push_rules", column: "project_id")
+ remove_foreign_key_without_error("resource_label_events", column: "epic_id")
+ remove_foreign_key_without_error("reviews", column: "merge_request_id")
+ remove_foreign_key_without_error("reviews", column: "project_id")
+ remove_foreign_key_without_error("reviews", column: "author_id")
+ remove_foreign_key_without_error("saml_providers", column: "group_id")
+ remove_foreign_key_without_error("scim_oauth_access_tokens", column: "group_id")
+ remove_foreign_key_without_error("slack_integrations", column: "service_id")
+ remove_foreign_key_without_error("smartcard_identities", column: "user_id")
+ remove_foreign_key_without_error("software_license_policies", column: "project_id")
+ remove_foreign_key_without_error("software_license_policies", column: "software_license_id")
+ remove_foreign_key_without_error("users", column: "managing_group_id")
+ remove_foreign_key_without_error("users_ops_dashboard_projects", column: "project_id")
+ remove_foreign_key_without_error("users_ops_dashboard_projects", column: "user_id")
+ remove_foreign_key_without_error("vulnerability_feedback", column: "pipeline_id")
+ remove_foreign_key_without_error("vulnerability_feedback", column: "issue_id")
+ remove_foreign_key_without_error("vulnerability_feedback", column: "merge_request_id")
+ remove_foreign_key_without_error("vulnerability_feedback", column: "project_id")
+ remove_foreign_key_without_error("vulnerability_feedback", column: "author_id")
+ remove_foreign_key_without_error("vulnerability_identifiers", column: "project_id")
+ remove_foreign_key_without_error("vulnerability_occurrence_identifiers", column: "identifier_id")
+ remove_foreign_key_without_error("vulnerability_occurrence_identifiers", column: "occurrence_id")
+ remove_foreign_key_without_error("vulnerability_occurrence_pipelines", column: "pipeline_id")
+ remove_foreign_key_without_error("vulnerability_occurrence_pipelines", column: "occurrence_id")
+ remove_foreign_key_without_error("vulnerability_occurrences", column: "project_id")
+ remove_foreign_key_without_error("vulnerability_occurrences", column: "primary_identifier_id")
+ remove_foreign_key_without_error("vulnerability_occurrences", column: "scanner_id")
+ remove_foreign_key_without_error("vulnerability_scanners", column: "project_id")
+ remove_foreign_key_without_error("dependency_proxy_blobs", column: "group_id")
+ remove_foreign_key_without_error("dependency_proxy_group_settings", column: "group_id")
+ remove_foreign_key_without_error("jira_connect_subscriptions", "jira_connect_installations", column: "jira_connect_installation_id")
+ remove_foreign_key_without_error("jira_connect_subscriptions", "namespaces", column: "namespace_id")
+
+ remove_foreign_key_without_error("protected_tag_create_access_levels", column: :group_id)
+ add_concurrent_foreign_key("protected_tag_create_access_levels", "namespaces", column: :group_id, on_delete: nil)
+ end
+end
+# rubocop: enable Metrics/AbcSize
+# rubocop: enable Migration/Datetime
diff --git a/db/migrate/20190403161806_update_designs_index.rb b/db/migrate/20190403161806_update_designs_index.rb
new file mode 100644
index 00000000000..78517e372d5
--- /dev/null
+++ b/db/migrate/20190403161806_update_designs_index.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class UpdateDesignsIndex < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index :design_management_designs, :issue_id, unique: true
+ end
+
+ def down
+ add_concurrent_index :design_management_designs, :issue_id, unique: true
+ end
+end
diff --git a/db/migrate/20190409224933_add_name_to_geo_nodes.rb b/db/migrate/20190409224933_add_name_to_geo_nodes.rb
new file mode 100644
index 00000000000..2dff81b429c
--- /dev/null
+++ b/db/migrate/20190409224933_add_name_to_geo_nodes.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddNameToGeoNodes < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ def up
+ add_column :geo_nodes, :name, :string
+
+ # url is also unique, and its type and size is identical to the name column,
+ # so this is safe.
+ execute "UPDATE geo_nodes SET name = url;"
+
+ # url is also `null: false`, so this is safe.
+ change_column :geo_nodes, :name, :string, null: false
+ end
+
+ def down
+ remove_column :geo_nodes, :name
+ end
+end
diff --git a/db/migrate/20190410173409_add_name_index_to_geo_nodes.rb b/db/migrate/20190410173409_add_name_index_to_geo_nodes.rb
new file mode 100644
index 00000000000..efbdaf1d025
--- /dev/null
+++ b/db/migrate/20190410173409_add_name_index_to_geo_nodes.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddNameIndexToGeoNodes < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :geo_nodes, :name, unique: true
+ end
+
+ def down
+ remove_concurrent_index :geo_nodes, :name
+ end
+end
diff --git a/db/migrate/20190412183653_remove_url_index_from_geo_nodes.rb b/db/migrate/20190412183653_remove_url_index_from_geo_nodes.rb
new file mode 100644
index 00000000000..86a46260553
--- /dev/null
+++ b/db/migrate/20190412183653_remove_url_index_from_geo_nodes.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class RemoveUrlIndexFromGeoNodes < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index :geo_nodes, :url
+ end
+
+ def down
+ add_concurrent_index :geo_nodes, :url, unique: true
+ end
+end
diff --git a/db/migrate/20190414185432_add_comment_to_vulnerability_feedback.rb b/db/migrate/20190414185432_add_comment_to_vulnerability_feedback.rb
new file mode 100644
index 00000000000..63644a2f8fd
--- /dev/null
+++ b/db/migrate/20190414185432_add_comment_to_vulnerability_feedback.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddCommentToVulnerabilityFeedback < ActiveRecord::Migration[5.1]
+ DOWNTIME = false
+
+ def up
+ add_column :vulnerability_feedback, :comment_author_id, :integer
+ add_column :vulnerability_feedback, :comment, :text
+ add_column :vulnerability_feedback, :comment_timestamp, :datetime_with_timezone
+ end
+
+ def down
+ remove_column :vulnerability_feedback, :comment_author_id
+ remove_column :vulnerability_feedback, :comment
+ remove_column :vulnerability_feedback, :comment_timestamp
+ end
+end
diff --git a/db/migrate/20190415172035_update_insights_foreign_keys.rb b/db/migrate/20190415172035_update_insights_foreign_keys.rb
new file mode 100644
index 00000000000..5d3aa4c05e9
--- /dev/null
+++ b/db/migrate/20190415172035_update_insights_foreign_keys.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+# rubocop: disable Migration/AddConcurrentForeignKey
+
+class UpdateInsightsForeignKeys < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ remove_foreign_key_if_exists(:insights, column: :project_id)
+ add_foreign_key(:insights, :projects, column: :project_id, on_delete: :cascade)
+
+ remove_foreign_key_if_exists(:insights, column: :namespace_id)
+ add_foreign_key(:insights, :namespaces, column: :namespace_id, on_delete: :cascade)
+ end
+
+ def down
+ remove_foreign_key_if_exists(:insights, column: :namespace_id)
+ add_foreign_key(:insights, :namespaces, column: :namespace_id)
+
+ remove_foreign_key_if_exists(:insights, column: :project_id)
+ add_foreign_key(:insights, :projects, column: :project_id)
+ end
+end
diff --git a/db/migrate/20190418132750_add_foreign_key_from_vulnerability_feedback_to_users.rb b/db/migrate/20190418132750_add_foreign_key_from_vulnerability_feedback_to_users.rb
new file mode 100644
index 00000000000..0bd9012aee8
--- /dev/null
+++ b/db/migrate/20190418132750_add_foreign_key_from_vulnerability_feedback_to_users.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddForeignKeyFromVulnerabilityFeedbackToUsers < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :vulnerability_feedback, :users, column: :comment_author_id, on_delete: :nullify
+ add_concurrent_index :vulnerability_feedback, :comment_author_id
+ end
+
+ def down
+ remove_foreign_key :vulnerability_feedback, column: :comment_author_id
+ remove_concurrent_index :vulnerability_feedback, :comment_author_id
+ end
+end
diff --git a/db/migrate/20190419121952_add_bridged_pipeline_id_to_bridges.rb b/db/migrate/20190419121952_add_bridged_pipeline_id_to_bridges.rb
new file mode 100644
index 00000000000..fac556c1897
--- /dev/null
+++ b/db/migrate/20190419121952_add_bridged_pipeline_id_to_bridges.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddBridgedPipelineIdToBridges < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ def change
+ add_column :ci_builds, :upstream_pipeline_id, :integer
+ end
+end
diff --git a/db/migrate/20190419123057_add_bridged_pipeline_id_foreign_key.rb b/db/migrate/20190419123057_add_bridged_pipeline_id_foreign_key.rb
new file mode 100644
index 00000000000..c31ec7bc107
--- /dev/null
+++ b/db/migrate/20190419123057_add_bridged_pipeline_id_foreign_key.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddBridgedPipelineIdForeignKey < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :ci_builds, :upstream_pipeline_id, where: 'upstream_pipeline_id IS NOT NULL'
+ add_concurrent_foreign_key :ci_builds, :ci_pipelines, column: :upstream_pipeline_id
+ end
+
+ def down
+ remove_foreign_key :ci_builds, column: :upstream_pipeline_id
+ remove_concurrent_index :ci_builds, :upstream_pipeline_id
+ end
+end
diff --git a/db/migrate/20190423124640_add_index_to_projects_mirror_user_id.rb b/db/migrate/20190423124640_add_index_to_projects_mirror_user_id.rb
new file mode 100644
index 00000000000..b008d8ce0cc
--- /dev/null
+++ b/db/migrate/20190423124640_add_index_to_projects_mirror_user_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexToProjectsMirrorUserId < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :projects, :mirror_user_id
+ end
+
+ def down
+ remove_concurrent_index :projects, :mirror_user_id
+ end
+end
diff --git a/db/migrate/20190520200123_add_rule_type_to_approval_merge_request_approval_rules.rb b/db/migrate/20190520200123_add_rule_type_to_approval_merge_request_approval_rules.rb
new file mode 100644
index 00000000000..7339a4fccba
--- /dev/null
+++ b/db/migrate/20190520200123_add_rule_type_to_approval_merge_request_approval_rules.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddRuleTypeToApprovalMergeRequestApprovalRules < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_column_with_default(:approval_merge_request_rules, :rule_type, :integer, limit: 2, default: 1)
+ end
+
+ def down
+ remove_column(:approval_merge_request_rules, :rule_type)
+ end
+end
diff --git a/db/migrate/20190528173628_add_index_for_code_owner_rule_type_on_approval_merge_request_rules.rb b/db/migrate/20190528173628_add_index_for_code_owner_rule_type_on_approval_merge_request_rules.rb
new file mode 100644
index 00000000000..96d878a98f2
--- /dev/null
+++ b/db/migrate/20190528173628_add_index_for_code_owner_rule_type_on_approval_merge_request_rules.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddIndexForCodeOwnerRuleTypeOnApprovalMergeRequestRules < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ INDEX_CODE_OWNERS_RULES_UNIQUENESS_NAME = 'index_approval_rule_name_for_code_owners_rule_type'
+ INDEX_CODE_OWNERS_RULES_QUERY_NAME = 'index_approval_rules_code_owners_rule_type'
+
+ class ApprovalMergeRequestRule < ActiveRecord::Base
+ include EachBatch
+
+ enum rule_types: {
+ regular: 1,
+ code_owner: 2
+ }
+ end
+
+ def up
+ # Ensure only 1 code_owner rule per merge_request
+ add_concurrent_index(
+ :approval_merge_request_rules,
+ [:merge_request_id, :rule_type, :name],
+ unique: true,
+ where: "rule_type = #{ApprovalMergeRequestRule.rule_types[:code_owner]}",
+ name: INDEX_CODE_OWNERS_RULES_UNIQUENESS_NAME
+ )
+
+ # Support lookups for all code_owner rules per merge_request
+ add_concurrent_index(
+ :approval_merge_request_rules,
+ [:merge_request_id, :rule_type],
+ where: "rule_type = #{ApprovalMergeRequestRule.rule_types[:code_owner]}",
+ name: INDEX_CODE_OWNERS_RULES_QUERY_NAME
+ )
+ end
+
+ def down
+ remove_concurrent_index_by_name(
+ :approval_merge_request_rules,
+ INDEX_CODE_OWNERS_RULES_UNIQUENESS_NAME
+ )
+
+ remove_concurrent_index_by_name(
+ :approval_merge_request_rules,
+ INDEX_CODE_OWNERS_RULES_QUERY_NAME
+ )
+ end
+end
diff --git a/db/migrate/20190603124955_add_index_to_count_pending_mirror_updates.rb b/db/migrate/20190603124955_add_index_to_count_pending_mirror_updates.rb
new file mode 100644
index 00000000000..6aa94f7b20b
--- /dev/null
+++ b/db/migrate/20190603124955_add_index_to_count_pending_mirror_updates.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexToCountPendingMirrorUpdates < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :project_mirror_data, [:last_update_at, :retry_count]
+ end
+
+ def down
+ remove_concurrent_index :project_mirror_data, [:last_update_at, :retry_count]
+ end
+end
diff --git a/db/post_migrate/20161128170531_drop_user_activities_table.rb b/db/post_migrate/20161128170531_drop_user_activities_table.rb
index 64d13a08953..d8b1e0731f3 100644
--- a/db/post_migrate/20161128170531_drop_user_activities_table.rb
+++ b/db/post_migrate/20161128170531_drop_user_activities_table.rb
@@ -1,9 +1,33 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
class DropUserActivitiesTable < ActiveRecord::Migration[4.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
- # This migration is a no-op. It just exists to match EE.
- def change
+ # When using the methods "add_concurrent_index" or "add_column_with_default"
+ # you must disable the use of transactions as these methods can not run in an
+ # existing transaction. When using "add_concurrent_index" make sure that this
+ # method is the _only_ method called in the migration, any other changes
+ # should go in a separate migration. This ensures that upon failure _only_ the
+ # index creation fails and can be retried or reverted easily.
+ #
+ # To disable transactions uncomment the following line and remove these
+ # comments:
+ # disable_ddl_transaction!
+
+ def up
+ drop_table :user_activities if table_exists?(:user_activities)
+ end
+
+ def down
+ unless table_exists?(:user_activities)
+ create_table "user_activities", force: :cascade do |t|
+ t.integer "user_id"
+ t.datetime "last_activity_at", null: false
+ end
+
+ add_index "user_activities", ["user_id"], name: "index_user_activities_on_user_id", unique: true, using: :btree
+ end
end
end
diff --git a/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb b/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb
deleted file mode 100644
index c018d30c175..00000000000
--- a/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# This is the counterpart of RequeuePendingDeleteProjects and cleans all
-# projects with `pending_delete = true` and that do not have a namespace.
-class CleanupNamespacelessPendingDeleteProjects < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- @offset = 0
-
- loop do
- ids = pending_delete_batch
-
- break if ids.empty?
-
- args = ids.map { |id| Array(id) }
-
- NamespacelessProjectDestroyWorker.bulk_perform_async(args)
-
- @offset += 1
- end
- end
-
- def down
- # noop
- end
-
- private
-
- def pending_delete_batch
- connection.exec_query(find_batch).map { |row| row['id'].to_i }
- end
-
- BATCH_SIZE = 5000
-
- def find_batch
- projects = Arel::Table.new(:projects)
- projects.project(projects[:id])
- .where(projects[:pending_delete].eq(true))
- .where(projects[:namespace_id].eq(nil))
- .skip(@offset * BATCH_SIZE)
- .take(BATCH_SIZE)
- .to_sql
- end
-end
diff --git a/db/post_migrate/20170703130158_schedule_merge_request_diff_migrations.rb b/db/post_migrate/20170703130158_schedule_merge_request_diff_migrations.rb
deleted file mode 100644
index fd4b2859f7f..00000000000
--- a/db/post_migrate/20170703130158_schedule_merge_request_diff_migrations.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-class ScheduleMergeRequestDiffMigrations < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 2500
- MIGRATION = 'DeserializeMergeRequestDiffsAndCommits'
-
- disable_ddl_transaction!
-
- class MergeRequestDiff < ActiveRecord::Base
- self.table_name = 'merge_request_diffs'
-
- include ::EachBatch
- end
-
- # Assuming that there are 5 million rows affected (which is more than on
- # GitLab.com), and that each batch of 2,500 rows takes up to 5 minutes, then
- # we can migrate all the rows in 7 days.
- #
- # On staging, plucking the IDs themselves takes 5 seconds.
- def up
- non_empty = 'st_commits IS NOT NULL OR st_diffs IS NOT NULL'
-
- MergeRequestDiff.where(non_empty).each_batch(of: BATCH_SIZE) do |relation, index|
- range = relation.pluck('MIN(id)', 'MAX(id)').first
-
- BackgroundMigrationWorker.perform_in(index * 5.minutes, MIGRATION, range)
- end
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20170926150348_schedule_merge_request_diff_migrations_take_two.rb b/db/post_migrate/20170926150348_schedule_merge_request_diff_migrations_take_two.rb
deleted file mode 100644
index 9b675a51725..00000000000
--- a/db/post_migrate/20170926150348_schedule_merge_request_diff_migrations_take_two.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-class ScheduleMergeRequestDiffMigrationsTakeTwo < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 500
- MIGRATION = 'DeserializeMergeRequestDiffsAndCommits'
- DELAY_INTERVAL = 10.minutes
-
- disable_ddl_transaction!
-
- class MergeRequestDiff < ActiveRecord::Base
- self.table_name = 'merge_request_diffs'
-
- include ::EachBatch
-
- default_scope { where('st_commits IS NOT NULL OR st_diffs IS NOT NULL') }
- end
-
- # By this point, we assume ScheduleMergeRequestDiffMigrations - the first
- # version of this - has already run. On GitLab.com, we have ~220k un-migrated
- # rows, but these rows will, in general, take a long time.
- #
- # With a gap of 10 minutes per batch, and 500 rows per batch, these migrations
- # are scheduled over 220_000 / 500 / 6 ~= 74 hours, which is a little over
- # three days.
- def up
- queue_background_migration_jobs_by_range_at_intervals(MergeRequestDiff, MIGRATION, DELAY_INTERVAL, batch_size: BATCH_SIZE)
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20171005130944_schedule_create_gpg_key_subkeys_from_gpg_keys.rb b/db/post_migrate/20171005130944_schedule_create_gpg_key_subkeys_from_gpg_keys.rb
deleted file mode 100644
index e49a70f902c..00000000000
--- a/db/post_migrate/20171005130944_schedule_create_gpg_key_subkeys_from_gpg_keys.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class ScheduleCreateGpgKeySubkeysFromGpgKeys < ActiveRecord::Migration[4.2]
- disable_ddl_transaction!
-
- DOWNTIME = false
- MIGRATION = 'CreateGpgKeySubkeysFromGpgKeys'
-
- class GpgKey < ActiveRecord::Base
- self.table_name = 'gpg_keys'
-
- include EachBatch
- end
-
- def up
- GpgKey.select(:id).each_batch do |gpg_keys|
- jobs = gpg_keys.pluck(:id).map do |id|
- [MIGRATION, [id]]
- end
-
- BackgroundMigrationWorker.bulk_perform_async(jobs)
- end
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20171128214150_schedule_populate_merge_request_metrics_with_events_data.rb b/db/post_migrate/20171128214150_schedule_populate_merge_request_metrics_with_events_data.rb
deleted file mode 100644
index 51441a36e4b..00000000000
--- a/db/post_migrate/20171128214150_schedule_populate_merge_request_metrics_with_events_data.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-class SchedulePopulateMergeRequestMetricsWithEventsData < ActiveRecord::Migration[4.2]
- DOWNTIME = false
- BATCH_SIZE = 10_000
- MIGRATION = 'PopulateMergeRequestMetricsWithEventsData'
-
- disable_ddl_transaction!
-
- class MergeRequest < ActiveRecord::Base
- self.table_name = 'merge_requests'
-
- include ::EachBatch
- end
-
- def up
- say 'Scheduling `PopulateMergeRequestMetricsWithEventsData` jobs'
- # It will update around 4_000_000 records in batches of 10_000 merge
- # requests (running between 10 minutes) and should take around 66 hours to complete.
- # Apparently, production PostgreSQL is able to vacuum 10k-20k dead_tuples by
- # minute, and at maximum, each of these jobs should UPDATE 20k records.
- #
- # More information about the updates in `PopulateMergeRequestMetricsWithEventsData` class.
- #
- MergeRequest.all.each_batch(of: BATCH_SIZE) do |relation, index|
- range = relation.pluck('MIN(id)', 'MAX(id)').first
-
- BackgroundMigrationWorker.perform_in(index * 10.minutes, MIGRATION, range)
- end
- end
-
- def down
- execute "update merge_request_metrics set latest_closed_at = null"
- execute "update merge_request_metrics set latest_closed_by_id = null"
- execute "update merge_request_metrics set merged_by_id = null"
- end
-end
diff --git a/db/post_migrate/20171207150343_remove_soft_removed_objects.rb b/db/post_migrate/20171207150343_remove_soft_removed_objects.rb
deleted file mode 100644
index 53707c67d36..00000000000
--- a/db/post_migrate/20171207150343_remove_soft_removed_objects.rb
+++ /dev/null
@@ -1,208 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RemoveSoftRemovedObjects < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- module SoftRemoved
- extend ActiveSupport::Concern
-
- included do
- scope :soft_removed, -> { where('deleted_at IS NOT NULL') }
- end
- end
-
- class User < ActiveRecord::Base
- self.table_name = 'users'
-
- include EachBatch
- end
-
- class Issue < ActiveRecord::Base
- self.table_name = 'issues'
-
- include EachBatch
- include SoftRemoved
- end
-
- class MergeRequest < ActiveRecord::Base
- self.table_name = 'merge_requests'
-
- include EachBatch
- include SoftRemoved
- end
-
- class Namespace < ActiveRecord::Base
- self.table_name = 'namespaces'
-
- include EachBatch
- include SoftRemoved
-
- scope :soft_removed_personal, -> { soft_removed.where(type: nil) }
- scope :soft_removed_group, -> { soft_removed.where(type: 'Group') }
- end
-
- class Route < ActiveRecord::Base
- self.table_name = 'routes'
-
- include EachBatch
- include SoftRemoved
- end
-
- class Project < ActiveRecord::Base
- self.table_name = 'projects'
-
- include EachBatch
- include SoftRemoved
- end
-
- class CiPipelineSchedule < ActiveRecord::Base
- self.table_name = 'ci_pipeline_schedules'
-
- include EachBatch
- include SoftRemoved
- end
-
- class CiTrigger < ActiveRecord::Base
- self.table_name = 'ci_triggers'
-
- include EachBatch
- include SoftRemoved
- end
-
- MODELS = [Issue, MergeRequest, CiPipelineSchedule, CiTrigger].freeze
-
- def up
- disable_statement_timeout do
- remove_personal_routes
- remove_personal_namespaces
- remove_group_namespaces
- remove_simple_soft_removed_rows
- end
- end
-
- def down
- # The data removed by this migration can't be restored in an automated way.
- end
-
- def remove_simple_soft_removed_rows
- create_temporary_indexes
-
- MODELS.each do |model|
- say_with_time("Removing soft removed rows from #{model.table_name}") do
- model.soft_removed.each_batch do |batch, index|
- batch.delete_all
- end
- end
- end
- ensure
- remove_temporary_indexes
- end
-
- def create_temporary_indexes
- MODELS.each do |model|
- index_name = temporary_index_name_for(model)
-
- # Without this index the removal process can take a very long time. For
- # example, getting the next ID of a batch for the `issues` table in
- # staging would take between 15 and 20 seconds.
- next if temporary_index_exists?(model)
-
- say_with_time("Creating temporary index #{index_name}") do
- add_concurrent_index(
- model.table_name,
- [:deleted_at, :id],
- name: index_name,
- where: 'deleted_at IS NOT NULL'
- )
- end
- end
- end
-
- def remove_temporary_indexes
- MODELS.each do |model|
- index_name = temporary_index_name_for(model)
-
- next unless temporary_index_exists?(model)
-
- say_with_time("Removing temporary index #{index_name}") do
- remove_concurrent_index_by_name(model.table_name, index_name)
- end
- end
- end
-
- def temporary_index_name_for(model)
- "index_on_#{model.table_name}_tmp"
- end
-
- def temporary_index_exists?(model)
- index_name = temporary_index_name_for(model)
-
- index_exists?(model.table_name, [:deleted_at, :id], name: index_name)
- end
-
- def remove_personal_namespaces
- # Some personal namespaces are left behind in case of GitLab.com. In these
- # cases the associated data such as the projects and users has already been
- # removed.
- Namespace.soft_removed_personal.each_batch do |batch|
- batch.delete_all
- end
- end
-
- def remove_group_namespaces
- admin_id = id_for_admin_user
-
- unless admin_id
- say 'Not scheduling soft removed groups for removal as no admin user ' \
- 'could be found. You will need to remove any such groups manually.'
-
- return
- end
-
- # Left over groups can't be easily removed because we may also need to
- # remove memberships, repositories, and other associated data. As a result
- # we'll just schedule a Sidekiq job to remove these.
- #
- # As of January 5th, 2018 there are 36 groups that will be removed using
- # this code.
- Namespace.select(:id).soft_removed_group.each_batch(of: 10) do |batch, index|
- batch.each do |ns|
- schedule_group_removal(index * 5.minutes, ns.id, admin_id)
- end
- end
- end
-
- def schedule_group_removal(delay, group_id, user_id)
- if migrate_inline?
- GroupDestroyWorker.new.perform(group_id, user_id)
- else
- GroupDestroyWorker.perform_in(delay, group_id, user_id)
- end
- end
-
- def remove_personal_routes
- namespaces = Namespace.select(1)
- .soft_removed
- .where('namespaces.type IS NULL')
- .where('routes.source_type = ?', 'Namespace')
- .where('routes.source_id = namespaces.id')
-
- Route.where('EXISTS (?)', namespaces).each_batch do |batch|
- batch.delete_all
- end
- end
-
- def id_for_admin_user
- User.where(admin: true).limit(1).pluck(:id).first
- end
-
- def migrate_inline?
- Rails.env.test? || Rails.env.development?
- end
-end
diff --git a/db/post_migrate/20180502134117_migrate_import_attributes_data_from_projects_to_project_mirror_data.rb b/db/post_migrate/20180502134117_migrate_import_attributes_data_from_projects_to_project_mirror_data.rb
deleted file mode 100644
index b82ee3569c9..00000000000
--- a/db/post_migrate/20180502134117_migrate_import_attributes_data_from_projects_to_project_mirror_data.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-class MigrateImportAttributesDataFromProjectsToProjectMirrorData < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- UP_MIGRATION = 'PopulateImportState'.freeze
- DOWN_MIGRATION = 'RollbackImportStateData'.freeze
-
- BATCH_SIZE = 1000
- DELAY_INTERVAL = 5.minutes
-
- disable_ddl_transaction!
-
- class Project < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'projects'
- end
-
- class ProjectImportState < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'project_mirror_data'
- end
-
- def up
- projects = Project.where.not(import_status: :none)
-
- queue_background_migration_jobs_by_range_at_intervals(projects, UP_MIGRATION, DELAY_INTERVAL, batch_size: BATCH_SIZE)
- end
-
- def down
- import_state = ProjectImportState.where.not(status: :none)
-
- queue_background_migration_jobs_by_range_at_intervals(import_state, DOWN_MIGRATION, DELAY_INTERVAL, batch_size: BATCH_SIZE)
- end
-end
diff --git a/db/post_migrate/20180521162137_migrate_remaining_mr_metrics_populating_background_migration.rb b/db/post_migrate/20180521162137_migrate_remaining_mr_metrics_populating_background_migration.rb
deleted file mode 100644
index 39666a0cd2a..00000000000
--- a/db/post_migrate/20180521162137_migrate_remaining_mr_metrics_populating_background_migration.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-class MigrateRemainingMrMetricsPopulatingBackgroundMigration < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 5_000
- MIGRATION = 'PopulateMergeRequestMetricsWithEventsData'
- DELAY_INTERVAL = 10.minutes
-
- disable_ddl_transaction!
-
- class MergeRequest < ActiveRecord::Base
- self.table_name = 'merge_requests'
-
- include ::EachBatch
- end
-
- def up
- # Perform any ongoing background migration that might still be running. This
- # avoids scheduling way too many of the same jobs on self-hosted instances
- # if they're updating GitLab across multiple versions. The "Take one"
- # migration was executed on 10.4 on
- # SchedulePopulateMergeRequestMetricsWithEventsData.
- Gitlab::BackgroundMigration.steal(MIGRATION)
-
- metrics_not_exists_clause = <<~SQL
- NOT EXISTS (SELECT 1 FROM merge_request_metrics
- WHERE merge_request_metrics.merge_request_id = merge_requests.id)
- SQL
-
- relation = MergeRequest.where(metrics_not_exists_clause)
-
- # We currently have ~400_000 MR records without metrics on GitLab.com.
- # This means it'll schedule ~80 jobs (5000 MRs each) with a 10 minutes gap,
- # so this should take ~14 hours for all background migrations to complete.
- #
- queue_background_migration_jobs_by_range_at_intervals(relation,
- MIGRATION,
- DELAY_INTERVAL,
- batch_size: BATCH_SIZE)
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20180619121030_enqueue_delete_diff_files_workers.rb b/db/post_migrate/20180619121030_enqueue_delete_diff_files_workers.rb
deleted file mode 100644
index 73f6a3a2a43..00000000000
--- a/db/post_migrate/20180619121030_enqueue_delete_diff_files_workers.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-class EnqueueDeleteDiffFilesWorkers < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- SCHEDULER = 'ScheduleDiffFilesDeletion'.freeze
- TMP_INDEX = 'tmp_partial_diff_id_with_files_index'.freeze
-
- disable_ddl_transaction!
-
- def up
- unless index_exists_by_name?(:merge_request_diffs, TMP_INDEX)
- add_concurrent_index(:merge_request_diffs, :id, where: "(state NOT IN ('without_files', 'empty'))", name: TMP_INDEX)
- end
-
- BackgroundMigrationWorker.perform_async(SCHEDULER)
-
- # We don't remove the index since it's going to be used on DeleteDiffFiles
- # worker. We should remove it in an upcoming release.
- end
-
- def down
- if index_exists_by_name?(:merge_request_diffs, TMP_INDEX)
- remove_concurrent_index_by_name(:merge_request_diffs, TMP_INDEX)
- end
- end
-end
diff --git a/db/post_migrate/20180723130817_delete_inconsistent_internal_id_records.rb b/db/post_migrate/20180723130817_delete_inconsistent_internal_id_records.rb
deleted file mode 100644
index 440868005bb..00000000000
--- a/db/post_migrate/20180723130817_delete_inconsistent_internal_id_records.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-class DeleteInconsistentInternalIdRecords < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- # This migration cleans up any inconsistent records in internal_ids.
- #
- # That is, it deletes records that track a `last_value` that is
- # smaller than the maximum internal id (usually `iid`) found in
- # the corresponding model records.
-
- def up
- disable_statement_timeout do
- delete_internal_id_records('issues', 'project_id')
- delete_internal_id_records('merge_requests', 'project_id', 'target_project_id')
- delete_internal_id_records('deployments', 'project_id')
- delete_internal_id_records('milestones', 'project_id')
- delete_internal_id_records('milestones', 'namespace_id', 'group_id')
- delete_internal_id_records('ci_pipelines', 'project_id')
- end
- end
-
- class InternalId < ActiveRecord::Base
- self.table_name = 'internal_ids'
- enum usage: { issues: 0, merge_requests: 1, deployments: 2, milestones: 3, epics: 4, ci_pipelines: 5 }
- end
-
- private
-
- def delete_internal_id_records(base_table, scope_column_name, base_scope_column_name = scope_column_name)
- sql = <<~SQL
- SELECT id FROM ( -- workaround for MySQL
- SELECT internal_ids.id FROM (
- SELECT #{base_scope_column_name} AS #{scope_column_name}, max(iid) as maximum_iid from #{base_table} GROUP BY #{scope_column_name}
- ) maxima JOIN internal_ids USING (#{scope_column_name})
- WHERE internal_ids.usage=#{InternalId.usages.fetch(base_table)} AND maxima.maximum_iid > internal_ids.last_value
- ) internal_ids
- SQL
-
- InternalId.where("id IN (#{sql})").tap do |ids| # rubocop:disable GitlabSecurity/SqlInjection
- say "Deleting internal_id records for #{base_table}: #{ids.pluck(:project_id, :last_value)}" unless ids.empty?
- end.delete_all
- end
-end
diff --git a/db/post_migrate/20180906051323_remove_orphaned_label_links.rb b/db/post_migrate/20180906051323_remove_orphaned_label_links.rb
deleted file mode 100644
index a474aaf534c..00000000000
--- a/db/post_migrate/20180906051323_remove_orphaned_label_links.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveOrphanedLabelLinks < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class LabelLinks < ActiveRecord::Base
- self.table_name = 'label_links'
- include EachBatch
-
- def self.orphaned
- where('NOT EXISTS ( SELECT 1 FROM labels WHERE labels.id = label_links.label_id )')
- end
- end
-
- def up
- # Some of these queries can take up to 10 seconds to run on GitLab.com,
- # which is pretty close to our 15 second statement timeout. To ensure a
- # smooth deployment procedure we disable the statement timeouts for this
- # migration, just in case.
- disable_statement_timeout do
- # On GitLab.com there are over 2,000,000 orphaned label links. On
- # staging, removing 100,000 rows generated a max replication lag of 6.7
- # MB. In total, removing all these rows will only generate about 136 MB
- # of data, so it should be safe to do this.
- LabelLinks.orphaned.each_batch(of: 100_000) do |batch|
- batch.delete_all
- end
- end
-
- add_concurrent_foreign_key(:label_links, :labels, column: :label_id, on_delete: :cascade)
- end
-
- def down
- # There is no way to restore orphaned label links.
- if foreign_key_exists?(:label_links, column: :label_id)
- remove_foreign_key(:label_links, column: :label_id)
- end
- end
-end
diff --git a/db/post_migrate/20180913051323_consume_remaining_diff_files_deletion_jobs.rb b/db/post_migrate/20180913051323_consume_remaining_diff_files_deletion_jobs.rb
deleted file mode 100644
index 2c266a4695b..00000000000
--- a/db/post_migrate/20180913051323_consume_remaining_diff_files_deletion_jobs.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class ConsumeRemainingDiffFilesDeletionJobs < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- MIGRATION = 'ScheduleDiffFilesDeletion'.freeze
- TMP_INDEX = 'tmp_partial_diff_id_with_files_index'.freeze
-
- def up
- # Perform any ongoing background migration that might still be scheduled.
- Gitlab::BackgroundMigration.steal(MIGRATION)
-
- remove_concurrent_index_by_name(:merge_request_diffs, TMP_INDEX)
- end
-
- def down
- add_concurrent_index(:merge_request_diffs, :id, where: "(state NOT IN ('without_files', 'empty'))", name: TMP_INDEX)
- end
-end
diff --git a/db/post_migrate/20180916014356_populate_external_pipeline_source.rb b/db/post_migrate/20180916014356_populate_external_pipeline_source.rb
deleted file mode 100644
index a3d2df1f2bd..00000000000
--- a/db/post_migrate/20180916014356_populate_external_pipeline_source.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class PopulateExternalPipelineSource < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
- MIGRATION = 'PopulateExternalPipelineSource'.freeze
- BATCH_SIZE = 500
-
- disable_ddl_transaction!
-
- class Pipeline < ActiveRecord::Base
- include EachBatch
- self.table_name = 'ci_pipelines'
- end
-
- def up
- Pipeline.where(source: nil).tap do |relation|
- queue_background_migration_jobs_by_range_at_intervals(relation,
- MIGRATION,
- 5.minutes,
- batch_size: BATCH_SIZE)
- end
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20181014121030_enqueue_redact_links.rb b/db/post_migrate/20181014121030_enqueue_redact_links.rb
deleted file mode 100644
index 8d1a840d594..00000000000
--- a/db/post_migrate/20181014121030_enqueue_redact_links.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# frozen_string_literal: true
-
-class EnqueueRedactLinks < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 1000
- DELAY_INTERVAL = 5.minutes.to_i
- MIGRATION = 'RedactLinks'
-
- disable_ddl_transaction!
-
- class Note < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'notes'
- self.inheritance_column = :_type_disabled
- end
-
- class Issue < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'issues'
- self.inheritance_column = :_type_disabled
- end
-
- class MergeRequest < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'merge_requests'
- self.inheritance_column = :_type_disabled
- end
-
- class Snippet < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'snippets'
- self.inheritance_column = :_type_disabled
- end
-
- def up
- disable_statement_timeout do
- schedule_migration(Note, 'note')
- schedule_migration(Issue, 'description')
- schedule_migration(MergeRequest, 'description')
- schedule_migration(Snippet, 'description')
- end
- end
-
- def down
- # nothing to do
- end
-
- private
-
- def schedule_migration(model, field)
- link_pattern = "%/sent_notifications/" + ("_" * 32) + "/unsubscribe%"
-
- model.where("#{field} like ?", link_pattern).each_batch(of: BATCH_SIZE) do |batch, index|
- start_id, stop_id = batch.pluck('MIN(id)', 'MAX(id)').first
-
- BackgroundMigrationWorker.perform_in(index * DELAY_INTERVAL, MIGRATION, [model.name.demodulize, field, start_id, stop_id])
- end
- end
-end
diff --git a/db/post_migrate/20181204154019_populate_mr_metrics_with_events_data.rb b/db/post_migrate/20181204154019_populate_mr_metrics_with_events_data.rb
deleted file mode 100644
index 1e43e3dd790..00000000000
--- a/db/post_migrate/20181204154019_populate_mr_metrics_with_events_data.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class PopulateMrMetricsWithEventsData < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 10_000
- MIGRATION = 'PopulateMergeRequestMetricsWithEventsDataImproved'
- PREVIOUS_MIGRATION = 'PopulateMergeRequestMetricsWithEventsData'
-
- disable_ddl_transaction!
-
- def up
- # Perform any ongoing background migration that might still be running from
- # previous try (see https://gitlab.com/gitlab-org/gitlab-ce/issues/47676).
- Gitlab::BackgroundMigration.steal(PREVIOUS_MIGRATION)
-
- say 'Scheduling `PopulateMergeRequestMetricsWithEventsData` jobs'
- # It will update around 4_000_000 records in batches of 10_000 merge
- # requests (running between 5 minutes) and should take around 53 hours to complete.
- # Apparently, production PostgreSQL is able to vacuum 10k-20k dead_tuples
- # per minute. So this should give us enough space.
- #
- # More information about the updates in `PopulateMergeRequestMetricsWithEventsDataImproved` class.
- #
- MergeRequest.all.each_batch(of: BATCH_SIZE) do |relation, index|
- range = relation.pluck('MIN(id)', 'MAX(id)').first
-
- BackgroundMigrationWorker.perform_in(index * 8.minutes, MIGRATION, range)
- end
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20190402224749_schedule_merge_request_assignees_migration_progress_check.rb b/db/post_migrate/20190402224749_schedule_merge_request_assignees_migration_progress_check.rb
new file mode 100644
index 00000000000..6fb67deb834
--- /dev/null
+++ b/db/post_migrate/20190402224749_schedule_merge_request_assignees_migration_progress_check.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class ScheduleMergeRequestAssigneesMigrationProgressCheck < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ MIGRATION = 'MergeRequestAssigneesMigrationProgressCheck'.freeze
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ BackgroundMigrationWorker.perform_async(MIGRATION)
+ end
+
+ def down
+ end
+end
diff --git a/db/post_migrate/20190404143330_add_unique_constraint_to_approvals_user_id_and_merge_request_id.rb b/db/post_migrate/20190404143330_add_unique_constraint_to_approvals_user_id_and_merge_request_id.rb
new file mode 100644
index 00000000000..447f91ebc7e
--- /dev/null
+++ b/db/post_migrate/20190404143330_add_unique_constraint_to_approvals_user_id_and_merge_request_id.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+class AddUniqueConstraintToApprovalsUserIdAndMergeRequestId < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ remove_duplicates
+ add_concurrent_index :approvals, [:user_id, :merge_request_id], unique: true
+ end
+
+ def down
+ remove_concurrent_index :approvals, [:user_id, :merge_request_id]
+ end
+
+ private
+
+ def remove_duplicates
+ add_concurrent_index :approvals, [:user_id, :merge_request_id, :id]
+
+ if Gitlab::Database.mysql?
+ execute <<-SQL
+ DELETE FROM a
+ USING approvals AS a
+ INNER JOIN (
+ SELECT user_id, merge_request_id, MIN(id) as min_id
+ FROM approvals
+ GROUP BY user_id, merge_request_id
+ HAVING COUNT(id) > 1
+ ) as approvals_with_duplicates
+ ON approvals_with_duplicates.user_id = a.user_id
+ AND approvals_with_duplicates.merge_request_id = a.merge_request_id
+ WHERE approvals_with_duplicates.min_id <> a.id;
+ SQL
+ else
+ execute <<-SQL
+ DELETE FROM approvals
+ USING (
+ SELECT user_id, merge_request_id, MIN(id) as min_id
+ FROM approvals
+ GROUP BY user_id, merge_request_id
+ HAVING COUNT(id) > 1
+ ) as approvals_with_duplicates
+ WHERE approvals_with_duplicates.user_id = approvals.user_id
+ AND approvals_with_duplicates.merge_request_id = approvals.merge_request_id
+ AND approvals_with_duplicates.min_id <> approvals.id;
+ SQL
+ end
+
+ remove_concurrent_index :approvals, [:user_id, :merge_request_id, :id]
+ end
+end
diff --git a/db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb b/db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb
new file mode 100644
index 00000000000..785ceb2fb28
--- /dev/null
+++ b/db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+# We are reverting the feature that created this column. This is for anyone who
+# migrated while the feature still existed in master.
+class RemoveAlternateUrlFromGeoNodes < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ def up
+ remove_column(:geo_nodes, :alternate_url) if column_exists?(:geo_nodes, :alternate_url)
+ end
+
+ def down
+ add_column :geo_nodes, :alternate_url, :string
+ end
+end
diff --git a/db/post_migrate/20190418132125_populate_project_statistics_packages_size.rb b/db/post_migrate/20190418132125_populate_project_statistics_packages_size.rb
new file mode 100644
index 00000000000..a6bee3453c1
--- /dev/null
+++ b/db/post_migrate/20190418132125_populate_project_statistics_packages_size.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+class PopulateProjectStatisticsPackagesSize < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ class ProjectStatistics < ActiveRecord::Base
+ self.table_name = 'project_statistics'
+ end
+
+ def up
+ stats_ids = ProjectStatistics.joins(
+ <<~SQL.strip_heredoc
+ INNER JOIN projects ON projects.id = project_statistics.project_id
+ INNER JOIN packages_packages ON packages_packages.project_id = projects.id
+ INNER JOIN packages_package_files ON packages_package_files.package_id = packages_packages.id
+ SQL
+ ).distinct.select(:id)
+
+ packages_size = Arel.sql(
+ '(SELECT SUM(size) FROM packages_package_files ' \
+ 'JOIN packages_packages ON packages_packages.id = packages_package_files.package_id ' \
+ 'WHERE packages_packages.project_id = project_statistics.project_id)'
+ )
+ update_column_in_batches(:project_statistics, :packages_size, packages_size) do |table, query|
+ query.where(table[:id].in(stats_ids))
+ end
+
+ storage_size = Arel.sql('(repository_size + lfs_objects_size + build_artifacts_size + COALESCE(packages_size, 0))')
+ update_column_in_batches(:project_statistics, :storage_size, storage_size) do |table, query|
+ query.where(table[:id].in(stats_ids))
+ end
+ end
+
+ def down
+ storage_size = Arel.sql('(repository_size + lfs_objects_size + build_artifacts_size)')
+ update_column_in_batches(:project_statistics, :storage_size, storage_size) do |table, query|
+ query.where(table[:packages_size].gt(0))
+ end
+
+ update_column_in_batches(:project_statistics, :packages_size, nil)
+ end
+end
diff --git a/db/post_migrate/20190511144331_remove_users_support_type.rb b/db/post_migrate/20190511144331_remove_users_support_type.rb
new file mode 100644
index 00000000000..32df33432b9
--- /dev/null
+++ b/db/post_migrate/20190511144331_remove_users_support_type.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class RemoveUsersSupportType < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ INDEX_STATE_INTERNAL_ATTRS = 'index_users_on_state_and_internal_attrs'
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index :users, :state, name: INDEX_STATE_INTERNAL_ATTRS
+ remove_concurrent_index :users, :support_bot
+
+ remove_column :users, :support_bot
+ end
+
+ def down
+ add_column :users, :support_bot, :boolean
+
+ add_concurrent_index :users, :support_bot
+ add_concurrent_index :users, :state,
+ name: INDEX_STATE_INTERNAL_ATTRS,
+ where: 'ghost <> true AND support_bot <> true'
+ end
+end
diff --git a/db/post_migrate/20190520201748_populate_rule_type_on_approval_merge_request_rules.rb b/db/post_migrate/20190520201748_populate_rule_type_on_approval_merge_request_rules.rb
new file mode 100644
index 00000000000..0f0df456134
--- /dev/null
+++ b/db/post_migrate/20190520201748_populate_rule_type_on_approval_merge_request_rules.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class PopulateRuleTypeOnApprovalMergeRequestRules < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ class ApprovalMergeRequestRule < ActiveRecord::Base
+ include EachBatch
+
+ enum rule_types: {
+ regular: 1,
+ code_owner: 2
+ }
+ end
+
+ def up
+ # On Gitlab.com, this should update about 17k rows. Since our updates are
+ # small and we are populating prior to indexing, the overhead should be small
+ ApprovalMergeRequestRule.where(code_owner: true).each_batch do |batch|
+ batch.update_all(rule_type: ApprovalMergeRequestRule.rule_types[:code_owner])
+ end
+ end
+
+ def down
+ # code_owner is already kept in sync with `rule_type`, so no changes are needed
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ef4ec57acec..a50ab02f718 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -45,6 +45,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.text "message_font_color"
t.string "favicon"
t.boolean "email_header_and_footer_enabled", default: false, null: false
+ t.integer "updated_by"
end
create_table "application_setting_terms", id: :serial, force: :cascade do |t|
@@ -153,7 +154,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.integer "throttle_authenticated_web_requests_per_period", default: 7200, null: false
t.integer "throttle_authenticated_web_period_in_seconds", default: 3600, null: false
t.boolean "password_authentication_enabled_for_web"
- t.boolean "password_authentication_enabled_for_git", default: true
+ t.boolean "password_authentication_enabled_for_git", default: true, null: false
t.integer "gitaly_timeout_default", default: 55, null: false
t.integer "gitaly_timeout_medium", default: 30, null: false
t.integer "gitaly_timeout_fast", default: 10, null: false
@@ -196,9 +197,136 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.boolean "dns_rebinding_protection_enabled", default: true, null: false
t.boolean "default_project_deletion_protection", default: false, null: false
t.boolean "lock_memberships_to_ldap", default: false, null: false
+ t.text "help_text"
+ t.boolean "elasticsearch_indexing", default: false, null: false
+ t.boolean "elasticsearch_search", default: false, null: false
+ t.integer "shared_runners_minutes", default: 0, null: false
+ t.bigint "repository_size_limit", default: 0
+ t.string "elasticsearch_url", default: "http://localhost:9200"
+ t.boolean "elasticsearch_aws", default: false, null: false
+ t.string "elasticsearch_aws_region", default: "us-east-1"
+ t.string "elasticsearch_aws_access_key"
+ t.string "elasticsearch_aws_secret_access_key"
+ t.integer "geo_status_timeout", default: 10
+ t.boolean "elasticsearch_experimental_indexer"
+ t.boolean "check_namespace_plan", default: false, null: false
+ t.integer "mirror_max_delay", default: 300, null: false
+ t.integer "mirror_max_capacity", default: 100, null: false
+ t.integer "mirror_capacity_threshold", default: 50, null: false
+ t.boolean "slack_app_enabled", default: false
+ t.string "slack_app_id"
+ t.string "slack_app_secret"
+ t.string "slack_app_verification_token"
+ t.boolean "allow_group_owners_to_manage_ldap", default: true, null: false
+ t.string "email_additional_text"
+ t.integer "file_template_project_id"
+ t.boolean "pseudonymizer_enabled", default: false, null: false
+ t.boolean "snowplow_enabled", default: false, null: false
+ t.string "snowplow_collector_uri"
+ t.string "snowplow_site_id"
+ t.string "snowplow_cookie_domain"
+ t.integer "custom_project_templates_group_id"
+ t.boolean "elasticsearch_limit_indexing", default: false, null: false
+ t.string "geo_node_allowed_ips", default: "0.0.0.0/0, ::/0"
+ t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id", using: :btree
+ t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id", using: :btree
t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id", using: :btree
end
+ create_table "approval_merge_request_rule_sources", force: :cascade do |t|
+ t.bigint "approval_merge_request_rule_id", null: false
+ t.bigint "approval_project_rule_id", null: false
+ t.index ["approval_merge_request_rule_id"], name: "index_approval_merge_request_rule_sources_1", unique: true, using: :btree
+ t.index ["approval_project_rule_id"], name: "index_approval_merge_request_rule_sources_2", using: :btree
+ end
+
+ create_table "approval_merge_request_rules", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "merge_request_id", null: false
+ t.integer "approvals_required", limit: 2, default: 0, null: false
+ t.boolean "code_owner", default: false, null: false
+ t.string "name", null: false
+ t.integer "rule_type", limit: 2, default: 1, null: false
+ t.index ["merge_request_id", "code_owner", "name"], name: "approval_rule_name_index_for_code_owners", unique: true, where: "(code_owner = true)", using: :btree
+ t.index ["merge_request_id", "code_owner"], name: "index_approval_merge_request_rules_1", using: :btree
+ t.index ["merge_request_id", "rule_type", "name"], name: "index_approval_rule_name_for_code_owners_rule_type", unique: true, where: "(rule_type = 2)", using: :btree
+ t.index ["merge_request_id", "rule_type"], name: "index_approval_rules_code_owners_rule_type", where: "(rule_type = 2)", using: :btree
+ end
+
+ create_table "approval_merge_request_rules_approved_approvers", force: :cascade do |t|
+ t.bigint "approval_merge_request_rule_id", null: false
+ t.integer "user_id", null: false
+ t.index ["approval_merge_request_rule_id", "user_id"], name: "index_approval_merge_request_rules_approved_approvers_1", unique: true, using: :btree
+ t.index ["user_id"], name: "index_approval_merge_request_rules_approved_approvers_2", using: :btree
+ end
+
+ create_table "approval_merge_request_rules_groups", force: :cascade do |t|
+ t.bigint "approval_merge_request_rule_id", null: false
+ t.integer "group_id", null: false
+ t.index ["approval_merge_request_rule_id", "group_id"], name: "index_approval_merge_request_rules_groups_1", unique: true, using: :btree
+ t.index ["group_id"], name: "index_approval_merge_request_rules_groups_2", using: :btree
+ end
+
+ create_table "approval_merge_request_rules_users", force: :cascade do |t|
+ t.bigint "approval_merge_request_rule_id", null: false
+ t.integer "user_id", null: false
+ t.index ["approval_merge_request_rule_id", "user_id"], name: "index_approval_merge_request_rules_users_1", unique: true, using: :btree
+ t.index ["user_id"], name: "index_approval_merge_request_rules_users_2", using: :btree
+ end
+
+ create_table "approval_project_rules", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.integer "approvals_required", limit: 2, default: 0, null: false
+ t.string "name", null: false
+ t.index ["project_id"], name: "index_approval_project_rules_on_project_id", using: :btree
+ end
+
+ create_table "approval_project_rules_groups", force: :cascade do |t|
+ t.bigint "approval_project_rule_id", null: false
+ t.integer "group_id", null: false
+ t.index ["approval_project_rule_id", "group_id"], name: "index_approval_project_rules_groups_1", unique: true, using: :btree
+ t.index ["group_id"], name: "index_approval_project_rules_groups_2", using: :btree
+ end
+
+ create_table "approval_project_rules_users", force: :cascade do |t|
+ t.bigint "approval_project_rule_id", null: false
+ t.integer "user_id", null: false
+ t.index ["approval_project_rule_id", "user_id"], name: "index_approval_project_rules_users_1", unique: true, using: :btree
+ t.index ["user_id"], name: "index_approval_project_rules_users_2", using: :btree
+ end
+
+ create_table "approvals", id: :serial, force: :cascade do |t|
+ t.integer "merge_request_id", null: false
+ t.integer "user_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["merge_request_id"], name: "index_approvals_on_merge_request_id", using: :btree
+ t.index ["user_id", "merge_request_id"], name: "index_approvals_on_user_id_and_merge_request_id", unique: true, using: :btree
+ end
+
+ create_table "approver_groups", id: :serial, force: :cascade do |t|
+ t.integer "target_id", null: false
+ t.string "target_type", null: false
+ t.integer "group_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["group_id"], name: "index_approver_groups_on_group_id", using: :btree
+ t.index ["target_id", "target_type"], name: "index_approver_groups_on_target_id_and_target_type", using: :btree
+ end
+
+ create_table "approvers", id: :serial, force: :cascade do |t|
+ t.integer "target_id", null: false
+ t.string "target_type"
+ t.integer "user_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["target_id", "target_type"], name: "index_approvers_on_target_id_and_target_type", using: :btree
+ t.index ["user_id"], name: "index_approvers_on_user_id", using: :btree
+ end
+
create_table "audit_events", id: :serial, force: :cascade do |t|
t.integer "author_id", null: false
t.string "type", null: false
@@ -233,6 +361,13 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["project_id"], name: "index_badges_on_project_id", using: :btree
end
+ create_table "board_assignees", id: :serial, force: :cascade do |t|
+ t.integer "board_id", null: false
+ t.integer "assignee_id", null: false
+ t.index ["assignee_id"], name: "index_board_assignees_on_assignee_id", using: :btree
+ t.index ["board_id", "assignee_id"], name: "index_board_assignees_on_board_id_and_assignee_id", unique: true, using: :btree
+ end
+
create_table "board_group_recent_visits", force: :cascade do |t|
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
@@ -245,6 +380,13 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["user_id"], name: "index_board_group_recent_visits_on_user_id", using: :btree
end
+ create_table "board_labels", id: :serial, force: :cascade do |t|
+ t.integer "board_id", null: false
+ t.integer "label_id", null: false
+ t.index ["board_id", "label_id"], name: "index_board_labels_on_board_id_and_label_id", unique: true, using: :btree
+ t.index ["label_id"], name: "index_board_labels_on_label_id", using: :btree
+ end
+
create_table "board_project_recent_visits", force: :cascade do |t|
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
@@ -262,7 +404,11 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "group_id"
+ t.integer "milestone_id"
+ t.integer "weight"
+ t.string "name", default: "Development", null: false
t.index ["group_id"], name: "index_boards_on_group_id", using: :btree
+ t.index ["milestone_id"], name: "index_boards_on_milestone_id", using: :btree
t.index ["project_id"], name: "index_boards_on_project_id", using: :btree
end
@@ -375,6 +521,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.integer "failure_reason"
t.datetime_with_timezone "scheduled_at"
t.string "token_encrypted"
+ t.integer "upstream_pipeline_id"
t.index ["artifacts_expire_at"], name: "index_ci_builds_on_artifacts_expire_at", where: "(artifacts_file <> ''::text)", using: :btree
t.index ["auto_canceled_by_id"], name: "index_ci_builds_on_auto_canceled_by_id", using: :btree
t.index ["commit_id", "artifacts_expire_at", "id"], name: "index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial", where: "(((type)::text = 'Ci::Build'::text) AND ((retried = false) OR (retried IS NULL)) AND ((name)::text = ANY (ARRAY[('sast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('sast:container'::character varying)::text, ('container_scanning'::character varying)::text, ('dast'::character varying)::text])))", using: :btree
@@ -382,6 +529,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["commit_id", "status", "type"], name: "index_ci_builds_on_commit_id_and_status_and_type", using: :btree
t.index ["commit_id", "type", "name", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_name_and_ref", using: :btree
t.index ["commit_id", "type", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_ref", using: :btree
+ t.index ["name"], name: "index_ci_builds_on_name_for_security_products_values", where: "((name)::text = ANY (ARRAY[('container_scanning'::character varying)::text, ('dast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('license_management'::character varying)::text, ('sast'::character varying)::text]))", using: :btree
t.index ["project_id", "id"], name: "index_ci_builds_on_project_id_and_id", using: :btree
t.index ["project_id", "status"], name: "index_ci_builds_project_id_and_status_for_live_jobs_partial2", where: "(((type)::text = 'Ci::Build'::text) AND ((status)::text = ANY (ARRAY[('running'::character varying)::text, ('pending'::character varying)::text, ('created'::character varying)::text])))", using: :btree
t.index ["protected"], name: "index_ci_builds_on_protected", using: :btree
@@ -394,6 +542,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["token"], name: "index_ci_builds_on_token", unique: true, using: :btree
t.index ["token_encrypted"], name: "index_ci_builds_on_token_encrypted", unique: true, where: "(token_encrypted IS NOT NULL)", using: :btree
t.index ["updated_at"], name: "index_ci_builds_on_updated_at", using: :btree
+ t.index ["upstream_pipeline_id"], name: "index_ci_builds_on_upstream_pipeline_id", where: "(upstream_pipeline_id IS NOT NULL)", using: :btree
t.index ["user_id"], name: "index_ci_builds_on_user_id", using: :btree
end
@@ -582,6 +731,19 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["token_encrypted"], name: "index_ci_runners_on_token_encrypted", using: :btree
end
+ create_table "ci_sources_pipelines", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.integer "pipeline_id"
+ t.integer "source_project_id"
+ t.integer "source_job_id"
+ t.integer "source_pipeline_id"
+ t.index ["pipeline_id"], name: "index_ci_sources_pipelines_on_pipeline_id", using: :btree
+ t.index ["project_id"], name: "index_ci_sources_pipelines_on_project_id", using: :btree
+ t.index ["source_job_id"], name: "index_ci_sources_pipelines_on_source_job_id", using: :btree
+ t.index ["source_pipeline_id"], name: "index_ci_sources_pipelines_on_source_pipeline_id", using: :btree
+ t.index ["source_project_id"], name: "index_ci_sources_pipelines_on_source_project_id", using: :btree
+ end
+
create_table "ci_stages", id: :serial, force: :cascade do |t|
t.integer "project_id"
t.integer "pipeline_id"
@@ -770,6 +932,9 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.text "status_reason"
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
+ t.string "encrypted_alert_manager_token"
+ t.string "encrypted_alert_manager_token_iv"
+ t.datetime_with_timezone "last_update_started_at"
t.index ["cluster_id"], name: "index_clusters_applications_prometheus_on_cluster_id", unique: true, using: :btree
end
@@ -846,6 +1011,25 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.float "percentage_service_desk_issues", default: 0.0, null: false
end
+ create_table "dependency_proxy_blobs", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.text "file", null: false
+ t.string "file_name", null: false
+ t.integer "file_store"
+ t.integer "group_id", null: false
+ t.bigint "size"
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["group_id", "file_name"], name: "index_dependency_proxy_blobs_on_group_id_and_file_name", using: :btree
+ end
+
+ create_table "dependency_proxy_group_settings", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.boolean "enabled", default: false, null: false
+ t.integer "group_id", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["group_id"], name: "index_dependency_proxy_group_settings_on_group_id", using: :btree
+ end
+
create_table "deploy_keys_projects", id: :serial, force: :cascade do |t|
t.integer "deploy_key_id", null: false
t.integer "project_id", null: false
@@ -893,6 +1077,55 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["project_id", "status"], name: "index_deployments_on_project_id_and_status", using: :btree
end
+ create_table "design_management_designs", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "issue_id", null: false
+ t.string "filename", null: false
+ t.index ["issue_id", "filename"], name: "index_design_management_designs_on_issue_id_and_filename", unique: true, using: :btree
+ t.index ["project_id"], name: "index_design_management_designs_on_project_id", using: :btree
+ end
+
+ create_table "design_management_designs_versions", id: false, force: :cascade do |t|
+ t.bigint "design_id", null: false
+ t.bigint "version_id", null: false
+ t.index ["design_id", "version_id"], name: "design_management_designs_versions_uniqueness", unique: true, using: :btree
+ t.index ["design_id"], name: "index_design_management_designs_versions_on_design_id", using: :btree
+ t.index ["version_id"], name: "index_design_management_designs_versions_on_version_id", using: :btree
+ end
+
+ create_table "design_management_versions", force: :cascade do |t|
+ t.binary "sha", null: false
+ t.index ["sha"], name: "index_design_management_versions_on_sha", unique: true, using: :btree
+ end
+
+ create_table "draft_notes", force: :cascade do |t|
+ t.integer "merge_request_id", null: false
+ t.integer "author_id", null: false
+ t.boolean "resolve_discussion", default: false, null: false
+ t.string "discussion_id"
+ t.text "note", null: false
+ t.text "position"
+ t.text "original_position"
+ t.text "change_position"
+ t.index ["author_id"], name: "index_draft_notes_on_author_id", using: :btree
+ t.index ["discussion_id"], name: "index_draft_notes_on_discussion_id", using: :btree
+ t.index ["merge_request_id"], name: "index_draft_notes_on_merge_request_id", using: :btree
+ end
+
+ create_table "elasticsearch_indexed_namespaces", id: false, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "namespace_id"
+ t.index ["namespace_id"], name: "index_elasticsearch_indexed_namespaces_on_namespace_id", unique: true, using: :btree
+ end
+
+ create_table "elasticsearch_indexed_projects", id: false, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id"
+ t.index ["project_id"], name: "index_elasticsearch_indexed_projects_on_project_id", unique: true, using: :btree
+ end
+
create_table "emails", id: :serial, force: :cascade do |t|
t.integer "user_id", null: false
t.string "email", null: false
@@ -915,10 +1148,67 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.string "environment_type"
t.string "state", default: "available", null: false
t.string "slug", null: false
+ t.index ["name"], name: "index_environments_on_name_varchar_pattern_ops", using: :btree, opclasses: {"name"=>"varchar_pattern_ops"}
t.index ["project_id", "name"], name: "index_environments_on_project_id_and_name", unique: true, using: :btree
t.index ["project_id", "slug"], name: "index_environments_on_project_id_and_slug", unique: true, using: :btree
end
+ create_table "epic_issues", id: :serial, force: :cascade do |t|
+ t.integer "epic_id", null: false
+ t.integer "issue_id", null: false
+ t.integer "relative_position", default: 1073741823, null: false
+ t.index ["epic_id"], name: "index_epic_issues_on_epic_id", using: :btree
+ t.index ["issue_id"], name: "index_epic_issues_on_issue_id", unique: true, using: :btree
+ end
+
+ create_table "epic_metrics", id: :serial, force: :cascade do |t|
+ t.integer "epic_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["epic_id"], name: "index_epic_metrics", using: :btree
+ end
+
+ create_table "epics", id: :serial, force: :cascade do |t|
+ t.integer "milestone_id"
+ t.integer "group_id", null: false
+ t.integer "author_id", null: false
+ t.integer "assignee_id"
+ t.integer "iid", null: false
+ t.integer "cached_markdown_version"
+ t.integer "updated_by_id"
+ t.integer "last_edited_by_id"
+ t.integer "lock_version"
+ t.date "start_date"
+ t.date "end_date"
+ t.datetime "last_edited_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "title", null: false
+ t.string "title_html", null: false
+ t.text "description"
+ t.text "description_html"
+ t.integer "start_date_sourcing_milestone_id"
+ t.integer "due_date_sourcing_milestone_id"
+ t.date "start_date_fixed"
+ t.date "due_date_fixed"
+ t.boolean "start_date_is_fixed"
+ t.boolean "due_date_is_fixed"
+ t.integer "state", limit: 2, default: 1, null: false
+ t.integer "closed_by_id"
+ t.datetime "closed_at"
+ t.integer "parent_id"
+ t.integer "relative_position"
+ t.index ["assignee_id"], name: "index_epics_on_assignee_id", using: :btree
+ t.index ["author_id"], name: "index_epics_on_author_id", using: :btree
+ t.index ["closed_by_id"], name: "index_epics_on_closed_by_id", using: :btree
+ t.index ["end_date"], name: "index_epics_on_end_date", using: :btree
+ t.index ["group_id"], name: "index_epics_on_group_id", using: :btree
+ t.index ["iid"], name: "index_epics_on_iid", using: :btree
+ t.index ["milestone_id"], name: "index_milestone", using: :btree
+ t.index ["parent_id"], name: "index_epics_on_parent_id", using: :btree
+ t.index ["start_date"], name: "index_epics_on_start_date", using: :btree
+ end
+
create_table "events", id: :serial, force: :cascade do |t|
t.integer "project_id"
t.integer "author_id", null: false
@@ -973,6 +1263,227 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree
end
+ create_table "geo_cache_invalidation_events", force: :cascade do |t|
+ t.string "key", null: false
+ end
+
+ create_table "geo_event_log", force: :cascade do |t|
+ t.datetime "created_at", null: false
+ t.bigint "repository_updated_event_id"
+ t.bigint "repository_deleted_event_id"
+ t.bigint "repository_renamed_event_id"
+ t.bigint "repositories_changed_event_id"
+ t.bigint "repository_created_event_id"
+ t.bigint "hashed_storage_migrated_event_id"
+ t.bigint "lfs_object_deleted_event_id"
+ t.bigint "hashed_storage_attachments_event_id"
+ t.bigint "upload_deleted_event_id"
+ t.bigint "job_artifact_deleted_event_id"
+ t.bigint "reset_checksum_event_id"
+ t.bigint "cache_invalidation_event_id"
+ t.index ["cache_invalidation_event_id"], name: "index_geo_event_log_on_cache_invalidation_event_id", where: "(cache_invalidation_event_id IS NOT NULL)", using: :btree
+ t.index ["hashed_storage_attachments_event_id"], name: "index_geo_event_log_on_hashed_storage_attachments_event_id", where: "(hashed_storage_attachments_event_id IS NOT NULL)", using: :btree
+ t.index ["hashed_storage_migrated_event_id"], name: "index_geo_event_log_on_hashed_storage_migrated_event_id", where: "(hashed_storage_migrated_event_id IS NOT NULL)", using: :btree
+ t.index ["job_artifact_deleted_event_id"], name: "index_geo_event_log_on_job_artifact_deleted_event_id", where: "(job_artifact_deleted_event_id IS NOT NULL)", using: :btree
+ t.index ["lfs_object_deleted_event_id"], name: "index_geo_event_log_on_lfs_object_deleted_event_id", where: "(lfs_object_deleted_event_id IS NOT NULL)", using: :btree
+ t.index ["repositories_changed_event_id"], name: "index_geo_event_log_on_repositories_changed_event_id", where: "(repositories_changed_event_id IS NOT NULL)", using: :btree
+ t.index ["repository_created_event_id"], name: "index_geo_event_log_on_repository_created_event_id", where: "(repository_created_event_id IS NOT NULL)", using: :btree
+ t.index ["repository_deleted_event_id"], name: "index_geo_event_log_on_repository_deleted_event_id", where: "(repository_deleted_event_id IS NOT NULL)", using: :btree
+ t.index ["repository_renamed_event_id"], name: "index_geo_event_log_on_repository_renamed_event_id", where: "(repository_renamed_event_id IS NOT NULL)", using: :btree
+ t.index ["repository_updated_event_id"], name: "index_geo_event_log_on_repository_updated_event_id", where: "(repository_updated_event_id IS NOT NULL)", using: :btree
+ t.index ["reset_checksum_event_id"], name: "index_geo_event_log_on_reset_checksum_event_id", where: "(reset_checksum_event_id IS NOT NULL)", using: :btree
+ t.index ["upload_deleted_event_id"], name: "index_geo_event_log_on_upload_deleted_event_id", where: "(upload_deleted_event_id IS NOT NULL)", using: :btree
+ end
+
+ create_table "geo_hashed_storage_attachments_events", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.text "old_attachments_path", null: false
+ t.text "new_attachments_path", null: false
+ t.index ["project_id"], name: "index_geo_hashed_storage_attachments_events_on_project_id", using: :btree
+ end
+
+ create_table "geo_hashed_storage_migrated_events", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.text "repository_storage_name", null: false
+ t.text "old_disk_path", null: false
+ t.text "new_disk_path", null: false
+ t.text "old_wiki_disk_path", null: false
+ t.text "new_wiki_disk_path", null: false
+ t.integer "old_storage_version", limit: 2
+ t.integer "new_storage_version", limit: 2, null: false
+ t.index ["project_id"], name: "index_geo_hashed_storage_migrated_events_on_project_id", using: :btree
+ end
+
+ create_table "geo_job_artifact_deleted_events", force: :cascade do |t|
+ t.integer "job_artifact_id", null: false
+ t.string "file_path", null: false
+ t.index ["job_artifact_id"], name: "index_geo_job_artifact_deleted_events_on_job_artifact_id", using: :btree
+ end
+
+ create_table "geo_lfs_object_deleted_events", force: :cascade do |t|
+ t.integer "lfs_object_id", null: false
+ t.string "oid", null: false
+ t.string "file_path", null: false
+ t.index ["lfs_object_id"], name: "index_geo_lfs_object_deleted_events_on_lfs_object_id", using: :btree
+ end
+
+ create_table "geo_node_namespace_links", id: :serial, force: :cascade do |t|
+ t.integer "geo_node_id", null: false
+ t.integer "namespace_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["geo_node_id", "namespace_id"], name: "index_geo_node_namespace_links_on_geo_node_id_and_namespace_id", unique: true, using: :btree
+ t.index ["geo_node_id"], name: "index_geo_node_namespace_links_on_geo_node_id", using: :btree
+ t.index ["namespace_id"], name: "index_geo_node_namespace_links_on_namespace_id", using: :btree
+ end
+
+ create_table "geo_node_statuses", id: :serial, force: :cascade do |t|
+ t.integer "geo_node_id", null: false
+ t.integer "db_replication_lag_seconds"
+ t.integer "repositories_synced_count"
+ t.integer "repositories_failed_count"
+ t.integer "lfs_objects_count"
+ t.integer "lfs_objects_synced_count"
+ t.integer "lfs_objects_failed_count"
+ t.integer "attachments_count"
+ t.integer "attachments_synced_count"
+ t.integer "attachments_failed_count"
+ t.integer "last_event_id"
+ t.datetime "last_event_date"
+ t.integer "cursor_last_event_id"
+ t.datetime "cursor_last_event_date"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.datetime "last_successful_status_check_at"
+ t.string "status_message"
+ t.integer "replication_slots_count"
+ t.integer "replication_slots_used_count"
+ t.bigint "replication_slots_max_retained_wal_bytes"
+ t.integer "wikis_synced_count"
+ t.integer "wikis_failed_count"
+ t.integer "job_artifacts_count"
+ t.integer "job_artifacts_synced_count"
+ t.integer "job_artifacts_failed_count"
+ t.string "version"
+ t.string "revision"
+ t.integer "repositories_verified_count"
+ t.integer "repositories_verification_failed_count"
+ t.integer "wikis_verified_count"
+ t.integer "wikis_verification_failed_count"
+ t.integer "lfs_objects_synced_missing_on_primary_count"
+ t.integer "job_artifacts_synced_missing_on_primary_count"
+ t.integer "attachments_synced_missing_on_primary_count"
+ t.integer "repositories_checksummed_count"
+ t.integer "repositories_checksum_failed_count"
+ t.integer "repositories_checksum_mismatch_count"
+ t.integer "wikis_checksummed_count"
+ t.integer "wikis_checksum_failed_count"
+ t.integer "wikis_checksum_mismatch_count"
+ t.binary "storage_configuration_digest"
+ t.integer "repositories_retrying_verification_count"
+ t.integer "wikis_retrying_verification_count"
+ t.integer "projects_count"
+ t.index ["geo_node_id"], name: "index_geo_node_statuses_on_geo_node_id", unique: true, using: :btree
+ end
+
+ create_table "geo_nodes", id: :serial, force: :cascade do |t|
+ t.boolean "primary"
+ t.integer "oauth_application_id"
+ t.boolean "enabled", default: true, null: false
+ t.string "access_key"
+ t.string "encrypted_secret_access_key"
+ t.string "encrypted_secret_access_key_iv"
+ t.string "clone_url_prefix"
+ t.integer "files_max_capacity", default: 10, null: false
+ t.integer "repos_max_capacity", default: 25, null: false
+ t.string "url", null: false
+ t.string "selective_sync_type"
+ t.text "selective_sync_shards"
+ t.integer "verification_max_capacity", default: 100, null: false
+ t.integer "minimum_reverification_interval", default: 7, null: false
+ t.string "internal_url"
+ t.string "name", null: false
+ t.index ["access_key"], name: "index_geo_nodes_on_access_key", using: :btree
+ t.index ["name"], name: "index_geo_nodes_on_name", unique: true, using: :btree
+ t.index ["primary"], name: "index_geo_nodes_on_primary", using: :btree
+ end
+
+ create_table "geo_repositories_changed_events", force: :cascade do |t|
+ t.integer "geo_node_id", null: false
+ t.index ["geo_node_id"], name: "index_geo_repositories_changed_events_on_geo_node_id", using: :btree
+ end
+
+ create_table "geo_repository_created_events", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.text "repository_storage_name", null: false
+ t.text "repo_path", null: false
+ t.text "wiki_path"
+ t.text "project_name", null: false
+ t.index ["project_id"], name: "index_geo_repository_created_events_on_project_id", using: :btree
+ end
+
+ create_table "geo_repository_deleted_events", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.text "repository_storage_name", null: false
+ t.text "deleted_path", null: false
+ t.text "deleted_wiki_path"
+ t.text "deleted_project_name", null: false
+ t.index ["project_id"], name: "index_geo_repository_deleted_events_on_project_id", using: :btree
+ end
+
+ create_table "geo_repository_renamed_events", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.text "repository_storage_name", null: false
+ t.text "old_path_with_namespace", null: false
+ t.text "new_path_with_namespace", null: false
+ t.text "old_wiki_path_with_namespace", null: false
+ t.text "new_wiki_path_with_namespace", null: false
+ t.text "old_path", null: false
+ t.text "new_path", null: false
+ t.index ["project_id"], name: "index_geo_repository_renamed_events_on_project_id", using: :btree
+ end
+
+ create_table "geo_repository_updated_events", force: :cascade do |t|
+ t.integer "branches_affected", null: false
+ t.integer "tags_affected", null: false
+ t.integer "project_id", null: false
+ t.integer "source", limit: 2, null: false
+ t.boolean "new_branch", default: false, null: false
+ t.boolean "remove_branch", default: false, null: false
+ t.text "ref"
+ t.index ["project_id"], name: "index_geo_repository_updated_events_on_project_id", using: :btree
+ t.index ["source"], name: "index_geo_repository_updated_events_on_source", using: :btree
+ end
+
+ create_table "geo_reset_checksum_events", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.index ["project_id"], name: "index_geo_reset_checksum_events_on_project_id", using: :btree
+ end
+
+ create_table "geo_upload_deleted_events", force: :cascade do |t|
+ t.integer "upload_id", null: false
+ t.string "file_path", null: false
+ t.integer "model_id", null: false
+ t.string "model_type", null: false
+ t.string "uploader", null: false
+ t.index ["upload_id"], name: "index_geo_upload_deleted_events_on_upload_id", using: :btree
+ end
+
+ create_table "gitlab_subscriptions", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.date "start_date"
+ t.date "end_date"
+ t.date "trial_ends_on"
+ t.integer "namespace_id"
+ t.integer "hosted_plan_id"
+ t.integer "max_seats_used", default: 0
+ t.integer "seats", default: 0
+ t.boolean "trial", default: false
+ t.index ["hosted_plan_id"], name: "index_gitlab_subscriptions_on_hosted_plan_id", using: :btree
+ t.index ["namespace_id"], name: "index_gitlab_subscriptions_on_namespace_id", unique: true, using: :btree
+ end
+
create_table "gpg_key_subkeys", id: :serial, force: :cascade do |t|
t.integer "gpg_key_id", null: false
t.binary "keyid"
@@ -1022,12 +1533,22 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["key", "value"], name: "index_group_custom_attributes_on_key_and_value", using: :btree
end
+ create_table "historical_data", id: :serial, force: :cascade do |t|
+ t.date "date", null: false
+ t.integer "active_user_count"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "identities", id: :serial, force: :cascade do |t|
t.string "extern_uid"
t.string "provider"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
+ t.integer "saml_provider_id"
+ t.string "secondary_extern_uid"
+ t.index ["saml_provider_id"], name: "index_identities_on_saml_provider_id", where: "(saml_provider_id IS NOT NULL)", using: :btree
t.index ["user_id"], name: "index_identities_on_user_id", using: :btree
end
@@ -1040,6 +1561,23 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["updated_at"], name: "index_import_export_uploads_on_updated_at", using: :btree
end
+ create_table "index_statuses", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.datetime "indexed_at"
+ t.text "note"
+ t.string "last_commit"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["project_id"], name: "index_index_statuses_on_project_id", unique: true, using: :btree
+ end
+
+ create_table "insights", id: :serial, force: :cascade do |t|
+ t.integer "namespace_id", null: false
+ t.integer "project_id", null: false
+ t.index ["namespace_id"], name: "index_insights_on_namespace_id", using: :btree
+ t.index ["project_id"], name: "index_insights_on_project_id", using: :btree
+ end
+
create_table "internal_ids", force: :cascade do |t|
t.integer "project_id"
t.integer "usage", null: false
@@ -1064,6 +1602,16 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["user_id"], name: "index_issue_assignees_on_user_id", using: :btree
end
+ create_table "issue_links", id: :serial, force: :cascade do |t|
+ t.integer "source_id", null: false
+ t.integer "target_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["source_id", "target_id"], name: "index_issue_links_on_source_id_and_target_id", unique: true, using: :btree
+ t.index ["source_id"], name: "index_issue_links_on_source_id", using: :btree
+ t.index ["target_id"], name: "index_issue_links_on_target_id", using: :btree
+ end
+
create_table "issue_metrics", id: :serial, force: :cascade do |t|
t.integer "issue_id", null: false
t.datetime "first_mentioned_in_commit_at"
@@ -1113,6 +1661,8 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.datetime_with_timezone "closed_at"
t.integer "closed_by_id"
t.integer "state_id", limit: 2
+ t.string "service_desk_reply_to"
+ t.integer "weight"
t.index ["author_id"], name: "index_issues_on_author_id", using: :btree
t.index ["closed_by_id"], name: "index_issues_on_closed_by_id", using: :btree
t.index ["confidential"], name: "index_issues_on_confidential", using: :btree
@@ -1130,6 +1680,24 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["updated_by_id"], name: "index_issues_on_updated_by_id", where: "(updated_by_id IS NOT NULL)", using: :btree
end
+ create_table "jira_connect_installations", force: :cascade do |t|
+ t.string "client_key"
+ t.string "encrypted_shared_secret"
+ t.string "encrypted_shared_secret_iv"
+ t.string "base_url"
+ t.index ["client_key"], name: "index_jira_connect_installations_on_client_key", unique: true, using: :btree
+ end
+
+ create_table "jira_connect_subscriptions", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.bigint "jira_connect_installation_id", null: false
+ t.integer "namespace_id", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["jira_connect_installation_id", "namespace_id"], name: "idx_jira_connect_subscriptions_on_installation_id_namespace_id", unique: true, using: :btree
+ t.index ["jira_connect_installation_id"], name: "idx_jira_connect_subscriptions_on_installation_id", using: :btree
+ t.index ["namespace_id"], name: "index_jira_connect_subscriptions_on_namespace_id", using: :btree
+ end
+
create_table "jira_tracker_data", force: :cascade do |t|
t.integer "service_id", null: false
t.datetime_with_timezone "created_at", null: false
@@ -1200,6 +1768,16 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["type", "project_id"], name: "index_labels_on_type_and_project_id", using: :btree
end
+ create_table "ldap_group_links", id: :serial, force: :cascade do |t|
+ t.string "cn"
+ t.integer "group_access", null: false
+ t.integer "group_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "provider"
+ t.string "filter"
+ end
+
create_table "lfs_file_locks", id: :serial, force: :cascade do |t|
t.integer "project_id", null: false
t.integer "user_id", null: false
@@ -1230,6 +1808,12 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["project_id"], name: "index_lfs_objects_projects_on_project_id", using: :btree
end
+ create_table "licenses", id: :serial, force: :cascade do |t|
+ t.text "data", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "lists", id: :serial, force: :cascade do |t|
t.integer "board_id", null: false
t.integer "label_id"
@@ -1237,9 +1821,13 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.integer "position"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.integer "milestone_id"
+ t.integer "user_id"
t.index ["board_id", "label_id"], name: "index_lists_on_board_id_and_label_id", unique: true, using: :btree
t.index ["label_id"], name: "index_lists_on_label_id", using: :btree
t.index ["list_type"], name: "index_lists_on_list_type", using: :btree
+ t.index ["milestone_id"], name: "index_lists_on_milestone_id", using: :btree
+ t.index ["user_id"], name: "index_lists_on_user_id", using: :btree
end
create_table "members", id: :serial, force: :cascade do |t|
@@ -1257,6 +1845,8 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.datetime "invite_accepted_at"
t.datetime "requested_at"
t.date "expires_at"
+ t.boolean "ldap", default: false, null: false
+ t.boolean "override", default: false, null: false
t.index ["access_level"], name: "index_members_on_access_level", using: :btree
t.index ["invite_token"], name: "index_members_on_invite_token", unique: true, using: :btree
t.index ["requested_at"], name: "index_members_on_requested_at", using: :btree
@@ -1389,6 +1979,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.boolean "squash", default: false, null: false
t.boolean "allow_maintainer_to_push"
t.integer "state_id", limit: 2
+ t.integer "approvals_before_merge"
t.index ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree
t.index ["author_id"], name: "index_merge_requests_on_author_id", using: :btree
t.index ["created_at"], name: "index_merge_requests_on_created_at", using: :btree
@@ -1456,6 +2047,13 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["title"], name: "index_milestones_on_title_trigram", using: :gin, opclasses: {"title"=>"gin_trgm_ops"}
end
+ create_table "namespace_statistics", id: :serial, force: :cascade do |t|
+ t.integer "namespace_id", null: false
+ t.integer "shared_runners_seconds", default: 0, null: false
+ t.datetime "shared_runners_seconds_last_reset"
+ t.index ["namespace_id"], name: "index_namespace_statistics_on_namespace_id", unique: true, using: :btree
+ end
+
create_table "namespaces", id: :serial, force: :cascade do |t|
t.string "name", null: false
t.string "path", null: false
@@ -1479,16 +2077,37 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.integer "project_creation_level"
t.boolean "auto_devops_enabled"
t.datetime_with_timezone "last_ci_minutes_notification_at"
+ t.integer "custom_project_templates_group_id"
+ t.integer "file_template_project_id"
+ t.string "ldap_sync_error"
+ t.datetime "ldap_sync_last_successful_update_at"
+ t.datetime "ldap_sync_last_sync_at"
+ t.datetime "ldap_sync_last_update_at"
+ t.integer "plan_id"
+ t.bigint "repository_size_limit"
+ t.string "saml_discovery_token"
+ t.integer "shared_runners_minutes_limit"
+ t.datetime_with_timezone "trial_ends_on"
+ t.integer "extra_shared_runners_minutes_limit"
+ t.string "ldap_sync_status", default: "ready", null: false
+ t.boolean "membership_lock", default: false
t.index ["created_at"], name: "index_namespaces_on_created_at", using: :btree
+ t.index ["custom_project_templates_group_id", "type"], name: "index_namespaces_on_custom_project_templates_group_id_and_type", where: "(custom_project_templates_group_id IS NOT NULL)", using: :btree
+ t.index ["file_template_project_id"], name: "index_namespaces_on_file_template_project_id", using: :btree
+ t.index ["ldap_sync_last_successful_update_at"], name: "index_namespaces_on_ldap_sync_last_successful_update_at", using: :btree
+ t.index ["ldap_sync_last_update_at"], name: "index_namespaces_on_ldap_sync_last_update_at", using: :btree
t.index ["name", "parent_id"], name: "index_namespaces_on_name_and_parent_id", unique: true, using: :btree
t.index ["name"], name: "index_namespaces_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"}
t.index ["owner_id"], name: "index_namespaces_on_owner_id", using: :btree
t.index ["parent_id", "id"], name: "index_namespaces_on_parent_id_and_id", unique: true, using: :btree
t.index ["path"], name: "index_namespaces_on_path", using: :btree
t.index ["path"], name: "index_namespaces_on_path_trigram", using: :gin, opclasses: {"path"=>"gin_trgm_ops"}
+ t.index ["plan_id"], name: "index_namespaces_on_plan_id", using: :btree
t.index ["require_two_factor_authentication"], name: "index_namespaces_on_require_two_factor_authentication", using: :btree
t.index ["runners_token"], name: "index_namespaces_on_runners_token", unique: true, using: :btree
t.index ["runners_token_encrypted"], name: "index_namespaces_on_runners_token_encrypted", unique: true, using: :btree
+ t.index ["shared_runners_minutes_limit", "extra_shared_runners_minutes_limit"], name: "index_namespaces_on_shared_and_extra_runners_minutes_limit", using: :btree
+ t.index ["trial_ends_on"], name: "index_namespaces_on_trial_ends_on", where: "(trial_ends_on IS NOT NULL)", using: :btree
t.index ["type"], name: "index_namespaces_on_type", using: :btree
end
@@ -1529,6 +2148,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.integer "cached_markdown_version"
t.text "change_position"
t.boolean "resolved_by_push"
+ t.bigint "review_id"
t.index ["author_id"], name: "index_notes_on_author_id", using: :btree
t.index ["commit_id"], name: "index_notes_on_commit_id", using: :btree
t.index ["created_at"], name: "index_notes_on_created_at", using: :btree
@@ -1538,6 +2158,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["noteable_id", "noteable_type"], name: "index_notes_on_noteable_id_and_noteable_type", using: :btree
t.index ["noteable_type"], name: "index_notes_on_noteable_type", using: :btree
t.index ["project_id", "noteable_type"], name: "index_notes_on_project_id_and_noteable_type", using: :btree
+ t.index ["review_id"], name: "index_notes_on_review_id", using: :btree
end
create_table "notification_settings", id: :serial, force: :cascade do |t|
@@ -1562,6 +2183,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.boolean "push_to_merge_request"
t.boolean "issue_due"
t.string "notification_email"
+ t.boolean "new_epic"
t.index ["source_id", "source_type"], name: "index_notification_settings_on_source_id_and_source_type", using: :btree
t.index ["user_id", "source_id", "source_type"], name: "index_notifications_on_user_id_and_source_id_and_source_type", unique: true, using: :btree
t.index ["user_id"], name: "index_notification_settings_on_user_id", using: :btree
@@ -1614,6 +2236,66 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["access_grant_id"], name: "index_oauth_openid_requests_on_access_grant_id", using: :btree
end
+ create_table "operations_feature_flag_scopes", force: :cascade do |t|
+ t.bigint "feature_flag_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.boolean "active", null: false
+ t.string "environment_scope", default: "*", null: false
+ t.index ["feature_flag_id", "environment_scope"], name: "index_feature_flag_scopes_on_flag_id_and_environment_scope", unique: true, using: :btree
+ end
+
+ create_table "operations_feature_flags", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.boolean "active", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "name", null: false
+ t.text "description"
+ t.index ["project_id", "name"], name: "index_operations_feature_flags_on_project_id_and_name", unique: true, using: :btree
+ end
+
+ create_table "operations_feature_flags_clients", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.string "token", null: false
+ t.index ["project_id", "token"], name: "index_operations_feature_flags_clients_on_project_id_and_token", unique: true, using: :btree
+ end
+
+ create_table "packages_maven_metadata", force: :cascade do |t|
+ t.bigint "package_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "app_group", null: false
+ t.string "app_name", null: false
+ t.string "app_version"
+ t.string "path", limit: 512, null: false
+ t.index ["package_id", "path"], name: "index_packages_maven_metadata_on_package_id_and_path", using: :btree
+ end
+
+ create_table "packages_package_files", force: :cascade do |t|
+ t.bigint "package_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "size"
+ t.integer "file_type"
+ t.integer "file_store"
+ t.binary "file_md5"
+ t.binary "file_sha1"
+ t.string "file_name", null: false
+ t.text "file", null: false
+ t.index ["package_id", "file_name"], name: "index_packages_package_files_on_package_id_and_file_name", using: :btree
+ end
+
+ create_table "packages_packages", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "name", null: false
+ t.string "version"
+ t.integer "package_type", limit: 2, null: false
+ t.index ["project_id"], name: "index_packages_packages_on_project_id", using: :btree
+ end
+
create_table "pages_domain_acme_orders", force: :cascade do |t|
t.integer "pages_domain_id", null: false
t.datetime_with_timezone "expires_at", null: false
@@ -1650,6 +2332,17 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["verified_at"], name: "index_pages_domains_on_verified_at", using: :btree
end
+ create_table "path_locks", id: :serial, force: :cascade do |t|
+ t.string "path", null: false
+ t.integer "project_id"
+ t.integer "user_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["path"], name: "index_path_locks_on_path", using: :btree
+ t.index ["project_id"], name: "index_path_locks_on_project_id", using: :btree
+ t.index ["user_id"], name: "index_path_locks_on_user_id", using: :btree
+ end
+
create_table "personal_access_tokens", id: :serial, force: :cascade do |t|
t.integer "user_id", null: false
t.string "name", null: false
@@ -1664,6 +2357,16 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["user_id"], name: "index_personal_access_tokens_on_user_id", using: :btree
end
+ create_table "plans", id: :serial, force: :cascade do |t|
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "name"
+ t.string "title"
+ t.integer "active_pipelines_limit"
+ t.integer "pipeline_size_limit"
+ t.index ["name"], name: "index_plans_on_name", using: :btree
+ end
+
create_table "pool_repositories", force: :cascade do |t|
t.integer "shard_id", null: false
t.string "disk_path"
@@ -1681,6 +2384,11 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["name"], name: "index_programming_languages_on_name", unique: true, using: :btree
end
+ create_table "project_alerting_settings", primary_key: "project_id", id: :integer, default: nil, force: :cascade do |t|
+ t.string "encrypted_token", null: false
+ t.string "encrypted_token_iv", null: false
+ end
+
create_table "project_authorizations", id: false, force: :cascade do |t|
t.integer "user_id", null: false
t.integer "project_id", null: false
@@ -1741,6 +2449,14 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.string "organization_name"
end
+ create_table "project_feature_usages", primary_key: "project_id", id: :integer, default: nil, force: :cascade do |t|
+ t.datetime "jira_dvcs_cloud_last_sync_at"
+ t.datetime "jira_dvcs_server_last_sync_at"
+ t.index ["jira_dvcs_cloud_last_sync_at", "project_id"], name: "idx_proj_feat_usg_on_jira_dvcs_cloud_last_sync_at_and_proj_id", where: "(jira_dvcs_cloud_last_sync_at IS NOT NULL)", using: :btree
+ t.index ["jira_dvcs_server_last_sync_at", "project_id"], name: "idx_proj_feat_usg_on_jira_dvcs_server_last_sync_at_and_proj_id", where: "(jira_dvcs_server_last_sync_at IS NOT NULL)", using: :btree
+ t.index ["project_id"], name: "index_project_feature_usages_on_project_id", using: :btree
+ end
+
create_table "project_features", id: :serial, force: :cascade do |t|
t.integer "project_id", null: false
t.integer "merge_requests_access_level"
@@ -1775,6 +2491,12 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["project_id"], name: "index_project_import_data_on_project_id", using: :btree
end
+ create_table "project_incident_management_settings", primary_key: "project_id", id: :integer, default: nil, force: :cascade do |t|
+ t.boolean "create_issue", default: false, null: false
+ t.boolean "send_email", default: true, null: false
+ t.text "issue_template_key"
+ end
+
create_table "project_metrics_settings", primary_key: "project_id", id: :integer, default: nil, force: :cascade do |t|
t.string "external_dashboard_url", null: false
end
@@ -1784,7 +2506,16 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.string "status"
t.string "jid"
t.text "last_error"
+ t.datetime_with_timezone "last_successful_update_at"
+ t.datetime_with_timezone "last_update_at"
+ t.datetime "last_update_scheduled_at"
+ t.datetime "last_update_started_at"
+ t.datetime "next_execution_timestamp"
+ t.integer "retry_count", default: 0, null: false
t.index ["jid"], name: "index_project_mirror_data_on_jid", using: :btree
+ t.index ["last_successful_update_at"], name: "index_project_mirror_data_on_last_successful_update_at", using: :btree
+ t.index ["last_update_at", "retry_count"], name: "index_project_mirror_data_on_last_update_at_and_retry_count", using: :btree
+ t.index ["next_execution_timestamp", "retry_count"], name: "index_mirror_data_on_next_execution_and_retry_count", using: :btree
t.index ["project_id"], name: "index_project_mirror_data_on_project_id", unique: true, using: :btree
t.index ["status"], name: "index_project_mirror_data_on_status", using: :btree
end
@@ -1798,6 +2529,26 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["shard_id"], name: "index_project_repositories_on_shard_id", using: :btree
end
+ create_table "project_repository_states", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.binary "repository_verification_checksum"
+ t.binary "wiki_verification_checksum"
+ t.string "last_repository_verification_failure"
+ t.string "last_wiki_verification_failure"
+ t.datetime_with_timezone "repository_retry_at"
+ t.datetime_with_timezone "wiki_retry_at"
+ t.integer "repository_retry_count"
+ t.integer "wiki_retry_count"
+ t.datetime_with_timezone "last_repository_verification_ran_at"
+ t.datetime_with_timezone "last_wiki_verification_ran_at"
+ t.index ["last_repository_verification_failure"], name: "idx_repository_states_on_repository_failure_partial", where: "(last_repository_verification_failure IS NOT NULL)", using: :btree
+ t.index ["last_wiki_verification_failure"], name: "idx_repository_states_on_wiki_failure_partial", where: "(last_wiki_verification_failure IS NOT NULL)", using: :btree
+ t.index ["project_id", "last_repository_verification_ran_at"], name: "idx_repository_states_on_last_repository_verification_ran_at", where: "((repository_verification_checksum IS NOT NULL) AND (last_repository_verification_failure IS NULL))", using: :btree
+ t.index ["project_id", "last_wiki_verification_ran_at"], name: "idx_repository_states_on_last_wiki_verification_ran_at", where: "((wiki_verification_checksum IS NOT NULL) AND (last_wiki_verification_failure IS NULL))", using: :btree
+ t.index ["project_id"], name: "idx_repository_states_outdated_checksums", where: "(((repository_verification_checksum IS NULL) AND (last_repository_verification_failure IS NULL)) OR ((wiki_verification_checksum IS NULL) AND (last_wiki_verification_failure IS NULL)))", using: :btree
+ t.index ["project_id"], name: "index_project_repository_states_on_project_id", unique: true, using: :btree
+ end
+
create_table "project_statistics", id: :serial, force: :cascade do |t|
t.integer "project_id", null: false
t.integer "namespace_id", null: false
@@ -1808,10 +2559,20 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.bigint "build_artifacts_size", default: 0, null: false
t.bigint "packages_size", default: 0, null: false
t.bigint "wiki_size"
+ t.bigint "shared_runners_seconds", default: 0, null: false
+ t.datetime "shared_runners_seconds_last_reset"
t.index ["namespace_id"], name: "index_project_statistics_on_namespace_id", using: :btree
t.index ["project_id"], name: "index_project_statistics_on_project_id", unique: true, using: :btree
end
+ create_table "project_tracing_settings", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.string "external_url", null: false
+ t.index ["project_id"], name: "index_project_tracing_settings_on_project_id", unique: true, using: :btree
+ end
+
create_table "projects", id: :serial, force: :cascade do |t|
t.string "name"
t.string "path"
@@ -1859,7 +2620,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.boolean "resolve_outdated_diff_discussions"
t.boolean "repository_read_only"
t.boolean "merge_requests_ff_only_enabled", default: false
- t.boolean "merge_requests_rebase_enabled", default: false, null: false
+ t.boolean "merge_requests_rebase_enabled", default: false
t.integer "jobs_cache_index"
t.boolean "pages_https_only", default: true
t.boolean "remote_mirror_available_overridden"
@@ -1868,14 +2629,40 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.string "bfg_object_map"
t.boolean "detected_repository_languages"
t.string "external_authorization_classification_label"
+ t.boolean "disable_overriding_approvers_per_merge_request"
+ t.string "external_webhook_token"
+ t.text "issues_template"
+ t.boolean "merge_requests_author_approval"
+ t.boolean "merge_requests_disable_committers_approval"
+ t.boolean "merge_requests_require_code_owner_approval"
+ t.text "merge_requests_template"
+ t.datetime "mirror_last_successful_update_at"
+ t.datetime "mirror_last_update_at"
+ t.boolean "mirror_overwrites_diverged_branches"
+ t.integer "mirror_user_id"
+ t.boolean "only_mirror_protected_branches"
+ t.boolean "packages_enabled"
+ t.boolean "pull_mirror_available_overridden"
+ t.bigint "repository_size_limit"
+ t.boolean "require_password_to_approve"
+ t.boolean "mirror", default: false, null: false
+ t.boolean "mirror_trigger_builds", default: false, null: false
+ t.boolean "reset_approvals_on_push", default: true
+ t.boolean "service_desk_enabled", default: true
+ t.integer "approvals_before_merge", default: 0, null: false
+ t.index ["archived", "pending_delete", "merge_requests_require_code_owner_approval"], name: "projects_requiring_code_owner_approval", where: "((pending_delete = false) AND (archived = false) AND (merge_requests_require_code_owner_approval = true))", using: :btree
t.index ["created_at"], name: "index_projects_on_created_at", using: :btree
t.index ["creator_id"], name: "index_projects_on_creator_id", using: :btree
t.index ["description"], name: "index_projects_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"}
+ t.index ["id", "repository_storage", "last_repository_updated_at"], name: "idx_projects_on_repository_storage_last_repository_updated_at", using: :btree
t.index ["id"], name: "index_projects_on_id_partial_for_visibility", unique: true, where: "(visibility_level = ANY (ARRAY[10, 20]))", using: :btree
+ t.index ["id"], name: "index_projects_on_mirror_and_mirror_trigger_builds_both_true", where: "((mirror IS TRUE) AND (mirror_trigger_builds IS TRUE))", using: :btree
t.index ["last_activity_at"], name: "index_projects_on_last_activity_at", using: :btree
t.index ["last_repository_check_at"], name: "index_projects_on_last_repository_check_at", where: "(last_repository_check_at IS NOT NULL)", using: :btree
t.index ["last_repository_check_failed"], name: "index_projects_on_last_repository_check_failed", using: :btree
t.index ["last_repository_updated_at"], name: "index_projects_on_last_repository_updated_at", using: :btree
+ t.index ["mirror_last_successful_update_at"], name: "index_projects_on_mirror_last_successful_update_at", using: :btree
+ t.index ["mirror_user_id"], name: "index_projects_on_mirror_user_id", using: :btree
t.index ["name"], name: "index_projects_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"}
t.index ["namespace_id"], name: "index_projects_on_namespace_id", using: :btree
t.index ["path"], name: "index_projects_on_path", using: :btree
@@ -1890,6 +2677,30 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["visibility_level"], name: "index_projects_on_visibility_level", using: :btree
end
+ create_table "prometheus_alert_events", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "prometheus_alert_id", null: false
+ t.datetime_with_timezone "started_at", null: false
+ t.datetime_with_timezone "ended_at"
+ t.integer "status", limit: 2
+ t.string "payload_key"
+ t.index ["project_id", "status"], name: "index_prometheus_alert_events_on_project_id_and_status", using: :btree
+ t.index ["prometheus_alert_id", "payload_key"], name: "index_prometheus_alert_event_scoped_payload_key", unique: true, using: :btree
+ end
+
+ create_table "prometheus_alerts", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.float "threshold", null: false
+ t.integer "operator", null: false
+ t.integer "environment_id", null: false
+ t.integer "project_id", null: false
+ t.integer "prometheus_metric_id", null: false
+ t.index ["environment_id"], name: "index_prometheus_alerts_on_environment_id", using: :btree
+ t.index ["project_id", "prometheus_metric_id", "environment_id"], name: "index_prometheus_alerts_metric_environment", unique: true, using: :btree
+ t.index ["prometheus_metric_id"], name: "index_prometheus_alerts_on_prometheus_metric_id", using: :btree
+ end
+
create_table "prometheus_metrics", id: :serial, force: :cascade do |t|
t.integer "project_id"
t.string "title", null: false
@@ -1910,18 +2721,36 @@ ActiveRecord::Schema.define(version: 20190611161641) do
create_table "protected_branch_merge_access_levels", id: :serial, force: :cascade do |t|
t.integer "protected_branch_id", null: false
- t.integer "access_level", default: 40, null: false
+ t.integer "access_level", default: 40
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.integer "group_id"
+ t.integer "user_id"
+ t.index ["group_id"], name: "index_protected_branch_merge_access_levels_on_group_id", using: :btree
t.index ["protected_branch_id"], name: "index_protected_branch_merge_access", using: :btree
+ t.index ["user_id"], name: "index_protected_branch_merge_access_levels_on_user_id", using: :btree
end
create_table "protected_branch_push_access_levels", id: :serial, force: :cascade do |t|
t.integer "protected_branch_id", null: false
- t.integer "access_level", default: 40, null: false
+ t.integer "access_level", default: 40
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.integer "group_id"
+ t.integer "user_id"
+ t.index ["group_id"], name: "index_protected_branch_push_access_levels_on_group_id", using: :btree
t.index ["protected_branch_id"], name: "index_protected_branch_push_access", using: :btree
+ t.index ["user_id"], name: "index_protected_branch_push_access_levels_on_user_id", using: :btree
+ end
+
+ create_table "protected_branch_unprotect_access_levels", id: :serial, force: :cascade do |t|
+ t.integer "protected_branch_id", null: false
+ t.integer "access_level", default: 40
+ t.integer "user_id"
+ t.integer "group_id"
+ t.index ["group_id"], name: "index_protected_branch_unprotect_access_levels_on_group_id", using: :btree
+ t.index ["protected_branch_id"], name: "index_protected_branch_unprotect_access", using: :btree
+ t.index ["user_id"], name: "index_protected_branch_unprotect_access_levels_on_user_id", using: :btree
end
create_table "protected_branches", id: :serial, force: :cascade do |t|
@@ -1932,6 +2761,27 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["project_id"], name: "index_protected_branches_on_project_id", using: :btree
end
+ create_table "protected_environment_deploy_access_levels", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "access_level", default: 40
+ t.integer "protected_environment_id", null: false
+ t.integer "user_id"
+ t.integer "group_id"
+ t.index ["group_id"], name: "index_protected_environment_deploy_access_levels_on_group_id", using: :btree
+ t.index ["protected_environment_id"], name: "index_protected_environment_deploy_access", using: :btree
+ t.index ["user_id"], name: "index_protected_environment_deploy_access_levels_on_user_id", using: :btree
+ end
+
+ create_table "protected_environments", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "name", null: false
+ t.index ["project_id", "name"], name: "index_protected_environments_on_project_id_and_name", unique: true, using: :btree
+ t.index ["project_id"], name: "index_protected_environments_on_project_id", using: :btree
+ end
+
create_table "protected_tag_create_access_levels", id: :serial, force: :cascade do |t|
t.integer "protected_tag_id", null: false
t.integer "access_level", default: 40
@@ -1965,6 +2815,29 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["event_id"], name: "index_push_event_payloads_on_event_id", unique: true, using: :btree
end
+ create_table "push_rules", id: :serial, force: :cascade do |t|
+ t.string "force_push_regex"
+ t.string "delete_branch_regex"
+ t.string "commit_message_regex"
+ t.boolean "deny_delete_tag"
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "author_email_regex"
+ t.boolean "member_check", default: false, null: false
+ t.string "file_name_regex"
+ t.boolean "is_sample", default: false
+ t.integer "max_file_size", default: 0, null: false
+ t.boolean "prevent_secrets", default: false, null: false
+ t.string "branch_name_regex"
+ t.boolean "reject_unsigned_commits"
+ t.boolean "commit_committer_check"
+ t.boolean "regexp_uses_re2", default: true
+ t.string "commit_message_negative_regex"
+ t.index ["is_sample"], name: "index_push_rules_on_is_sample", where: "is_sample", using: :btree
+ t.index ["project_id"], name: "index_push_rules_on_project_id", using: :btree
+ end
+
create_table "redirect_routes", id: :serial, force: :cascade do |t|
t.integer "source_id", null: false
t.string "source_type", null: false
@@ -2039,12 +2912,24 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.integer "cached_markdown_version"
t.text "reference"
t.text "reference_html"
+ t.integer "epic_id"
+ t.index ["epic_id"], name: "index_resource_label_events_on_epic_id", using: :btree
t.index ["issue_id"], name: "index_resource_label_events_on_issue_id", using: :btree
t.index ["label_id"], name: "index_resource_label_events_on_label_id", using: :btree
t.index ["merge_request_id"], name: "index_resource_label_events_on_merge_request_id", using: :btree
t.index ["user_id"], name: "index_resource_label_events_on_user_id", using: :btree
end
+ create_table "reviews", force: :cascade do |t|
+ t.integer "author_id"
+ t.integer "merge_request_id", null: false
+ t.integer "project_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.index ["author_id"], name: "index_reviews_on_author_id", using: :btree
+ t.index ["merge_request_id"], name: "index_reviews_on_merge_request_id", using: :btree
+ t.index ["project_id"], name: "index_reviews_on_project_id", using: :btree
+ end
+
create_table "routes", id: :serial, force: :cascade do |t|
t.integer "source_id", null: false
t.string "source_type", null: false
@@ -2057,6 +2942,24 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["source_type", "source_id"], name: "index_routes_on_source_type_and_source_id", unique: true, using: :btree
end
+ create_table "saml_providers", id: :serial, force: :cascade do |t|
+ t.integer "group_id", null: false
+ t.boolean "enabled", null: false
+ t.string "certificate_fingerprint", null: false
+ t.string "sso_url", null: false
+ t.boolean "enforced_sso", default: false, null: false
+ t.boolean "enforced_group_managed_accounts", default: false, null: false
+ t.index ["group_id"], name: "index_saml_providers_on_group_id", using: :btree
+ end
+
+ create_table "scim_oauth_access_tokens", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "group_id", null: false
+ t.string "token_encrypted", null: false
+ t.index ["group_id", "token_encrypted"], name: "index_scim_oauth_access_tokens_on_group_id_and_token_encrypted", unique: true, using: :btree
+ end
+
create_table "sent_notifications", id: :serial, force: :cascade do |t|
t.integer "project_id"
t.integer "noteable_id"
@@ -2104,6 +3007,26 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["name"], name: "index_shards_on_name", unique: true, using: :btree
end
+ create_table "slack_integrations", id: :serial, force: :cascade do |t|
+ t.integer "service_id", null: false
+ t.string "team_id", null: false
+ t.string "team_name", null: false
+ t.string "alias", null: false
+ t.string "user_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["service_id"], name: "index_slack_integrations_on_service_id", using: :btree
+ t.index ["team_id", "alias"], name: "index_slack_integrations_on_team_id_and_alias", unique: true, using: :btree
+ end
+
+ create_table "smartcard_identities", force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.string "subject", null: false
+ t.string "issuer", null: false
+ t.index ["subject", "issuer"], name: "index_smartcard_identities_on_subject_and_issuer", unique: true, using: :btree
+ t.index ["user_id"], name: "index_smartcard_identities_on_user_id", using: :btree
+ end
+
create_table "snippets", id: :serial, force: :cascade do |t|
t.string "title"
t.text "content"
@@ -2127,6 +3050,19 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["visibility_level"], name: "index_snippets_on_visibility_level", using: :btree
end
+ create_table "software_license_policies", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "software_license_id", null: false
+ t.integer "approval_status", default: 0, null: false
+ t.index ["project_id", "software_license_id"], name: "index_software_license_policies_unique_per_project", unique: true, using: :btree
+ t.index ["software_license_id"], name: "index_software_license_policies_on_software_license_id", using: :btree
+ end
+
+ create_table "software_licenses", id: :serial, force: :cascade do |t|
+ t.string "name", null: false
+ t.index ["name"], name: "index_software_licenses_on_name", using: :btree
+ end
+
create_table "spam_logs", id: :serial, force: :cascade do |t|
t.integer "user_id"
t.string "source_ip"
@@ -2326,6 +3262,10 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.string "timezone"
t.boolean "time_display_relative"
t.boolean "time_format_in_24h"
+ t.integer "epic_notes_filter", limit: 2, default: 0, null: false
+ t.string "epics_sort"
+ t.integer "roadmap_epics_state"
+ t.string "roadmaps_sort"
t.index ["user_id"], name: "index_user_preferences_on_user_id", unique: true, using: :btree
end
@@ -2415,24 +3355,48 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.boolean "private_profile"
t.boolean "include_private_contributions"
t.string "commit_email"
+ t.boolean "auditor", default: false, null: false
+ t.datetime "admin_email_unsubscribed_at"
+ t.boolean "email_opted_in"
+ t.datetime "email_opted_in_at"
+ t.string "email_opted_in_ip"
+ t.integer "email_opted_in_source_id"
+ t.integer "group_view"
+ t.integer "managing_group_id"
+ t.text "note"
+ t.integer "roadmap_layout", limit: 2
+ t.integer "bot_type", limit: 2
t.index ["accepted_term_id"], name: "index_users_on_accepted_term_id", using: :btree
t.index ["admin"], name: "index_users_on_admin", using: :btree
+ t.index ["bot_type"], name: "index_users_on_bot_type", using: :btree
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
t.index ["created_at"], name: "index_users_on_created_at", using: :btree
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
t.index ["email"], name: "index_users_on_email_trigram", using: :gin, opclasses: {"email"=>"gin_trgm_ops"}
t.index ["feed_token"], name: "index_users_on_feed_token", using: :btree
t.index ["ghost"], name: "index_users_on_ghost", using: :btree
+ t.index ["group_view"], name: "index_users_on_group_view", using: :btree
t.index ["incoming_email_token"], name: "index_users_on_incoming_email_token", using: :btree
+ t.index ["managing_group_id"], name: "index_users_on_managing_group_id", using: :btree
t.index ["name"], name: "index_users_on_name", using: :btree
t.index ["name"], name: "index_users_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"}
t.index ["public_email"], name: "index_users_on_public_email", where: "((public_email)::text <> ''::text)", using: :btree
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
t.index ["state"], name: "index_users_on_state", using: :btree
+ t.index ["state"], name: "index_users_on_state_and_internal", where: "((ghost <> true) AND (bot_type IS NULL))", using: :btree
t.index ["username"], name: "index_users_on_username", using: :btree
t.index ["username"], name: "index_users_on_username_trigram", using: :gin, opclasses: {"username"=>"gin_trgm_ops"}
end
+ create_table "users_ops_dashboard_projects", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "user_id", null: false
+ t.integer "project_id", null: false
+ t.index ["project_id"], name: "index_users_ops_dashboard_projects_on_project_id", using: :btree
+ t.index ["user_id", "project_id"], name: "index_users_ops_dashboard_projects_on_user_id_and_project_id", unique: true, using: :btree
+ end
+
create_table "users_star_projects", id: :serial, force: :cascade do |t|
t.integer "project_id", null: false
t.integer "user_id", null: false
@@ -2442,6 +3406,88 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.index ["user_id", "project_id"], name: "index_users_star_projects_on_user_id_and_project_id", unique: true, using: :btree
end
+ create_table "vulnerability_feedback", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "feedback_type", limit: 2, null: false
+ t.integer "category", limit: 2, null: false
+ t.integer "project_id", null: false
+ t.integer "author_id", null: false
+ t.integer "pipeline_id"
+ t.integer "issue_id"
+ t.string "project_fingerprint", limit: 40, null: false
+ t.integer "merge_request_id"
+ t.integer "comment_author_id"
+ t.text "comment"
+ t.datetime_with_timezone "comment_timestamp"
+ t.index ["author_id"], name: "index_vulnerability_feedback_on_author_id", using: :btree
+ t.index ["comment_author_id"], name: "index_vulnerability_feedback_on_comment_author_id", using: :btree
+ t.index ["issue_id"], name: "index_vulnerability_feedback_on_issue_id", using: :btree
+ t.index ["merge_request_id"], name: "index_vulnerability_feedback_on_merge_request_id", using: :btree
+ t.index ["pipeline_id"], name: "index_vulnerability_feedback_on_pipeline_id", using: :btree
+ t.index ["project_id", "category", "feedback_type", "project_fingerprint"], name: "vulnerability_feedback_unique_idx", unique: true, using: :btree
+ end
+
+ create_table "vulnerability_identifiers", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.binary "fingerprint", null: false
+ t.string "external_type", null: false
+ t.string "external_id", null: false
+ t.string "name", null: false
+ t.text "url"
+ t.index ["project_id", "fingerprint"], name: "index_vulnerability_identifiers_on_project_id_and_fingerprint", unique: true, using: :btree
+ end
+
+ create_table "vulnerability_occurrence_identifiers", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "occurrence_id", null: false
+ t.bigint "identifier_id", null: false
+ t.index ["identifier_id"], name: "index_vulnerability_occurrence_identifiers_on_identifier_id", using: :btree
+ t.index ["occurrence_id", "identifier_id"], name: "index_vulnerability_occurrence_identifiers_on_unique_keys", unique: true, using: :btree
+ end
+
+ create_table "vulnerability_occurrence_pipelines", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "occurrence_id", null: false
+ t.integer "pipeline_id", null: false
+ t.index ["occurrence_id", "pipeline_id"], name: "vulnerability_occurrence_pipelines_on_unique_keys", unique: true, using: :btree
+ t.index ["pipeline_id"], name: "index_vulnerability_occurrence_pipelines_on_pipeline_id", using: :btree
+ end
+
+ create_table "vulnerability_occurrences", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "severity", limit: 2, null: false
+ t.integer "confidence", limit: 2, null: false
+ t.integer "report_type", limit: 2, null: false
+ t.integer "project_id", null: false
+ t.bigint "scanner_id", null: false
+ t.bigint "primary_identifier_id", null: false
+ t.binary "project_fingerprint", null: false
+ t.binary "location_fingerprint", null: false
+ t.string "uuid", limit: 36, null: false
+ t.string "name", null: false
+ t.string "metadata_version", null: false
+ t.text "raw_metadata", null: false
+ t.index ["primary_identifier_id"], name: "index_vulnerability_occurrences_on_primary_identifier_id", using: :btree
+ t.index ["project_id", "primary_identifier_id", "location_fingerprint", "scanner_id"], name: "index_vulnerability_occurrences_on_unique_keys", unique: true, using: :btree
+ t.index ["scanner_id"], name: "index_vulnerability_occurrences_on_scanner_id", using: :btree
+ t.index ["uuid"], name: "index_vulnerability_occurrences_on_uuid", unique: true, using: :btree
+ end
+
+ create_table "vulnerability_scanners", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.string "external_id", null: false
+ t.string "name", null: false
+ t.index ["project_id", "external_id"], name: "index_vulnerability_scanners_on_project_id_and_external_id", unique: true, using: :btree
+ end
+
create_table "web_hook_logs", id: :serial, force: :cascade do |t|
t.integer "web_hook_id", null: false
t.string "trigger"
@@ -2482,16 +3528,39 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.string "encrypted_token_iv"
t.string "encrypted_url"
t.string "encrypted_url_iv"
+ t.integer "group_id"
t.index ["project_id"], name: "index_web_hooks_on_project_id", using: :btree
t.index ["type"], name: "index_web_hooks_on_type", using: :btree
end
+ add_foreign_key "application_settings", "namespaces", column: "custom_project_templates_group_id", on_delete: :nullify
+ add_foreign_key "application_settings", "projects", column: "file_template_project_id", name: "fk_ec757bd087", on_delete: :nullify
add_foreign_key "application_settings", "users", column: "usage_stats_set_by_user_id", name: "fk_964370041d", on_delete: :nullify
+ add_foreign_key "approval_merge_request_rule_sources", "approval_merge_request_rules", on_delete: :cascade
+ add_foreign_key "approval_merge_request_rule_sources", "approval_project_rules", on_delete: :cascade
+ add_foreign_key "approval_merge_request_rules", "merge_requests", on_delete: :cascade
+ add_foreign_key "approval_merge_request_rules_approved_approvers", "approval_merge_request_rules", on_delete: :cascade
+ add_foreign_key "approval_merge_request_rules_approved_approvers", "users", on_delete: :cascade
+ add_foreign_key "approval_merge_request_rules_groups", "approval_merge_request_rules", on_delete: :cascade
+ add_foreign_key "approval_merge_request_rules_groups", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "approval_merge_request_rules_users", "approval_merge_request_rules", on_delete: :cascade
+ add_foreign_key "approval_merge_request_rules_users", "users", on_delete: :cascade
+ add_foreign_key "approval_project_rules", "projects", on_delete: :cascade
+ add_foreign_key "approval_project_rules_groups", "approval_project_rules", on_delete: :cascade
+ add_foreign_key "approval_project_rules_groups", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "approval_project_rules_users", "approval_project_rules", on_delete: :cascade
+ add_foreign_key "approval_project_rules_users", "users", on_delete: :cascade
+ add_foreign_key "approvals", "merge_requests", name: "fk_310d714958", on_delete: :cascade
+ add_foreign_key "approver_groups", "namespaces", column: "group_id", on_delete: :cascade
add_foreign_key "badges", "namespaces", column: "group_id", on_delete: :cascade
add_foreign_key "badges", "projects", on_delete: :cascade
+ add_foreign_key "board_assignees", "boards", on_delete: :cascade
+ add_foreign_key "board_assignees", "users", column: "assignee_id", on_delete: :cascade
add_foreign_key "board_group_recent_visits", "boards", on_delete: :cascade
add_foreign_key "board_group_recent_visits", "namespaces", column: "group_id", on_delete: :cascade
add_foreign_key "board_group_recent_visits", "users", on_delete: :cascade
+ add_foreign_key "board_labels", "boards", on_delete: :cascade
+ add_foreign_key "board_labels", "labels", on_delete: :cascade
add_foreign_key "board_project_recent_visits", "boards", on_delete: :cascade
add_foreign_key "board_project_recent_visits", "projects", on_delete: :cascade
add_foreign_key "board_project_recent_visits", "users", on_delete: :cascade
@@ -2505,6 +3574,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "ci_build_trace_sections", "projects", on_delete: :cascade
add_foreign_key "ci_builds", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_a2141b1522", on_delete: :nullify
add_foreign_key "ci_builds", "ci_pipelines", column: "commit_id", name: "fk_d3130c9a7f", on_delete: :cascade
+ add_foreign_key "ci_builds", "ci_pipelines", column: "upstream_pipeline_id", name: "fk_87f4cefcda", on_delete: :cascade
add_foreign_key "ci_builds", "ci_stages", column: "stage_id", name: "fk_3a9eaa254d", on_delete: :cascade
add_foreign_key "ci_builds", "projects", name: "fk_befce0568a", on_delete: :cascade
add_foreign_key "ci_builds_metadata", "ci_builds", column: "build_id", on_delete: :cascade
@@ -2526,6 +3596,11 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "ci_runner_namespaces", "ci_runners", column: "runner_id", on_delete: :cascade
add_foreign_key "ci_runner_namespaces", "namespaces", on_delete: :cascade
add_foreign_key "ci_runner_projects", "projects", name: "fk_4478a6f1e4", on_delete: :cascade
+ add_foreign_key "ci_sources_pipelines", "ci_builds", column: "source_job_id", name: "fk_be5624bf37", on_delete: :cascade
+ add_foreign_key "ci_sources_pipelines", "ci_pipelines", column: "pipeline_id", name: "fk_e1bad85861", on_delete: :cascade
+ add_foreign_key "ci_sources_pipelines", "ci_pipelines", column: "source_pipeline_id", name: "fk_d4e29af7d7", on_delete: :cascade
+ add_foreign_key "ci_sources_pipelines", "projects", column: "source_project_id", name: "fk_acd9737679", on_delete: :cascade
+ add_foreign_key "ci_sources_pipelines", "projects", name: "fk_1e53c97c0a", on_delete: :cascade
add_foreign_key "ci_stages", "ci_pipelines", column: "pipeline_id", name: "fk_fb57e6cc56", on_delete: :cascade
add_foreign_key "ci_stages", "projects", name: "fk_2360681d1d", on_delete: :cascade
add_foreign_key "ci_trigger_requests", "ci_triggers", column: "trigger_id", name: "fk_b8ec8b7245", on_delete: :cascade
@@ -2552,9 +3627,28 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "clusters_kubernetes_namespaces", "clusters", on_delete: :cascade
add_foreign_key "clusters_kubernetes_namespaces", "projects", on_delete: :nullify
add_foreign_key "container_repositories", "projects"
+ add_foreign_key "dependency_proxy_blobs", "namespaces", column: "group_id", name: "fk_db58bbc5d7", on_delete: :cascade
+ add_foreign_key "dependency_proxy_group_settings", "namespaces", column: "group_id", name: "fk_616ddd680a", on_delete: :cascade
add_foreign_key "deploy_keys_projects", "projects", name: "fk_58a901ca7e", on_delete: :cascade
add_foreign_key "deployments", "projects", name: "fk_b9a3851b82", on_delete: :cascade
+ add_foreign_key "design_management_designs", "issues", on_delete: :cascade
+ add_foreign_key "design_management_designs", "projects", on_delete: :cascade
+ add_foreign_key "design_management_designs_versions", "design_management_designs", column: "design_id", name: "fk_03c671965c", on_delete: :cascade
+ add_foreign_key "design_management_designs_versions", "design_management_versions", column: "version_id", name: "fk_f4d25ba00c", on_delete: :cascade
+ add_foreign_key "draft_notes", "merge_requests", on_delete: :cascade
+ add_foreign_key "draft_notes", "users", column: "author_id", on_delete: :cascade
+ add_foreign_key "elasticsearch_indexed_namespaces", "namespaces", on_delete: :cascade
+ add_foreign_key "elasticsearch_indexed_projects", "projects", on_delete: :cascade
add_foreign_key "environments", "projects", name: "fk_d1c8c1da6a", on_delete: :cascade
+ add_foreign_key "epic_issues", "epics", on_delete: :cascade
+ add_foreign_key "epic_issues", "issues", on_delete: :cascade
+ add_foreign_key "epic_metrics", "epics", on_delete: :cascade
+ add_foreign_key "epics", "epics", column: "parent_id", name: "fk_25b99c1be3", on_delete: :cascade
+ add_foreign_key "epics", "milestones", on_delete: :nullify
+ add_foreign_key "epics", "namespaces", column: "group_id", name: "fk_f081aa4489", on_delete: :cascade
+ add_foreign_key "epics", "users", column: "assignee_id", name: "fk_dccd3f98fc", on_delete: :nullify
+ add_foreign_key "epics", "users", column: "author_id", name: "fk_3654b61b03", on_delete: :cascade
+ add_foreign_key "epics", "users", column: "closed_by_id", name: "fk_aa5798e761", on_delete: :nullify
add_foreign_key "events", "projects", on_delete: :cascade
add_foreign_key "events", "users", column: "author_id", name: "fk_edfd187b6f", on_delete: :cascade
add_foreign_key "fork_network_members", "fork_networks", on_delete: :cascade
@@ -2562,18 +3656,47 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "fork_network_members", "projects", on_delete: :cascade
add_foreign_key "fork_networks", "projects", column: "root_project_id", name: "fk_e7b436b2b5", on_delete: :nullify
add_foreign_key "forked_project_links", "projects", column: "forked_to_project_id", name: "fk_434510edb0", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_cache_invalidation_events", column: "cache_invalidation_event_id", name: "fk_42c3b54bed", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_hashed_storage_migrated_events", column: "hashed_storage_migrated_event_id", name: "fk_27548c6db3", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_job_artifact_deleted_events", column: "job_artifact_deleted_event_id", name: "fk_176d3fbb5d", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_lfs_object_deleted_events", column: "lfs_object_deleted_event_id", name: "fk_d5af95fcd9", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_repositories_changed_events", column: "repositories_changed_event_id", name: "fk_4a99ebfd60", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_repository_created_events", column: "repository_created_event_id", name: "fk_9b9afb1916", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_repository_deleted_events", column: "repository_deleted_event_id", name: "fk_c4b1c1f66e", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_repository_renamed_events", column: "repository_renamed_event_id", name: "fk_86c84214ec", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_repository_updated_events", column: "repository_updated_event_id", name: "fk_78a6492f68", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_reset_checksum_events", column: "reset_checksum_event_id", name: "fk_cff7185ad2", on_delete: :cascade
+ add_foreign_key "geo_event_log", "geo_upload_deleted_events", column: "upload_deleted_event_id", name: "fk_c1f241c70d", on_delete: :cascade
+ add_foreign_key "geo_hashed_storage_attachments_events", "projects", on_delete: :cascade
+ add_foreign_key "geo_hashed_storage_migrated_events", "projects", on_delete: :cascade
+ add_foreign_key "geo_node_namespace_links", "geo_nodes", on_delete: :cascade
+ add_foreign_key "geo_node_namespace_links", "namespaces", on_delete: :cascade
+ add_foreign_key "geo_node_statuses", "geo_nodes", on_delete: :cascade
+ add_foreign_key "geo_repositories_changed_events", "geo_nodes", on_delete: :cascade
+ add_foreign_key "geo_repository_created_events", "projects", on_delete: :cascade
+ add_foreign_key "geo_repository_renamed_events", "projects", on_delete: :cascade
+ add_foreign_key "geo_repository_updated_events", "projects", on_delete: :cascade
+ add_foreign_key "geo_reset_checksum_events", "projects", on_delete: :cascade
+ add_foreign_key "gitlab_subscriptions", "namespaces", name: "fk_e2595d00a1", on_delete: :cascade
+ add_foreign_key "gitlab_subscriptions", "plans", column: "hosted_plan_id", name: "fk_bd0c4019c3", on_delete: :cascade
add_foreign_key "gpg_key_subkeys", "gpg_keys", on_delete: :cascade
add_foreign_key "gpg_keys", "users", on_delete: :cascade
add_foreign_key "gpg_signatures", "gpg_key_subkeys", on_delete: :nullify
add_foreign_key "gpg_signatures", "gpg_keys", on_delete: :nullify
add_foreign_key "gpg_signatures", "projects", on_delete: :cascade
add_foreign_key "group_custom_attributes", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "identities", "saml_providers", name: "fk_aade90f0fc", on_delete: :cascade
add_foreign_key "import_export_uploads", "projects", on_delete: :cascade
+ add_foreign_key "index_statuses", "projects", name: "fk_74b2492545", on_delete: :cascade
+ add_foreign_key "insights", "namespaces", on_delete: :cascade
+ add_foreign_key "insights", "projects", on_delete: :cascade
add_foreign_key "internal_ids", "namespaces", name: "fk_162941d509", on_delete: :cascade
add_foreign_key "internal_ids", "projects", on_delete: :cascade
add_foreign_key "ip_restrictions", "namespaces", column: "group_id", on_delete: :cascade
add_foreign_key "issue_assignees", "issues", name: "fk_b7d881734a", on_delete: :cascade
add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade
+ add_foreign_key "issue_links", "issues", column: "source_id", name: "fk_c900194ff2", on_delete: :cascade
+ add_foreign_key "issue_links", "issues", column: "target_id", name: "fk_e71bb44f1f", on_delete: :cascade
add_foreign_key "issue_metrics", "issues", on_delete: :cascade
add_foreign_key "issue_tracker_data", "services", on_delete: :cascade
add_foreign_key "issues", "issues", column: "moved_to_id", name: "fk_a194299be1", on_delete: :nullify
@@ -2582,6 +3705,8 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "issues", "users", column: "author_id", name: "fk_05f1e72feb", on_delete: :nullify
add_foreign_key "issues", "users", column: "closed_by_id", name: "fk_c63cbf6c25", on_delete: :nullify
add_foreign_key "issues", "users", column: "updated_by_id", name: "fk_ffed080f01", on_delete: :nullify
+ add_foreign_key "jira_connect_subscriptions", "jira_connect_installations", name: "fk_f1d617343f", on_delete: :cascade
+ add_foreign_key "jira_connect_subscriptions", "namespaces", name: "fk_a3c10bcf7d", on_delete: :cascade
add_foreign_key "jira_tracker_data", "services", on_delete: :cascade
add_foreign_key "label_links", "labels", name: "fk_d97dd08678", on_delete: :cascade
add_foreign_key "label_priorities", "labels", on_delete: :cascade
@@ -2592,6 +3717,8 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "lfs_file_locks", "users", on_delete: :cascade
add_foreign_key "lists", "boards", name: "fk_0d3f677137", on_delete: :cascade
add_foreign_key "lists", "labels", name: "fk_7a5553d60f", on_delete: :cascade
+ add_foreign_key "lists", "milestones", on_delete: :cascade
+ add_foreign_key "lists", "users", name: "fk_d6cf4279f7", on_delete: :cascade
add_foreign_key "members", "users", name: "fk_2e88fb7ce9", on_delete: :cascade
add_foreign_key "merge_request_assignees", "merge_requests", on_delete: :cascade
add_foreign_key "merge_request_assignees", "users", on_delete: :cascade
@@ -2621,15 +3748,29 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "merge_trains", "users", on_delete: :cascade
add_foreign_key "milestones", "namespaces", column: "group_id", name: "fk_95650a40d4", on_delete: :cascade
add_foreign_key "milestones", "projects", name: "fk_9bd0a0c791", on_delete: :cascade
+ add_foreign_key "namespace_statistics", "namespaces", on_delete: :cascade
+ add_foreign_key "namespaces", "namespaces", column: "custom_project_templates_group_id", name: "fk_e7a0b20a6b", on_delete: :nullify
+ add_foreign_key "namespaces", "plans", name: "fk_fdd12e5b80", on_delete: :nullify
+ add_foreign_key "namespaces", "projects", column: "file_template_project_id", name: "fk_319256d87a", on_delete: :nullify
add_foreign_key "note_diff_files", "notes", column: "diff_note_id", on_delete: :cascade
add_foreign_key "notes", "projects", name: "fk_99e097b079", on_delete: :cascade
+ add_foreign_key "notes", "reviews", name: "fk_2e82291620", on_delete: :nullify
add_foreign_key "notification_settings", "users", name: "fk_0c95e91db7", on_delete: :cascade
add_foreign_key "oauth_openid_requests", "oauth_access_grants", column: "access_grant_id", name: "fk_oauth_openid_requests_oauth_access_grants_access_grant_id"
+ add_foreign_key "operations_feature_flag_scopes", "operations_feature_flags", column: "feature_flag_id", on_delete: :cascade
+ add_foreign_key "operations_feature_flags", "projects", on_delete: :cascade
+ add_foreign_key "operations_feature_flags_clients", "projects", on_delete: :cascade
+ add_foreign_key "packages_maven_metadata", "packages_packages", column: "package_id", name: "fk_be88aed360", on_delete: :cascade
+ add_foreign_key "packages_package_files", "packages_packages", column: "package_id", name: "fk_86f0f182f8", on_delete: :cascade
+ add_foreign_key "packages_packages", "projects", on_delete: :cascade
add_foreign_key "pages_domain_acme_orders", "pages_domains", on_delete: :cascade
add_foreign_key "pages_domains", "projects", name: "fk_ea2f6dfc6f", on_delete: :cascade
+ add_foreign_key "path_locks", "projects", name: "fk_5265c98f24", on_delete: :cascade
+ add_foreign_key "path_locks", "users"
add_foreign_key "personal_access_tokens", "users"
add_foreign_key "pool_repositories", "projects", column: "source_project_id", on_delete: :nullify
add_foreign_key "pool_repositories", "shards", on_delete: :restrict
+ add_foreign_key "project_alerting_settings", "projects", on_delete: :cascade
add_foreign_key "project_authorizations", "projects", on_delete: :cascade
add_foreign_key "project_authorizations", "users", on_delete: :cascade
add_foreign_key "project_auto_devops", "projects", on_delete: :cascade
@@ -2639,35 +3780,66 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "project_deploy_tokens", "deploy_tokens", on_delete: :cascade
add_foreign_key "project_deploy_tokens", "projects", on_delete: :cascade
add_foreign_key "project_error_tracking_settings", "projects", on_delete: :cascade
+ add_foreign_key "project_feature_usages", "projects", on_delete: :cascade
add_foreign_key "project_features", "projects", name: "fk_18513d9b92", on_delete: :cascade
add_foreign_key "project_group_links", "projects", name: "fk_daa8cee94c", on_delete: :cascade
add_foreign_key "project_import_data", "projects", name: "fk_ffb9ee3a10", on_delete: :cascade
+ add_foreign_key "project_incident_management_settings", "projects", on_delete: :cascade
add_foreign_key "project_metrics_settings", "projects", on_delete: :cascade
add_foreign_key "project_mirror_data", "projects", on_delete: :cascade
add_foreign_key "project_repositories", "projects", on_delete: :cascade
add_foreign_key "project_repositories", "shards", on_delete: :restrict
+ add_foreign_key "project_repository_states", "projects", on_delete: :cascade
add_foreign_key "project_statistics", "projects", on_delete: :cascade
+ add_foreign_key "project_tracing_settings", "projects", on_delete: :cascade
add_foreign_key "projects", "pool_repositories", name: "fk_6e5c14658a", on_delete: :nullify
+ add_foreign_key "prometheus_alert_events", "projects", on_delete: :cascade
+ add_foreign_key "prometheus_alert_events", "prometheus_alerts", on_delete: :cascade
+ add_foreign_key "prometheus_alerts", "environments", on_delete: :cascade
+ add_foreign_key "prometheus_alerts", "projects", on_delete: :cascade
+ add_foreign_key "prometheus_alerts", "prometheus_metrics", on_delete: :cascade
add_foreign_key "prometheus_metrics", "projects", on_delete: :cascade
+ add_foreign_key "protected_branch_merge_access_levels", "namespaces", column: "group_id", name: "fk_98f3d044fe", on_delete: :cascade
add_foreign_key "protected_branch_merge_access_levels", "protected_branches", name: "fk_8a3072ccb3", on_delete: :cascade
+ add_foreign_key "protected_branch_merge_access_levels", "users"
+ add_foreign_key "protected_branch_push_access_levels", "namespaces", column: "group_id", name: "fk_7111b68cdb", on_delete: :cascade
add_foreign_key "protected_branch_push_access_levels", "protected_branches", name: "fk_9ffc86a3d9", on_delete: :cascade
+ add_foreign_key "protected_branch_push_access_levels", "users"
+ add_foreign_key "protected_branch_unprotect_access_levels", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "protected_branch_unprotect_access_levels", "protected_branches", on_delete: :cascade
+ add_foreign_key "protected_branch_unprotect_access_levels", "users", on_delete: :cascade
add_foreign_key "protected_branches", "projects", name: "fk_7a9c6d93e7", on_delete: :cascade
- add_foreign_key "protected_tag_create_access_levels", "namespaces", column: "group_id"
+ add_foreign_key "protected_environment_deploy_access_levels", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "protected_environment_deploy_access_levels", "protected_environments", on_delete: :cascade
+ add_foreign_key "protected_environment_deploy_access_levels", "users", on_delete: :cascade
+ add_foreign_key "protected_environments", "projects", on_delete: :cascade
+ add_foreign_key "protected_tag_create_access_levels", "namespaces", column: "group_id", name: "fk_b4eb82fe3c", on_delete: :cascade
add_foreign_key "protected_tag_create_access_levels", "protected_tags", name: "fk_f7dfda8c51", on_delete: :cascade
add_foreign_key "protected_tag_create_access_levels", "users"
add_foreign_key "protected_tags", "projects", name: "fk_8e4af87648", on_delete: :cascade
add_foreign_key "push_event_payloads", "events", name: "fk_36c74129da", on_delete: :cascade
+ add_foreign_key "push_rules", "projects", name: "fk_83b29894de", on_delete: :cascade
add_foreign_key "release_links", "releases", on_delete: :cascade
add_foreign_key "releases", "projects", name: "fk_47fe2a0596", on_delete: :cascade
add_foreign_key "releases", "users", column: "author_id", name: "fk_8e4456f90f", on_delete: :nullify
add_foreign_key "remote_mirrors", "projects", on_delete: :cascade
add_foreign_key "repository_languages", "projects", on_delete: :cascade
+ add_foreign_key "resource_label_events", "epics", on_delete: :cascade
add_foreign_key "resource_label_events", "issues", on_delete: :cascade
add_foreign_key "resource_label_events", "labels", on_delete: :nullify
add_foreign_key "resource_label_events", "merge_requests", on_delete: :cascade
add_foreign_key "resource_label_events", "users", on_delete: :nullify
+ add_foreign_key "reviews", "merge_requests", on_delete: :cascade
+ add_foreign_key "reviews", "projects", on_delete: :cascade
+ add_foreign_key "reviews", "users", column: "author_id", on_delete: :nullify
+ add_foreign_key "saml_providers", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "scim_oauth_access_tokens", "namespaces", column: "group_id", on_delete: :cascade
add_foreign_key "services", "projects", name: "fk_71cce407f9", on_delete: :cascade
+ add_foreign_key "slack_integrations", "services", on_delete: :cascade
+ add_foreign_key "smartcard_identities", "users", on_delete: :cascade
add_foreign_key "snippets", "projects", name: "fk_be41fd4bb7", on_delete: :cascade
+ add_foreign_key "software_license_policies", "projects", on_delete: :cascade
+ add_foreign_key "software_license_policies", "software_licenses", on_delete: :cascade
add_foreign_key "subscriptions", "projects", on_delete: :cascade
add_foreign_key "suggestions", "notes", on_delete: :cascade
add_foreign_key "system_note_metadata", "notes", name: "fk_d83a918cb1", on_delete: :cascade
@@ -2690,7 +3862,25 @@ ActiveRecord::Schema.define(version: 20190611161641) do
add_foreign_key "user_statuses", "users", on_delete: :cascade
add_foreign_key "user_synced_attributes_metadata", "users", on_delete: :cascade
add_foreign_key "users", "application_setting_terms", column: "accepted_term_id", name: "fk_789cd90b35", on_delete: :cascade
+ add_foreign_key "users", "namespaces", column: "managing_group_id", name: "fk_a4b8fefe3e", on_delete: :nullify
+ add_foreign_key "users_ops_dashboard_projects", "projects", on_delete: :cascade
+ add_foreign_key "users_ops_dashboard_projects", "users", on_delete: :cascade
add_foreign_key "users_star_projects", "projects", name: "fk_22cd27ddfc", on_delete: :cascade
+ add_foreign_key "vulnerability_feedback", "ci_pipelines", column: "pipeline_id", on_delete: :nullify
+ add_foreign_key "vulnerability_feedback", "issues", on_delete: :nullify
+ add_foreign_key "vulnerability_feedback", "merge_requests", name: "fk_563ff1912e", on_delete: :nullify
+ add_foreign_key "vulnerability_feedback", "projects", on_delete: :cascade
+ add_foreign_key "vulnerability_feedback", "users", column: "author_id", on_delete: :cascade
+ add_foreign_key "vulnerability_feedback", "users", column: "comment_author_id", name: "fk_94f7c8a81e", on_delete: :nullify
+ add_foreign_key "vulnerability_identifiers", "projects", on_delete: :cascade
+ add_foreign_key "vulnerability_occurrence_identifiers", "vulnerability_identifiers", column: "identifier_id", on_delete: :cascade
+ add_foreign_key "vulnerability_occurrence_identifiers", "vulnerability_occurrences", column: "occurrence_id", on_delete: :cascade
+ add_foreign_key "vulnerability_occurrence_pipelines", "ci_pipelines", column: "pipeline_id", on_delete: :cascade
+ add_foreign_key "vulnerability_occurrence_pipelines", "vulnerability_occurrences", column: "occurrence_id", on_delete: :cascade
+ add_foreign_key "vulnerability_occurrences", "projects", on_delete: :cascade
+ add_foreign_key "vulnerability_occurrences", "vulnerability_identifiers", column: "primary_identifier_id", on_delete: :cascade
+ add_foreign_key "vulnerability_occurrences", "vulnerability_scanners", column: "scanner_id", on_delete: :cascade
+ add_foreign_key "vulnerability_scanners", "projects", on_delete: :cascade
add_foreign_key "web_hook_logs", "web_hooks", on_delete: :cascade
add_foreign_key "web_hooks", "projects", name: "fk_0c8ca6d9d1", on_delete: :cascade
end