module Parts::PartitionAdapter
Public Instance Methods
attach_child_to(parent_table_name, child_table_name, constraint_clause, lock_timeout: 5)
click to toggle source
# File lib/parts/partition_adapter.rb, line 57 def attach_child_to(parent_table_name, child_table_name, constraint_clause, lock_timeout: 5) execute <<~SQL SET LOCAL lock_timeout TO '#{lock_timeout}s'; ALTER TABLE #{quote_table_name(parent_table_name)} ATTACH PARTITION #{quote_table_name(child_table_name)} FOR VALUES #{constraint_clause}; SQL end
attach_hash_child_to(parent_table_name, child_table_name, modulus:, remainder:, **options)
click to toggle source
# File lib/parts/partition_adapter.rb, line 53 def attach_hash_child_to(parent_table_name, child_table_name, modulus:, remainder:, **options) attach_child_to(parent_table_name, child_table_name, hash_constraint_clause(modulus, remainder), **options) end
attach_list_child_to(parent_table_name, child_table_name, values, **options)
click to toggle source
# File lib/parts/partition_adapter.rb, line 45 def attach_list_child_to(parent_table_name, child_table_name, values, **options) attach_child_to(parent_table_name, child_table_name, list_constraint_clause(values), **options) end
attach_range_child_to(parent_table_name, child_table_name, start_range:, end_range:)
click to toggle source
# File lib/parts/partition_adapter.rb, line 49 def attach_range_child_to(parent_table_name, child_table_name, start_range:, end_range:) attach_child_to(parent_table_name, child_table_name, range_constraint_clause(start_range, end_range), **options) end
create_hash_child_of(parent_table_name, table_name, modulus:, remainder:, **options)
click to toggle source
# File lib/parts/partition_adapter.rb, line 25 def create_hash_child_of(parent_table_name, table_name, modulus:, remainder:, **options) create_child_of(parent_table_name, table_name, hash_constraint_clause(modulus, remainder), **options) end
create_hash_children_of(parent_table_name, total, **options)
click to toggle source
# File lib/parts/partition_adapter.rb, line 29 def create_hash_children_of(parent_table_name, total, **options) raise "'total' must be an Integer" unless total.is_a?(Integer) total.times do |t| create_hash_child_of(parent_table_name, "#{parent_table_name}_#{t}", modulus: total, remainder: t, **options) end end
create_hash_parent(table_name, partition_key, **options, &blk)
click to toggle source
# File lib/parts/partition_adapter.rb, line 13 def create_hash_parent(table_name, partition_key, **options, &blk) create_parent(table_name, :hash, partition_key, options, &blk) end
create_list_child_of(parent_table_name, table_name, values, **options)
click to toggle source
# File lib/parts/partition_adapter.rb, line 21 def create_list_child_of(parent_table_name, table_name, values, **options) create_child_of(parent_table_name, table_name, list_constraint_clause(values), **options) end
create_list_parent(table_name, partition_key, **options, &blk)
click to toggle source
# File lib/parts/partition_adapter.rb, line 9 def create_list_parent(table_name, partition_key, **options, &blk) create_parent(table_name, :list, partition_key, options, &blk) end
create_range_child_of(parent_table_name, table_name, start_range:, end_range:, **options)
click to toggle source
# File lib/parts/partition_adapter.rb, line 17 def create_range_child_of(parent_table_name, table_name, start_range:, end_range:, **options) create_child_of(parent_table_name, table_name, range_constraint_clause(start_range, end_range), **options) end
create_range_parent(table_name, partition_key, **options, &blk)
click to toggle source
# File lib/parts/partition_adapter.rb, line 5 def create_range_parent(table_name, partition_key, **options, &blk) create_parent(table_name, :range, partition_key, options, &blk) end
create_sub_parent(table_name, parent_table_name:, parent_type:, parent_values:, type:, partition_key:, lock_timeout: 5)
click to toggle source
# File lib/parts/partition_adapter.rb, line 66 def create_sub_parent(table_name, parent_table_name:, parent_type:, parent_values:, type:, partition_key:, lock_timeout: 5) # rubocop:disable Metrics/ParameterLists constraint_clause = case parent_type when :list list_constraint_clause(parent_values) when :range range_constraint_clause(parent_values[0], parent_values[1]) when :hash hash_constraint_clause(parent_values[0], parent_values[1]) end execute <<~SQL SET LOCAL lock_timeout TO '#{lock_timeout}s'; CREATE TABLE #{table_name} PARTITION OF #{parent_table_name} FOR VALUES #{constraint_clause} PARTITION BY #{type.to_s.upcase} (#{partition_key}); SQL end
detach_child_from(parent_table_name, child_table_name, lock_timeout: 5)
click to toggle source
# File lib/parts/partition_adapter.rb, line 37 def detach_child_from(parent_table_name, child_table_name, lock_timeout: 5) execute <<~SQL SET LOCAL lock_timeout TO '#{lock_timeout}s'; ALTER TABLE #{quote_table_name(parent_table_name)} DETACH PARTITION #{quote_table_name(child_table_name)}; SQL end
Private Instance Methods
calculate_primary_key(table_name)
click to toggle source
# File lib/parts/partition_adapter.rb, line 107 def calculate_primary_key(table_name) ActiveRecord::Base.get_primary_key(table_name.to_s.singularize).to_sym end
create_child_of(parent_table_name, table_name, constraint_clause, lock_timeout: 5)
click to toggle source
# File lib/parts/partition_adapter.rb, line 100 def create_child_of(parent_table_name, table_name, constraint_clause, lock_timeout: 5) execute <<~SQL SET LOCAL lock_timeout TO '#{lock_timeout}s'; CREATE TABLE #{table_name} PARTITION OF #{parent_table_name} FOR VALUES #{constraint_clause}; SQL end
create_parent(table_name, type, partition_key, options) { |t| ... }
click to toggle source
# File lib/parts/partition_adapter.rb, line 85 def create_parent(table_name, type, partition_key, options) options[:options] = "PARTITION BY #{type.to_s.upcase} (#{quote_partition_key(partition_key)})" id = options.fetch(:id, :bigserial) primary_key = options.fetch(:primary_key) { calculate_primary_key(table_name) } if id != false options[:id] = false validate_primary_key(primary_key) create_table(table_name, **options) do |t| t.column(primary_key, id, null: false) if id != false yield(t) if block_given? end end
hash_constraint_clause(modulus, remainder)
click to toggle source
# File lib/parts/partition_adapter.rb, line 135 def hash_constraint_clause(modulus, remainder) "WITH (MODULUS #{modulus}, REMAINDER #{remainder})" end
list_constraint_clause(values)
click to toggle source
# File lib/parts/partition_adapter.rb, line 131 def list_constraint_clause(values) "IN (#{quote_collection(values)})" end
quote_collection(values)
click to toggle source
# File lib/parts/partition_adapter.rb, line 123 def quote_collection(values) Array.wrap(values).map(&method(:quote)).join(',') end
quote_partition_key(key)
click to toggle source
# File lib/parts/partition_adapter.rb, line 115 def quote_partition_key(key) if key.is_a?(Proc) key.call.to_s else quote_column_name(key) end end
range_constraint_clause(start_range, end_range)
click to toggle source
# File lib/parts/partition_adapter.rb, line 127 def range_constraint_clause(start_range, end_range) "FROM (#{quote_collection(start_range)}) TO (#{quote_collection(end_range)})" end
validate_primary_key(key)
click to toggle source
# File lib/parts/partition_adapter.rb, line 111 def validate_primary_key(key) raise ArgumentError, 'composite primary key not supported' if key.is_a?(Array) end