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 +26 -0
- data/VERSION +1 -1
- data/lib/.gitignore +1 -0
- data/lib/reporter/data_source/active_record_source.rb +13 -31
- data/lib/reporter/data_source/scoping.rb +1 -4
- data/reporter.gemspec +81 -0
- metadata +50 -42
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
|
+
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
|
-
#
|
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
|
-
|
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
|
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
|
-
|
5
|
-
|
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:
|
19
|
-
default_executable:
|
13
|
+
date: 2011-09-19 00:00:00 Z
|
20
14
|
dependencies:
|
21
15
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
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
|
-
|
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:
|
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:
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
142
|
+
rubygems_version: 1.8.10
|
135
143
|
signing_key:
|
136
144
|
specification_version: 3
|
137
145
|
summary: Report builder.
|