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:
authorYorick Peterse <yorickpeterse@gmail.com>2019-04-29 15:16:03 +0300
committerYorick Peterse <yorickpeterse@gmail.com>2019-06-17 18:09:05 +0300
commit8469f59d786be6762908f62d642625790999cb9b (patch)
tree03f99c605e465673e017e775a623ffa5b62f18d3 /db
parent0f777a8d49568d3f5ffdd4b75b594f07e9fbd2f0 (diff)
Backport the EE schema and migrations to CE
This backports all EE schema changes to CE, including EE migrations, ensuring both use the same schema. == Updated tests A spec related to ghost and support bot users had to be modified to make it pass. The spec in question assumes that the "support_bot" column exists when defining the spec. In the single codebase setup this is not the case, as the column is backported in a later migration. Any attempt to use a different schema version or use of "around" blocks to conditionally disable specs won't help, as reverting the backport migration would also drop the "support_bot" column. Removing the "support_bot" tests entirely appears to be the only solution. We also need to update some foreign key tests now that we have backported the EE columns. Fortunately, these changes are very minor. == Backporting migrations This commit moves EE specific migrations (except those for the Geo tracking database) and related files to CE, and also removes any traces of the ee/db directory. Some migrations had to be modified or removed, as they no longer work with the schema being backported. These migrations were all quite old, so we opted for removing them where modifying them would take too much time and effort. Some old migrations were modified in EE, while also existing in CE. In these cases we took the EE code, and in one case removed them entirely. It's not worth spending time trying to merge these changes somehow as we plan to remove old migrations around the release of 12.0, see https://gitlab.com/gitlab-org/gitlab-ce/issues/59177 for more details.
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 db1ef81ede6..4cece7c8ecc 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
@@ -1058,6 +1596,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"
@@ -1107,6 +1655,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
@@ -1124,6 +1674,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
@@ -1194,6 +1762,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
@@ -1224,6 +1802,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"
@@ -1231,9 +1815,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|
@@ -1251,6 +1839,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
@@ -1383,6 +1973,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
@@ -1450,6 +2041,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
@@ -1473,16 +2071,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
@@ -1523,6 +2142,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
@@ -1532,6 +2152,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|
@@ -1556,6 +2177,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
@@ -1608,6 +2230,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
@@ -1644,6 +2326,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
@@ -1658,6 +2351,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"
@@ -1675,6 +2378,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
@@ -1735,6 +2443,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"
@@ -1769,6 +2485,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
@@ -1778,7 +2500,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
@@ -1792,6 +2523,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
@@ -1802,10 +2553,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"
@@ -1853,7 +2614,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"
@@ -1862,14 +2623,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
@@ -1884,6 +2671,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
@@ -1904,18 +2715,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|
@@ -1926,6 +2755,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
@@ -1959,6 +2809,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
@@ -2033,12 +2906,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
@@ -2051,6 +2936,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"
@@ -2098,6 +3001,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"
@@ -2121,6 +3044,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"
@@ -2320,6 +3256,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
@@ -2409,24 +3349,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
@@ -2436,6 +3400,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"
@@ -2476,16 +3522,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
@@ -2499,6 +3568,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
@@ -2520,6 +3590,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
@@ -2546,9 +3621,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
@@ -2556,17 +3650,46 @@ 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 "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
@@ -2575,6 +3698,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
@@ -2585,6 +3710,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
@@ -2614,15 +3741,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
@@ -2632,35 +3773,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
@@ -2683,7 +3855,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