diff options
author | Phil Hughes <me@iamphill.com> | 2016-11-24 14:31:59 +0300 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2016-11-24 14:31:59 +0300 |
commit | 79a791a30d60d04be34d0e6d36c9cc145b97635b (patch) | |
tree | 7495834ed7bdfb51946c5f40fc61f1568ff0f823 /db | |
parent | fa04393482eff8d7d7cdb71c3bdea2c918a49a57 (diff) | |
parent | 3e44ed3e2bf75bb14a2d8b0466b3d92afd0ea067 (diff) |
Merge branch 'master' into menu-resize-hidemenu-resize-hide
Diffstat (limited to 'db')
53 files changed, 2163 insertions, 582 deletions
diff --git a/db/fixtures/development/04_project.rb b/db/fixtures/development/04_project.rb index e3316ecdb6c..18a2df7c059 100644 --- a/db/fixtures/development/04_project.rb +++ b/db/fixtures/development/04_project.rb @@ -1,13 +1,14 @@ require 'sidekiq/testing' +require './db/fixtures/support/serialized_transaction' Sidekiq::Testing.inline! do Gitlab::Seeder.quiet do project_urls = [ - 'https://github.com/documentcloud/underscore.git', + 'https://gitlab.com/gitlab-org/gitlab-test.git', 'https://gitlab.com/gitlab-org/gitlab-ce.git', 'https://gitlab.com/gitlab-org/gitlab-ci.git', 'https://gitlab.com/gitlab-org/gitlab-shell.git', - 'https://gitlab.com/gitlab-org/gitlab-test.git', + 'https://github.com/documentcloud/underscore.git', 'https://github.com/twitter/flight.git', 'https://github.com/twitter/typeahead.js.git', 'https://github.com/h5bp/html5-boilerplate.git', @@ -38,12 +39,7 @@ Sidekiq::Testing.inline! do ] # You can specify how many projects you need during seed execution - size = if ENV['SIZE'].present? - ENV['SIZE'].to_i - else - 8 - end - + size = ENV['SIZE'].present? ? ENV['SIZE'].to_i : 8 project_urls.first(size).each_with_index do |url, i| group_path, project_path = url.split('/')[-2..-1] diff --git a/db/fixtures/development/06_teams.rb b/db/fixtures/development/06_teams.rb index 3e8cdcd67b4..04c3690e152 100644 --- a/db/fixtures/development/06_teams.rb +++ b/db/fixtures/development/06_teams.rb @@ -1,20 +1,25 @@ -Gitlab::Seeder.quiet do - Group.all.each do |group| - User.all.sample(4).each do |user| - if group.add_users([user.id], Gitlab::Access.values.sample) - print '.' - else - print 'F' +require 'sidekiq/testing' +require './db/fixtures/support/serialized_transaction' + +Sidekiq::Testing.inline! do + Gitlab::Seeder.quiet do + Group.all.each do |group| + User.all.sample(4).each do |user| + if group.add_user(user, Gitlab::Access.values.sample).persisted? + print '.' + else + print 'F' + end end end - end - Project.all.each do |project| - User.all.sample(4).each do |user| - if project.team << [user, Gitlab::Access.values.sample] - print '.' - else - print 'F' + Project.all.each do |project| + User.all.sample(4).each do |user| + if project.team << [user, Gitlab::Access.values.sample] + print '.' + else + print 'F' + end end end end diff --git a/db/fixtures/development/14_pipelines.rb b/db/fixtures/development/14_pipelines.rb index 650b410595c..08ad3097d34 100644 --- a/db/fixtures/development/14_pipelines.rb +++ b/db/fixtures/development/14_pipelines.rb @@ -16,7 +16,8 @@ class Gitlab::Seeder::Pipelines { name: 'env:alpha', stage: 'deploy', environment: 'alpha', status: :pending }, { name: 'env:beta', stage: 'deploy', environment: 'beta', status: :running }, { name: 'env:gamma', stage: 'deploy', environment: 'gamma', status: :canceled }, - { name: 'staging', stage: 'deploy', environment: 'staging', status_event: :success }, + { name: 'staging', stage: 'deploy', environment: 'staging', status_event: :success, options: { environment: { on_stop: 'stop staging' } } }, + { name: 'stop staging', stage: 'deploy', environment: 'staging', when: 'manual', status: :skipped }, { name: 'production', stage: 'deploy', environment: 'production', when: 'manual', status: :skipped }, { name: 'slack', stage: 'notify', when: 'manual', status: :created }, ] @@ -34,7 +35,7 @@ class Gitlab::Seeder::Pipelines rescue ActiveRecord::RecordInvalid print 'F' ensure - pipeline.build_updated + pipeline.update_status end end end diff --git a/db/fixtures/development/17_cycle_analytics.rb b/db/fixtures/development/17_cycle_analytics.rb new file mode 100644 index 00000000000..7b3908fae98 --- /dev/null +++ b/db/fixtures/development/17_cycle_analytics.rb @@ -0,0 +1,249 @@ +require 'sidekiq/testing' +require './spec/support/test_env' +require './db/fixtures/support/serialized_transaction' + +class Gitlab::Seeder::CycleAnalytics + def initialize(project, perf: false) + @project = project + @user = User.order(:id).last + @issue_count = perf ? 1000 : 5 + stub_git_pre_receive! + end + + # The GitLab API needn't be running for the fixtures to be + # created. Since we're performing a number of git actions + # here (like creating a branch or committing a file), we need + # to disable the `pre_receive` hook in order to remove this + # dependency on the GitLab API. + def stub_git_pre_receive! + GitHooksService.class_eval do + def run_hook(name) + [true, ''] + end + end + end + + def seed_metrics! + @issue_count.times do |index| + # Issue + Timecop.travel 5.days.from_now + title = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}" + issue = Issue.create(project: @project, title: title, author: @user) + issue_metrics = issue.metrics + + # Milestones / Labels + Timecop.travel 5.days.from_now + if index.even? + issue_metrics.first_associated_with_milestone_at = rand(6..12).hours.from_now + else + issue_metrics.first_added_to_board_at = rand(6..12).hours.from_now + end + + # Commit + Timecop.travel 5.days.from_now + issue_metrics.first_mentioned_in_commit_at = rand(6..12).hours.from_now + + # MR + Timecop.travel 5.days.from_now + branch_name = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}" + @project.repository.add_branch(@user, branch_name, 'master') + merge_request = MergeRequest.create(target_project: @project, source_project: @project, source_branch: branch_name, target_branch: 'master', title: branch_name, author: @user) + merge_request_metrics = merge_request.metrics + + # MR closing issues + Timecop.travel 5.days.from_now + MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request) + + # Merge + Timecop.travel 5.days.from_now + merge_request_metrics.merged_at = rand(6..12).hours.from_now + + # Start build + Timecop.travel 5.days.from_now + merge_request_metrics.latest_build_started_at = rand(6..12).hours.from_now + + # Finish build + Timecop.travel 5.days.from_now + merge_request_metrics.latest_build_finished_at = rand(6..12).hours.from_now + + # Deploy to production + Timecop.travel 5.days.from_now + merge_request_metrics.first_deployed_to_production_at = rand(6..12).hours.from_now + + issue_metrics.save! + merge_request_metrics.save! + + print '.' + end + end + + def seed! + Sidekiq::Testing.inline! do + issues = create_issues + puts '.' + + # Stage 1 + Timecop.travel 5.days.from_now + add_milestones_and_list_labels(issues) + print '.' + + # Stage 2 + Timecop.travel 5.days.from_now + branches = mention_in_commits(issues) + print '.' + + # Stage 3 + Timecop.travel 5.days.from_now + merge_requests = create_merge_requests_closing_issues(issues, branches) + print '.' + + # Stage 4 + Timecop.travel 5.days.from_now + run_builds(merge_requests) + print '.' + + # Stage 5 + Timecop.travel 5.days.from_now + merge_merge_requests(merge_requests) + print '.' + + # Stage 6 / 7 + Timecop.travel 5.days.from_now + deploy_to_production(merge_requests) + print '.' + end + + print '.' + end + + private + + def create_issues + Array.new(@issue_count) do + issue_params = { + title: "Cycle Analytics: #{FFaker::Lorem.sentence(6)}", + description: FFaker::Lorem.sentence, + state: 'opened', + assignee: @project.team.users.sample + } + + Issues::CreateService.new(@project, @project.team.users.sample, issue_params).execute + end + end + + def add_milestones_and_list_labels(issues) + issues.shuffle.map.with_index do |issue, index| + Timecop.travel 12.hours.from_now + + if index.even? + issue.update(milestone: @project.milestones.sample) + else + label_name = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}" + list_label = FactoryGirl.create(:label, title: label_name, project: issue.project) + FactoryGirl.create(:list, board: FactoryGirl.create(:board, project: issue.project), label: list_label) + issue.update(labels: [list_label]) + end + + issue + end + end + + def mention_in_commits(issues) + issues.map do |issue| + Timecop.travel 12.hours.from_now + + branch_name = filename = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}" + + issue.project.repository.add_branch(@user, branch_name, 'master') + + options = { + committer: issue.project.repository.user_to_committer(@user), + author: issue.project.repository.user_to_committer(@user), + commit: { message: "Commit for ##{issue.iid}", branch: branch_name, update_ref: true }, + file: { content: "content", path: filename, update: false } + } + + commit_sha = Gitlab::Git::Blob.commit(issue.project.repository, options) + issue.project.repository.commit(commit_sha) + + + GitPushService.new(issue.project, + @user, + oldrev: issue.project.repository.commit("master").sha, + newrev: commit_sha, + ref: 'refs/heads/master').execute + + branch_name + end + end + + def create_merge_requests_closing_issues(issues, branches) + issues.zip(branches).map do |issue, branch| + Timecop.travel 12.hours.from_now + + opts = { + title: 'Cycle Analytics merge_request', + description: "Fixes #{issue.to_reference}", + source_branch: branch, + target_branch: 'master' + } + + MergeRequests::CreateService.new(issue.project, @user, opts).execute + end + end + + def run_builds(merge_requests) + merge_requests.each do |merge_request| + Timecop.travel 12.hours.from_now + + service = Ci::CreatePipelineService.new(merge_request.project, + @user, + ref: "refs/heads/#{merge_request.source_branch}") + pipeline = service.execute(ignore_skip_ci: true, save_on_errors: false) + + pipeline.run! + Timecop.travel rand(1..6).hours.from_now + pipeline.succeed! + + PipelineMetricsWorker.new.perform(pipeline.id) + end + end + + def merge_merge_requests(merge_requests) + merge_requests.each do |merge_request| + Timecop.travel 12.hours.from_now + + MergeRequests::MergeService.new(merge_request.project, @user).execute(merge_request) + end + end + + def deploy_to_production(merge_requests) + merge_requests.each do |merge_request| + Timecop.travel 12.hours.from_now + + CreateDeploymentService.new(merge_request.project, @user, { + environment: 'production', + ref: 'master', + tag: false, + sha: @project.repository.commit('master').sha + }).execute + end + end +end + +Gitlab::Seeder.quiet do + if ENV['SEED_CYCLE_ANALYTICS'] + Project.all.each do |project| + seeder = Gitlab::Seeder::CycleAnalytics.new(project) + seeder.seed! + end + elsif ENV['CYCLE_ANALYTICS_PERF_TEST'] + seeder = Gitlab::Seeder::CycleAnalytics.new(Project.order(:id).first, perf: true) + seeder.seed! + elsif ENV['CYCLE_ANALYTICS_POPULATE_METRICS_DIRECTLY'] + seeder = Gitlab::Seeder::CycleAnalytics.new(Project.order(:id).first, perf: true) + seeder.seed_metrics! + else + puts "Not running the cycle analytics seed file. Use the `SEED_CYCLE_ANALYTICS` environment variable to enable it." + end +end diff --git a/db/fixtures/support/serialized_transaction.rb b/db/fixtures/support/serialized_transaction.rb new file mode 100644 index 00000000000..d3305b661e5 --- /dev/null +++ b/db/fixtures/support/serialized_transaction.rb @@ -0,0 +1,9 @@ +require 'gitlab/database' + +module Gitlab + module Database + def self.serialized_transaction + connection.transaction { yield } + end + end +end diff --git a/db/migrate/20160808085531_add_token_to_build.rb b/db/migrate/20160808085531_add_token_to_build.rb new file mode 100644 index 00000000000..3ed2a103ae3 --- /dev/null +++ b/db/migrate/20160808085531_add_token_to_build.rb @@ -0,0 +1,10 @@ +class AddTokenToBuild < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + def change + add_column :ci_builds, :token, :string + end +end diff --git a/db/migrate/20160808085602_add_index_for_build_token.rb b/db/migrate/20160808085602_add_index_for_build_token.rb new file mode 100644 index 00000000000..10ef42afce1 --- /dev/null +++ b/db/migrate/20160808085602_add_index_for_build_token.rb @@ -0,0 +1,12 @@ +class AddIndexForBuildToken < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + disable_ddl_transaction! + + def change + add_concurrent_index :ci_builds, :token, unique: true + end +end diff --git a/db/migrate/20160819232256_add_incoming_email_token_to_users.rb b/db/migrate/20160819232256_add_incoming_email_token_to_users.rb new file mode 100644 index 00000000000..f2cf956adc9 --- /dev/null +++ b/db/migrate/20160819232256_add_incoming_email_token_to_users.rb @@ -0,0 +1,16 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddIncomingEmailTokenToUsers < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + disable_ddl_transaction! + + def change + add_column :users, :incoming_email_token, :string + add_concurrent_index :users, :incoming_email_token + end +end diff --git a/db/migrate/20160824124900_add_table_issue_metrics.rb b/db/migrate/20160824124900_add_table_issue_metrics.rb new file mode 100644 index 00000000000..e9bb79b3c62 --- /dev/null +++ b/db/migrate/20160824124900_add_table_issue_metrics.rb @@ -0,0 +1,37 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddTableIssueMetrics < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # 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' + + # 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 change + create_table :issue_metrics do |t| + t.references :issue, index: { name: "index_issue_metrics" }, foreign_key: { on_delete: :cascade }, null: false + + t.datetime 'first_mentioned_in_commit_at' + t.datetime 'first_associated_with_milestone_at' + t.datetime 'first_added_to_board_at' + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160825052008_add_table_merge_request_metrics.rb b/db/migrate/20160825052008_add_table_merge_request_metrics.rb new file mode 100644 index 00000000000..e01cc5038b9 --- /dev/null +++ b/db/migrate/20160825052008_add_table_merge_request_metrics.rb @@ -0,0 +1,38 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddTableMergeRequestMetrics < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # 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' + + # 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 change + create_table :merge_request_metrics do |t| + t.references :merge_request, index: { name: "index_merge_request_metrics" }, foreign_key: { on_delete: :cascade }, null: false + + t.datetime 'latest_build_started_at' + t.datetime 'latest_build_finished_at' + t.datetime 'first_deployed_to_production_at', index: true + t.datetime 'merged_at' + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160829114652_add_markdown_cache_columns.rb b/db/migrate/20160829114652_add_markdown_cache_columns.rb new file mode 100644 index 00000000000..8753e55e058 --- /dev/null +++ b/db/migrate/20160829114652_add_markdown_cache_columns.rb @@ -0,0 +1,38 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddMarkdownCacheColumns < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + COLUMNS = { + abuse_reports: [:message], + appearances: [:description], + application_settings: [ + :sign_in_text, + :help_page_text, + :shared_runners_text, + :after_sign_up_text + ], + broadcast_messages: [:message], + issues: [:title, :description], + labels: [:description], + merge_requests: [:title, :description], + milestones: [:title, :description], + namespaces: [:description], + notes: [:note], + projects: [:description], + releases: [:description], + snippets: [:title, :content], + } + + def change + COLUMNS.each do |table, columns| + columns.each do |column| + add_column table, "#{column}_html", :text + end + end + end +end diff --git a/db/migrate/20160907131111_add_environment_type_to_environments.rb b/db/migrate/20160907131111_add_environment_type_to_environments.rb new file mode 100644 index 00000000000..fac73753d5b --- /dev/null +++ b/db/migrate/20160907131111_add_environment_type_to_environments.rb @@ -0,0 +1,9 @@ +class AddEnvironmentTypeToEnvironments < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column :environments, :environment_type, :string + end +end diff --git a/db/migrate/20160913212128_change_artifacts_size_column.rb b/db/migrate/20160913212128_change_artifacts_size_column.rb new file mode 100644 index 00000000000..063bbca537c --- /dev/null +++ b/db/migrate/20160913212128_change_artifacts_size_column.rb @@ -0,0 +1,15 @@ +class ChangeArtifactsSizeColumn < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + + DOWNTIME_REASON = 'Changing an integer column size requires a full table rewrite.' + + def up + change_column :ci_builds, :artifacts_size, :integer, limit: 8 + end + + def down + # do nothing + end +end diff --git a/db/migrate/20160914131004_only_allow_merge_if_all_discussions_are_resolved.rb b/db/migrate/20160914131004_only_allow_merge_if_all_discussions_are_resolved.rb new file mode 100644 index 00000000000..4da5ec9bd28 --- /dev/null +++ b/db/migrate/20160914131004_only_allow_merge_if_all_discussions_are_resolved.rb @@ -0,0 +1,14 @@ +class OnlyAllowMergeIfAllDiscussionsAreResolved < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + disable_ddl_transaction! + + def up + add_column :projects, :only_allow_merge_if_all_discussions_are_resolved, :boolean + end + + def down + remove_column(:projects, :only_allow_merge_if_all_discussions_are_resolved) + end +end diff --git a/db/migrate/20160915042921_create_merge_requests_closing_issues.rb b/db/migrate/20160915042921_create_merge_requests_closing_issues.rb new file mode 100644 index 00000000000..94874a853da --- /dev/null +++ b/db/migrate/20160915042921_create_merge_requests_closing_issues.rb @@ -0,0 +1,34 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class CreateMergeRequestsClosingIssues < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # 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 keys' + + # 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 change + create_table :merge_requests_closing_issues do |t| + t.references :merge_request, foreign_key: { on_delete: :cascade }, index: true, null: false + t.references :issue, foreign_key: { on_delete: :cascade }, index: true, null: false + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160919144305_add_type_to_labels.rb b/db/migrate/20160919144305_add_type_to_labels.rb new file mode 100644 index 00000000000..66172bda6ff --- /dev/null +++ b/db/migrate/20160919144305_add_type_to_labels.rb @@ -0,0 +1,14 @@ +class AddTypeToLabels < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'Labels will not work as expected until this migration is complete.' + + def change + add_column :labels, :type, :string + + update_column_in_batches(:labels, :type, 'ProjectLabel') do |table, query| + query.where(table[:project_id].not_eq(nil)) + end + end +end diff --git a/db/migrate/20160919145149_add_group_id_to_labels.rb b/db/migrate/20160919145149_add_group_id_to_labels.rb new file mode 100644 index 00000000000..05e21af0584 --- /dev/null +++ b/db/migrate/20160919145149_add_group_id_to_labels.rb @@ -0,0 +1,13 @@ +class AddGroupIdToLabels < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def change + add_column :labels, :group_id, :integer + add_foreign_key :labels, :namespaces, column: :group_id, on_delete: :cascade + add_concurrent_index :labels, :group_id + end +end diff --git a/db/migrate/20160920160832_add_index_to_labels_title.rb b/db/migrate/20160920160832_add_index_to_labels_title.rb new file mode 100644 index 00000000000..b5de552b98c --- /dev/null +++ b/db/migrate/20160920160832_add_index_to_labels_title.rb @@ -0,0 +1,11 @@ +class AddIndexToLabelsTitle < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def change + add_concurrent_index :labels, :title + end +end diff --git a/db/migrate/20160926145521_add_organization_to_user.rb b/db/migrate/20160926145521_add_organization_to_user.rb new file mode 100644 index 00000000000..e0bef6e7548 --- /dev/null +++ b/db/migrate/20160926145521_add_organization_to_user.rb @@ -0,0 +1,12 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddOrganizationToUser < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column :users, :organization, :string + end +end diff --git a/db/migrate/20161006104309_add_state_to_environment.rb b/db/migrate/20161006104309_add_state_to_environment.rb new file mode 100644 index 00000000000..ccb546654f9 --- /dev/null +++ b/db/migrate/20161006104309_add_state_to_environment.rb @@ -0,0 +1,15 @@ +class AddStateToEnvironment < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + DOWNTIME = false + + def up + add_column_with_default(:environments, :state, :string, default: :available) + end + + def down + remove_column(:environments, :state) + end +end diff --git a/db/migrate/20161007133303_precalculate_trending_projects.rb b/db/migrate/20161007133303_precalculate_trending_projects.rb new file mode 100644 index 00000000000..b324cd94268 --- /dev/null +++ b/db/migrate/20161007133303_precalculate_trending_projects.rb @@ -0,0 +1,38 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class PrecalculateTrendingProjects < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def up + create_table :trending_projects do |t| + t.references :project, index: true, foreign_key: { on_delete: :cascade }, null: false + end + + timestamp = connection.quote(1.month.ago) + + # We're hardcoding the visibility level (public) here so that if it ever + # changes this query doesn't suddenly use the new value (which may break + # later migrations). + visibility = 20 + + execute <<-EOF.strip_heredoc + INSERT INTO trending_projects (project_id) + SELECT project_id + FROM notes + INNER JOIN projects ON projects.id = notes.project_id + WHERE notes.created_at >= #{timestamp} + AND notes.system IS FALSE + AND projects.visibility_level = #{visibility} + GROUP BY project_id + ORDER BY count(*) DESC + LIMIT 100; + EOF + end + + def down + drop_table :trending_projects + end +end diff --git a/db/migrate/20161010142410_create_project_authorizations.rb b/db/migrate/20161010142410_create_project_authorizations.rb new file mode 100644 index 00000000000..e095ab969f8 --- /dev/null +++ b/db/migrate/20161010142410_create_project_authorizations.rb @@ -0,0 +1,15 @@ +class CreateProjectAuthorizations < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + create_table :project_authorizations do |t| + t.references :user, foreign_key: { on_delete: :cascade } + t.references :project, foreign_key: { on_delete: :cascade } + t.integer :access_level + + t.index [:user_id, :project_id, :access_level], unique: true, name: 'index_project_authorizations_on_user_id_project_id_access_level' + end + end +end diff --git a/db/migrate/20161012180455_add_repository_access_level_to_project_feature.rb b/db/migrate/20161012180455_add_repository_access_level_to_project_feature.rb new file mode 100644 index 00000000000..7b33da3ea11 --- /dev/null +++ b/db/migrate/20161012180455_add_repository_access_level_to_project_feature.rb @@ -0,0 +1,14 @@ +class AddRepositoryAccessLevelToProjectFeature < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + disable_ddl_transaction! + + DOWNTIME = false + + def up + add_column_with_default(:project_features, :repository_access_level, :integer, default: ProjectFeature::ENABLED) + end + + def down + remove_column :project_features, :repository_access_level + end +end diff --git a/db/migrate/20161014173530_create_label_priorities.rb b/db/migrate/20161014173530_create_label_priorities.rb new file mode 100644 index 00000000000..2c22841c28a --- /dev/null +++ b/db/migrate/20161014173530_create_label_priorities.rb @@ -0,0 +1,25 @@ +class CreateLabelPriorities < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'This migration adds foreign keys' + + disable_ddl_transaction! + + def up + create_table :label_priorities do |t| + t.references :project, foreign_key: { on_delete: :cascade }, null: false + t.references :label, foreign_key: { on_delete: :cascade }, null: false + t.integer :priority, null: false + + t.timestamps null: false + end + + add_concurrent_index :label_priorities, [:project_id, :label_id], unique: true + add_concurrent_index :label_priorities, :priority + end + + def down + drop_table :label_priorities + end +end diff --git a/db/migrate/20161017091941_add_authorized_projects_populated_to_users.rb b/db/migrate/20161017091941_add_authorized_projects_populated_to_users.rb new file mode 100644 index 00000000000..8f6be9dd677 --- /dev/null +++ b/db/migrate/20161017091941_add_authorized_projects_populated_to_users.rb @@ -0,0 +1,9 @@ +class AddAuthorizedProjectsPopulatedToUsers < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column :users, :authorized_projects_populated, :boolean + end +end diff --git a/db/migrate/20161017095000_add_properties_to_deployment.rb b/db/migrate/20161017095000_add_properties_to_deployment.rb new file mode 100644 index 00000000000..f620ee0de1c --- /dev/null +++ b/db/migrate/20161017095000_add_properties_to_deployment.rb @@ -0,0 +1,9 @@ +class AddPropertiesToDeployment < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column :deployments, :on_stop, :string + end +end diff --git a/db/migrate/20161017125927_add_unique_index_to_labels.rb b/db/migrate/20161017125927_add_unique_index_to_labels.rb new file mode 100644 index 00000000000..f2b56ebfb7b --- /dev/null +++ b/db/migrate/20161017125927_add_unique_index_to_labels.rb @@ -0,0 +1,32 @@ +class AddUniqueIndexToLabels < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'This migration removes duplicated labels.' + + disable_ddl_transaction! + + def up + select_all('SELECT title, project_id, COUNT(id) as cnt FROM labels GROUP BY project_id, title HAVING COUNT(id) > 1').each do |label| + label_title = quote_string(label['title']) + duplicated_ids = select_all("SELECT id FROM labels WHERE project_id = #{label['project_id']} AND title = '#{label_title}' ORDER BY id ASC").map{ |label| label['id'] } + label_id = duplicated_ids.first + duplicated_ids.delete(label_id) + + execute("UPDATE label_links SET label_id = #{label_id} WHERE label_id IN(#{duplicated_ids.join(",")})") + execute("DELETE FROM labels WHERE id IN(#{duplicated_ids.join(",")})") + end + + remove_index :labels, column: :project_id if index_exists?(:labels, :project_id) + remove_index :labels, column: :title if index_exists?(:labels, :title) + + add_concurrent_index :labels, [:group_id, :project_id, :title], unique: true + end + + def down + remove_index :labels, column: [:group_id, :project_id, :title] if index_exists?(:labels, [:group_id, :project_id, :title], unique: true) + + add_concurrent_index :labels, :project_id + add_concurrent_index :labels, :title + end +end diff --git a/db/migrate/20161018024215_migrate_labels_priority.rb b/db/migrate/20161018024215_migrate_labels_priority.rb new file mode 100644 index 00000000000..22bec2382f4 --- /dev/null +++ b/db/migrate/20161018024215_migrate_labels_priority.rb @@ -0,0 +1,36 @@ +class MigrateLabelsPriority < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'Prioritized labels will not work as expected until this migration is complete.' + + disable_ddl_transaction! + + def up + execute <<-EOF.strip_heredoc + INSERT INTO label_priorities (project_id, label_id, priority, created_at, updated_at) + SELECT labels.project_id, labels.id, labels.priority, NOW(), NOW() + FROM labels + WHERE labels.project_id IS NOT NULL + AND labels.priority IS NOT NULL; + EOF + end + + def down + if Gitlab::Database.mysql? + execute <<-EOF.strip_heredoc + UPDATE labels + INNER JOIN label_priorities ON labels.id = label_priorities.label_id AND labels.project_id = label_priorities.project_id + SET labels.priority = label_priorities.priority; + EOF + else + execute <<-EOF.strip_heredoc + UPDATE labels + SET priority = label_priorities.priority + FROM label_priorities + WHERE labels.id = label_priorities.label_id + AND labels.project_id = label_priorities.project_id; + EOF + end + end +end diff --git a/db/migrate/20161018024550_remove_priority_from_labels.rb b/db/migrate/20161018024550_remove_priority_from_labels.rb new file mode 100644 index 00000000000..b7416cca664 --- /dev/null +++ b/db/migrate/20161018024550_remove_priority_from_labels.rb @@ -0,0 +1,17 @@ +class RemovePriorityFromLabels < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'This migration removes an existing column' + + disable_ddl_transaction! + + def up + remove_column :labels, :priority, :integer, index: true + end + + def down + add_column :labels, :priority, :integer + add_concurrent_index :labels, :priority + end +end diff --git a/db/migrate/20161018124658_make_project_owners_masters.rb b/db/migrate/20161018124658_make_project_owners_masters.rb new file mode 100644 index 00000000000..a576bb7b622 --- /dev/null +++ b/db/migrate/20161018124658_make_project_owners_masters.rb @@ -0,0 +1,15 @@ +class MakeProjectOwnersMasters < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def up + update_column_in_batches(:members, :access_level, 40) do |table, query| + query.where(table[:access_level].eq(50).and(table[:source_type].eq('Project'))) + end + end + + def down + # do nothing + end +end diff --git a/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb b/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb new file mode 100644 index 00000000000..e875213ab96 --- /dev/null +++ b/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb @@ -0,0 +1,109 @@ +require 'json' + +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class MigrateSidekiqQueuesFromDefault < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + + DOWNTIME_REASON = <<-EOF + Moving Sidekiq jobs from queues requires Sidekiq to be stopped. Not stopping + Sidekiq will result in the loss of jobs that are scheduled after this + migration completes. + EOF + + disable_ddl_transaction! + + # Jobs for which the queue names have been changed (e.g. multiple workers + # using the same non-default queue). + # + # The keys are the old queue names, the values the jobs to move and their new + # queue names. + RENAMED_QUEUES = { + gitlab_shell: { + 'GitGarbageCollectorWorker' => :git_garbage_collector, + 'ProjectExportWorker' => :project_export, + 'RepositoryForkWorker' => :repository_fork, + 'RepositoryImportWorker' => :repository_import + }, + project_web_hook: { + 'ProjectServiceWorker' => :project_service + }, + incoming_email: { + 'EmailReceiverWorker' => :email_receiver + }, + mailers: { + 'EmailsOnPushWorker' => :emails_on_push + }, + default: { + 'AdminEmailWorker' => :cronjob, + 'BuildCoverageWorker' => :build, + 'BuildEmailWorker' => :build, + 'BuildFinishedWorker' => :build, + 'BuildHooksWorker' => :build, + 'BuildSuccessWorker' => :build, + 'ClearDatabaseCacheWorker' => :clear_database_cache, + 'DeleteUserWorker' => :delete_user, + 'ExpireBuildArtifactsWorker' => :cronjob, + 'ExpireBuildInstanceArtifactsWorker' => :expire_build_instance_artifacts, + 'GroupDestroyWorker' => :group_destroy, + 'ImportExportProjectCleanupWorker' => :cronjob, + 'IrkerWorker' => :irker, + 'MergeWorker' => :merge, + 'NewNoteWorker' => :new_note, + 'PipelineHooksWorker' => :pipeline, + 'PipelineMetricsWorker' => :pipeline, + 'PipelineProcessWorker' => :pipeline, + 'PipelineSuccessWorker' => :pipeline, + 'PipelineUpdateWorker' => :pipeline, + 'ProjectCacheWorker' => :project_cache, + 'ProjectDestroyWorker' => :project_destroy, + 'PruneOldEventsWorker' => :cronjob, + 'RemoveExpiredGroupLinksWorker' => :cronjob, + 'RemoveExpiredMembersWorker' => :cronjob, + 'RepositoryArchiveCacheWorker' => :cronjob, + 'RepositoryCheck::BatchWorker' => :cronjob, + 'RepositoryCheck::ClearWorker' => :repository_check, + 'RepositoryCheck::SingleRepositoryWorker' => :repository_check, + 'RequestsProfilesWorker' => :cronjob, + 'StuckCiBuildsWorker' => :cronjob, + 'UpdateMergeRequestsWorker' => :update_merge_requests + } + } + + def up + Sidekiq.redis do |redis| + RENAMED_QUEUES.each do |queue, jobs| + migrate_from_queue(redis, queue, jobs) + end + end + end + + def down + Sidekiq.redis do |redis| + RENAMED_QUEUES.each do |dest_queue, jobs| + jobs.each do |worker, from_queue| + migrate_from_queue(redis, from_queue, worker => dest_queue) + end + end + end + end + + def migrate_from_queue(redis, queue, job_mapping) + while job = redis.lpop("queue:#{queue}") + payload = JSON.load(job) + new_queue = job_mapping[payload['class']] + + # If we have no target queue to migrate to we're probably dealing with + # some ancient job for which the worker no longer exists. In that case + # there's no sane option we can take, other than just dropping the job. + next unless new_queue + + payload['queue'] = new_queue + + redis.lpush("queue:#{new_queue}", JSON.dump(payload)) + end + end +end diff --git a/db/migrate/20161019213545_generate_project_feature_for_projects.rb b/db/migrate/20161019213545_generate_project_feature_for_projects.rb new file mode 100644 index 00000000000..4554e14b0df --- /dev/null +++ b/db/migrate/20161019213545_generate_project_feature_for_projects.rb @@ -0,0 +1,28 @@ +class GenerateProjectFeatureForProjects < ActiveRecord::Migration + DOWNTIME = true + + DOWNTIME_REASON = <<-HEREDOC + Application was eager loading project_feature for all projects generating an extra query + everytime a project was fetched. We removed that behavior to avoid the extra query, this migration + makes sure all projects have a project_feature record associated. + HEREDOC + + def up + # Generate enabled values for each project feature 20, 20, 20, 20, 20 + # All features are enabled by default + enabled_values = [ProjectFeature::ENABLED] * 5 + + execute <<-EOF.strip_heredoc + INSERT INTO project_features + (project_id, merge_requests_access_level, builds_access_level, + issues_access_level, snippets_access_level, wiki_access_level) + (SELECT projects.id, #{enabled_values.join(',')} FROM projects LEFT OUTER JOIN project_features + ON project_features.project_id = projects.id + WHERE project_features.id IS NULL) + EOF + end + + def down + "Not needed" + end +end diff --git a/db/migrate/20161020075734_default_request_access_groups.rb b/db/migrate/20161020075734_default_request_access_groups.rb new file mode 100644 index 00000000000..9721cc88724 --- /dev/null +++ b/db/migrate/20161020075734_default_request_access_groups.rb @@ -0,0 +1,12 @@ +class DefaultRequestAccessGroups < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + DOWNTIME = false + + def up + change_column_default :namespaces, :request_access_enabled, false + end + + def down + change_column_default :namespaces, :request_access_enabled, true + end +end diff --git a/db/migrate/20161020075830_default_request_access_projects.rb b/db/migrate/20161020075830_default_request_access_projects.rb new file mode 100644 index 00000000000..cb790291b24 --- /dev/null +++ b/db/migrate/20161020075830_default_request_access_projects.rb @@ -0,0 +1,12 @@ +class DefaultRequestAccessProjects < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + DOWNTIME = false + + def up + change_column_default :projects, :request_access_enabled, false + end + + def down + change_column_default :projects, :request_access_enabled, true + end +end diff --git a/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb b/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb new file mode 100644 index 00000000000..f49df6802a7 --- /dev/null +++ b/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb @@ -0,0 +1,33 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddPipelineIdToMergeRequestMetrics < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + # 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 a foreign key' + + # 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 change + add_column :merge_request_metrics, :pipeline_id, :integer + add_concurrent_index :merge_request_metrics, :pipeline_id + add_foreign_key :merge_request_metrics, :ci_commits, column: :pipeline_id, on_delete: :cascade + end +end diff --git a/db/migrate/20161021114307_add_lock_version_to_build_and_pipelines.rb b/db/migrate/20161021114307_add_lock_version_to_build_and_pipelines.rb new file mode 100644 index 00000000000..b47f3aa2810 --- /dev/null +++ b/db/migrate/20161021114307_add_lock_version_to_build_and_pipelines.rb @@ -0,0 +1,14 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddLockVersionToBuildAndPipelines < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + def change + add_column :ci_builds, :lock_version, :integer + add_column :ci_commits, :lock_version, :integer + end +end diff --git a/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb b/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb new file mode 100644 index 00000000000..06d07bdb835 --- /dev/null +++ b/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb @@ -0,0 +1,63 @@ +require 'json' + +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class MigrateMailroomQueueFromDefault < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + + DOWNTIME_REASON = <<-EOF + Moving Sidekiq jobs from queues requires Sidekiq to be stopped. Not stopping + Sidekiq will result in the loss of jobs that are scheduled after this + migration completes. + EOF + + disable_ddl_transaction! + + # Jobs for which the queue names have been changed (e.g. multiple workers + # using the same non-default queue). + # + # The keys are the old queue names, the values the jobs to move and their new + # queue names. + RENAMED_QUEUES = { + incoming_email: { + 'EmailReceiverWorker' => :email_receiver + } + } + + def up + Sidekiq.redis do |redis| + RENAMED_QUEUES.each do |queue, jobs| + migrate_from_queue(redis, queue, jobs) + end + end + end + + def down + Sidekiq.redis do |redis| + RENAMED_QUEUES.each do |dest_queue, jobs| + jobs.each do |worker, from_queue| + migrate_from_queue(redis, from_queue, worker => dest_queue) + end + end + end + end + + def migrate_from_queue(redis, queue, job_mapping) + while job = redis.lpop("queue:#{queue}") + payload = JSON.load(job) + new_queue = job_mapping[payload['class']] + + # If we have no target queue to migrate to we're probably dealing with + # some ancient job for which the worker no longer exists. In that case + # there's no sane option we can take, other than just dropping the job. + next unless new_queue + + payload['queue'] = new_queue + + redis.lpush("queue:#{new_queue}", JSON.dump(payload)) + end + end +end diff --git a/db/migrate/20161025231710_migrate_jira_to_gem.rb b/db/migrate/20161025231710_migrate_jira_to_gem.rb new file mode 100644 index 00000000000..870b00411d2 --- /dev/null +++ b/db/migrate/20161025231710_migrate_jira_to_gem.rb @@ -0,0 +1,73 @@ +class MigrateJiraToGem < ActiveRecord::Migration + DOWNTIME = true + + DOWNTIME_REASON = <<-HEREDOC + Refactor all Jira services properties(serialized field) to use new jira-ruby gem. + There were properties on old Jira service that are not needed anymore after the + service refactoring: api_url, project_url, new_issue_url, issues_url. + We extract the new necessary some properties from old keys and delete them: + taking project_key from project_url and url from api_url + HEREDOC + + def up + active_services_query = "SELECT id, properties FROM services WHERE services.type IN ('JiraService') AND services.active = true" + + select_all(active_services_query).each do |service| + id = service['id'] + properties = JSON.parse(service['properties']) + properties_was = properties.clone + + # Migrate `project_url` to `project_key` + # Ignore if `project_url` doesn't have jql project query with project key + if properties['project_url'].present? + jql = properties['project_url'].match('project=([A-Za-z]*)') + properties['project_key'] = jql.captures.first if jql + end + + # Migrate `api_url` to `url` + if properties['api_url'].present? + url = properties['api_url'].match('(.*)\/rest\/api') + properties['url'] = url.captures.first if url + end + + # Delete now unnecessary properties + properties.delete('api_url') + properties.delete('project_url') + properties.delete('new_issue_url') + properties.delete('issues_url') + + # Update changes properties + if properties != properties_was + execute("UPDATE services SET properties = '#{quote_string(properties.to_json)}' WHERE id = #{id}") + end + end + end + + def down + active_services_query = "SELECT id, properties FROM services WHERE services.type IN ('JiraService') AND services.active = true" + + select_all(active_services_query).each do |service| + id = service['id'] + properties = JSON.parse(service['properties']) + properties_was = properties.clone + + # Rebuild old properties based on sane defaults + if properties['url'].present? + properties['api_url'] = "#{properties['url']}/rest/api/2" + properties['project_url'] = + "#{properties['url']}/issues/?jql=project=#{properties['project_key']}" + properties['issues_url'] = "#{properties['url']}/browse/:id" + properties['new_issue_url'] = "#{properties['url']}/secure/CreateIssue.jspa" + end + + # Delete the new properties + properties.delete('url') + properties.delete('project_key') + + # Update changes properties + if properties != properties_was + execute("UPDATE services SET properties = '#{quote_string(properties.to_json)}' WHERE id = #{id}") + end + end + end +end diff --git a/db/migrate/20161031155516_add_housekeeping_to_application_settings.rb b/db/migrate/20161031155516_add_housekeeping_to_application_settings.rb new file mode 100644 index 00000000000..5a451fb575b --- /dev/null +++ b/db/migrate/20161031155516_add_housekeeping_to_application_settings.rb @@ -0,0 +1,32 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddHousekeepingToApplicationSettings < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + # 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 = '' + + disable_ddl_transaction! + + def up + add_column_with_default(:application_settings, :housekeeping_enabled, :boolean, default: true, allow_null: false) + add_column_with_default(:application_settings, :housekeeping_bitmaps_enabled, :boolean, default: true, allow_null: false) + add_column_with_default(:application_settings, :housekeeping_incremental_repack_period, :integer, default: 10, allow_null: false) + add_column_with_default(:application_settings, :housekeeping_full_repack_period, :integer, default: 50, allow_null: false) + add_column_with_default(:application_settings, :housekeeping_gc_period, :integer, default: 200, allow_null: false) + end + + def down + remove_column(:application_settings, :housekeeping_enabled, :boolean, default: true, allow_null: false) + remove_column(:application_settings, :housekeeping_bitmaps_enabled, :boolean, default: true, allow_null: false) + remove_column(:application_settings, :housekeeping_incremental_repack_period, :integer, default: 10, allow_null: false) + remove_column(:application_settings, :housekeeping_full_repack_period, :integer, default: 50, allow_null: false) + remove_column(:application_settings, :housekeeping_gc_period, :integer, default: 200, allow_null: false) + end +end diff --git a/db/migrate/20161031171301_add_project_id_to_subscriptions.rb b/db/migrate/20161031171301_add_project_id_to_subscriptions.rb new file mode 100644 index 00000000000..97534679b59 --- /dev/null +++ b/db/migrate/20161031171301_add_project_id_to_subscriptions.rb @@ -0,0 +1,14 @@ +class AddProjectIdToSubscriptions < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def up + add_column :subscriptions, :project_id, :integer + add_foreign_key :subscriptions, :projects, column: :project_id, on_delete: :cascade + end + + def down + remove_column :subscriptions, :project_id + end +end diff --git a/db/migrate/20161031174110_migrate_subscriptions_project_id.rb b/db/migrate/20161031174110_migrate_subscriptions_project_id.rb new file mode 100644 index 00000000000..549145a0a65 --- /dev/null +++ b/db/migrate/20161031174110_migrate_subscriptions_project_id.rb @@ -0,0 +1,44 @@ +class MigrateSubscriptionsProjectId < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'Subscriptions will not work as expected until this migration is complete.' + + def up + execute <<-EOF.strip_heredoc + UPDATE subscriptions + SET project_id = ( + SELECT issues.project_id + FROM issues + WHERE issues.id = subscriptions.subscribable_id + ) + WHERE subscriptions.subscribable_type = 'Issue'; + EOF + + execute <<-EOF.strip_heredoc + UPDATE subscriptions + SET project_id = ( + SELECT merge_requests.target_project_id + FROM merge_requests + WHERE merge_requests.id = subscriptions.subscribable_id + ) + WHERE subscriptions.subscribable_type = 'MergeRequest'; + EOF + + execute <<-EOF.strip_heredoc + UPDATE subscriptions + SET project_id = ( + SELECT projects.id + FROM labels INNER JOIN projects ON projects.id = labels.project_id + WHERE labels.id = subscriptions.subscribable_id + ) + WHERE subscriptions.subscribable_type = 'Label'; + EOF + end + + def down + execute <<-EOF.strip_heredoc + UPDATE subscriptions SET project_id = NULL; + EOF + end +end diff --git a/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb b/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb new file mode 100644 index 00000000000..4b1b29e1265 --- /dev/null +++ b/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb @@ -0,0 +1,18 @@ +class AddUniqueIndexToSubscriptions < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'This migration requires downtime because it changes a column to not accept null values.' + + disable_ddl_transaction! + + def up + add_concurrent_index :subscriptions, [:subscribable_id, :subscribable_type, :user_id, :project_id], { unique: true, name: 'index_subscriptions_on_subscribable_and_user_id_and_project_id' } + remove_index :subscriptions, name: 'subscriptions_user_id_and_ref_fields' if index_name_exists?(:subscriptions, 'subscriptions_user_id_and_ref_fields', false) + end + + def down + add_concurrent_index :subscriptions, [:subscribable_id, :subscribable_type, :user_id], { unique: true, name: 'subscriptions_user_id_and_ref_fields' } + remove_index :subscriptions, name: 'index_subscriptions_on_subscribable_and_user_id_and_project_id' if index_name_exists?(:subscriptions, 'index_subscriptions_on_subscribable_and_user_id_and_project_id', false) + end +end diff --git a/db/migrate/20161103171205_rename_repository_storage_column.rb b/db/migrate/20161103171205_rename_repository_storage_column.rb new file mode 100644 index 00000000000..93280573939 --- /dev/null +++ b/db/migrate/20161103171205_rename_repository_storage_column.rb @@ -0,0 +1,29 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class RenameRepositoryStorageColumn < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # 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 = 'Renaming the application_settings.repository_storage column' + + # 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 change + rename_column :application_settings, :repository_storage, :repository_storages + end +end diff --git a/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb b/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb new file mode 100644 index 00000000000..e644a174964 --- /dev/null +++ b/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb @@ -0,0 +1,31 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddSidekiqThrottlingToApplicationSettings < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + # 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 = '' + + # 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 change + add_column :application_settings, :sidekiq_throttling_enabled, :boolean, default: false + add_column :application_settings, :sidekiq_throttling_queues, :string + add_column :application_settings, :sidekiq_throttling_factor, :decimal + end +end diff --git a/db/migrate/20161106185620_add_project_import_data_project_index.rb b/db/migrate/20161106185620_add_project_import_data_project_index.rb new file mode 100644 index 00000000000..750a6a8c51e --- /dev/null +++ b/db/migrate/20161106185620_add_project_import_data_project_index.rb @@ -0,0 +1,12 @@ +class AddProjectImportDataProjectIndex < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + disable_ddl_transaction! + + def change + add_concurrent_index :project_import_data, :project_id + end +end diff --git a/db/migrate/20161113184239_create_user_chat_names_table.rb b/db/migrate/20161113184239_create_user_chat_names_table.rb new file mode 100644 index 00000000000..97b597654f7 --- /dev/null +++ b/db/migrate/20161113184239_create_user_chat_names_table.rb @@ -0,0 +1,21 @@ +class CreateUserChatNamesTable < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + create_table :chat_names do |t| + t.integer :user_id, null: false + t.integer :service_id, null: false + t.string :team_id, null: false + t.string :team_domain + t.string :chat_id, null: false + t.string :chat_name + t.datetime :last_used_at + t.timestamps null: false + end + + add_index :chat_names, [:user_id, :service_id], unique: true + add_index :chat_names, [:service_id, :team_id, :chat_id], unique: true + end +end diff --git a/db/migrate/20161115173905_add_start_date_to_milestones.rb b/db/migrate/20161115173905_add_start_date_to_milestones.rb new file mode 100644 index 00000000000..413733b8db7 --- /dev/null +++ b/db/migrate/20161115173905_add_start_date_to_milestones.rb @@ -0,0 +1,12 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddStartDateToMilestones < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column :milestones, :start_date, :date + end +end diff --git a/db/migrate/20161117114805_remove_undeleted_groups.rb b/db/migrate/20161117114805_remove_undeleted_groups.rb new file mode 100644 index 00000000000..696914f8e4d --- /dev/null +++ b/db/migrate/20161117114805_remove_undeleted_groups.rb @@ -0,0 +1,57 @@ +# 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 + DOWNTIME = false + + def up + execute <<-EOF.strip_heredoc + DELETE FROM projects + WHERE namespace_id IN ( + SELECT id FROM ( + SELECT id + FROM namespaces + WHERE deleted_at IS NOT NULL + ) namespace_ids + ); + EOF + + if defined?(Gitlab::License) + # 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 ( + SELECT id FROM ( + SELECT id + FROM namespaces + WHERE deleted_at IS NOT NULL + ) namespace_ids + ); + EOF + + execute <<-EOF.strip_heredoc + DELETE FROM protected_branch_merge_access_levels + WHERE group_id IN ( + SELECT id FROM ( + SELECT id + FROM namespaces + WHERE deleted_at IS NOT NULL + ) namespace_ids + ); + EOF + end + + # This removes namespaces that were supposed to be soft 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 +end diff --git a/db/migrate/20161118183841_add_commit_events_to_services.rb b/db/migrate/20161118183841_add_commit_events_to_services.rb new file mode 100644 index 00000000000..4f9b5dd2281 --- /dev/null +++ b/db/migrate/20161118183841_add_commit_events_to_services.rb @@ -0,0 +1,15 @@ +class AddCommitEventsToServices < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_column_with_default(:services, :commit_events, :boolean, default: true, allow_null: false) + end + + def down + remove_column(:services, :commit_events) + end +end diff --git a/db/fixtures/test/001_repo.rb b/db/post_migrate/.gitkeep index e69de29bb2d..e69de29bb2d 100644 --- a/db/fixtures/test/001_repo.rb +++ b/db/post_migrate/.gitkeep diff --git a/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb b/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb new file mode 100644 index 00000000000..319d86ac159 --- /dev/null +++ b/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb @@ -0,0 +1,10 @@ +class RemoveInactiveJiraServiceProperties < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = "Removes all inactive jira_service properties" + + def up + execute("UPDATE services SET properties = '{}' WHERE services.type = 'JiraService' and services.active = false") + end +end diff --git a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb new file mode 100644 index 00000000000..df38591a333 --- /dev/null +++ b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb @@ -0,0 +1,49 @@ +class FixProjectRecordsWithInvalidVisibility < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + BATCH_SIZE = 500 + DOWNTIME = false + + # This migration is idempotent and there's no sense in throwing away the + # partial result if it's interrupted + disable_ddl_transaction! + + def up + projects = Arel::Table.new(:projects) + namespaces = Arel::Table.new(:namespaces) + + finder_sql = + projects. + join(namespaces, Arel::Nodes::InnerJoin). + on(projects[:namespace_id].eq(namespaces[:id])). + where(projects[:visibility_level].gt(namespaces[:visibility_level])). + project(projects[:id], namespaces[:visibility_level]). + take(BATCH_SIZE). + to_sql + + # Update matching rows in batches. Each batch can cause up to 3 UPDATE + # statements, in addition to the SELECT: one per visibility_level + loop do + to_update = connection.exec_query(finder_sql) + break if to_update.rows.count == 0 + + # row[0] is projects.id, row[1] is namespaces.visibility_level + updates = to_update.rows.each_with_object(Hash.new {|h, k| h[k] = [] }) do |row, obj| + obj[row[1]] << row[0] + end + + updates.each do |visibility_level, project_ids| + updater = Arel::UpdateManager.new(ActiveRecord::Base). + table(projects). + set(projects[:visibility_level] => visibility_level). + where(projects[:id].in(project_ids)) + + ActiveRecord::Base.connection.exec_update(updater.to_sql, self.class.name, []) + end + end + end + + def down + # no-op + end +end diff --git a/db/schema.rb b/db/schema.rb index 70279f372c9..b3c49b52597 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,95 +11,109 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160913162434) do +ActiveRecord::Schema.define(version: 20161118183841) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "pg_trgm" create_table "abuse_reports", force: :cascade do |t| - t.integer "reporter_id" - t.integer "user_id" - t.text "message" + t.integer "reporter_id" + t.integer "user_id" + t.text "message" t.datetime "created_at" t.datetime "updated_at" + t.text "message_html" end create_table "appearances", force: :cascade do |t| - t.string "title" - t.text "description" - t.string "header_logo" - t.string "logo" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "title" + t.text "description" + t.string "header_logo" + t.string "logo" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "description_html" end create_table "application_settings", force: :cascade do |t| - t.integer "default_projects_limit" - t.boolean "signup_enabled" - t.boolean "signin_enabled" - t.boolean "gravatar_enabled" - t.text "sign_in_text" + t.integer "default_projects_limit" + t.boolean "signup_enabled" + t.boolean "signin_enabled" + t.boolean "gravatar_enabled" + t.text "sign_in_text" t.datetime "created_at" t.datetime "updated_at" - t.string "home_page_url" - t.integer "default_branch_protection", default: 2 - t.text "restricted_visibility_levels" - t.boolean "version_check_enabled", default: true - t.integer "max_attachment_size", default: 10, null: false - t.integer "default_project_visibility" - t.integer "default_snippet_visibility" - t.text "domain_whitelist" - t.boolean "user_oauth_applications", default: true - t.string "after_sign_out_path" - t.integer "session_expire_delay", default: 10080, null: false - t.text "import_sources" - t.text "help_page_text" - t.string "admin_notification_email" - t.boolean "shared_runners_enabled", default: true, null: false - t.integer "max_artifacts_size", default: 100, null: false - t.string "runners_registration_token" - t.boolean "require_two_factor_authentication", default: false - t.integer "two_factor_grace_period", default: 48 - t.boolean "metrics_enabled", default: false - t.string "metrics_host", default: "localhost" - t.integer "metrics_pool_size", default: 16 - t.integer "metrics_timeout", default: 10 - t.integer "metrics_method_call_threshold", default: 10 - t.boolean "recaptcha_enabled", default: false - t.string "recaptcha_site_key" - t.string "recaptcha_private_key" - t.integer "metrics_port", default: 8089 - t.boolean "akismet_enabled", default: false - t.string "akismet_api_key" - t.integer "metrics_sample_interval", default: 15 - t.boolean "sentry_enabled", default: false - t.string "sentry_dsn" - t.boolean "email_author_in_body", default: false - t.integer "default_group_visibility" - t.boolean "repository_checks_enabled", default: false - t.text "shared_runners_text" - t.integer "metrics_packet_size", default: 1 - t.text "disabled_oauth_sign_in_sources" - t.string "health_check_access_token" - t.boolean "send_user_confirmation_email", default: false - t.integer "container_registry_token_expire_delay", default: 5 - t.text "after_sign_up_text" - t.boolean "user_default_external", default: false, null: false - t.string "repository_storage", default: "default" - t.string "enabled_git_access_protocol" - t.boolean "domain_blacklist_enabled", default: false - t.text "domain_blacklist" - t.boolean "koding_enabled" - t.string "koding_url" + t.string "home_page_url" + t.integer "default_branch_protection", default: 2 + t.text "restricted_visibility_levels" + t.boolean "version_check_enabled", default: true + t.integer "max_attachment_size", default: 10, null: false + t.integer "default_project_visibility" + t.integer "default_snippet_visibility" + t.text "domain_whitelist" + t.boolean "user_oauth_applications", default: true + t.string "after_sign_out_path" + t.integer "session_expire_delay", default: 10080, null: false + t.text "import_sources" + t.text "help_page_text" + t.string "admin_notification_email" + t.boolean "shared_runners_enabled", default: true, null: false + t.integer "max_artifacts_size", default: 100, null: false + t.string "runners_registration_token" + t.boolean "require_two_factor_authentication", default: false + t.integer "two_factor_grace_period", default: 48 + t.boolean "metrics_enabled", default: false + t.string "metrics_host", default: "localhost" + t.integer "metrics_pool_size", default: 16 + t.integer "metrics_timeout", default: 10 + t.integer "metrics_method_call_threshold", default: 10 + t.boolean "recaptcha_enabled", default: false + t.string "recaptcha_site_key" + t.string "recaptcha_private_key" + t.integer "metrics_port", default: 8089 + t.boolean "akismet_enabled", default: false + t.string "akismet_api_key" + t.integer "metrics_sample_interval", default: 15 + t.boolean "sentry_enabled", default: false + t.string "sentry_dsn" + t.boolean "email_author_in_body", default: false + t.integer "default_group_visibility" + t.boolean "repository_checks_enabled", default: false + t.text "shared_runners_text" + t.integer "metrics_packet_size", default: 1 + t.text "disabled_oauth_sign_in_sources" + t.string "health_check_access_token" + t.boolean "send_user_confirmation_email", default: false + t.integer "container_registry_token_expire_delay", default: 5 + t.text "after_sign_up_text" + t.boolean "user_default_external", default: false, null: false + t.string "repository_storages", default: "default" + t.string "enabled_git_access_protocol" + t.boolean "domain_blacklist_enabled", default: false + t.text "domain_blacklist" + t.boolean "koding_enabled" + t.string "koding_url" + t.text "sign_in_text_html" + t.text "help_page_text_html" + t.text "shared_runners_text_html" + t.text "after_sign_up_text_html" + t.boolean "sidekiq_throttling_enabled", default: false + t.string "sidekiq_throttling_queues" + t.decimal "sidekiq_throttling_factor" + t.boolean "housekeeping_enabled", default: true, null: false + t.boolean "housekeeping_bitmaps_enabled", default: true, null: false + t.integer "housekeeping_incremental_repack_period", default: 10, null: false + t.integer "housekeeping_full_repack_period", default: 50, null: false + t.integer "housekeeping_gc_period", default: 200, null: false end create_table "audit_events", force: :cascade do |t| - t.integer "author_id", null: false - t.string "type", null: false - t.integer "entity_id", null: false - t.string "entity_type", null: false - t.text "details" + t.integer "author_id", null: false + t.string "type", null: false + t.integer "entity_id", null: false + t.string "entity_type", null: false + t.text "details" t.datetime "created_at" t.datetime "updated_at" end @@ -107,10 +121,10 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "audit_events", ["entity_id", "entity_type"], name: "index_audit_events_on_entity_id_and_entity_type", using: :btree create_table "award_emoji", force: :cascade do |t| - t.string "name" - t.integer "user_id" - t.integer "awardable_id" - t.string "awardable_type" + t.string "name" + t.integer "user_id" + t.integer "awardable_id" + t.string "awardable_type" t.datetime "created_at" t.datetime "updated_at" end @@ -120,7 +134,7 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "award_emoji", ["user_id"], name: "index_award_emoji_on_user_id", using: :btree create_table "boards", force: :cascade do |t| - t.integer "project_id", null: false + t.integer "project_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false end @@ -128,59 +142,77 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "boards", ["project_id"], name: "index_boards_on_project_id", using: :btree create_table "broadcast_messages", force: :cascade do |t| - t.text "message", null: false + t.text "message", null: false t.datetime "starts_at" t.datetime "ends_at" t.datetime "created_at" t.datetime "updated_at" - t.string "color" - t.string "font" + t.string "color" + t.string "font" + t.text "message_html" + end + + create_table "chat_names", force: :cascade do |t| + t.integer "user_id", null: false + t.integer "service_id", null: false + t.string "team_id", null: false + t.string "team_domain" + t.string "chat_id", null: false + t.string "chat_name" + t.datetime "last_used_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end + add_index "chat_names", ["service_id", "team_id", "chat_id"], name: "index_chat_names_on_service_id_and_team_id_and_chat_id", unique: true, using: :btree + add_index "chat_names", ["user_id", "service_id"], name: "index_chat_names_on_user_id_and_service_id", unique: true, using: :btree + create_table "ci_application_settings", force: :cascade do |t| - t.boolean "all_broken_builds" - t.boolean "add_pusher" + t.boolean "all_broken_builds" + t.boolean "add_pusher" t.datetime "created_at" t.datetime "updated_at" end create_table "ci_builds", force: :cascade do |t| - t.integer "project_id" - t.string "status" + t.integer "project_id" + t.string "status" t.datetime "finished_at" - t.text "trace" + t.text "trace" t.datetime "created_at" t.datetime "updated_at" t.datetime "started_at" - t.integer "runner_id" - t.float "coverage" - t.integer "commit_id" - t.text "commands" - t.integer "job_id" - t.string "name" - t.boolean "deploy", default: false - t.text "options" - t.boolean "allow_failure", default: false, null: false - t.string "stage" - t.integer "trigger_request_id" - t.integer "stage_idx" - t.boolean "tag" - t.string "ref" - t.integer "user_id" - t.string "type" - t.string "target_url" - t.string "description" - t.text "artifacts_file" - t.integer "gl_project_id" - t.text "artifacts_metadata" - t.integer "erased_by_id" + t.integer "runner_id" + t.float "coverage" + t.integer "commit_id" + t.text "commands" + t.integer "job_id" + t.string "name" + t.boolean "deploy", default: false + t.text "options" + t.boolean "allow_failure", default: false, null: false + t.string "stage" + t.integer "trigger_request_id" + t.integer "stage_idx" + t.boolean "tag" + t.string "ref" + t.integer "user_id" + t.string "type" + t.string "target_url" + t.string "description" + t.text "artifacts_file" + t.integer "gl_project_id" + t.text "artifacts_metadata" + t.integer "erased_by_id" t.datetime "erased_at" t.datetime "artifacts_expire_at" - t.string "environment" - t.integer "artifacts_size" - t.string "when" - t.text "yaml_variables" + t.string "environment" + t.integer "artifacts_size", limit: 8 + t.string "when" + t.text "yaml_variables" t.datetime "queued_at" + t.string "token" + t.integer "lock_version" end add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree @@ -192,24 +224,26 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "ci_builds", ["project_id"], name: "index_ci_builds_on_project_id", using: :btree add_index "ci_builds", ["runner_id"], name: "index_ci_builds_on_runner_id", using: :btree add_index "ci_builds", ["status"], name: "index_ci_builds_on_status", using: :btree + add_index "ci_builds", ["token"], name: "index_ci_builds_on_token", unique: true, using: :btree create_table "ci_commits", force: :cascade do |t| - t.integer "project_id" - t.string "ref" - t.string "sha" - t.string "before_sha" - t.text "push_data" + t.integer "project_id" + t.string "ref" + t.string "sha" + t.string "before_sha" + t.text "push_data" t.datetime "created_at" t.datetime "updated_at" - t.boolean "tag", default: false - t.text "yaml_errors" + t.boolean "tag", default: false + t.text "yaml_errors" t.datetime "committed_at" - t.integer "gl_project_id" - t.string "status" + t.integer "gl_project_id" + t.string "status" t.datetime "started_at" t.datetime "finished_at" - t.integer "duration" - t.integer "user_id" + t.integer "duration" + t.integer "user_id" + t.integer "lock_version" end add_index "ci_commits", ["gl_project_id", "sha"], name: "index_ci_commits_on_gl_project_id_and_sha", using: :btree @@ -219,140 +253,140 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "ci_commits", ["user_id"], name: "index_ci_commits_on_user_id", using: :btree create_table "ci_events", force: :cascade do |t| - t.integer "project_id" - t.integer "user_id" - t.integer "is_admin" - t.text "description" + t.integer "project_id" + t.integer "user_id" + t.integer "is_admin" + t.text "description" t.datetime "created_at" t.datetime "updated_at" end create_table "ci_jobs", force: :cascade do |t| - t.integer "project_id", null: false - t.text "commands" - t.boolean "active", default: true, null: false + t.integer "project_id", null: false + t.text "commands" + t.boolean "active", default: true, null: false t.datetime "created_at" t.datetime "updated_at" - t.string "name" - t.boolean "build_branches", default: true, null: false - t.boolean "build_tags", default: false, null: false - t.string "job_type", default: "parallel" - t.string "refs" + t.string "name" + t.boolean "build_branches", default: true, null: false + t.boolean "build_tags", default: false, null: false + t.string "job_type", default: "parallel" + t.string "refs" t.datetime "deleted_at" end create_table "ci_projects", force: :cascade do |t| - t.string "name" - t.integer "timeout", default: 3600, null: false + t.string "name" + t.integer "timeout", default: 3600, null: false t.datetime "created_at" t.datetime "updated_at" - t.string "token" - t.string "default_ref" - t.string "path" - t.boolean "always_build", default: false, null: false - t.integer "polling_interval" - t.boolean "public", default: false, null: false - t.string "ssh_url_to_repo" - t.integer "gitlab_id" - t.boolean "allow_git_fetch", default: true, null: false - t.string "email_recipients", default: "", null: false - t.boolean "email_add_pusher", default: true, null: false - t.boolean "email_only_broken_builds", default: true, null: false - t.string "skip_refs" - t.string "coverage_regex" - t.boolean "shared_runners_enabled", default: false - t.text "generated_yaml_config" + t.string "token" + t.string "default_ref" + t.string "path" + t.boolean "always_build", default: false, null: false + t.integer "polling_interval" + t.boolean "public", default: false, null: false + t.string "ssh_url_to_repo" + t.integer "gitlab_id" + t.boolean "allow_git_fetch", default: true, null: false + t.string "email_recipients", default: "", null: false + t.boolean "email_add_pusher", default: true, null: false + t.boolean "email_only_broken_builds", default: true, null: false + t.string "skip_refs" + t.string "coverage_regex" + t.boolean "shared_runners_enabled", default: false + t.text "generated_yaml_config" end create_table "ci_runner_projects", force: :cascade do |t| - t.integer "runner_id", null: false - t.integer "project_id" + t.integer "runner_id", null: false + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" + t.integer "gl_project_id" end add_index "ci_runner_projects", ["gl_project_id"], name: "index_ci_runner_projects_on_gl_project_id", using: :btree add_index "ci_runner_projects", ["runner_id"], name: "index_ci_runner_projects_on_runner_id", using: :btree create_table "ci_runners", force: :cascade do |t| - t.string "token" + t.string "token" t.datetime "created_at" t.datetime "updated_at" - t.string "description" + t.string "description" t.datetime "contacted_at" - t.boolean "active", default: true, null: false - t.boolean "is_shared", default: false - t.string "name" - t.string "version" - t.string "revision" - t.string "platform" - t.string "architecture" - t.boolean "run_untagged", default: true, null: false - t.boolean "locked", default: false, null: false + t.boolean "active", default: true, null: false + t.boolean "is_shared", default: false + t.string "name" + t.string "version" + t.string "revision" + t.string "platform" + t.string "architecture" + t.boolean "run_untagged", default: true, null: false + t.boolean "locked", default: false, null: false end add_index "ci_runners", ["locked"], name: "index_ci_runners_on_locked", using: :btree add_index "ci_runners", ["token"], name: "index_ci_runners_on_token", using: :btree create_table "ci_sessions", force: :cascade do |t| - t.string "session_id", null: false - t.text "data" + t.string "session_id", null: false + t.text "data" t.datetime "created_at" t.datetime "updated_at" end create_table "ci_taggings", force: :cascade do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context", limit: 128 + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context", limit: 128 t.datetime "created_at" end add_index "ci_taggings", ["taggable_id", "taggable_type", "context"], name: "index_ci_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree create_table "ci_tags", force: :cascade do |t| - t.string "name" + t.string "name" t.integer "taggings_count", default: 0 end create_table "ci_trigger_requests", force: :cascade do |t| - t.integer "trigger_id", null: false - t.text "variables" + t.integer "trigger_id", null: false + t.text "variables" t.datetime "created_at" t.datetime "updated_at" - t.integer "commit_id" + t.integer "commit_id" end create_table "ci_triggers", force: :cascade do |t| - t.string "token" - t.integer "project_id" + t.string "token" + t.integer "project_id" t.datetime "deleted_at" t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" + t.integer "gl_project_id" end add_index "ci_triggers", ["gl_project_id"], name: "index_ci_triggers_on_gl_project_id", using: :btree create_table "ci_variables", force: :cascade do |t| t.integer "project_id" - t.string "key" - t.text "value" - t.text "encrypted_value" - t.string "encrypted_value_salt" - t.string "encrypted_value_iv" + t.string "key" + t.text "value" + t.text "encrypted_value" + t.string "encrypted_value_salt" + t.string "encrypted_value_iv" t.integer "gl_project_id" end add_index "ci_variables", ["gl_project_id"], name: "index_ci_variables_on_gl_project_id", using: :btree create_table "deploy_keys_projects", force: :cascade do |t| - t.integer "deploy_key_id", null: false - t.integer "project_id", null: false + t.integer "deploy_key_id", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -360,17 +394,18 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "deploy_keys_projects", ["project_id"], name: "index_deploy_keys_projects_on_project_id", using: :btree create_table "deployments", force: :cascade do |t| - t.integer "iid", null: false - t.integer "project_id", null: false - t.integer "environment_id", null: false - t.string "ref", null: false - t.boolean "tag", null: false - t.string "sha", null: false - t.integer "user_id" - t.integer "deployable_id" - t.string "deployable_type" + t.integer "iid", null: false + t.integer "project_id", null: false + t.integer "environment_id", null: false + t.string "ref", null: false + t.boolean "tag", null: false + t.string "sha", null: false + t.integer "user_id" + t.integer "deployable_id" + t.string "deployable_type" t.datetime "created_at" t.datetime "updated_at" + t.string "on_stop" end add_index "deployments", ["project_id", "environment_id", "iid"], name: "index_deployments_on_project_id_and_environment_id_and_iid", using: :btree @@ -379,8 +414,8 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "deployments", ["project_id"], name: "index_deployments_on_project_id", using: :btree create_table "emails", force: :cascade do |t| - t.integer "user_id", null: false - t.string "email", null: false + t.integer "user_id", null: false + t.string "email", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -389,25 +424,27 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "emails", ["user_id"], name: "index_emails_on_user_id", using: :btree create_table "environments", force: :cascade do |t| - t.integer "project_id" - t.string "name", null: false + t.integer "project_id" + t.string "name", null: false t.datetime "created_at" t.datetime "updated_at" - t.string "external_url" + t.string "external_url" + t.string "environment_type" + t.string "state", default: "available", null: false end add_index "environments", ["project_id", "name"], name: "index_environments_on_project_id_and_name", using: :btree create_table "events", force: :cascade do |t| - t.string "target_type" - t.integer "target_id" - t.string "title" - t.text "data" - t.integer "project_id" + t.string "target_type" + t.integer "target_id" + t.string "title" + t.text "data" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "action" - t.integer "author_id" + t.integer "action" + t.integer "author_id" end add_index "events", ["action"], name: "index_events_on_action", using: :btree @@ -418,8 +455,8 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "events", ["target_type"], name: "index_events_on_target_type", using: :btree create_table "forked_project_links", force: :cascade do |t| - t.integer "forked_to_project_id", null: false - t.integer "forked_from_project_id", null: false + t.integer "forked_to_project_id", null: false + t.integer "forked_from_project_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -427,34 +464,47 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree create_table "identities", force: :cascade do |t| - t.string "extern_uid" - t.string "provider" - t.integer "user_id" + t.string "extern_uid" + t.string "provider" + t.integer "user_id" t.datetime "created_at" t.datetime "updated_at" end add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree + create_table "issue_metrics", force: :cascade do |t| + t.integer "issue_id", null: false + t.datetime "first_mentioned_in_commit_at" + t.datetime "first_associated_with_milestone_at" + t.datetime "first_added_to_board_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "issue_metrics", ["issue_id"], name: "index_issue_metrics", using: :btree + create_table "issues", force: :cascade do |t| - t.string "title" - t.integer "assignee_id" - t.integer "author_id" - t.integer "project_id" + t.string "title" + t.integer "assignee_id" + t.integer "author_id" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "position", default: 0 - t.string "branch_name" - t.text "description" - t.integer "milestone_id" - t.string "state" - t.integer "iid" - t.integer "updated_by_id" - t.boolean "confidential", default: false + t.integer "position", default: 0 + t.string "branch_name" + t.text "description" + t.integer "milestone_id" + t.string "state" + t.integer "iid" + t.integer "updated_by_id" + t.boolean "confidential", default: false t.datetime "deleted_at" - t.date "due_date" - t.integer "moved_to_id" - t.integer "lock_version" + t.date "due_date" + t.integer "moved_to_id" + t.integer "lock_version" + t.text "title_html" + t.text "description_html" end add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree @@ -470,23 +520,23 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "issues", ["title"], name: "index_issues_on_title_trigram", using: :gin, opclasses: {"title"=>"gin_trgm_ops"} create_table "keys", force: :cascade do |t| - t.integer "user_id" + t.integer "user_id" t.datetime "created_at" t.datetime "updated_at" - t.text "key" - t.string "title" - t.string "type" - t.string "fingerprint" - t.boolean "public", default: false, null: false + t.text "key" + t.string "title" + t.string "type" + t.string "fingerprint" + t.boolean "public", default: false, null: false end add_index "keys", ["fingerprint"], name: "index_keys_on_fingerprint", unique: true, using: :btree add_index "keys", ["user_id"], name: "index_keys_on_user_id", using: :btree create_table "label_links", force: :cascade do |t| - t.integer "label_id" - t.integer "target_id" - t.string "target_type" + t.integer "label_id" + t.integer "target_id" + t.string "target_type" t.datetime "created_at" t.datetime "updated_at" end @@ -494,33 +544,46 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "label_links", ["label_id"], name: "index_label_links_on_label_id", using: :btree add_index "label_links", ["target_id", "target_type"], name: "index_label_links_on_target_id_and_target_type", using: :btree + create_table "label_priorities", force: :cascade do |t| + t.integer "project_id", null: false + t.integer "label_id", null: false + t.integer "priority", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "label_priorities", ["priority"], name: "index_label_priorities_on_priority", using: :btree + add_index "label_priorities", ["project_id", "label_id"], name: "index_label_priorities_on_project_id_and_label_id", unique: true, using: :btree + create_table "labels", force: :cascade do |t| - t.string "title" - t.string "color" - t.integer "project_id" + t.string "title" + t.string "color" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.boolean "template", default: false - t.string "description" - t.integer "priority" + t.boolean "template", default: false + t.string "description" + t.text "description_html" + t.string "type" + t.integer "group_id" end - add_index "labels", ["priority"], name: "index_labels_on_priority", using: :btree - add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree + add_index "labels", ["group_id", "project_id", "title"], name: "index_labels_on_group_id_and_project_id_and_title", unique: true, using: :btree + add_index "labels", ["group_id"], name: "index_labels_on_group_id", using: :btree create_table "lfs_objects", force: :cascade do |t| - t.string "oid", null: false - t.integer "size", limit: 8, null: false + t.string "oid", null: false + t.integer "size", limit: 8, null: false t.datetime "created_at" t.datetime "updated_at" - t.string "file" + t.string "file" end add_index "lfs_objects", ["oid"], name: "index_lfs_objects_on_oid", unique: true, using: :btree create_table "lfs_objects_projects", force: :cascade do |t| - t.integer "lfs_object_id", null: false - t.integer "project_id", null: false + t.integer "lfs_object_id", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -528,12 +591,12 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "lfs_objects_projects", ["project_id"], name: "index_lfs_objects_projects_on_project_id", using: :btree create_table "lists", force: :cascade do |t| - t.integer "board_id", null: false - t.integer "label_id" - t.integer "list_type", default: 1, null: false - t.integer "position" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "board_id", null: false + t.integer "label_id" + t.integer "list_type", default: 1, null: false + t.integer "position" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "lists", ["board_id", "label_id"], name: "index_lists_on_board_id_and_label_id", unique: true, using: :btree @@ -541,20 +604,20 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "lists", ["label_id"], name: "index_lists_on_label_id", using: :btree create_table "members", force: :cascade do |t| - t.integer "access_level", null: false - t.integer "source_id", null: false - t.string "source_type", null: false - t.integer "user_id" - t.integer "notification_level", null: false - t.string "type" + t.integer "access_level", null: false + t.integer "source_id", null: false + t.string "source_type", null: false + t.integer "user_id" + t.integer "notification_level", null: false + t.string "type" t.datetime "created_at" t.datetime "updated_at" - t.integer "created_by_id" - t.string "invite_email" - t.string "invite_token" + t.integer "created_by_id" + t.string "invite_email" + t.string "invite_token" t.datetime "invite_accepted_at" t.datetime "requested_at" - t.date "expires_at" + t.date "expires_at" end add_index "members", ["access_level"], name: "index_members_on_access_level", using: :btree @@ -564,46 +627,63 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "members", ["user_id"], name: "index_members_on_user_id", using: :btree create_table "merge_request_diffs", force: :cascade do |t| - t.string "state" - t.text "st_commits" - t.text "st_diffs" - t.integer "merge_request_id", null: false + t.string "state" + t.text "st_commits" + t.text "st_diffs" + t.integer "merge_request_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.string "base_commit_sha" - t.string "real_size" - t.string "head_commit_sha" - t.string "start_commit_sha" + t.string "base_commit_sha" + t.string "real_size" + t.string "head_commit_sha" + t.string "start_commit_sha" end add_index "merge_request_diffs", ["merge_request_id"], name: "index_merge_request_diffs_on_merge_request_id", using: :btree + create_table "merge_request_metrics", force: :cascade do |t| + t.integer "merge_request_id", null: false + t.datetime "latest_build_started_at" + t.datetime "latest_build_finished_at" + t.datetime "first_deployed_to_production_at" + t.datetime "merged_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "pipeline_id" + end + + add_index "merge_request_metrics", ["first_deployed_to_production_at"], name: "index_merge_request_metrics_on_first_deployed_to_production_at", using: :btree + add_index "merge_request_metrics", ["merge_request_id"], name: "index_merge_request_metrics", using: :btree + add_index "merge_request_metrics", ["pipeline_id"], name: "index_merge_request_metrics_on_pipeline_id", using: :btree + create_table "merge_requests", force: :cascade do |t| - t.string "target_branch", null: false - t.string "source_branch", null: false - t.integer "source_project_id", null: false - t.integer "author_id" - t.integer "assignee_id" - t.string "title" + t.string "target_branch", null: false + t.string "source_branch", null: false + t.integer "source_project_id", null: false + t.integer "author_id" + t.integer "assignee_id" + t.string "title" t.datetime "created_at" t.datetime "updated_at" - t.integer "milestone_id" - t.string "state" - t.string "merge_status" - t.integer "target_project_id", null: false - t.integer "iid" - t.text "description" - t.integer "position", default: 0 + t.integer "milestone_id" + t.string "state" + t.string "merge_status" + t.integer "target_project_id", null: false + t.integer "iid" + t.text "description" + t.integer "position", default: 0 t.datetime "locked_at" - t.integer "updated_by_id" - t.text "merge_error" - t.text "merge_params" - t.boolean "merge_when_build_succeeds", default: false, null: false - t.integer "merge_user_id" - t.string "merge_commit_sha" + t.integer "updated_by_id" + t.text "merge_error" + t.text "merge_params" + t.boolean "merge_when_build_succeeds", default: false, null: false + t.integer "merge_user_id" + t.string "merge_commit_sha" t.datetime "deleted_at" - t.string "in_progress_merge_commit_sha" - t.integer "lock_version" + t.string "in_progress_merge_commit_sha" + t.integer "lock_version" + t.text "title_html" + t.text "description_html" end add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree @@ -619,15 +699,28 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "merge_requests", ["title"], name: "index_merge_requests_on_title", using: :btree add_index "merge_requests", ["title"], name: "index_merge_requests_on_title_trigram", using: :gin, opclasses: {"title"=>"gin_trgm_ops"} + create_table "merge_requests_closing_issues", force: :cascade do |t| + t.integer "merge_request_id", null: false + t.integer "issue_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "merge_requests_closing_issues", ["issue_id"], name: "index_merge_requests_closing_issues_on_issue_id", using: :btree + add_index "merge_requests_closing_issues", ["merge_request_id"], name: "index_merge_requests_closing_issues_on_merge_request_id", using: :btree + create_table "milestones", force: :cascade do |t| - t.string "title", null: false - t.integer "project_id", null: false - t.text "description" - t.date "due_date" + t.string "title", null: false + t.integer "project_id", null: false + t.text "description" + t.date "due_date" t.datetime "created_at" t.datetime "updated_at" - t.string "state" - t.integer "iid" + t.string "state" + t.integer "iid" + t.text "title_html" + t.text "description_html" + t.date "start_date" end add_index "milestones", ["description"], name: "index_milestones_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"} @@ -638,19 +731,20 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "milestones", ["title"], name: "index_milestones_on_title_trigram", using: :gin, opclasses: {"title"=>"gin_trgm_ops"} create_table "namespaces", force: :cascade do |t| - t.string "name", null: false - t.string "path", null: false - t.integer "owner_id" + t.string "name", null: false + t.string "path", null: false + t.integer "owner_id" t.datetime "created_at" t.datetime "updated_at" - t.string "type" - t.string "description", default: "", null: false - t.string "avatar" - t.boolean "share_with_group_lock", default: false - t.integer "visibility_level", default: 20, null: false - t.boolean "request_access_enabled", default: true, null: false + t.string "type" + t.string "description", default: "", null: false + t.string "avatar" + t.boolean "share_with_group_lock", default: false + t.integer "visibility_level", default: 20, null: false + t.boolean "request_access_enabled", default: false, null: false t.datetime "deleted_at" - t.boolean "lfs_enabled" + t.boolean "lfs_enabled" + t.text "description_html" end add_index "namespaces", ["created_at"], name: "index_namespaces_on_created_at", using: :btree @@ -663,26 +757,27 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "namespaces", ["type"], name: "index_namespaces_on_type", using: :btree create_table "notes", force: :cascade do |t| - t.text "note" - t.string "noteable_type" - t.integer "author_id" + t.text "note" + t.string "noteable_type" + t.integer "author_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "project_id" - t.string "attachment" - t.string "line_code" - t.string "commit_id" - t.integer "noteable_id" - t.boolean "system", default: false, null: false - t.text "st_diff" - t.integer "updated_by_id" - t.string "type" - t.text "position" - t.text "original_position" + t.integer "project_id" + t.string "attachment" + t.string "line_code" + t.string "commit_id" + t.integer "noteable_id" + t.boolean "system", default: false, null: false + t.text "st_diff" + t.integer "updated_by_id" + t.string "type" + t.text "position" + t.text "original_position" t.datetime "resolved_at" - t.integer "resolved_by_id" - t.string "discussion_id" - t.string "original_discussion_id" + t.integer "resolved_by_id" + t.string "discussion_id" + t.string "original_discussion_id" + t.text "note_html" end add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree @@ -698,13 +793,13 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree create_table "notification_settings", force: :cascade do |t| - t.integer "user_id", null: false - t.integer "source_id" - t.string "source_type" - t.integer "level", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.text "events" + t.integer "user_id", null: false + t.integer "source_id" + t.string "source_type" + t.integer "level", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "events" end add_index "notification_settings", ["source_id", "source_type"], name: "index_notification_settings_on_source_id_and_source_type", using: :btree @@ -712,27 +807,27 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "notification_settings", ["user_id"], name: "index_notification_settings_on_user_id", using: :btree create_table "oauth_access_grants", force: :cascade do |t| - t.integer "resource_owner_id", null: false - t.integer "application_id", null: false - t.string "token", null: false - t.integer "expires_in", null: false - t.text "redirect_uri", null: false - t.datetime "created_at", null: false + t.integer "resource_owner_id", null: false + t.integer "application_id", null: false + t.string "token", null: false + t.integer "expires_in", null: false + t.text "redirect_uri", null: false + t.datetime "created_at", null: false t.datetime "revoked_at" - t.string "scopes" + t.string "scopes" end add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree create_table "oauth_access_tokens", force: :cascade do |t| - t.integer "resource_owner_id" - t.integer "application_id" - t.string "token", null: false - t.string "refresh_token" - t.integer "expires_in" + t.integer "resource_owner_id" + t.integer "application_id" + t.string "token", null: false + t.string "refresh_token" + t.integer "expires_in" t.datetime "revoked_at" - t.datetime "created_at", null: false - t.string "scopes" + t.datetime "created_at", null: false + t.string "scopes" end add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree @@ -740,100 +835,113 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree create_table "oauth_applications", force: :cascade do |t| - t.string "name", null: false - t.string "uid", null: false - t.string "secret", null: false - t.text "redirect_uri", null: false - t.string "scopes", default: "", null: false + t.string "name", null: false + t.string "uid", null: false + t.string "secret", null: false + t.text "redirect_uri", null: false + t.string "scopes", default: "", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "owner_id" - t.string "owner_type" + t.integer "owner_id" + t.string "owner_type" end add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree create_table "personal_access_tokens", force: :cascade do |t| - t.integer "user_id", null: false - t.string "token", null: false - t.string "name", null: false - t.boolean "revoked", default: false + t.integer "user_id", null: false + t.string "token", null: false + t.string "name", null: false + t.boolean "revoked", default: false t.datetime "expires_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "personal_access_tokens", ["token"], name: "index_personal_access_tokens_on_token", unique: true, using: :btree add_index "personal_access_tokens", ["user_id"], name: "index_personal_access_tokens_on_user_id", using: :btree + create_table "project_authorizations", force: :cascade do |t| + t.integer "user_id" + t.integer "project_id" + t.integer "access_level" + end + + add_index "project_authorizations", ["user_id", "project_id", "access_level"], name: "index_project_authorizations_on_user_id_project_id_access_level", unique: true, using: :btree + create_table "project_features", force: :cascade do |t| - t.integer "project_id" - t.integer "merge_requests_access_level" - t.integer "issues_access_level" - t.integer "wiki_access_level" - t.integer "snippets_access_level" - t.integer "builds_access_level" + t.integer "project_id" + t.integer "merge_requests_access_level" + t.integer "issues_access_level" + t.integer "wiki_access_level" + t.integer "snippets_access_level" + t.integer "builds_access_level" t.datetime "created_at" t.datetime "updated_at" + t.integer "repository_access_level", default: 20, null: false end add_index "project_features", ["project_id"], name: "index_project_features_on_project_id", using: :btree create_table "project_group_links", force: :cascade do |t| - t.integer "project_id", null: false - t.integer "group_id", null: false + t.integer "project_id", null: false + t.integer "group_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "group_access", default: 30, null: false - t.date "expires_at" + t.integer "group_access", default: 30, null: false + t.date "expires_at" end create_table "project_import_data", force: :cascade do |t| t.integer "project_id" - t.text "data" - t.text "encrypted_credentials" - t.string "encrypted_credentials_iv" - t.string "encrypted_credentials_salt" + t.text "data" + t.text "encrypted_credentials" + t.string "encrypted_credentials_iv" + t.string "encrypted_credentials_salt" end + add_index "project_import_data", ["project_id"], name: "index_project_import_data_on_project_id", using: :btree + create_table "projects", force: :cascade do |t| - t.string "name" - t.string "path" - t.text "description" + t.string "name" + t.string "path" + t.text "description" t.datetime "created_at" t.datetime "updated_at" - t.integer "creator_id" - t.integer "namespace_id" + t.integer "creator_id" + t.integer "namespace_id" t.datetime "last_activity_at" - t.string "import_url" - t.integer "visibility_level", default: 0, null: false - t.boolean "archived", default: false, null: false - t.string "avatar" - t.string "import_status" - t.float "repository_size", default: 0.0 - t.integer "star_count", default: 0, null: false - t.string "import_type" - t.string "import_source" - t.integer "commit_count", default: 0 - t.text "import_error" - t.integer "ci_id" - t.boolean "shared_runners_enabled", default: true, null: false - t.string "runners_token" - t.string "build_coverage_regex" - t.boolean "build_allow_git_fetch", default: true, null: false - t.integer "build_timeout", default: 3600, null: false - t.boolean "pending_delete", default: false - t.boolean "public_builds", default: true, null: false - t.boolean "last_repository_check_failed" + t.string "import_url" + t.integer "visibility_level", default: 0, null: false + t.boolean "archived", default: false, null: false + t.string "avatar" + t.string "import_status" + t.float "repository_size", default: 0.0 + t.integer "star_count", default: 0, null: false + t.string "import_type" + t.string "import_source" + t.integer "commit_count", default: 0 + t.text "import_error" + t.integer "ci_id" + t.boolean "shared_runners_enabled", default: true, null: false + t.string "runners_token" + t.string "build_coverage_regex" + t.boolean "build_allow_git_fetch", default: true, null: false + t.integer "build_timeout", default: 3600, null: false + t.boolean "pending_delete", default: false + t.boolean "public_builds", default: true, null: false + t.boolean "last_repository_check_failed" t.datetime "last_repository_check_at" - t.boolean "container_registry_enabled" - t.boolean "only_allow_merge_if_build_succeeds", default: false, null: false - t.boolean "has_external_issue_tracker" - t.string "repository_storage", default: "default", null: false - t.boolean "request_access_enabled", default: true, null: false - t.boolean "has_external_wiki" - t.boolean "lfs_enabled" + t.boolean "container_registry_enabled" + t.boolean "only_allow_merge_if_build_succeeds", default: false, null: false + t.boolean "has_external_issue_tracker" + t.string "repository_storage", default: "default", null: false + t.boolean "request_access_enabled", default: false, null: false + t.boolean "has_external_wiki" + t.boolean "lfs_enabled" + t.text "description_html" + t.boolean "only_allow_merge_if_all_discussions_are_resolved" end add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree @@ -852,26 +960,26 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "projects", ["visibility_level"], name: "index_projects_on_visibility_level", using: :btree create_table "protected_branch_merge_access_levels", force: :cascade do |t| - t.integer "protected_branch_id", null: false - t.integer "access_level", default: 40, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "protected_branch_id", null: false + t.integer "access_level", default: 40, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "protected_branch_merge_access_levels", ["protected_branch_id"], name: "index_protected_branch_merge_access", using: :btree create_table "protected_branch_push_access_levels", force: :cascade do |t| - t.integer "protected_branch_id", null: false - t.integer "access_level", default: 40, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "protected_branch_id", null: false + t.integer "access_level", default: 40, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "protected_branch_push_access_levels", ["protected_branch_id"], name: "index_protected_branch_push_access", using: :btree create_table "protected_branches", force: :cascade do |t| - t.integer "project_id", null: false - t.string "name", null: false + t.integer "project_id", null: false + t.string "name", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -879,11 +987,12 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree create_table "releases", force: :cascade do |t| - t.string "tag" - t.text "description" - t.integer "project_id" + t.string "tag" + t.text "description" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" + t.text "description_html" end add_index "releases", ["project_id", "tag"], name: "index_releases_on_project_id_and_tag", using: :btree @@ -892,52 +1001,55 @@ ActiveRecord::Schema.define(version: 20160913162434) do create_table "sent_notifications", force: :cascade do |t| t.integer "project_id" t.integer "noteable_id" - t.string "noteable_type" + t.string "noteable_type" t.integer "recipient_id" - t.string "commit_id" - t.string "reply_key", null: false - t.string "line_code" - t.string "note_type" - t.text "position" + t.string "commit_id" + t.string "reply_key", null: false + t.string "line_code" + t.string "note_type" + t.text "position" end add_index "sent_notifications", ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true, using: :btree create_table "services", force: :cascade do |t| - t.string "type" - t.string "title" - t.integer "project_id" + t.string "type" + t.string "title" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.boolean "active", default: false, null: false - t.text "properties" - t.boolean "template", default: false - t.boolean "push_events", default: true - t.boolean "issues_events", default: true - t.boolean "merge_requests_events", default: true - t.boolean "tag_push_events", default: true - t.boolean "note_events", default: true, null: false - t.boolean "build_events", default: false, null: false - t.string "category", default: "common", null: false - t.boolean "default", default: false - t.boolean "wiki_page_events", default: true - t.boolean "pipeline_events", default: false, null: false - t.boolean "confidential_issues_events", default: true, null: false + t.boolean "active", default: false, null: false + t.text "properties" + t.boolean "template", default: false + t.boolean "push_events", default: true + t.boolean "issues_events", default: true + t.boolean "merge_requests_events", default: true + t.boolean "tag_push_events", default: true + t.boolean "note_events", default: true, null: false + t.boolean "build_events", default: false, null: false + t.string "category", default: "common", null: false + t.boolean "default", default: false + t.boolean "wiki_page_events", default: true + t.boolean "pipeline_events", default: false, null: false + t.boolean "confidential_issues_events", default: true, null: false + t.boolean "commit_events", default: true, null: false end add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree add_index "services", ["template"], name: "index_services_on_template", using: :btree create_table "snippets", force: :cascade do |t| - t.string "title" - t.text "content" - t.integer "author_id", null: false - t.integer "project_id" + t.string "title" + t.text "content" + t.integer "author_id", null: false + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.string "file_name" - t.string "type" - t.integer "visibility_level", default: 0, null: false + t.string "file_name" + t.string "type" + t.integer "visibility_level", default: 0, null: false + t.text "title_html" + t.text "content_html" end add_index "snippets", ["author_id"], name: "index_snippets_on_author_id", using: :btree @@ -948,36 +1060,37 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "snippets", ["visibility_level"], name: "index_snippets_on_visibility_level", using: :btree create_table "spam_logs", force: :cascade do |t| - t.integer "user_id" - t.string "source_ip" - t.string "user_agent" - t.boolean "via_api" - t.string "noteable_type" - t.string "title" - t.text "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.boolean "submitted_as_ham", default: false, null: false + t.integer "user_id" + t.string "source_ip" + t.string "user_agent" + t.boolean "via_api" + t.string "noteable_type" + t.string "title" + t.text "description" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "submitted_as_ham", default: false, null: false end create_table "subscriptions", force: :cascade do |t| - t.integer "user_id" - t.integer "subscribable_id" - t.string "subscribable_type" - t.boolean "subscribed" + t.integer "user_id" + t.integer "subscribable_id" + t.string "subscribable_type" + t.boolean "subscribed" t.datetime "created_at" t.datetime "updated_at" + t.integer "project_id" end - add_index "subscriptions", ["subscribable_id", "subscribable_type", "user_id"], name: "subscriptions_user_id_and_ref_fields", unique: true, using: :btree + add_index "subscriptions", ["subscribable_id", "subscribable_type", "user_id", "project_id"], name: "index_subscriptions_on_subscribable_and_user_id_and_project_id", unique: true, using: :btree create_table "taggings", force: :cascade do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context" + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context" t.datetime "created_at" end @@ -985,24 +1098,24 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree create_table "tags", force: :cascade do |t| - t.string "name" + t.string "name" t.integer "taggings_count", default: 0 end add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree create_table "todos", force: :cascade do |t| - t.integer "user_id", null: false - t.integer "project_id", null: false - t.integer "target_id" - t.string "target_type", null: false - t.integer "author_id" - t.integer "action", null: false - t.string "state", null: false + t.integer "user_id", null: false + t.integer "project_id", null: false + t.integer "target_id" + t.string "target_type", null: false + t.integer "author_id" + t.integer "action", null: false + t.string "state", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "note_id" - t.string "commit_id" + t.integer "note_id" + t.string "commit_id" end add_index "todos", ["author_id"], name: "index_todos_on_author_id", using: :btree @@ -1012,88 +1125,97 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "todos", ["target_type", "target_id"], name: "index_todos_on_target_type_and_target_id", using: :btree add_index "todos", ["user_id"], name: "index_todos_on_user_id", using: :btree + create_table "trending_projects", force: :cascade do |t| + t.integer "project_id", null: false + end + + add_index "trending_projects", ["project_id"], name: "index_trending_projects_on_project_id", using: :btree + create_table "u2f_registrations", force: :cascade do |t| - t.text "certificate" - t.string "key_handle" - t.string "public_key" - t.integer "counter" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" + t.text "certificate" + t.string "key_handle" + t.string "public_key" + t.integer "counter" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" end add_index "u2f_registrations", ["key_handle"], name: "index_u2f_registrations_on_key_handle", using: :btree add_index "u2f_registrations", ["user_id"], name: "index_u2f_registrations_on_user_id", using: :btree create_table "user_agent_details", force: :cascade do |t| - t.string "user_agent", null: false - t.string "ip_address", null: false - t.integer "subject_id", null: false - t.string "subject_type", null: false - t.boolean "submitted", default: false, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "user_agent", null: false + t.string "ip_address", null: false + t.integer "subject_id", null: false + t.string "subject_type", null: false + t.boolean "submitted", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "users", force: :cascade do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false + t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" t.datetime "created_at" t.datetime "updated_at" - t.string "name" - t.boolean "admin", default: false, null: false - t.integer "projects_limit", default: 10 - t.string "skype", default: "", null: false - t.string "linkedin", default: "", null: false - t.string "twitter", default: "", null: false - t.string "authentication_token" - t.integer "theme_id", default: 1, null: false - t.string "bio" - t.integer "failed_attempts", default: 0 + t.string "name" + t.boolean "admin", default: false, null: false + t.integer "projects_limit", default: 10 + t.string "skype", default: "", null: false + t.string "linkedin", default: "", null: false + t.string "twitter", default: "", null: false + t.string "authentication_token" + t.integer "theme_id", default: 1, null: false + t.string "bio" + t.integer "failed_attempts", default: 0 t.datetime "locked_at" - t.string "username" - t.boolean "can_create_group", default: true, null: false - t.boolean "can_create_team", default: true, null: false - t.string "state" - t.integer "color_scheme_id", default: 1, null: false + t.string "username" + t.boolean "can_create_group", default: true, null: false + t.boolean "can_create_team", default: true, null: false + t.string "state" + t.integer "color_scheme_id", default: 1, null: false t.datetime "password_expires_at" - t.integer "created_by_id" + t.integer "created_by_id" t.datetime "last_credential_check_at" - t.string "avatar" - t.string "confirmation_token" + t.string "avatar" + t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" - t.string "unconfirmed_email" - t.boolean "hide_no_ssh_key", default: false - t.string "website_url", default: "", null: false - t.string "notification_email" - t.boolean "hide_no_password", default: false - t.boolean "password_automatically_set", default: false - t.string "location" - t.string "encrypted_otp_secret" - t.string "encrypted_otp_secret_iv" - t.string "encrypted_otp_secret_salt" - t.boolean "otp_required_for_login", default: false, null: false - t.text "otp_backup_codes" - t.string "public_email", default: "", null: false - t.integer "dashboard", default: 0 - t.integer "project_view", default: 0 - t.integer "consumed_timestep" - t.integer "layout", default: 0 - t.boolean "hide_project_limit", default: false - t.string "unlock_token" + t.string "unconfirmed_email" + t.boolean "hide_no_ssh_key", default: false + t.string "website_url", default: "", null: false + t.string "notification_email" + t.boolean "hide_no_password", default: false + t.boolean "password_automatically_set", default: false + t.string "location" + t.string "encrypted_otp_secret" + t.string "encrypted_otp_secret_iv" + t.string "encrypted_otp_secret_salt" + t.boolean "otp_required_for_login", default: false, null: false + t.text "otp_backup_codes" + t.string "public_email", default: "", null: false + t.integer "dashboard", default: 0 + t.integer "project_view", default: 0 + t.integer "consumed_timestep" + t.integer "layout", default: 0 + t.boolean "hide_project_limit", default: false + t.string "unlock_token" t.datetime "otp_grace_period_started_at" - t.boolean "ldap_email", default: false, null: false - t.boolean "external", default: false + t.boolean "ldap_email", default: false, null: false + t.boolean "external", default: false + t.string "organization" + t.string "incoming_email_token" + t.boolean "authorized_projects_populated" end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree @@ -1103,6 +1225,7 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "users", ["current_sign_in_at"], name: "index_users_on_current_sign_in_at", using: :btree add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree add_index "users", ["email"], name: "index_users_on_email_trigram", using: :gin, opclasses: {"email"=>"gin_trgm_ops"} + add_index "users", ["incoming_email_token"], name: "index_users_on_incoming_email_token", using: :btree add_index "users", ["name"], name: "index_users_on_name", using: :btree add_index "users", ["name"], name: "index_users_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"} add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree @@ -1111,8 +1234,8 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "users", ["username"], name: "index_users_on_username_trigram", using: :gin, opclasses: {"username"=>"gin_trgm_ops"} create_table "users_star_projects", force: :cascade do |t| - t.integer "project_id", null: false - t.integer "user_id", null: false + t.integer "project_id", null: false + t.integer "user_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -1122,32 +1245,44 @@ ActiveRecord::Schema.define(version: 20160913162434) do add_index "users_star_projects", ["user_id"], name: "index_users_star_projects_on_user_id", using: :btree create_table "web_hooks", force: :cascade do |t| - t.string "url", limit: 2000 - t.integer "project_id" + t.string "url", limit: 2000 + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.string "type", default: "ProjectHook" - t.integer "service_id" - t.boolean "push_events", default: true, null: false - t.boolean "issues_events", default: false, null: false - t.boolean "merge_requests_events", default: false, null: false - t.boolean "tag_push_events", default: false - t.boolean "note_events", default: false, null: false - t.boolean "enable_ssl_verification", default: true - t.boolean "build_events", default: false, null: false - t.boolean "wiki_page_events", default: false, null: false - t.string "token" - t.boolean "pipeline_events", default: false, null: false - t.boolean "confidential_issues_events", default: false, null: false + t.string "type", default: "ProjectHook" + t.integer "service_id" + t.boolean "push_events", default: true, null: false + t.boolean "issues_events", default: false, null: false + t.boolean "merge_requests_events", default: false, null: false + t.boolean "tag_push_events", default: false + t.boolean "note_events", default: false, null: false + t.boolean "enable_ssl_verification", default: true + t.boolean "build_events", default: false, null: false + t.boolean "wiki_page_events", default: false, null: false + t.string "token" + t.boolean "pipeline_events", default: false, null: false + t.boolean "confidential_issues_events", default: false, null: false end add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree add_foreign_key "boards", "projects" + add_foreign_key "issue_metrics", "issues", on_delete: :cascade + add_foreign_key "label_priorities", "labels", on_delete: :cascade + add_foreign_key "label_priorities", "projects", on_delete: :cascade + add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade add_foreign_key "lists", "boards" add_foreign_key "lists", "labels" + add_foreign_key "merge_request_metrics", "ci_commits", column: "pipeline_id", on_delete: :cascade + add_foreign_key "merge_request_metrics", "merge_requests", on_delete: :cascade + add_foreign_key "merge_requests_closing_issues", "issues", on_delete: :cascade + add_foreign_key "merge_requests_closing_issues", "merge_requests", on_delete: :cascade add_foreign_key "personal_access_tokens", "users" + add_foreign_key "project_authorizations", "projects", on_delete: :cascade + add_foreign_key "project_authorizations", "users", on_delete: :cascade add_foreign_key "protected_branch_merge_access_levels", "protected_branches" add_foreign_key "protected_branch_push_access_levels", "protected_branches" + add_foreign_key "subscriptions", "projects", on_delete: :cascade + add_foreign_key "trending_projects", "projects", on_delete: :cascade add_foreign_key "u2f_registrations", "users" end |