reporter 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.1)
5
+ activesupport (= 3.0.1)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.4.1)
8
+ activerecord (3.0.1)
9
+ activemodel (= 3.0.1)
10
+ activesupport (= 3.0.1)
11
+ arel (~> 1.0.0)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.1)
14
+ arel (1.0.1)
15
+ activesupport (~> 3.0.0)
16
+ builder (2.1.2)
17
+ i18n (0.4.2)
18
+ tzinfo (0.3.29)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ activerecord (~> 3.0.0)
25
+ activesupport (~> 3.0.0)
26
+ arel (~> 1.0.1)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
data/lib/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .idea
@@ -1,6 +1,3 @@
1
- # ActiveRecordSource supplies information about the datasources and executes the queries upon it.
2
- # The source holds the active record model to build queries upon.
3
- #
4
1
  class Reporter::DataSource::ActiveRecordSource
5
2
 
6
3
  def initialize(data_source, active_record)
@@ -11,13 +8,17 @@ class Reporter::DataSource::ActiveRecordSource
11
8
 
12
9
  attr_reader :active_record, :name
13
10
 
14
- # returns all date columns
11
+ # scope detection methods
12
+ def references
13
+ load_columns if @references.nil?
14
+ @references
15
+ end
16
+
15
17
  def date_columns
16
18
  load_columns if @date_columns.nil?
17
19
  @date_columns
18
20
  end
19
21
 
20
- # returns all associations, grouped by the type of model linked to.
21
22
  def relations_to_objects
22
23
  load_columns if @object_links.nil?
23
24
  @object_links
@@ -32,12 +33,8 @@ class Reporter::DataSource::ActiveRecordSource
32
33
  active_record.name
33
34
  end
34
35
 
35
- VALID_CALCULATIONS = %w(count sum average minimum maximum)
36
-
37
36
  # retrieve data from source
38
37
  def calculate calculation, *args, &block
39
- raise "invalid calculation: #{calculation}" unless VALID_CALCULATIONS.include? calculation.to_s
40
- # TODO: include check for valid calculations and required parameters
41
38
  options = args.extract_options!.dup
42
39
  scope_options = extract_scope_options_from options
43
40
  source = source_with_applied_scopes(scope_options)
@@ -45,7 +42,6 @@ class Reporter::DataSource::ActiveRecordSource
45
42
  source.send *([calculation] + args + [options])
46
43
  end
47
44
 
48
- # performs a calculation for an entire period, in groups of months, years, weeks, quarters or days
49
45
  def calculate_for_period calculation, period, filter, scope, *args, &block
50
46
  options = args.extract_options!.dup
51
47
  # remove the time scope from the default scopes
@@ -53,26 +49,16 @@ class Reporter::DataSource::ActiveRecordSource
53
49
  scope_options[:ignore_scopes] << scope.name.to_sym
54
50
  scope_options[:ignore_scopes].uniq!
55
51
  source = source_with_applied_scopes(scope_options)
56
-
57
52
  source = block.call(source, data_source.scopes) if block_given?
58
-
59
53
  # add time scope seperately with full period
60
54
  source = scope.apply_on source, period
61
55
 
62
- # group on the given filters (year and month, in case of months)
63
56
  grouping = filter.collect { |f| scope.group_on source, f }
64
57
  source = source.group grouping.join(", ")
65
-
66
- # set the columns for the selection. We have to do this in manual SQL, since Rails does not
67
- # support multiple group by's in the calculation functions.
68
58
  select = []
69
59
  select << calculation_function(calculation, args)
70
60
  filter.each_with_index { |f, index| select << "#{grouping[index]} as #{f.to_s}" }
71
- source = source.select select
72
- #Rails.logger.info source.to_sql
73
-
74
- # execute the query and collect the results
75
- # place all results in an collection hash with their filter attributes as key
61
+ source = source.select select
76
62
  result = source.collect do |r|
77
63
  result = r.result.to_f
78
64
  result = result.to_i if result.floor == result
@@ -80,10 +66,10 @@ class Reporter::DataSource::ActiveRecordSource
80
66
  filter.each { |f| res[f] = r[f.to_s].to_i }
81
67
  res
82
68
  end
69
+ #Rails.logger.info source.to_sql
83
70
  result
84
71
  end
85
72
 
86
- # apply all scopes on the active record model
87
73
  def source_with_applied_scopes(options)
88
74
  #Rails.logger.info options.inspect
89
75
  data_source.scopes.apply_on(active_record, options)
@@ -93,16 +79,18 @@ class Reporter::DataSource::ActiveRecordSource
93
79
 
94
80
  attr_reader :data_source
95
81
 
