Module: Legion::Data::PartitionManager
- Defined in:
- lib/legion/data/partition_manager.rb
Constant Summary collapse
- NOT_POSTGRES =
{ skipped: true, reason: 'not_postgres' }.freeze
Class Method Summary collapse
- .drop_old_partitions(table:, retention_months: 24) ⇒ Object
- .ensure_partitions(table:, months_ahead: 3) ⇒ Object
- .list_partitions(table:) ⇒ Object
Class Method Details
.drop_old_partitions(table:, retention_months: 24) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/legion/data/partition_manager.rb', line 44 def drop_old_partitions(table:, retention_months: 24) return NOT_POSTGRES unless postgres? cutoff = advance_months(Date.today, -retention_months) dropped = [] retained = [] partition_names_for(table).each do |part| part_date = parse_partition_date(part) next unless part_date if part_date < cutoff Legion::Data.connection.run("DROP TABLE #{part}") log_info("Dropped partition #{part}") if logging? dropped << part else retained << part end end { dropped: dropped, retained: retained } rescue StandardError => e log_warn("drop_old_partitions failed for #{table}: #{e.}") if logging? { dropped: [], retained: [], error: e. } end |
.ensure_partitions(table:, months_ahead: 3) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/legion/data/partition_manager.rb', line 9 def ensure_partitions(table:, months_ahead: 3) return NOT_POSTGRES unless postgres? created = [] existing = [] base = Date.today months_ahead.times do |i| target = advance_months(base, i) partition = partition_name(table, target) from_str = target.strftime('%Y-%m-%d') to_str = advance_months(target, 1).strftime('%Y-%m-%d') ddl = "CREATE TABLE IF NOT EXISTS #{partition} " \ "PARTITION OF #{table} " \ "FOR VALUES FROM ('#{from_str}') TO ('#{to_str}')" before_count = partition_names_for(table).size Legion::Data.connection.run(ddl) after_count = partition_names_for(table).size if after_count > before_count log_info("Created partition #{partition}") if logging? created << partition else existing << partition end end { created: created, existing: existing } rescue StandardError => e log_warn("ensure_partitions failed for #{table}: #{e.}") if logging? { created: [], existing: [], error: e. } end |
.list_partitions(table:) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/legion/data/partition_manager.rb', line 70 def list_partitions(table:) return NOT_POSTGRES unless postgres? sql = <<~SQL SELECT c.relname AS name, pg_get_expr(c.relpartbound, c.oid) AS bound FROM pg_inherits i JOIN pg_class p ON p.oid = i.inhparent JOIN pg_class c ON c.oid = i.inhrelid WHERE p.relname = '#{table}' ORDER BY c.relname SQL Legion::Data.connection.fetch(sql).map do |row| from_val, to_val = parse_bound(row[:bound]) { name: row[:name], from: from_val, to: to_val } end rescue StandardError => e log_warn("list_partitions failed for #{table}: #{e.}") if logging? [] end |