class PgClosureTreeRebuild::Builder
Constants
- COLUMNS
Public Class Methods
new(table, hierarchies_table_name, options = {})
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 3 def initialize(table, hierarchies_table_name, options = {}) @table = table @hierarchies_table_name = hierarchies_table_name.to_sym @id = options.delete(:id) || :id @parent_id = options.delete(:parent_id) || :parent_id end
Public Instance Methods
chains()
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 26 def chains @chains ||= build_chains end
rebuild(db) { || ... }
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 10 def rebuild(db) io = StringIO.new write_header(io) chains.each do |row| io.write([row.size].pack('n')) row.each { |v| write_integer(v, io) } yield if block_given? end write_close(io) copy(db, io) end
tuples()
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 22 def tuples @tuples ||= @table.order(@parent_id).select_map([@id, @parent_id]) end
Private Instance Methods
build_chains()
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 32 def build_chains [].tap do |c| tuples.each { |tuple| c.concat(chains_for(tuple[0])) } end end
chains_for(id)
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 38 def chains_for(id) [].tap do |c| c << [id, id, 0] walk_up(id).each.with_index do |parent_id, index| c << [parent_id, id, index + 1] end end end
copy(db, io)
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 87 def copy(db, io) db[@hierarchies_table_name].truncate db.run('SET client_min_messages TO warning;') db.copy_into( @hierarchies_table_name, columns: COLUMNS, format: :binary, data: io.read ) end
index_tuples_by_id()
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 63 def index_tuples_by_id {}.tap do |c| tuples.each do |(id, parent_id)| c[id] = parent_id end end end
tuples_hash()
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 59 def tuples_hash @tuples_hash ||= index_tuples_by_id end
walk_up(id, cref = [])
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 48 def walk_up(id, cref = []) parent_id = tuples_hash[id] return [] unless parent_id if cref.include?(parent_id) fail "Cycle reference detected: #{id} <=> #{parent_id}" end [parent_id] + walk_up(parent_id, cref + [parent_id]) end
write_close(io)
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 82 def write_close(io) io.write([-1].pack('n')) io.rewind end
write_header(io)
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 77 def write_header(io) io.write("PGCOPY\n\377\r\n\0") io.write([0, 0].pack('NN')) end
write_integer(value, io)
click to toggle source
# File lib/pg_closure_tree_rebuild/builder.rb, line 71 def write_integer(value, io) buf = [value].pack('N') io.write([buf.bytesize].pack('N')) io.write(buf) end