statistics 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/VERSION +1 -1
  2. data/lib/statistics.rb +40 -40
  3. data/statistics.gemspec +2 -2
  4. metadata +2 -2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 1.0.0
@@ -2,39 +2,39 @@ module Statistics
2
2
  class << self
3
3
  def included(base)
4
4
  base.extend(HasStats)
5
- end
5
+ end
6
6
 
7
7
  def default_filters(filters)
8
8
  ActiveRecord::Base.instance_eval { @filter_all_on = filters }
9
9
  end
10
10
 
11
11
  def supported_calculations
12
- [:average, :count, :maximum, :minimum, :sum]
12
+ [:average, :count, :maximum, :minimum, :sum]
13
13
  end
14
- end
14
+ end
15
15
 
16
16
  # This extension provides the ability to define statistics for reporting purposes
17
17
  module HasStats
18
18
 
19
19
  # OPTIONS:
20
20
  #
21
- #* +average+, +count+, +sum+, +maximum+, +minimum+ - Only one of these keys is passed, which
22
- # one depends on the type of operation. The value is an array of named scopes to scope the
21
+ #* +average+, +count+, +sum+, +maximum+, +minimum+ - Only one of these keys is passed, which
22
+ # one depends on the type of operation. The value is an array of named scopes to scope the
23
23
  # operation by (+:all+ should be used if no scopes are to be applied)
24
24
  #* +column_name+ - The SQL column to perform the operation on (default: +id+)
25
- #* +filter_on+ - A hash with keys that represent filters. The with values in the has are rules
25
+ #* +filter_on+ - A hash with keys that represent filters. The with values in the has are rules
26
26
  # on how to generate the query for the correspond filter.
27
27
  #* +cached_for+ - A duration for how long to cache this specific statistic
28
28
  #
29
- # Additional options can also be passed in that would normally be passed to an ActiveRecord
29
+ # Additional options can also be passed in that would normally be passed to an ActiveRecord
30
30
  # +calculate+ call, like +conditions+, +joins+, etc
31
31
  #
32
32
  # EXAMPLE:
33
33
  #
34
34
  # class MockModel < ActiveRecord::Base
35
- #
35
+ #
36
36
  # named_scope :my_scope, :conditions => 'value > 5'
37
- #
37
+ #
38
38
  # define_statistic "Basic Count", :count => :all
39
39
  # define_statistic "Basic Sum", :sum => :all, :column_name => 'amount'
40
40
  # define_statistic "Chained Scope Count", :count => [:all, :my_scope]
@@ -44,18 +44,18 @@ module Statistics
44
44
  # end
45
45
  def define_statistic(name, options)
46
46
  method_name = name.to_s.gsub(" ", "").underscore + "_stat"
47
-
47
+
48
48
  @statistics ||= {}
49
49
  @filter_all_on ||= ActiveRecord::Base.instance_eval { @filter_all_on }
50
50
  @statistics[name] = method_name
51
-
51
+
52
52
  options = { :column_name => :id }.merge(options)
53
53
 
54
54
  calculation = options.keys.find {|opt| Statistics::supported_calculations.include?(opt)}
55
55
  calculation ||= :count
56
56
 
57
57
  # We must use the metaclass here to metaprogrammatically define a class method
58
- (class<<self; self; end).instance_eval do
58
+ (class<<self; self; end).instance_eval do
59
59
  define_method(method_name) do |filters|
60
60
  # check the cache before running a query for the stat
61
61
  cached_val = Rails.cache.read("#{self.name}#{method_name}#{filters}") if options[:cache_for]
@@ -64,37 +64,37 @@ module Statistics
64
64
  scoped_options = Marshal.load(Marshal.dump(options))
65
65
 
66
66
  filters.each do |key, value|
67
- if value
67
+ unless value.nil?
68
68
  sql = ((@filter_all_on || {}).merge(scoped_options[:filter_on] || {}))[key].gsub("?", "'#{value}'")
69
69
  sql = sql.gsub("%t", "#{table_name}")
70
70
  sql_frag = send(:sanitize_sql_for_conditions, sql)