96
- # examine the active record model and store all relevant data for scoping
97
82
  def load_columns
83
+ @references = []
98
84
  @date_columns = []
85
+ @object_links = {}
99
86
  active_record.columns.collect do |column|
100
- if [Time, Date].include? column.klass
87
+ if column.name =~ /^(.*)_id$/ and column.klass == Fixnum
88
+ @references << $1
89
+ elsif [Time, Date].include? column.klass
101
90
  @date_columns << column.name
102
91
  end
103
92
  end.compact
104
93
 
105
- @object_links = {}
106
94
  active_record.reflect_on_all_associations.each do |reflection|
107
95
  @object_links[reflection.klass] ||= []
108
96
  @object_links[reflection.klass] << reflection.name.to_s
@@ -124,12 +112,6 @@ class Reporter::DataSource::ActiveRecordSource
124
112
  "COUNT(*) AS result"
125
113
  when :average :
126
114
  "AVG(#{args.first}) AS result"
127
- when :minimum :
128
- "MIN(#{args.first}) AS result"
129
- when :maximum :
130
- "MAX(#{args.first}) AS result"
131
- else
132
- raise "Invalid calculation: #{calculation}"
133
115
  end
134
116
  end
135
117
 
@@ -1,6 +1,3 @@
1
- # The scoping class manages the active scopes applied on all datasources.
2
- # It takes care of serialization of the scopes when they are switched between iterations of the data.
3
- #
4
1
  class Reporter::DataSource::Scoping
5
2
 
6
3
  SUPPORTED_SCOPES = {
@@ -17,7 +14,6 @@ class Reporter::DataSource::Scoping
17
14
 
18
15
  public
19
16
 
20
- # returns an array with all possible scopes between all datasources
21
17
  def possible
22
18
  return @possible_scopes if @possible_scopes
23
19
  results = SUPPORTED_SCOPES.collect { |type_name, scope_type| scope_type.possible_scopes data_source.sources }.flatten
@@ -31,6 +27,7 @@ class Reporter::DataSource::Scoping
31
27
  #Rails.logger.info "Added scope #{name}: #{scope_type}"
32
28
  self
33
29
  end
30
+
34
31
  alias :add :<<
35
32
 
36
33
  def limit_scope scope, *args
data/reporter.gemspec ADDED
@@ -0,0 +1,81 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "reporter"
8
+ s.version = "0.0.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Matthijs Groen"]
12
+ s.date = "2011-09-19"
13
+ s.description = "\n Reporter adds a consistent way to build reports.\n "
14
+ s.email = "matthijs.groen@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "README.markdown"
17
+ ]
18
+ s.files = [
19
+ "Gemfile",
20
+ "Gemfile.lock",
21
+ "MIT-LICENSE",
22
+ "README.markdown",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lib/.gitignore",
26
+ "lib/reporter/data_set.rb",
27
+ "lib/reporter/data_source.rb",
28
+ "lib/reporter/data_source/active_record_source.rb",
29
+ "lib/reporter/data_source/scoping.rb",
30
+ "lib/reporter/data_structure.rb",
31
+ "lib/reporter/field/average_field.rb",
32
+ "lib/reporter/field/base.rb",
33
+ "lib/reporter/field/calculation_field.rb",
34
+ "lib/reporter/field/count_field.rb",
35
+ "lib/reporter/field/field.rb",
36
+ "lib/reporter/field/formula_field.rb",
37
+ "lib/reporter/field/sum_field.rb",
38
+ "lib/reporter/formula.rb",
39
+ "lib/reporter/result_row.rb",
40
+ "lib/reporter/scope/base.rb",
41
+ "lib/reporter/scope/date_scope.rb",
42
+ "lib/reporter/scope/reference_scope.rb",
43
+ "lib/reporter/support/time_range.rb",
44
+ "lib/reporter/time_iterator.rb",
45
+ "lib/reporter/time_optimized_result_row.rb",
46
+ "lib/reporter/value.rb",
47
+ "reporter.gemspec"
48
+ ]
49
+ s.homepage = "http://github.com/matthijsgroen/reporter"
50
+ s.require_paths = ["lib"]
51
+ s.rubygems_version = "1.8.10"
52
+ s.summary = "Report builder."
53
+
54
+ if s.respond_to? :specification_version then
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
+ s.add_runtime_dependency(%q<arel>, ["~> 1.0.1"])
59
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0"])
60
+ s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0"])
61
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0"])
62
+ s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0"])
63
+ s.add_runtime_dependency(%q<arel>, ["~> 1.0.1"])
64
+ else
65
+ s.add_dependency(%q<arel>, ["~> 1.0.1"])
66
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
67
+ s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
68
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
69
+ s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
70
+ s.add_dependency(%q<arel>, ["~> 1.0.1"])
71
+ end
72
+ else
73
+ s.add_dependency(%q<arel>, ["~> 1.0.1"])
74
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
75
+ s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
76
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
77
+ s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
78
+ s.add_dependency(%q<arel>, ["~> 1.0.1"])
79
+ end
80
+ end
81
+
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reporter
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
4
+ prerelease:
5
+ version: 0.0.2
11
6
  platform: ruby
