class PgParty::ModelDecorator

Public Class Methods

allocate() click to toggle source

when returning records from a query, Rails allocates objects first, then initializes

# File lib/pg_party/model_decorator.rb, line 17
def self.allocate
  superclass.allocate
end
name() click to toggle source

to avoid argument errors when calling model_name

# File lib/pg_party/model_decorator.rb, line 11
def self.name
  superclass.name
end
new(*args, &blk) click to toggle source

creating and persisting new records from a child partition will ultimately insert into the parent partition table

# File lib/pg_party/model_decorator.rb, line 23
def self.new(*args, &blk)
  superclass.new(*args, &blk)
end
partitions() click to toggle source

to avoid unnecessary db lookups

# File lib/pg_party/model_decorator.rb, line 28
def self.partitions
  []
end

Public Instance Methods

create_default_partition(**options) click to toggle source
# File lib/pg_party/model_decorator.rb, line 104
def create_default_partition(**options)
  modified_options = options.merge(
    primary_key: primary_key,
  )
  create_partition(:create_default_partition_of, table_name, **modified_options)
end
create_hash_partition(modulus:, remainder:, **options) click to toggle source
# File lib/pg_party/model_decorator.rb, line 94
def create_hash_partition(modulus:, remainder:, **options)
  modified_options = options.merge(
    modulus: modulus,
    remainder: remainder,
    primary_key: primary_key,
  )

  create_partition(:create_hash_partition_of, table_name, **modified_options)
end
create_list_partition(values:, **options) click to toggle source
# File lib/pg_party/model_decorator.rb, line 85
def create_list_partition(values:, **options)
  modified_options = options.merge(
    values: values,
    primary_key: primary_key,
  )

  create_partition(:create_list_partition_of, table_name, **modified_options)
end
create_range_partition(start_range:, end_range:, **options) click to toggle source
# File lib/pg_party/model_decorator.rb, line 75
def create_range_partition(start_range:, end_range:, **options)
  modified_options = options.merge(
    start_range: start_range,
    end_range: end_range,
    primary_key: primary_key,
  )

  create_partition(:create_range_partition_of, table_name, **modified_options)
end
hash_partition_key_in(*values)
in_partition(child_table_name) click to toggle source
# File lib/pg_party/model_decorator.rb, line 5
def in_partition(child_table_name)
  PgParty.cache.fetch_model(cache_key, child_table_name) do
    Class.new(__getobj__) do
      self.table_name = child_table_name

      # to avoid argument errors when calling model_name
      def self.name
        superclass.name
      end

      # when returning records from a query, Rails
      # allocates objects first, then initializes
      def self.allocate
        superclass.allocate
      end

      # creating and persisting new records from a child partition
      # will ultimately insert into the parent partition table
      def self.new(*args, &blk)
        superclass.new(*args, &blk)
      end

      # to avoid unnecessary db lookups
      def self.partitions
        []
      end
    end
  end
end
list_partition_key_in(*values) click to toggle source
# File lib/pg_party/model_decorator.rb, line 57
def list_partition_key_in(*values)
  if complex_partition_key
    complex_partition_key_query("(#{partition_key}) IN (?)", values.flatten)
  else
    where(current_arel_table[partition_key].in(values.flatten))
  end
end
Also aliased as: hash_partition_key_in
partition_key_eq(value) click to toggle source
# File lib/pg_party/model_decorator.rb, line 35
def partition_key_eq(value)
  if complex_partition_key
    complex_partition_key_query("(#{partition_key}) = (?)", value)
  else
    where_partition_key(:eq, value)
  end
end
partitions(include_subpartitions: PgParty.config.include_subpartitions_in_partition_list) click to toggle source
# File lib/pg_party/model_decorator.rb, line 67
def partitions(include_subpartitions: PgParty.config.include_subpartitions_in_partition_list)
  PgParty.cache.fetch_partitions(cache_key, include_subpartitions) do
    connection.partitions_for_table_name(table_name, include_subpartitions: include_subpartitions)
  end
rescue
  []
end
range_partition_key_in(start_range, end_range) click to toggle source
# File lib/pg_party/model_decorator.rb, line 43
def range_partition_key_in(start_range, end_range)
  if complex_partition_key
    complex_partition_key_query(
      "(#{partition_key}) >= (?) AND (#{partition_key}) < (?)",
      start_range,
      end_range
    )
  else
    where_partition_key(:gteq, start_range).merge(
      where_partition_key(:lt, end_range)
    )
  end
end

Private Instance Methods

cache_key() click to toggle source
# File lib/pg_party/model_decorator.rb, line 117
def cache_key
  __getobj__.object_id
end
complex_partition_key_query(clause, *interpolated_values) click to toggle source
# File lib/pg_party/model_decorator.rb, line 141
def complex_partition_key_query(clause, *interpolated_values)
  subquery = unscoped
    .select("*")
    .where(clause, *interpolated_values)

  from(subquery, current_alias)
end
create_partition(migration_method, table_name, **options) click to toggle source
# File lib/pg_party/model_decorator.rb, line 113
def create_partition(migration_method, table_name, **options)
  transaction { connection.send(migration_method, table_name, **options) }
end
current_alias() click to toggle source
# File lib/pg_party/model_decorator.rb, line 130
def current_alias
  arel_node = current_arel_table

  case arel_node
  when Arel::Table
    arel_node.name
  when Arel::Nodes::TableAlias
    arel_node.right
  end
end
current_arel_table() click to toggle source

stackoverflow.com/questions/28685149/activerecord-query-with-aliasd-table-names

# File lib/pg_party/model_decorator.rb, line 122
def current_arel_table
  none.arel.source.left.tap do |node|
    if [Arel::Table, Arel::Nodes::TableAlias].exclude?(node.class)
      raise "could not find arel table in current scope"
    end
  end
end
where_partition_key(meth, values) click to toggle source
# File lib/pg_party/model_decorator.rb, line 149
def where_partition_key(meth, values)
  partition_key_array = Array.wrap(partition_key)
  values = Array.wrap(values)

  if partition_key_array.size != values.size
    raise "number of provided values does not match the number of partition key columns"
  end

  arel_query = partition_key_array.zip(values).inject(nil) do |obj, (column, value)|
    node = current_arel_table[column].send(meth, value)

    if obj.nil?
      node
    else
      obj.and(node)
    end
  end

  where(arel_query)
end