table datastructure now creates gaps

git-svn-id: https://dev.finn.de/svn/cockpit/branches/reporting_merge@1193 7926756e-e54e-46e6-9721-ed318f58905e
pull/6827/head
rkh 15 years ago
parent 4ad44da2f1
commit e5c1f3e3da
  1. 85
      app/models/cost_query/table.rb
  2. 4
      init.rb

@ -1,8 +1,9 @@
# encoding: UTF-8 # encoding: UTF-8
require 'enumerator'
## ##
# @example # @example
# CostQuery::Table.new query, :rows => [:project_id, :user_id], :columns => [:spent_on, :tweak] # CostQuery::Table.new query, :rows => [:project_id, :user_id], :columns => [:tweak, :spent_on]
class CostQuery::Table class CostQuery::Table
attr_accessor :query attr_accessor :query
@ -14,16 +15,82 @@ class CostQuery::Table
end end
end end
def rows(*rows) def row_index
return @rows if rows.empty? get_index :row
@rows = rows
end end
def columns(*rows) def column_index
return @rows if rows.empty? get_index :column
@rows = rows 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)
fields_for(type).map { |k| result[k] }
end
##
# @param [Array] expected Fields expected
# @param [Array,Hash,Resul] given Fields/result to be tested
# @return [TrueClass,FalseClass]
def satisfies?(type, expected, given)
given = fields_from(result, type) if given.respond_to? :to_hash
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] = [] }
fields[child.type].push(*child.group_fields) until child.filter?
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
result.each do |subresult|
yield nil until satisfies? type, stack.shift, subresult
yield subresult
end
end
def [](x,y)
get_row(row_index[y]).first(x).last
end
def all_types(&block)
return [:row, :column] unless block
all_types.each(&block)
end
def get_index(type)
@indexes ||= begin
indexes = Hash.new(&method(:compare_fields))
query.each_direct_result { |result| all_types { |t| indexes[t] = fields_from result, t }
indexes.keys.each { |k| indexes[k] = indexes[k].to_a.uniq }
end
@indexes[type]
end
def compare_fields(a, b)
a.zip(b).each { |x,y| return x > y unless x == y }
true
end end
def rows_for(result) rows.map { |k| result[k] } end
def columns_for(result) columns.map { |k| result[k] } end
end end

@ -2,6 +2,10 @@ require 'redmine'
fail "upgrade ruby version, ruby < 1.8.7 suffers from Hash#hash bug" if {:a => 10}.hash != {:a => 10}.hash fail "upgrade ruby version, ruby < 1.8.7 suffers from Hash#hash bug" if {:a => 10}.hash != {:a => 10}.hash
Rails.configuration.after_initialize do
Rails.configuration.gem 'algorithms'
end
Redmine::Plugin.register :redmine_reporting do Redmine::Plugin.register :redmine_reporting do
name 'Reporting Plugin' name 'Reporting Plugin'
author 'Konstantin Haase, Philipp Tessenow @ finnlabs' author 'Konstantin Haase, Philipp Tessenow @ finnlabs'

Loading…
Cancel
Save