12
7
  authors:
13
8
  - Matthijs Groen
@@ -15,57 +10,74 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2010-09-16 00:00:00 +02:00
19
- default_executable:
13
+ date: 2011-09-19 00:00:00 Z
20
14
  dependencies:
21
15
  - !ruby/object:Gem::Dependency
22
- name: activerecord
23
- prerelease: false
16
+ name: arel
24
17
  requirement: &id001 !ruby/object:Gem::Requirement
25
18
  none: false
26
19
  requirements:
27
20
  - - ~>
28
21
  - !ruby/object:Gem::Version
29
- hash: 7
30
- segments:
31
- - 3
32
- - 0
33
- - 0
34
- version: 3.0.0
22
+ version: 1.0.1
35
23
  type: :runtime
24
+ prerelease: false
36
25
  version_requirements: *id001
37
26
  - !ruby/object:Gem::Dependency
38
- name: activesupport
39
- prerelease: false
27
+ name: activerecord
40
28
  requirement: &id002 !ruby/object:Gem::Requirement
41
29
  none: false
42
30
  requirements:
43
31
  - - ~>
44
32
  - !ruby/object:Gem::Version
45
- hash: 7
46
- segments:
47
- - 3
48
- - 0
49
- - 0
50
33
  version: 3.0.0
51
34
  type: :runtime
35
+ prerelease: false
52
36
  version_requirements: *id002
53
37
  - !ruby/object:Gem::Dependency
54
- name: arel
55
- prerelease: false
38
+ name: activesupport
56
39
  requirement: &id003 !ruby/object:Gem::Requirement
57
40
  none: false
58
41
  requirements:
59
42
  - - ~>
60
43
  - !ruby/object:Gem::Version
61
- hash: 21
62
- segments:
63
- - 1
64
- - 0
65
- - 1
66
- version: 1.0.1
44
+ version: 3.0.0
67
45
  type: :runtime
46
+ prerelease: false
68
47
  version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: activerecord
50
+ requirement: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 3.0.0
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: activesupport
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 3.0.0
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: arel
72
+ requirement: &id006 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.0.1
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: *id006
69
81
  description: "\n Reporter adds a consistent way to build reports.\n "
70
82
  email: matthijs.groen@gmail.com
71
83
  executables: []
@@ -76,10 +88,12 @@ extra_rdoc_files:
76
88
  - README.markdown
77
89
  files:
78
90
  - Gemfile
91
+ - Gemfile.lock
79
92
  - MIT-LICENSE
80
93
  - README.markdown
81
94
  - Rakefile
82
95
  - VERSION
96
+ - lib/.gitignore
83
97
  - lib/reporter/data_set.rb
84
98
  - lib/reporter/data_source.rb
85
99
  - lib/reporter/data_source/active_record_source.rb
@@ -101,13 +115,13 @@ files:
101
115
  - lib/reporter/time_iterator.rb
102
116
  - lib/reporter/time_optimized_result_row.rb
103
117
  - lib/reporter/value.rb
104
- has_rdoc: true
118
+ - reporter.gemspec
105
119
  homepage: http://github.com/matthijsgroen/reporter
106
120
  licenses: []
107
121
 
108
122
  post_install_message:
109
- rdoc_options:
110
- - --charset=UTF-8
123
+ rdoc_options: []
124
+
111
125
  require_paths:
112
126
  - lib
113
127
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -115,23 +129,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
129
  requirements:
116
130
  - - ">="
117
131
  - !ruby/object:Gem::Version
118
- hash: 3
119
- segments:
120
- - 0
121
132
  version: "0"
122
133
  required_rubygems_version: !ruby/object:Gem::Requirement
123
134
  none: false
124
135
  requirements:
125
136
  - - ">="
126
137
  - !ruby/object:Gem::Version
127
- hash: 3
128
- segments:
129
- - 0
130
138
  version: "0"
131
139
  requirements: []
132
140
 
133
141
  rubyforge_project:
134
- rubygems_version: 1.3.7
142
+ rubygems_version: 1.8.10
135
143
  signing_key:
136
144
  specification_version: 3
137
145
  summary: Report builder.