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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 16:18:24 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 16:18:24 +0300
commit0653e08efd039a5905f3fa4f6e9cef9f5d2f799c (patch)
tree4dcc884cf6d81db44adae4aa99f8ec1233a41f55 /app/models/loose_foreign_keys
parent744144d28e3e7fddc117924fef88de5d9674fe4c (diff)
Add latest changes from gitlab-org/gitlab@14-3-stable-eev14.3.0-rc42
Diffstat (limited to 'app/models/loose_foreign_keys')
-rw-r--r--app/models/loose_foreign_keys/deleted_record.rb49
1 files changed, 49 insertions, 0 deletions
diff --git a/app/models/loose_foreign_keys/deleted_record.rb b/app/models/loose_foreign_keys/deleted_record.rb
new file mode 100644
index 00000000000..a39d88b2e49
--- /dev/null
+++ b/app/models/loose_foreign_keys/deleted_record.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+class LooseForeignKeys::DeletedRecord < ApplicationRecord
+ extend SuppressCompositePrimaryKeyWarning
+ include PartitionedTable
+
+ partitioned_by :created_at, strategy: :monthly, retain_for: 3.months, retain_non_empty_partitions: true
+
+ scope :ordered_by_primary_keys, -> { order(:created_at, :deleted_table_name, :deleted_table_primary_key_value) }
+
+ def self.load_batch(batch_size)
+ ordered_by_primary_keys
+ .limit(batch_size)
+ .to_a
+ end
+
+ # Because the table has composite primary keys, the delete_all or delete methods are not going to work.
+ # This method implements deletion that benefits from the primary key index, example:
+ #
+ # > DELETE
+ # > FROM "loose_foreign_keys_deleted_records"
+ # > WHERE (created_at,
+ # > deleted_table_name,
+ # > deleted_table_primary_key_value) IN
+ # > (SELECT created_at::TIMESTAMP WITH TIME ZONE,
+ # > deleted_table_name,
+ # > deleted_table_primary_key_value
+ # > FROM (VALUES (LIST_OF_VALUES)) AS primary_key_values (created_at, deleted_table_name, deleted_table_primary_key_value))
+ def self.delete_records(records)
+ values = records.pluck(:created_at, :deleted_table_name, :deleted_table_primary_key_value)
+
+ primary_keys = connection.primary_keys(table_name).join(', ')
+
+ primary_keys_with_type_cast = [
+ Arel.sql('created_at::timestamp with time zone'),
+ Arel.sql('deleted_table_name'),
+ Arel.sql('deleted_table_primary_key_value')
+ ]
+
+ value_list = Arel::Nodes::ValuesList.new(values)
+
+ # (SELECT primary keys FROM VALUES)
+ inner_query = Arel::SelectManager.new
+ inner_query.from("#{Arel::Nodes::Grouping.new([value_list]).as('primary_key_values').to_sql} (#{primary_keys})")
+ inner_query.projections = primary_keys_with_type_cast
+
+ where(Arel::Nodes::Grouping.new([Arel.sql(primary_keys)]).in(inner_query)).delete_all
+ end
+end