From 1b14e34b38fb9b26c3737a93c189804464ca88fe Mon Sep 17 00:00:00 2001 From: Javiera Tapia <jtapia@gitlab.com> Date: Wed, 19 Jun 2024 22:54:22 +0000 Subject: [PATCH] Extend organization to snippets table This commit extends the snippets table adding the organization_id column to support Cells 1.0. It also provides an index to the organization_id column and the corresponding associations in models. Changelog: added --- app/models/organizations/organization.rb | 1 + app/models/snippet.rb | 1 + config/gitlab_loose_foreign_keys.yml | 4 ++++ ...06124806_add_organization_id_to_snippets.rb | 13 +++++++++++++ ...dd_index_for_organization_id_on_snippets.rb | 18 ++++++++++++++++++ db/schema_migrations/20240606124806 | 1 + db/schema_migrations/20240613214355 | 1 + db/structure.sql | 5 ++++- spec/db/schema_spec.rb | 3 ++- spec/lib/gitlab/import_export/all_models.yml | 1 + spec/models/organizations/organization_spec.rb | 1 + spec/models/snippet_spec.rb | 10 ++++++++++ 12 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20240606124806_add_organization_id_to_snippets.rb create mode 100644 db/post_migrate/20240613214355_add_index_for_organization_id_on_snippets.rb create mode 100644 db/schema_migrations/20240606124806 create mode 100644 db/schema_migrations/20240613214355 diff --git a/app/models/organizations/organization.rb b/app/models/organizations/organization.rb index be8b97be6ca15..90c172e3c0455 100644 --- a/app/models/organizations/organization.rb +++ b/app/models/organizations/organization.rb @@ -15,6 +15,7 @@ class Organization < MainClusterwide::ApplicationRecord has_many :namespaces has_many :groups has_many :projects + has_many :snippets has_one :settings, class_name: "OrganizationSetting" has_one :organization_detail, inverse_of: :organization, autosave: true diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 799303e013991..c8858a7e1e660 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -47,6 +47,7 @@ def content_html_invalidated? belongs_to :author, class_name: 'User' belongs_to :project + belongs_to :organization, class_name: 'Organizations::Organization' alias_method :resource_parent, :project has_many :notes, as: :noteable, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent diff --git a/config/gitlab_loose_foreign_keys.yml b/config/gitlab_loose_foreign_keys.yml index 44c8878a4747f..7b545f01800d7 100644 --- a/config/gitlab_loose_foreign_keys.yml +++ b/config/gitlab_loose_foreign_keys.yml @@ -389,6 +389,10 @@ security_scans: - table: p_ci_builds column: build_id on_delete: async_delete +snippets: + - table: organizations + column: organization_id + on_delete: async_nullify terraform_state_versions: - table: ci_builds column: ci_build_id diff --git a/db/migrate/20240606124806_add_organization_id_to_snippets.rb b/db/migrate/20240606124806_add_organization_id_to_snippets.rb new file mode 100644 index 0000000000000..e781036c95a86 --- /dev/null +++ b/db/migrate/20240606124806_add_organization_id_to_snippets.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class AddOrganizationIdToSnippets < Gitlab::Database::Migration[2.2] + DEFAULT_ORGANIZATION_ID = 1 + + milestone '17.2' + + enable_lock_retries! + + def change + add_column :snippets, :organization_id, :bigint, default: DEFAULT_ORGANIZATION_ID, null: true + end +end diff --git a/db/post_migrate/20240613214355_add_index_for_organization_id_on_snippets.rb b/db/post_migrate/20240613214355_add_index_for_organization_id_on_snippets.rb new file mode 100644 index 0000000000000..927f2b06d5c32 --- /dev/null +++ b/db/post_migrate/20240613214355_add_index_for_organization_id_on_snippets.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class AddIndexForOrganizationIdOnSnippets < Gitlab::Database::Migration[2.2] + milestone '17.2' + + disable_ddl_transaction! + + TABLE_NAME = :snippets + INDEX_NAME = 'index_snippets_on_organization_id' + + def up + add_concurrent_index TABLE_NAME, :organization_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME + end +end diff --git a/db/schema_migrations/20240606124806 b/db/schema_migrations/20240606124806 new file mode 100644 index 0000000000000..dc37ec0fc24b5 --- /dev/null +++ b/db/schema_migrations/20240606124806 @@ -0,0 +1 @@ +73631774f68f3d4012b413d549458316c70e5828b83b387d77329249fa661514 \ No newline at end of file diff --git a/db/schema_migrations/20240613214355 b/db/schema_migrations/20240613214355 new file mode 100644 index 0000000000000..de48c74bd1b61 --- /dev/null +++ b/db/schema_migrations/20240613214355 @@ -0,0 +1 @@ +5eaea04d560ff1d1a5c604aba0f847edfc03cafb0b8b9103677e1061608109a8 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index f7a6a01befcf1..3121ad08a0c3e 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -17296,7 +17296,8 @@ CREATE TABLE snippets ( secret boolean DEFAULT false NOT NULL, repository_read_only boolean DEFAULT false NOT NULL, imported smallint DEFAULT 0 NOT NULL, - imported_from smallint DEFAULT 0 NOT NULL + imported_from smallint DEFAULT 0 NOT NULL, + organization_id bigint DEFAULT 1 ); CREATE SEQUENCE snippets_id_seq @@ -28618,6 +28619,8 @@ CREATE INDEX index_snippets_on_id_and_created_at ON snippets USING btree (id, cr CREATE INDEX index_snippets_on_id_and_type ON snippets USING btree (id, type); +CREATE INDEX index_snippets_on_organization_id ON snippets USING btree (organization_id); + CREATE INDEX index_snippets_on_project_id_and_title ON snippets USING btree (project_id, title); CREATE INDEX index_snippets_on_project_id_and_visibility_level ON snippets USING btree (project_id, visibility_level); diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index 503106eeec1d3..bbc1b5184400d 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -19,7 +19,8 @@ users: [%w[accepted_term_id]], ci_builds: [%w[partition_id stage_id], %w[partition_id execution_config_id]], # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142804#note_1745483081 p_ci_builds: [%w[partition_id stage_id], %w[partition_id execution_config_id]], # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142804#note_1745483081 - ai_testing_terms_acceptances: %w[user_id] # testing terms only have 1 entry, and if the user is deleted the record should remain + ai_testing_terms_acceptances: %w[user_id], # testing terms only have 1 entry, and if the user is deleted the record should remain + snippets: %w[organization_id] # this index is added in an async manner, hence it needs to be ignored in the first phase. }.with_indifferent_access.freeze TABLE_PARTITIONS = %w[ci_builds_metadata].freeze diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 4749d88430566..7edeeeb25909c 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -165,6 +165,7 @@ snippets: - snippet_repository - statistics - repository_storage_moves +- organization releases: - author - project diff --git a/spec/models/organizations/organization_spec.rb b/spec/models/organizations/organization_spec.rb index 868fd2cc58359..a0eab9852315f 100644 --- a/spec/models/organizations/organization_spec.rb +++ b/spec/models/organizations/organization_spec.rb @@ -14,6 +14,7 @@ it { is_expected.to have_many(:users).through(:organization_users).inverse_of(:organizations) } it { is_expected.to have_many(:organization_users).inverse_of(:organization) } it { is_expected.to have_many :projects } + it { is_expected.to have_many :snippets } end describe 'validations' do diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index 96dba4f18592c..fcb6fe8b1dddf 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -16,6 +16,7 @@ end describe 'associations' do + it { is_expected.to belong_to(:organization) } it { is_expected.to belong_to(:author).class_name('User') } it { is_expected.to belong_to(:project) } it { is_expected.to have_many(:notes).dependent(:destroy) } @@ -515,6 +516,15 @@ it { is_expected.to match_array(snippet) } end + describe 'with loose foreign keys' do + context 'on organization_id' do + it_behaves_like 'cleanup by a loose foreign key' do + let_it_be(:parent) { create(:organization) } + let_it_be(:model) { create(:snippet, organization: parent) } + end + end + end + describe '#participants' do let_it_be(:project) { create(:project, :public) } let_it_be(:snippet) { create(:snippet, content: 'foo', project: project) } -- GitLab