1# frozen_string_literal: true
2
3module Gitlab
4  module Database
5    module Partitioning
6      class TableWithoutModel
7        include PartitionedTable::ClassMethods
8
9        attr_reader :table_name
10
11        def initialize(table_name:, partitioned_column:, strategy:)
12          @table_name = table_name
13          partitioned_by(partitioned_column, strategy: strategy)
14        end
15
16        def connection
17          Gitlab::Database::SharedModel.connection
18        end
19      end
20
21      class << self
22        def register_models(models)
23          models.each do |model|
24            raise "#{model} should have partitioning strategy defined" unless model.respond_to?(:partitioning_strategy)
25
26            registered_models << model
27          end
28        end
29
30        def register_tables(tables)
31          registered_tables.merge(tables)
32        end
33
34        def sync_partitions_ignore_db_error
35          sync_partitions unless ENV['DISABLE_POSTGRES_PARTITION_CREATION_ON_STARTUP']
36        rescue ActiveRecord::ActiveRecordError, PG::Error
37          # ignore - happens when Rake tasks yet have to create a database, e.g. for testing
38        end
39
40        def sync_partitions(models_to_sync = registered_for_sync)
41          Gitlab::AppLogger.info(message: 'Syncing dynamic postgres partitions')
42
43          Gitlab::Database::EachDatabase.each_model_connection(models_to_sync) do |model|
44            PartitionManager.new(model).sync_partitions
45          end
46
47          Gitlab::AppLogger.info(message: 'Finished sync of dynamic postgres partitions')
48        end
49
50        def report_metrics(models_to_monitor = registered_models)
51          partition_monitoring = PartitionMonitoring.new
52
53          Gitlab::Database::EachDatabase.each_model_connection(models_to_monitor) do |model|
54            partition_monitoring.report_metrics_for_model(model)
55          end
56        end
57
58        def drop_detached_partitions
59          Gitlab::AppLogger.info(message: 'Dropping detached postgres partitions')
60
61          Gitlab::Database::EachDatabase.each_database_connection do
62            DetachedPartitionDropper.new.perform
63          end
64
65          Gitlab::AppLogger.info(message: 'Finished dropping detached postgres partitions')
66        end
67
68        def registered_models
69          @registered_models ||= Set.new
70        end
71
72        def registered_tables
73          @registered_tables ||= Set.new
74        end
75
76        private
77
78        def registered_for_sync
79          registered_models + registered_tables.map do |table|
80            TableWithoutModel.new(**table)
81          end
82        end
83      end
84    end
85  end
86end
87