71
- case
72
- when sql_frag.nil? : nil
73
- when scoped_options[:conditions].nil? : scoped_options[:conditions] = sql_frag
74
- when scoped_options[:conditions].is_a?(Array) : scoped_options[:conditions][0].concat(" AND #{sql_frag}")
75
- when scoped_options[:conditions].is_a?(String) : scoped_options[:conditions].concat(" AND #{sql_frag}")
71
+ case
72
+ when sql_frag.nil? then nil
73
+ when scoped_options[:conditions].nil? then scoped_options[:conditions] = sql_frag
74
+ when scoped_options[:conditions].is_a?(Array) then scoped_options[:conditions][0].concat(" AND #{sql_frag}")
75
+ when scoped_options[:conditions].is_a?(String) then scoped_options[:conditions].concat(" AND #{sql_frag}")
76
76
  end
77
77
  end
78
78
  end if filters.is_a?(Hash)
79
-
79
+
80
80
  base = self
81
81
  # chain named scopes
82
82
  scopes = Array(scoped_options[calculation])
83
83
  scopes.each do |scope|
84
84
  base = base.send(scope)
85
- end if scopes != [:all]
85
+ end if scopes != [:all]
86
86
  stat_value = base.send(calculation, scoped_options[:column_name], sql_options(scoped_options))
87
87
 
88
88
  # cache stat value
89
- Rails.cache.write("#{self.name}#{method_name}#{filters}", stat_value, :expires_in => options[:cache_for]) if options[:cache_for]
89
+ Rails.cache.write("#{self.name}#{method_name}#{filters}", stat_value, :expires_in => options[:cache_for]) if options[:cache_for]
90
90
 
91
91
  stat_value
92
92
  end
93
93
  end
94
94
  end
95
-
95
+
96
96
  # Defines a statistic using a block that has access to all other defined statistics
97
- #
97
+ #
98
98
  # EXAMPLE:
99
99
  # class MockModel < ActiveRecord::Base
100
100
  # define_statistic "Basic Count", :count => :all
@@ -107,20 +107,20 @@ module Statistics
107
107
 
108
108
  @statistics ||= {}
109
109
  @statistics[name] = method_name
110
-
111
- (class<<self; self; end).instance_eval do
110
+
111
+ (class<<self; self; end).instance_eval do
112
112
  define_method(method_name) do |filters|
113
113
  @filters = filters
114
114
  yield
115
115
  end
116
116
  end
117
117
  end
118
-
118
+
119
119
  # returns an array containing the names/keys of all defined statistics
120
120
  def statistics_keys
121
121
  @statistics.keys
122
122
  end
123
-
123
+
124
124
  # Calculates all the statistics defined for this AR class and returns a hash with the values.
125
125
  # There is an optional parameter that is a hash of all values you want to filter by.
126
126
  #
@@ -133,7 +133,7 @@ module Statistics
133
133
  stats_hash
134
134
  end
135
135
  end
136
-
136
+
137
137
  # returns a single statistic based on the +stat_name+ paramater passed in and
138
138
  # similarly to the +statistics+ method, it also can take filters.
139
139
  #
@@ -143,7 +143,7 @@ module Statistics
143
143
  def get_stat(stat_name, filters = {})
144
144
  send(@statistics[stat_name], filters) if @statistics[stat_name]
145
145
  end
146
-
146
+
147
147
  # to keep things DRY anything that all statistics need to be filterable by can be defined
148
148
  # seperatly using this method
149
149
  #
@@ -162,19 +162,19 @@ module Statistics
162
162
 
163
163
  private
164
164
 
165
- def defined_stats(name)
166
- get_stat(name, @filters)
167
- end
165
+ def defined_stats(name)
166
+ get_stat(name, @filters)
167
+ end
168
168
 
169
- def sql_options(options)
170
- Statistics::supported_calculations.each do |deletable|
171
- options.delete(deletable)
169
+ def sql_options(options)
170
+ Statistics::supported_calculations.each do |deletable|
171
+ options.delete(deletable)
172
+ end
173
+ options.delete(:column_name)
174
+ options.delete(:filter_on)
175
+ options.delete(:cache_for)
176
+ options
172
177
  end
173
- options.delete(:column_name)
174
- options.delete(:filter_on)
175
- options.delete(:cache_for)
176
- options
177
- end
178
178
  end
179
179
  end
180
180
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{statistics}
8
- s.version = "0.1.1"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Alexandru Catighera"]
12
- s.date = %q{2010-02-18}
12
+ s.date = %q{2010-09-10}
13
13
  s.email = %q{acatighera@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "README.markdown"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statistics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandru Catighera
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-18 00:00:00 -05:00
12
+ date: 2010-09-10 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15