module Workbook::Modules::TableDiffSort

Adds diffing and sorting functions

Public Instance Methods

align(other, options={:sort=>true,:ignore_headers=>false}) click to toggle source

aligns itself with another table, used by diff

@param [Workbook::Table] other table to align with @param [Hash] options default to: `{:sort=>true,:ignore_headers=>false}`

# File lib/workbook/modules/diff_sort.rb, line 141
def align other, options={:sort=>true,:ignore_headers=>false}

  options = {:sort=>true,:ignore_headers=>false}.merge(options)

  sother = other.clone.remove_empty_lines!
  sself = self.clone.remove_empty_lines!

  if options[:ignore_headers]
    sother.header = false
    sself.header = false
  end

  sother = options[:sort] ? Workbook::Table.new(sother.sort) : sother
  sself = options[:sort] ? Workbook::Table.new(sself.sort) : sself

  row_index = 0
  while row_index < [sother.count,sself.count].max and row_index < other.count+self.count do
    row_index = align_row(sself, sother, row_index)
  end

  {:self=>sself, :other=>sother}
end
align_row(sself, sother, row_index) click to toggle source

for use in the align 'while' loop

# File lib/workbook/modules/diff_sort.rb, line 165
def align_row sself, sother, row_index
  asd = 0
  if sself[row_index] and sother[row_index]
    asd = sself[row_index].key <=> sother[row_index].key
  elsif sself[row_index]
    asd = -1
  elsif sother[row_index]
    asd = 1
  end
  if asd == -1 and insert_placeholder?(sother, sself, row_index)
    sother.insert row_index, placeholder_row
    row_index -=1
  elsif asd == 1 and insert_placeholder?(sother, sself, row_index)
    sself.insert row_index, placeholder_row
    row_index -=1
  end

  row_index += 1
end
create_diff_cell(scell, ocell) click to toggle source

creates a new cell describing the difference between two cells

@return [Workbook::Cell] the diff cell

# File lib/workbook/modules/diff_sort.rb, line 96
def create_diff_cell(scell, ocell)
  dcell = scell.nil? ? Workbook::Cell.new(nil) : scell
  if (scell == ocell)
    dcell.format = scell.format if scell
  elsif scell.nil?
    dcell = Workbook::Cell.new "(was: #{ocell.to_s})"
    dcell.format = diff_template.template.create_or_find_format_by 'destroyed'
  elsif ocell.nil?
    dcell = scell.clone
    fmt = scell.nil? ? :default : scell.format[:number_format]
    f = diff_template.template.create_or_find_format_by 'created', fmt
    f[:number_format] = scell.format[:number_format]
    dcell.format = f
  elsif scell != ocell
    dcell = Workbook::Cell.new "#{scell.to_s} (was: #{ocell.to_s})"
    f = diff_template.template.create_or_find_format_by 'updated'
    dcell.format = f
  end

  dcell
end
diff(other, options={}) click to toggle source

create an overview of the differences between itself with another 'previous' table, returns a book with a single sheet and table (containing the diffs)

@return [Workbook::Table] the return result

# File lib/workbook/modules/diff_sort.rb, line 58
def diff other, options={}
  options = {:sort=>true,:ignore_headers=>false}.merge(options)

  aligned = align(other, options)
  aself = aligned[:self]
  aother = aligned[:other]

  iteration_cols = []
  if options[:ignore_headers]
    iteration_cols = [aother.first.count,aself.first.count].max.times.collect
  else
    iteration_cols = (aother.header.to_symbols+aother.header.to_symbols).uniq
  end

  diff_table = diff_template
  maxri = (aself.count-1)

  for ri in 0..maxri do
    row = diff_table[ri] = Workbook::Row.new(nil, diff_table)
    srow = aself[ri]
    orow = aother[ri]

    iteration_cols.each_with_index do |ch, ci|
      scell = srow[ch]
      ocell = orow[ch]
      row[ci] = create_diff_cell(scell, ocell)
    end
  end
  if !options[:ignore_headers]
    diff_table[0].format = diff_template.template.create_or_find_format_by 'header'
  end

  diff_table
end
diff_template() click to toggle source

Return template table to write the diff result in; in case non exists a default is generated.

@return [Workbook::Table] the empty table, linked to a book

# File lib/workbook/modules/diff_sort.rb, line 121
def diff_template
  return @diff_template if defined?(@diff_template)
  diffbook = Workbook::Book.new_diff_template
  difftable = diffbook.sheet.table
  @diff_template ||= difftable
end
diff_template=(table) click to toggle source

Set the template table to write the diff result in; in case non exists a default is generated. Make sure that the following formats exists: destroyed, updated, created and header.

@param [Workbook::Table] table to diff inside @return [Workbook::Table] the passed table

# File lib/workbook/modules/diff_sort.rb, line 133
def diff_template= table
  @diff_template= table
end
insert_placeholder?(sother, sself, row_index) click to toggle source
# File lib/workbook/modules/diff_sort.rb, line 185
def insert_placeholder? sother, sself, row_index
  (sother[row_index].nil? or !sother[row_index].placeholder?) and
  (sself[row_index].nil? or !sself[row_index].placeholder?)
end
placeholder_row() click to toggle source

returns a placeholder row, for internal use only

# File lib/workbook/modules/diff_sort.rb, line 191
def placeholder_row
  if defined?(@placeholder_row) and !@placeholder_row.nil?
    return @placeholder_row
  else
    @placeholder_row = Workbook::Row.new [nil]
    placeholder_row.placeholder = true
    return @placeholder_row
  end
end