groupdate 5.1.0 → 5.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
  SHA256:
3
- metadata.gz: 163a969c3eb174890b78b4512c6a6631e02722a43f1fbcc30926f3e48cdba461
4
- data.tar.gz: 256ee01a6e991c7513390e8cdf6d27b3e4458018e0980d63e9506bccfc6923d8
3
+ metadata.gz: 0d18870af57fc18006c5f176fa3138dfe36a715b16e5a6113f447aee6d3b7468
4
+ data.tar.gz: 889870a1a2db8784e28413c6071a784dff66d00b4aaf05a323e70e5d16f09fd8
5
5
  SHA512:
6
- metadata.gz: 37093986846259dc59a17187af24097a2ed9d881de6a48ff9a394883e5a936a569fd758daf820cc9444e69212d29548ab21a816f7fac0cba1b7e502ac2d99198
7
- data.tar.gz: d1639375454ed0d1d33600226287a484ae7001c3759446b2c196dd24f1e003f3fce7f0c8f2253d90819bc280260bedfed2fa6f622f24ad46c590c05739177df2
6
+ metadata.gz: 2ae29a1e8d0eb14c4ef904fbe366cb5f7029d9e94429a74f6f70073a880f2910f62d5161d39618808c09dc937185cc79ba233ac3fc7e34f983a8e32d60e0be70
7
+ data.tar.gz: 6348f6853cf2015f6777bcc63e1e416a31456a0e779678164992bd6424daca73272bb5fcb12016d1f3c085b4e14e991afa067f4f93354982e7229699f3ea2eab
@@ -1,3 +1,8 @@
1
+ ## 5.2.0 (2020-09-07)
2
+
3
+ - Added warning for non-attribute argument
4
+ - Added support for beginless and endless ranges in `range` option
5
+
1
6
  ## 5.1.0 (2020-07-30)
2
7
 
3
8
  - Added `n` option to minute and second for custom durations
data/README.md CHANGED
@@ -60,7 +60,7 @@ and
60
60
  - day_of_year
61
61
  - month_of_year
62
62
 
