Class: PgParty::AdapterDecorator
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- PgParty::AdapterDecorator
- Defined in:
- lib/pg_party/adapter_decorator.rb
Constant Summary collapse
- SUPPORTED_PARTITION_TYPES =
%i[range list hash].freeze
Instance Method Summary collapse
- #add_index_on_all_partitions(table_name, column_name, in_threads: nil, **options) ⇒ Object
- #attach_default_partition(parent_table_name, child_table_name) ⇒ Object
- #attach_hash_partition(parent_table_name, child_table_name, modulus:, remainder:) ⇒ Object
- #attach_list_partition(parent_table_name, child_table_name, values:) ⇒ Object
- #attach_range_partition(parent_table_name, child_table_name, start_range:, end_range:) ⇒ Object
- #create_default_partition_of(table_name, **options) ⇒ Object
- #create_hash_partition(table_name, partition_key:, **options, &blk) ⇒ Object
- #create_hash_partition_of(table_name, modulus:, remainder:, **options) ⇒ Object
- #create_list_partition(table_name, partition_key:, **options, &blk) ⇒ Object
- #create_list_partition_of(table_name, values:, **options) ⇒ Object
- #create_range_partition(table_name, partition_key:, **options, &blk) ⇒ Object
- #create_range_partition_of(table_name, start_range:, end_range:, **options) ⇒ Object
- #create_table_like(table_name, new_table_name, **options) ⇒ Object
- #detach_partition(parent_table_name, child_table_name) ⇒ Object
-
#initialize(adapter) ⇒ AdapterDecorator
constructor
A new instance of AdapterDecorator.
- #parent_for_table_name(table_name, traverse: false) ⇒ Object
- #partitions_for_table_name(table_name, include_subpartitions:, _accumulator: []) ⇒ Object
- #table_partitioned?(table_name) ⇒ Boolean
Constructor Details
#initialize(adapter) ⇒ AdapterDecorator
Returns a new instance of AdapterDecorator.
10 11 12 13 14 |
# File 'lib/pg_party/adapter_decorator.rb', line 10 def initialize(adapter) super(adapter) raise "Partitioning only supported in PostgreSQL >= 10.0" unless supports_partitions? end |
Instance Method Details
#add_index_on_all_partitions(table_name, column_name, in_threads: nil, **options) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/pg_party/adapter_decorator.rb', line 146 def add_index_on_all_partitions(table_name, column_name, in_threads: nil, **) if in_threads && open_transactions > 0 raise ArgumentError, '`in_threads:` cannot be used within a transaction. If running in a migration, use '\ '`disable_ddl_transaction!` and break out this operation into its own migration.' end index_name, index_type, index_columns, , algorithm, using = ( table_name, column_name, ) # Postgres limits index name to 63 bytes (characters). We will use 8 characters for a `_random_suffix` # on partitions to ensure no conflicts, leaving 55 chars for the specified index name raise ArgumentError 'index name is too long - must be 55 characters or fewer' if index_name.length > 55 recursive_add_index( table_name: table_name, index_name: index_name, index_type: index_type, index_columns: index_columns, index_options: , algorithm: algorithm, using: using, in_threads: in_threads ) end |
#attach_default_partition(parent_table_name, child_table_name) ⇒ Object
93 94 95 96 97 98 99 100 101 |
# File 'lib/pg_party/adapter_decorator.rb', line 93 def attach_default_partition(parent_table_name, child_table_name) execute(<<-SQL) ALTER TABLE #{quote_table_name(parent_table_name)} ATTACH PARTITION #{quote_table_name(child_table_name)} DEFAULT SQL PgParty.cache.clear! end |
#attach_hash_partition(parent_table_name, child_table_name, modulus:, remainder:) ⇒ Object
89 90 91 |
# File 'lib/pg_party/adapter_decorator.rb', line 89 def attach_hash_partition(parent_table_name, child_table_name, modulus:, remainder:) attach_partition(parent_table_name, child_table_name, hash_constraint_clause(modulus, remainder)) end |
#attach_list_partition(parent_table_name, child_table_name, values:) ⇒ Object
85 86 87 |
# File 'lib/pg_party/adapter_decorator.rb', line 85 def attach_list_partition(parent_table_name, child_table_name, values:) attach_partition(parent_table_name, child_table_name, list_constraint_clause(values)) end |
#attach_range_partition(parent_table_name, child_table_name, start_range:, end_range:) ⇒ Object
81 82 83 |
# File 'lib/pg_party/adapter_decorator.rb', line 81 def attach_range_partition(parent_table_name, child_table_name, start_range:, end_range:) attach_partition(parent_table_name, child_table_name, range_constraint_clause(start_range, end_range)) end |
#create_default_partition_of(table_name, **options) ⇒ Object
40 41 42 |
# File 'lib/pg_party/adapter_decorator.rb', line 40 def create_default_partition_of(table_name, **) create_partition_of(table_name, nil, default_partition: true, **) end |
#create_hash_partition(table_name, partition_key:, **options, &blk) ⇒ Object
24 25 26 |
# File 'lib/pg_party/adapter_decorator.rb', line 24 def create_hash_partition(table_name, partition_key:, **, &blk) create_partition(table_name, :hash, partition_key, **, &blk) end |
#create_hash_partition_of(table_name, modulus:, remainder:, **options) ⇒ Object
36 37 38 |
# File 'lib/pg_party/adapter_decorator.rb', line 36 def create_hash_partition_of(table_name, modulus:, remainder:, **) create_partition_of(table_name, hash_constraint_clause(modulus, remainder), **) end |
#create_list_partition(table_name, partition_key:, **options, &blk) ⇒ Object
20 21 22 |
# File 'lib/pg_party/adapter_decorator.rb', line 20 def create_list_partition(table_name, partition_key:, **, &blk) create_partition(table_name, :list, partition_key, **, &blk) end |
#create_list_partition_of(table_name, values:, **options) ⇒ Object
32 33 34 |
# File 'lib/pg_party/adapter_decorator.rb', line 32 def create_list_partition_of(table_name, values:, **) create_partition_of(table_name, list_constraint_clause(values), **) end |
#create_range_partition(table_name, partition_key:, **options, &blk) ⇒ Object
16 17 18 |
# File 'lib/pg_party/adapter_decorator.rb', line 16 def create_range_partition(table_name, partition_key:, **, &blk) create_partition(table_name, :range, partition_key, **, &blk) end |
#create_range_partition_of(table_name, start_range:, end_range:, **options) ⇒ Object
28 29 30 |
# File 'lib/pg_party/adapter_decorator.rb', line 28 def create_range_partition_of(table_name, start_range:, end_range:, **) create_partition_of(table_name, range_constraint_clause(start_range, end_range), **) end |
#create_table_like(table_name, new_table_name, **options) ⇒ 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 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/pg_party/adapter_decorator.rb', line 44 def create_table_like(table_name, new_table_name, **) primary_key = .fetch(:primary_key) { calculate_primary_key(table_name) } partition_key = .fetch(:partition_key, nil) partition_type = .fetch(:partition_type, nil) create_with_pks = .fetch( :create_with_primary_key, PgParty.config.create_with_primary_key ) validate_primary_key(primary_key) unless create_with_pks if partition_type validate_supported_partition_type!(partition_type) raise ArgumentError, '`partition_key` is required when specifying a partition_type' unless partition_key end like_option = if !partition_type || create_with_pks 'INCLUDING ALL' else 'INCLUDING ALL EXCLUDING INDEXES' end execute(<<-SQL) CREATE TABLE #{quote_table_name(new_table_name)} ( LIKE #{quote_table_name(table_name)} #{like_option} ) #{partition_type ? partition_by_clause(partition_type, partition_key) : nil} SQL return if partition_type return if !primary_key return if has_primary_key?(new_table_name) execute(<<-SQL) ALTER TABLE #{quote_table_name(new_table_name)} ADD PRIMARY KEY (#{quote_column_name(primary_key)}) SQL end |
#detach_partition(parent_table_name, child_table_name) ⇒ Object
103 104 105 106 107 108 109 110 |
# File 'lib/pg_party/adapter_decorator.rb', line 103 def detach_partition(parent_table_name, child_table_name) execute(<<-SQL) ALTER TABLE #{quote_table_name(parent_table_name)} DETACH PARTITION #{quote_table_name(child_table_name)} SQL PgParty.cache.clear! end |
#parent_for_table_name(table_name, traverse: false) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/pg_party/adapter_decorator.rb', line 128 def parent_for_table_name(table_name, traverse: false) parent = select_values(%[ SELECT pg_inherits.inhparent::regclass::text FROM pg_tables INNER JOIN pg_inherits ON pg_tables.tablename::regclass = pg_inherits.inhrelid::regclass WHERE pg_tables.schemaname = current_schema() AND pg_tables.tablename = #{quote(table_name)} ]).first return parent if parent.nil? || !traverse while (parents_parent = parent_for_table_name(parent)) do parent = parents_parent end parent end |
#partitions_for_table_name(table_name, include_subpartitions:, _accumulator: []) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/pg_party/adapter_decorator.rb', line 112 def partitions_for_table_name(table_name, include_subpartitions:, _accumulator: []) select_values(%[ SELECT pg_inherits.inhrelid::regclass::text FROM pg_tables INNER JOIN pg_inherits ON pg_tables.tablename::regclass = pg_inherits.inhparent::regclass WHERE pg_tables.schemaname = current_schema() AND pg_tables.tablename = #{quote(table_name)} ]).each_with_object(_accumulator) do |partition, acc| acc << partition next unless include_subpartitions partitions_for_table_name(partition, include_subpartitions: true, _accumulator: acc) end end |
#table_partitioned?(table_name) ⇒ Boolean
172 173 174 175 176 177 178 |
# File 'lib/pg_party/adapter_decorator.rb', line 172 def table_partitioned?(table_name) select_values(%[ SELECT relkind FROM pg_catalog.pg_class AS c JOIN pg_catalog.pg_namespace AS ns ON c.relnamespace = ns.oid WHERE relname = #{quote(table_name)} AND nspname = current_schema() ]).first == 'p' end |