kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.0 KiB
87 lines
2.0 KiB
15 years ago
|
# encoding: UTF-8
|
||
15 years ago
|
require 'enumerator'
|
||
15 years ago
|
|
||
14 years ago
|
class Report::Table
|
||
15 years ago
|
attr_accessor :query
|
||
14 years ago
|
include Report::QueryUtils
|
||
15 years ago
|
|
||
15 years ago
|
def initialize(query)
|
||
|
@query = query
|
||
15 years ago
|
end
|
||
|
|
||
15 years ago
|
def row_index
|
||
|
get_index :row
|
||
15 years ago
|
end
|
||
|
|
||
15 years ago
|
def column_index
|
||
|
get_index :column
|
||
|
end
|
||
|
|
||
|
def row_fields
|
||
|
fields_for :row
|
||
|
end
|
||
|
|
||
|
def column_fields
|
||
|
fields_for :column
|
||
|
end
|
||
|
|
||
|
def rows_for(result) fields_for result, :row end
|
||
|
def columns_for(result) fields_for result, :column end
|
||
|
|
||
|
def fields_from(result, type)
|
||
15 years ago
|
#fields_for(type).map { |k| result[k] }
|
||
15 years ago
|
fields_for(type).map { |k| map_field k, result.fields[k] }
|
||
15 years ago
|
end
|
||
|
|
||
|
##
|
||
|
# @param [Array] expected Fields expected
|
||
|
# @param [Array,Hash,Resul] given Fields/result to be tested
|
||
|
# @return [TrueClass,FalseClass]
|
||
|
def satisfies?(type, expected, given)
|
||
15 years ago
|
given = fields_from(given, type) if given.respond_to? :to_hash
|
||
15 years ago
|
zipped = expected.zip given
|
||
|
zipped.all? { |a,b| a == b or b.nil? }
|
||
|
end
|
||
|
|
||
|
def fields_for(type)
|
||
|
@fields_for ||= begin
|
||
|
child, fields = query.chain, Hash.new { |h,k| h[k] = [] }
|
||
15 years ago
|
until child.filter?
|
||
|
fields[child.type].push(*child.group_fields)
|
||
|
child = child.child
|
||
|
end
|
||
|
fields
|
||
15 years ago
|
end
|
||
|
@fields_for[type]
|
||
|
end
|
||
|
|
||
|
def get_row(*args)
|
||
|
@query.each_row { |result| return with_gaps_for(type, result) if satisfies? :row, args, result }
|
||
|
[]
|
||
|
end
|
||
|
|
||
|
def with_gaps_for(type, result)
|
||
|
return enum_for(:with_gaps_for, type, result) unless block_given?
|
||
|
stack = get_index(type).dup
|
||
15 years ago
|
result.each_direct_result do |subresult|
|
||
|
yield nil until stack.empty? or satisfies? type, stack.shift, subresult
|
||
15 years ago
|
yield subresult
|
||
|
end
|
||
15 years ago
|
stack.size.times { yield nil }
|
||
15 years ago
|
end
|
||
|
|
||
|
def [](x,y)
|
||
|
get_row(row_index[y]).first(x).last
|
||
|
end
|
||
|
|
||
|
def get_index(type)
|
||
|
@indexes ||= begin
|
||
15 years ago
|
indexes = Hash.new { |h,k| h[k] = Set.new }
|
||
|
query.each_direct_result { |result| [:row, :column].each { |t| indexes[t] << fields_from(result, t) } }
|
||
15 years ago
|
indexes.keys.each { |k| indexes[k] = indexes[k].sort { |x, y| x <=> y } }
|
||
15 years ago
|
indexes
|
||
15 years ago
|
end
|
||
|
@indexes[type]
|
||
|
end
|
||
15 years ago
|
end
|