63
- Use it anywhere you can use `group`. Works with `count`, `sum`, `minimum`, `maximum`, and `average`. For `median`, check out [ActiveMedian](https://github.com/ankane/active_median).
63
+ Use it anywhere you can use `group`. Works with `count`, `sum`, `minimum`, `maximum`, and `average`. For `median` and `percentile`, check out [ActiveMedian](https://github.com/ankane/active_median).
64
64
 
65
65
  ### Time Zones
66
66
 
@@ -47,7 +47,6 @@ module Groupdate
47
47
  # TODO better messages
48
48
  raise ArgumentError, "Unrecognized time zone" unless time_zone
49
49
  raise ArgumentError, "Unrecognized :week_start option" unless week_start
50
- raise ArgumentError, "Cannot use endless range for :range option" if options[:range].is_a?(Range) && !options[:range].end
51
50
  raise ArgumentError, ":day_start must be between 0 and 24" if (day_start / 3600) < 0 || (day_start / 3600) >= 24
52
51
  end
53
52
 
@@ -3,6 +3,9 @@ module Groupdate
3
3
  attr_reader :period, :column, :day_start, :week_start, :n_seconds
4
4
 
5
5
  def initialize(relation, column:, period:, time_zone:, time_range:, week_start:, day_start:, n_seconds:)
6
+ # very important
7
+ validate_column(column)
8
+
6
9
  @relation = relation
7
10
  @column = resolve_column(relation, column)
8
11
  @period = period
@@ -188,13 +191,30 @@ module Groupdate
188
191
 
189
192
  def where_clause
190
193
  if @time_range.is_a?(Range)
191
- op = @time_range.exclude_end? ? "<" : "<="
192
- ["#{column} >= ? AND #{column} #{op} ?", @time_range.first, @time_range.last]
194
+ if @time_range.end
195
+ op = @time_range.exclude_end? ? "<" : "<="
196
+ if @time_range.begin
197
+ ["#{column} >= ? AND #{column} #{op} ?", @time_range.first, @time_range.last]
198
+ else
199
+ ["#{column} #{op} ?", @time_range.last]
200
+ end
201
+ else
202
+ ["#{column} >= ?", @time_range.first]
203
+ end
193
204
  else
194
205
  ["#{column} IS NOT NULL"]
195
206
  end
196
207
  end
197
208
 
209
+ # basic version of Active Record disallow_raw_sql!
210
+ # symbol = column (safe), Arel node = SQL (safe), other = untrusted
211
+ def validate_column(column)
212
+ # matches table.column and column
213
+ unless column.is_a?(Symbol) || column.is_a?(Arel::Nodes::SqlLiteral) || /\A\w+(\.\w+)?\z/i.match(column.to_s)
214
+ warn "[groupdate] Non-attribute argument: #{column}. Use Arel.sql() for known-safe values. This will raise an error in Groupdate 6"
215
+ end
216
+ end
217
+
198
218
  # resolves eagerly
199
219
  # need to convert both where_clause (easy)
200
220
  # and group_clause (not easy) if want to avoid this
@@ -11,7 +11,6 @@ module Groupdate
11
11
  @day_start = day_start
12
12
  @n_seconds = n_seconds
13
13
  @options = options
14
- @round_time = {}
15
14
  @week_start_key = Groupdate::Magic::DAYS[@week_start] if @week_start
16
15
  end
17
16
 
@@ -142,11 +141,16 @@ module Groupdate
142
141
  def time_range
143
142
  @time_range ||= begin
144
143
  time_range = options[:range]
145
- if time_range.is_a?(Range) && time_range.first.is_a?(Date)
146
- # convert range of dates to range of times
147
- last = time_range.last.in_time_zone(time_zone)
148
- last += 1.day unless time_range.exclude_end?
149
- time_range = Range.new(time_range.first.in_time_zone(time_zone), last, true)
144
+ # entire range must be Date if begin or end is Date
145
+ if time_range.is_a?(Range) && (time_range.begin.is_a?(Date) || time_range.end.is_a?(Date))
146
+ if time_range.begin
147
+ start = time_zone.parse(time_range.first.to_s)
148
+ end
149
+ if time_range.end
150
+ last = time_zone.parse(time_range.last.to_s)
151
+ last += 1.day unless time_range.exclude_end?
152
+ end
153
+ time_range = Range.new(start, last, true)
150
154
  elsif !time_range && options[:last]
151
155
  if period == :quarter
152
156
  step = 3.months
@@ -200,7 +204,7 @@ module Groupdate
200
204
  else
201
205
  time_range = self.time_range
202
206
  time_range =
203
- if time_range.is_a?(Range)
207
+ if time_range.is_a?(Range) && time_range.begin && time_range.end
204
208
  time_range
205
209
  else
206
210
  # use first and last values
@@ -211,11 +215,23 @@ module Groupdate
211
215
  data.keys.sort
212
216
  end
213
217
 
214
- tr = sorted_keys.first..sorted_keys.last
215
- if options[:current] == false && sorted_keys.any? && round_time(now) >= tr.last
216
- tr = tr.first...round_time(now)
218
+ if time_range.is_a?(Range)
219
+ if sorted_keys.any?
220
+ if time_range.begin
221
+ time_range.begin..sorted_keys.last
222
+ else
223
+ Range.new(sorted_keys.first, time_range.end, time_range.exclude_end?)
224
+ end
225
+ else
226
+ nil..nil
227
+ end
228
+ else
229
+ tr = sorted_keys.first..sorted_keys.last
230
+ if options[:current] == false && sorted_keys.any? && round_time(now) >= tr.last
231
+ tr = tr.first...round_time(now)
232
+ end
233
+ tr
217
234
  end
218
- tr
219
235
  end
220
236
 
221
237
  if time_range.begin
@@ -1,3 +1,3 @@
1
1
  module Groupdate
2
- VERSION = "5.1.0"
2
+ VERSION = "5.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: groupdate
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-31 00:00:00.000000000 Z
11
+ date: 2020-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport