class Terrestrial::Adapters::MemoryAdapter::Relation

Attributes

all_rows[R]
applied_query[R]
schema[R]
selected_columns[R]

Public Class Methods

new(schema, all_rows, selected_columns: nil, applied_query: Query.new) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 121
def initialize(schema, all_rows, selected_columns: nil, applied_query: Query.new)
  @schema = schema
  @all_rows = all_rows
  @applied_query = applied_query
  @selected_columns = selected_columns || all_column_names
end

Public Instance Methods

columns() click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 132
def columns
  all_column_names
end
delete() click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 157
def delete
  matching_rows.each do |row_to_delete|
    all_rows.delete(row_to_delete)
  end
end
each(&block) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 153
def each(&block)
  matching_rows.each(&block)
end
empty?() click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 189
def empty?
  matching_rows.empty?
end
insert(new_row) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 167
def insert(new_row)
  new_row_with_all_fields = empty_row.merge(clone(new_row))
  row_id = extract_row_id(new_row_with_all_fields)

  if row_id.any? && where(row_id).any?
    raise DuplicateKeyError.new(row_id)
  else
    all_rows.push(new_row_with_all_fields)
  end
end
insert_conflict(target:, update: {}) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 163
def insert_conflict(target:, update: {})
  Upsert.new(self, target: target, update: update)
end
order(*columns) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 145
def order(*columns)
  new_with_query(applied_query.order(columns.flatten))
end
reverse() click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 149
def reverse
  new_with_query(@applied_query.reverse)
end
select(*new_selected_columns) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 140
def select(*new_selected_columns)
  selected_columns = new_selected_columns & all_column_names
  self.class.new(columns, all_rows, selected_columns: selected_columns, applied_query: applied_query)
end
update(attrs) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 178
def update(attrs)
  all_rows
    .select { |row| matching_rows.include?(row) }
    .each do |row|
      attrs.each do |k, v|
        row[clone(k)] = clone(v)
      end
    end
    .count
end
where(criteria, &block) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 136
def where(criteria, &block)
  new_with_query(Query.new(criteria: criteria, &block))
end

Protected Instance Methods

extract_values_for_sub_select(expected_columns: 1) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 195
def extract_values_for_sub_select(expected_columns: 1)
  unless selected_columns.size == expected_columns
    raise "Expected dataset with #{expected_columns} columns. Got #{selected_columns.size} columns."
  end

  matching_rows.flat_map(&:values)
end

Private Instance Methods

all_column_names() click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 250
def all_column_names
  schema.map { |f| f.fetch(:name) }
end
apply_sort(rows, order_columns, reverse_order) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 215
def apply_sort(rows, order_columns, reverse_order)
  sorted_rows = rows.sort_by{ |row|
    order_columns.map { |col| row.fetch(col) }
  }

  if reverse_order
    sorted_rows.reverse
  else
    sorted_rows
  end
end
clone(object) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 258
def clone(object)
  Marshal.load(Marshal.dump(object))
end
empty_row() click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 246
def empty_row
  Hash[all_column_names.map { |name| [ name, nil ] }]
end
equality_filter(rows, criteria) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 227
def equality_filter(rows, criteria)
  rows.select { |row|
    criteria.all? { |k, v| match(row.fetch(k), v) }
  }
end
extract_row_id(row) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 262
def extract_row_id(row)
  row.select { |k, _v| primary_key.include?(k) }
end
match(value, comparitor) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 233
def match(value, comparitor)
  case comparitor
  when Relation
    comparitor.extract_values_for_sub_select.include?(value)
  when Enumerable
    comparitor.include?(value)
  when Regexp
    comparitor === value
  else
    comparitor == value
  end
end
matching_rows() click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 205
def matching_rows
  apply_sort(
    equality_filter(all_rows, applied_query.criteria),
    applied_query.order_columns,
    applied_query.reverse_order?,
  )
    .map { |row| row.select { |k, _v| selected_columns.include?(k) } }
    .map { |row| Marshal.load(Marshal.dump(row)) }
end
new_with_query(query) click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 254
def new_with_query(query)
  self.class.new(schema, all_rows, selected_columns: selected_columns, applied_query: query)
end
primary_key() click to toggle source
# File lib/terrestrial/adapters/memory_adapter.rb, line 266
def primary_key
  @primary_key ||= schema
    .select { |col| col.fetch(:options, {}).fetch(:primary_key, nil) }
    .map { |col| col.fetch(:name) }
end