mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-03 16:04:30 +00:00
92 lines
2.5 KiB
Ruby
92 lines
2.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Database
|
|
module Partitioning
|
|
class IntRangePartition
|
|
include Comparable
|
|
|
|
def self.from_sql(table, partition_name, definition)
|
|
matches = definition.match(/FOR VALUES FROM \('?(?<from>\d+)'?\) TO \('?(?<to>\d+)'?\)/)
|
|
|
|
raise ArgumentError, "Unknown partition definition: #{definition}" unless matches
|
|
|
|
to = matches[:to].to_i
|
|
from = matches[:from].to_i
|
|
|
|
new(table, from, to, partition_name: partition_name)
|
|
end
|
|
|
|
attr_reader :table, :from, :to
|
|
|
|
def initialize(table, from, to, partition_name: nil)
|
|
@table = table.to_s
|
|
@from = from
|
|
@to = to
|
|
@partition_name = partition_name
|
|
|
|
validate!
|
|
end
|
|
|
|
def partition_name
|
|
@partition_name || "#{table}_#{from}"
|
|
end
|
|
|
|
def to_create_sql
|
|
<<~SQL
|
|
CREATE TABLE IF NOT EXISTS #{fully_qualified_partition}
|
|
(LIKE #{conn.quote_table_name(table)} INCLUDING ALL)
|
|
SQL
|
|
end
|
|
|
|
def to_attach_sql
|
|
from_sql = conn.quote(from)
|
|
to_sql = conn.quote(to)
|
|
|
|
<<~SQL
|
|
ALTER TABLE #{conn.quote_table_name(table)}
|
|
ATTACH PARTITION #{fully_qualified_partition}
|
|
FOR VALUES FROM (#{from_sql}) TO (#{to_sql})
|
|
SQL
|
|
end
|
|
|
|
def ==(other)
|
|
table == other.table && partition_name == other.partition_name && from == other.from && to == other.to
|
|
end
|
|
alias_method :eql?, :==
|
|
|
|
def hash
|
|
[table, partition_name, from, to].hash
|
|
end
|
|
|
|
def <=>(other)
|
|
return if table != other.table
|
|
|
|
[from.to_i, to.to_i] <=> [other.from.to_i, other.to.to_i]
|
|
end
|
|
|
|
def holds_data?
|
|
conn.execute("SELECT 1 FROM #{fully_qualified_partition} LIMIT 1").ntuples > 0
|
|
end
|
|
|
|
private
|
|
|
|
def validate!
|
|
raise '`to` statement must be greater than 0' unless to.to_i > 0
|
|
raise '`from` statement must be greater than 0' unless from.to_i > 0
|
|
raise '`to` must be greater than `from`' unless to.to_i > from.to_i
|
|
end
|
|
|
|
def fully_qualified_partition
|
|
format("%s.%s", conn.quote_table_name(Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA),
|
|
conn.quote_table_name(partition_name))
|
|
end
|
|
|
|
def conn
|
|
@conn ||= Gitlab::Database::SharedModel.connection
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|