ar_aggregate_by_interval 1.1.7 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e1c961b3ed5d12203cc873a4594870eb7408f5a4
4
- data.tar.gz: 0d3bd079ac028864d66b4b69f4908686dff8cf47
3
+ metadata.gz: 8c7e6ecadea46b5a620c4b4a6f2e86a4bd8cbb7d
4
+ data.tar.gz: 853b144cabd27a0fdbfbc3567c560a44fdc74bc1
5
5
  SHA512:
6
- metadata.gz: de4dc421547761903a03d2f2a2d7c20e83dfe702fe1364ed08628ed11ad10d9ac457f3ae554ef90b09ae72dde382b4507042e04654579135f9dc6054c836c057
7
- data.tar.gz: 2bf2561984d1adde9aeaad18e99191726d372525aa01ba0f192e58d0ceb219bcecd844ca1673e85349772f192457326480229b5ca0c2ba01d478b10b86041f04
6
+ metadata.gz: ccc8387f47774bcd549fd82be2c73f378ef4613e87769e0f3d402e75124dd1ca6d6094bf355a835f13149128a5e5cd2bd285d0d91bad4d2d7855bfe036c87c8f
7
+ data.tar.gz: 1f9eea1a86f3da795c343efeacfea8a944f53cd6f146634e7b702557534a621daf28b727e661f48cc4c28dff6309c1bb37c309e4787d29fb126cf94412a8cc12
data/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
  This file adheres to [Keep a changelog](http://keepachangelog.com/).
5
5
 
6
+ ## [1.2.0] - 2015-04-05
7
+ ### Added
8
+ - normalize_dates option
9
+
6
10
  ## [1.1.7] - 2015-03-15 (maintenance)
7
11
  ### Added
8
12
  - Tests for from and to parameters
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- # ArAggregateByInterval (Time series)
1
+ # ArAggregateByInterval
2
+ ## ActiveRecord time series
2
3
  ---
3
4
 
4
5
  [![Circle CI](https://circleci.com/gh/jotto/ar_aggregate_by_interval.svg?style=svg)](https://circleci.com/gh/jotto/ar_aggregate_by_interval)
@@ -26,15 +27,22 @@ Blog.avg_weekly(:created_at, :pageviews, 1.month.ago).values
26
27
 
27
28
  ## Usage
28
29
  ```ruby
29
- # be explicit and pass a hash
30
- # [:group_by_column, :from, :to, :aggregate_column]
31
-
32
- # or just pass arguments
33
- # count: arg_hash can be arguments: (group_by_col, from, to)
34
- # sum and avg: arg_hash can be arguments: (group_by_col, aggregate_col, from, to)
35
- Blog.{count,sum,avg}_{daily,weekly,monthly}(arg_hash).{values,values_and_dates}
30
+ Blog.{count,sum,avg}_{daily,weekly,monthly}(hash_or_arg_list).{values,values_and_dates}`
36
31
  ```
37
32
 
33
+ ### 1. "method_missing" methods on ActiveRecord
34
+ * `{count,sum,avg}_{daily,weekly,monthly}`
35
+
36
+ ### 2. pass hash or argument list
37
+
38
+ * pass a Hash
39
+ * `{:group_by_column, :from, :to, :aggregate_column, :normalize_dates}`
40
+ * or pass arguments
41
+ * when using count: `[group_by_col, from, to, options_hash]`
42
+ * when using sum or avg: `[group_by_col, aggregate_col, from, to, options_hash]`
43
+
44
+ ### 3. methods you can call: `#values` or `#values_and_dates`
45
+
38
46
  ```ruby
39
47
  #values //(returns an array of numerics)
40
48
  => [4, 2, 15, 0, 10]
@@ -72,3 +80,6 @@ Billing.sum_weekly({
72
80
  to: Time.zone.now
73
81
  }).values_and_dates
74
82
  ```
83
+
84
+ ## Options
85
+ * `normalize_dates` defaults to `True` which means the `from` argument is converted to beginning_of_{day,week,month} and the `to` argument is converted to end_of_{day,week,month}
@@ -17,7 +17,7 @@ module ArAggregateByInterval
17
17
 
18
18
  hash_args = if args.size == 1 && args.first.is_a?(Hash)
19
19
  args.first
20
- elsif args.size > 1 && !args.any?{ |a| a.is_a?(Hash) }
20
+ elsif args.size > 1 && !args[0..-2].any?{ |a| a.is_a?(Hash) }
21
21
  Utils.args_to_hash(aggregate_function, interval, *args)
22
22
  else
23
23
  nil
@@ -11,9 +11,6 @@ module ArAggregateByInterval
11
11
  VALID_HASH_ARGS = {
12
12
  date_values_hash: [Hash],
13
13
 
14
- # # hash with 1 key where the key is a date column and value is the column being aggegated
15
- # ar_result_select_col_mapping: -> (v) { v.is_a?(Hash) && v.size == 1 },
16
-
17
14
  from: [Date, DateTime, Time, ActiveSupport::TimeWithZone],
18
15
  to: [Date, DateTime, Time, ActiveSupport::TimeWithZone],
19
16
 
@@ -23,7 +20,6 @@ module ArAggregateByInterval
23
20
  def initialize(hash_args)
24
21
  ClassyHash.validate(hash_args, VALID_HASH_ARGS)
25
22
 
26
- # @dates_values_hash = Utils.ar_to_hash(args[:ar_result], args[:ar_result_select_col_mapping])
27
23
  @dates_values_hash = hash_args[:date_values_hash]
28
24
  @date_iterator_method = Utils::DATE_ITERATOR_METHOD_MAP[hash_args[:interval]]
29
25
 
@@ -49,15 +45,6 @@ module ArAggregateByInterval
49
45
 
50
46
  private
51
47
 
52
- # def validate_args!(hash_args)
53
- # ClassyHash.validate(hash_args, VALID_HASH_ARGS)
54
- # first_res = hash_args[:ar_result].first
55
- # keys = hash_args[:ar_result_select_col_mapping].to_a.flatten
56
- # if first_res && keys.any? { |key| !first_res.respond_to?(key) }
57
- # raise RuntimeError.new("the collection passed does not respond to all attribs: #{keys}")
58
- # end
59
- # end
60
-
61
48
  def array_of_dates
62
49
  @array_of_dates ||= @from.to_date.send(@date_iterator_method, @to.to_date).map do |date|
63
50
  [date, date.strftime(@strftime_format)]
@@ -16,7 +16,9 @@ module ArAggregateByInterval
16
16
  from: [Date, DateTime, Time, ActiveSupport::TimeWithZone],
17
17
  to: [:optional, Date, DateTime, Time, ActiveSupport::TimeWithZone],
18
18
 
19
- aggregate_column: [:optional, Symbol, NilClass] # required when using sum (as opposed to count)
19
+ aggregate_column: [:optional, Symbol, NilClass], # required when using sum (as opposed to count)
20
+
21
+ normalize_dates: [:optional, TrueClass, FalseClass]
20
22
  }
21
23
 
22
24
  attr_reader :values, :values_and_dates, :from, :to, :interval
@@ -27,8 +29,15 @@ module ArAggregateByInterval
27
29
 
28
30
  @ar_model = ar_model
29
31
 
30
- @from = normalize_from(hash_args[:from], hash_args[:interval])
31
- @to = normalize_to(hash_args[:to] || Time.zone.try(:now) || Time.now, hash_args[:interval])
32
+ @from = hash_args[:from]
33
+ @to = hash_args[:to] || Time.zone.try(:now) || Time.now
34
+
35
+ # by default, change dates to beginning and end of interval
36
+ # e.g. beginning and end of {day,week,month}
37
+ if hash_args[:normalize_dates] != false
38
+ @from = normalize_from(@from, hash_args[:interval])
39
+ @to = normalize_to(@to, hash_args[:interval])
40
+ end
32
41
 
33
42
  @db_vendor_select =
34
43
  Utils.select_for_grouping_column(hash_args[:group_by_column])[hash_args[:interval]]
@@ -11,19 +11,18 @@ module ArAggregateByInterval
11
11
 
12
12
  # support legacy arguments (as opposed to direct hash)
13
13
  # can do:
14
- # ArModel.count_weekly(:group_by_col, :from, :to, :return_dates_bool)
15
- # ArModel.count_weekly(:from, :to, :return_dates_bool) # defaults to :created_at
14
+ # ArModel.count_weekly(:group_by_col, :from, :to, :options_hash)
15
+ # ArModel.count_weekly(:from, :to, :options_hash) # defaults to :created_at
16
16
  # or
17
- # ArModel.sum_weekly(:group_by_col, :aggregate_col, :from, :to, :return_dates_bool)
17
+ # ArModel.sum_weekly(:group_by_col, :aggregate_col, :from, :to, :options_hash)
18
18
  def args_to_hash(sum_or_count, daily_weekly_monthly, *args)
19
- group_by_column, aggregate_column, from, to, return_dates = args
19
+ group_by_column, aggregate_column, from, to, options_hash = args
20
20
 
21
21
  group_by_column ||= 'created_at'
22
- return_dates ||= false
23
22
 
24
23
  if sum_or_count == 'count'
25
24
  if aggregate_column.present? && (aggregate_column.is_a?(Date) || aggregate_column.is_a?(Time))
26
- return_dates = to
25
+ options_hash = to
27
26
  to = from
28
27
  from = aggregate_column
29
28
  aggregate_column = nil
@@ -32,19 +31,16 @@ module ArAggregateByInterval
32
31
  raise ArgumentError, "aggregate_column cant be nil with #{sum_or_count}"
33
32
  end
34
33
 
35
- return {
34
+ if !options_hash.nil? && !options_hash.is_a?(Hash)
35
+ raise ArgumentError, 'last argument must be options hash'
36
+ end
37
+
38
+ return (options_hash || {}).merge({
36
39
  group_by_column: group_by_column.try(:intern),
37
40
  from: from,
38
41
  to: to,
39
42
  aggregate_column: aggregate_column.try(:intern)
40
- }.delete_if { |k, v| v.nil? }
41
- end
42
-
43
- def ar_to_hash(ar_result, mapping)
44
- ar_result.to_a.inject({}) do |memo, ar_obj|
45
- mapping.each { |key, val| memo.merge!(ar_obj.send(key).to_s => ar_obj.send(val)) }
46
- memo
47
- end
43
+ }).delete_if { |k, v| v.nil? }
48
44
  end
49
45
 
50
46
  def ruby_strftime_map
@@ -1,3 +1,3 @@
1
1
  module ArAggregateByInterval
2
- VERSION = '1.1.7'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -15,7 +15,7 @@ describe ArAggregateByInterval do
15
15
  @from = DateTime.parse '2013-08-05'
16
16
  @to = @from
17
17
  blog1 = Blog.create! arbitrary_number: 10, created_at: @from
18
- blog2 = Blog.create! arbitrary_number: 20, created_at: @from
18
+ blog2 = Blog.create! arbitrary_number: 20, created_at: @from + 1.day
19
19
 
20
20
  # extra row that should not be included in any of the calculations
21
21
  # verifying that the from and to parameters are working
@@ -61,6 +61,21 @@ describe ArAggregateByInterval do
61
61
 
62
62
  context 'hash args' do
63
63
 
64
+ context 'with normalize dates disabled' do
65
+ subject do
66
+ Blog.count_weekly({
67
+ group_by_column: :created_at,
68
+ from: @from,
69
+ to: @to,
70
+ normalize_dates: false
71
+ })
72
+ end
73
+
74
+ it "does not change dates on #{db_config}" do
75
+ expect(subject.values_and_dates).to eq([date: @from.to_date, value: 1])
76
+ end
77
+ end
78
+
64
79
  context 'for count' do
65
80
  subject do
66
81
  Blog.count_weekly({
@@ -112,6 +127,18 @@ describe ArAggregateByInterval do
112
127
 
113
128
  context 'normal args' do
114
129
 
130
+ context 'with normalize dates disabled' do
131
+ subject do
132
+ Blog.count_weekly(:created_at, @from, @from, {
133
+ normalize_dates: false
134
+ })
135
+ end
136
+
137
+ it "does not change dates on #{db_config}" do
138
+ expect(subject.values_and_dates).to eq([date: @from.to_date, value: 1])
139
+ end
140
+ end
141
+
115
142
  context 'with to' do
116
143
  subject do
117
144
  Blog.count_weekly(:created_at, @from, @from)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar_aggregate_by_interval
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Otto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-16 00:00:00.000000000 Z
11
+ date: 2015-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler