Commit 7e40a95f99ead429d168b8e5b7bc878385d74a9b

Authored by Andrew Kane
1 parent a3cd9f99

period, not field [skip ci]

Showing 1 changed file with 29 additions and 29 deletions   Show diff stats
lib/groupdate/magic.rb
@@ -2,15 +2,15 @@ require "i18n" @@ -2,15 +2,15 @@ require "i18n"
2 2
3 module Groupdate 3 module Groupdate
4 class Magic 4 class Magic
5 - attr_accessor :field, :options 5 + attr_accessor :period, :options
6 6
7 - def initialize(field, options)  
8 - @field = field 7 + def initialize(period, options)
  8 + @period = period
9 @options = options 9 @options = options
10 10
11 raise Groupdate::Error, "Unrecognized time zone" unless time_zone 11 raise Groupdate::Error, "Unrecognized time zone" unless time_zone
12 12
13 - raise Groupdate::Error, "Unrecognized :week_start option" if field == :week && !week_start 13 + raise Groupdate::Error, "Unrecognized :week_start option" if period == :week && !week_start
14 end 14 end
15 15
16 def group_by(enum, &_block) 16 def group_by(enum, &_block)
@@ -29,7 +29,7 @@ module Groupdate @@ -29,7 +29,7 @@ module Groupdate
29 query = 29 query =
30 case adapter_name 30 case adapter_name
31 when "MySQL", "Mysql2", "Mysql2Spatial" 31 when "MySQL", "Mysql2", "Mysql2Spatial"
32 - case field 32 + case period
33 when :day_of_week # Sunday = 0, Monday = 1, etc 33 when :day_of_week # Sunday = 0, Monday = 1, etc
34 # use CONCAT for consistent return type (String) 34 # use CONCAT for consistent return type (String)
35 ["DAYOFWEEK(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} second), '+00:00', ?)) - 1", time_zone] 35 ["DAYOFWEEK(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} second), '+00:00', ?)) - 1", time_zone]
@@ -47,7 +47,7 @@ module Groupdate @@ -47,7 +47,7 @@ module Groupdate
47 ["DATE_ADD(CONVERT_TZ(DATE_FORMAT(DATE(CONCAT(EXTRACT(YEAR FROM CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} second), '+00:00', ?)), '-', LPAD(1 + 3 * (QUARTER(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} second), '+00:00', ?)) - 1), 2, '00'), '-01')), '%Y-%m-%d %H:%i:%S'), ?, '+00:00'), INTERVAL #{day_start} second)", time_zone, time_zone, time_zone] 47 ["DATE_ADD(CONVERT_TZ(DATE_FORMAT(DATE(CONCAT(EXTRACT(YEAR FROM CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} second), '+00:00', ?)), '-', LPAD(1 + 3 * (QUARTER(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} second), '+00:00', ?)) - 1), 2, '00'), '-01')), '%Y-%m-%d %H:%i:%S'), ?, '+00:00'), INTERVAL #{day_start} second)", time_zone, time_zone, time_zone]
48 else 48 else
49 format = 49 format =
50 - case field 50 + case period
51 when :second 51 when :second
52 "%Y-%m-%d %H:%i:%S" 52 "%Y-%m-%d %H:%i:%S"
53 when :minute 53 when :minute
@@ -65,7 +65,7 @@ module Groupdate @@ -65,7 +65,7 @@ module Groupdate
65 ["DATE_ADD(CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} second), '+00:00', ?), '#{format}'), ?, '+00:00'), INTERVAL #{day_start} second)", time_zone, time_zone] 65 ["DATE_ADD(CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} second), '+00:00', ?), '#{format}'), ?, '+00:00'), INTERVAL #{day_start} second)", time_zone, time_zone]
66 end 66 end
67 when "PostgreSQL", "PostGIS" 67 when "PostgreSQL", "PostGIS"
68 - case field 68 + case period
69 when :day_of_week 69 when :day_of_week
70 ["EXTRACT(DOW from #{column}::timestamptz AT TIME ZONE ? - INTERVAL '#{day_start} second')::integer", time_zone] 70 ["EXTRACT(DOW from #{column}::timestamptz AT TIME ZONE ? - INTERVAL '#{day_start} second')::integer", time_zone]
71 when :hour_of_day 71 when :hour_of_day
@@ -77,20 +77,20 @@ module Groupdate @@ -77,20 +77,20 @@ module Groupdate
77 when :month_of_year 77 when :month_of_year
78 ["EXTRACT(MONTH from #{column}::timestamptz AT TIME ZONE ? - INTERVAL '#{day_start} second')::integer", time_zone] 78 ["EXTRACT(MONTH from #{column}::timestamptz AT TIME ZONE ? - INTERVAL '#{day_start} second')::integer", time_zone]
79 when :week # start on Sunday, not PostgreSQL default Monday 79 when :week # start on Sunday, not PostgreSQL default Monday
80 - ["(DATE_TRUNC('#{field}', (#{column}::timestamptz - INTERVAL '#{week_start} day' - INTERVAL '#{day_start} second') AT TIME ZONE ?) + INTERVAL '#{week_start} day' + INTERVAL '#{day_start} second') AT TIME ZONE ?", time_zone, time_zone] 80 + ["(DATE_TRUNC('#{period}', (#{column}::timestamptz - INTERVAL '#{week_start} day' - INTERVAL '#{day_start} second') AT TIME ZONE ?) + INTERVAL '#{week_start} day' + INTERVAL '#{day_start} second') AT TIME ZONE ?", time_zone, time_zone]
81 else 81 else
82 - ["(DATE_TRUNC('#{field}', (#{column}::timestamptz - INTERVAL '#{day_start} second') AT TIME ZONE ?) + INTERVAL '#{day_start} second') AT TIME ZONE ?", time_zone, time_zone] 82 + ["(DATE_TRUNC('#{period}', (#{column}::timestamptz - INTERVAL '#{day_start} second') AT TIME ZONE ?) + INTERVAL '#{day_start} second') AT TIME ZONE ?", time_zone, time_zone]
83 end 83 end
84 when "SQLite" 84 when "SQLite"
85 raise Groupdate::Error, "Time zones not supported for SQLite" unless self.time_zone.utc_offset.zero? 85 raise Groupdate::Error, "Time zones not supported for SQLite" unless self.time_zone.utc_offset.zero?
86 raise Groupdate::Error, "day_start not supported for SQLite" unless day_start.zero? 86 raise Groupdate::Error, "day_start not supported for SQLite" unless day_start.zero?
87 raise Groupdate::Error, "week_start not supported for SQLite" unless week_start == 6 87 raise Groupdate::Error, "week_start not supported for SQLite" unless week_start == 6
88 88
89 - if field == :week 89 + if period == :week
90 ["strftime('%%Y-%%m-%%d 00:00:00 UTC', #{column}, '-6 days', 'weekday 0')"] 90 ["strftime('%%Y-%%m-%%d 00:00:00 UTC', #{column}, '-6 days', 'weekday 0')"]
91 else 91 else
92 format = 92 format =
93 - case field 93 + case period
94 when :hour_of_day 94 when :hour_of_day
95 "%H" 95 "%H"
96 when :minute_of_hour 96 when :minute_of_hour
@@ -120,7 +120,7 @@ module Groupdate @@ -120,7 +120,7 @@ module Groupdate
120 ["strftime('#{format.gsub(/%/, '%%')}', #{column})"] 120 ["strftime('#{format.gsub(/%/, '%%')}', #{column})"]
121 end 121 end
122 when "Redshift" 122 when "Redshift"
123 - case field 123 + case period
124 when :day_of_week # Sunday = 0, Monday = 1, etc. 124 when :day_of_week # Sunday = 0, Monday = 1, etc.
125 ["EXTRACT(DOW from CONVERT_TIMEZONE(?, #{column}::timestamp) - INTERVAL '#{day_start} second')::integer", time_zone] 125 ["EXTRACT(DOW from CONVERT_TIMEZONE(?, #{column}::timestamp) - INTERVAL '#{day_start} second')::integer", time_zone]
126 when :hour_of_day 126 when :hour_of_day
@@ -136,19 +136,19 @@ module Groupdate @@ -136,19 +136,19 @@ module Groupdate
136 # always says it is in UTC time, so we must convert 136 # always says it is in UTC time, so we must convert
137 # back to UTC to play properly with the rest of Groupdate. 137 # back to UTC to play properly with the rest of Groupdate.
138 # 138 #
139 - ["CONVERT_TIMEZONE(?, 'Etc/UTC', DATE_TRUNC(?, CONVERT_TIMEZONE(?, #{column}) - INTERVAL '#{week_start} day' - INTERVAL '#{day_start} second'))::timestamp + INTERVAL '#{week_start} day' + INTERVAL '#{day_start} second'", time_zone, field, time_zone] 139 + ["CONVERT_TIMEZONE(?, 'Etc/UTC', DATE_TRUNC(?, CONVERT_TIMEZONE(?, #{column}) - INTERVAL '#{week_start} day' - INTERVAL '#{day_start} second'))::timestamp + INTERVAL '#{week_start} day' + INTERVAL '#{day_start} second'", time_zone, period, time_zone]
140 else 140 else
141 - ["CONVERT_TIMEZONE(?, 'Etc/UTC', DATE_TRUNC(?, CONVERT_TIMEZONE(?, #{column}) - INTERVAL '#{day_start} second'))::timestamp + INTERVAL '#{day_start} second'", time_zone, field, time_zone] 141 + ["CONVERT_TIMEZONE(?, 'Etc/UTC', DATE_TRUNC(?, CONVERT_TIMEZONE(?, #{column}) - INTERVAL '#{day_start} second'))::timestamp + INTERVAL '#{day_start} second'", time_zone, period, time_zone]
142 end 142 end
143 else 143 else
144 raise Groupdate::Error, "Connection adapter not supported: #{adapter_name}" 144 raise Groupdate::Error, "Connection adapter not supported: #{adapter_name}"
145 end 145 end
146 146
147 - if adapter_name == "MySQL" && field == :week 147 + if adapter_name == "MySQL" && period == :week
148 query[0] = "CAST(#{query[0]} AS DATETIME)" 148 query[0] = "CAST(#{query[0]} AS DATETIME)"
149 end 149 end
150 150
151 - group = relation.group(Groupdate::OrderHack.new(relation.send(:sanitize_sql_array, query), field, time_zone)) 151 + group = relation.group(Groupdate::OrderHack.new(relation.send(:sanitize_sql_array, query), period, time_zone))
152 relation = 152 relation =
153 if time_range.is_a?(Range) 153 if time_range.is_a?(Range)
154 # doesn't matter whether we include the end of a ... range - it will be excluded later 154 # doesn't matter whether we include the end of a ... range - it will be excluded later
@@ -170,7 +170,7 @@ module Groupdate @@ -170,7 +170,7 @@ module Groupdate
170 order = relation.order_values.first 170 order = relation.order_values.first
171 if order.is_a?(String) 171 if order.is_a?(String)
172 parts = order.split(" ") 172 parts = order.split(" ")
173 - reverse_order = (parts.size == 2 && (parts[0].to_sym == field || (activerecord42? && parts[0] == "#{relation.quoted_table_name}.#{relation.quoted_primary_key}")) && parts[1].to_s.downcase == "desc") 173 + reverse_order = (parts.size == 2 && (parts[0].to_sym == period || (activerecord42? && parts[0] == "#{relation.quoted_table_name}.#{relation.quoted_primary_key}")) && parts[1].to_s.downcase == "desc")
174 if reverse_order 174 if reverse_order
175 reverse = !reverse 175 reverse = !reverse
176 relation = relation.reorder(relation.order_values[1..-1]) 176 relation = relation.reorder(relation.order_values[1..-1])
@@ -180,7 +180,7 @@ module Groupdate @@ -180,7 +180,7 @@ module Groupdate
180 multiple_groups = relation.group_values.size > 1 180 multiple_groups = relation.group_values.size > 1
181 181
182 cast_method = 182 cast_method =
183 - case field 183 + case period
184 when :day_of_week, :hour_of_day, :day_of_month, :month_of_year, :minute_of_hour 184 when :day_of_week, :hour_of_day, :day_of_month, :month_of_year, :minute_of_hour
185 lambda { |k| k.to_i } 185 lambda { |k| k.to_i }
186 else 186 else
@@ -226,12 +226,12 @@ module Groupdate @@ -226,12 +226,12 @@ module Groupdate
226 last += 1.day unless time_range.exclude_end? 226 last += 1.day unless time_range.exclude_end?
227 time_range = Range.new(time_zone.parse(time_range.first.to_s), last, true) 227 time_range = Range.new(time_zone.parse(time_range.first.to_s), last, true)
228 elsif !time_range && options[:last] 228 elsif !time_range && options[:last]
229 - if field == :quarter 229 + if period == :quarter
230 step = 3.months 230 step = 3.months
231 - elsif 1.respond_to?(field)  
232 - step = 1.send(field) 231 + elsif 1.respond_to?(period)
  232 + step = 1.send(period)
233 else 233 else
234 - raise ArgumentError, "Cannot use last option with #{field}" 234 + raise ArgumentError, "Cannot use last option with #{period}"
235 end 235 end
236 if step 236 if step
237 now = Time.now 237 now = Time.now
@@ -257,7 +257,7 @@ module Groupdate @@ -257,7 +257,7 @@ module Groupdate
257 reverse = !reverse if options[:reverse] 257 reverse = !reverse if options[:reverse]
258 258
259 series = 259 series =
260 - case field 260 + case period
261 when :day_of_week 261 when :day_of_week
262 0..6 262 0..6
263 when :hour_of_day 263 when :hour_of_day
@@ -287,10 +287,10 @@ module Groupdate @@ -287,10 +287,10 @@ module Groupdate
287 if time_range.first 287 if time_range.first
288 series = [round_time(time_range.first)] 288 series = [round_time(time_range.first)]
289 289
290 - if field == :quarter 290 + if period == :quarter
291 step = 3.months 291 step = 3.months
292 else 292 else
293 - step = 1.send(field) 293 + step = 1.send(period)
294 end 294 end
295 295
296 last_step = series.last 296 last_step = series.last
@@ -332,7 +332,7 @@ module Groupdate @@ -332,7 +332,7 @@ module Groupdate
332 else 332 else
333 sunday = time_zone.parse("2014-03-02 00:00:00") 333 sunday = time_zone.parse("2014-03-02 00:00:00")
334 lambda do |key| 334 lambda do |key|
335 - case field 335 + case period
336 when :hour_of_day 336 when :hour_of_day
337 key = sunday + key.hours + day_start.seconds 337 key = sunday + key.hours + day_start.seconds
338 when :minute_of_hour 338 when :minute_of_hour
@@ -347,7 +347,7 @@ module Groupdate @@ -347,7 +347,7 @@ module Groupdate
347 I18n.localize(key, format: options[:format], locale: locale) 347 I18n.localize(key, format: options[:format], locale: locale)
348 end 348 end
349 end 349 end
350 - elsif [:day, :week, :month, :quarter, :year].include?(field) && use_dates 350 + elsif [:day, :week, :month, :quarter, :year].include?(period) && use_dates
351 lambda { |k| k.to_date } 351 lambda { |k| k.to_date }
352 else 352 else
353 lambda { |k| k } 353 lambda { |k| k }
@@ -369,7 +369,7 @@ module Groupdate @@ -369,7 +369,7 @@ module Groupdate
369 time = time.to_time.in_time_zone(time_zone) - day_start.seconds 369 time = time.to_time.in_time_zone(time_zone) - day_start.seconds
370 370
371 time = 371 time =
372 - case field 372 + case period
373 when :second 373 when :second
374 time.change(usec: 0) 374 time.change(usec: 0)
375 when :minute 375 when :minute
@@ -399,7 +399,7 @@ module Groupdate @@ -399,7 +399,7 @@ module Groupdate
399 when :month_of_year 399 when :month_of_year
400 time.month 400 time.month
401 else 401 else
402 - raise Groupdate::Error, "Invalid field" 402 + raise Groupdate::Error, "Invalid period"
403 end 403 end
404 404
405 time.is_a?(Time) ? time + day_start.seconds : time 405 time.is_a?(Time) ? time + day_start.seconds : time