Class: Groupdate::Magic::Relation
Constant Summary
DAYS
Instance Attribute Summary
#group_index, #options, #period
Class Method Summary
collapse
Instance Method Summary
collapse
#day_start, #series_builder, #series_label, #time_range, #time_zone, #validate_arguments, #validate_keywords, validate_period, #week_start
Constructor Details
#initialize(**options) ⇒ Relation
Returns a new instance of Relation.
102
103
104
105
|
# File 'lib/groupdate/magic.rb', line 102
def initialize(**options)
super(**options.reject { |k, _| [:default_value, :carry_forward, :last, :current].include?(k) })
@options = options
end
|
Class Method Details
.generate_relation(relation, field:, **options) ⇒ Object
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# File 'lib/groupdate/magic.rb', line 183
def self.generate_relation(relation, field:, **options)
magic = Groupdate::Magic::Relation.new(**options)
relation =
RelationBuilder.new(
relation,
column: field,
period: magic.period,
time_zone: magic.time_zone,
time_range: magic.time_range,
week_start: magic.week_start,
day_start: magic.day_start,
series_label: magic.series_label
).generate
magic.group_index = relation.group_values.size - 1
(relation.groupdate_values ||= []) << magic
relation
end
|
.process_result(relation, result, **options) ⇒ Object
allow any options to keep flexible for future
207
208
209
210
211
212
|
# File 'lib/groupdate/magic.rb', line 207
def self.process_result(relation, result, **options)
relation.groupdate_values.reverse.each do |gv|
result = gv.perform(relation, result, default_value: options[:default_value])
end
result
end
|
.process_series_label(relation, result) ⇒ Object
214
215
216
217
218
219
|
# File 'lib/groupdate/magic.rb', line 214
def self.process_series_label(relation, result)
relation.groupdate_values.reverse.each do |gv|
result = gv.perform_series_label(relation, result)
end
result
end
|
Instance Method Details
#cast_method ⇒ Object
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/groupdate/magic.rb', line 121
def cast_method
@cast_method ||= begin
case period
when :minute_of_hour, :hour_of_day, :day_of_month, :day_of_year, :month_of_year
lambda { |k| k.to_i }
when :day_of_week
lambda { |k| (k.to_i - 1 - week_start) % 7 }
else
utc = ActiveSupport::TimeZone["UTC"]
lambda { |k| (k.is_a?(String) || !k.respond_to?(:to_time) ? utc.parse(k.to_s) : k.to_time).in_time_zone(time_zone) }
end
end
end
|
#cast_result(result, multiple_groups) ⇒ Object
135
136
137
138
139
140
141
142
143
144
145
146
|
# File 'lib/groupdate/magic.rb', line 135
def cast_result(result, multiple_groups)
new_result = {}
result.each do |k, v|
if multiple_groups
k[group_index] = cast_method.call(k[group_index])
else
k = cast_method.call(k)
end
new_result[k] = v
end
new_result
end
|
#cast_series_label(original_label) ⇒ Object
179
180
181
|
# File 'lib/groupdate/magic.rb', line 179
def cast_series_label(original_label)
series_builder.format_series_label(cast_method.call(original_label))
end
|
#check_nils(result, multiple_groups, relation) ⇒ Object
158
159
160
161
162
163
164
165
166
167
|
# File 'lib/groupdate/magic.rb', line 158
def check_nils(result, multiple_groups, relation)
has_nils = multiple_groups ? (result.keys.first && result.keys.first[group_index].nil?) : result.key?(nil)
if has_nils
if time_zone_support?(relation)
raise Groupdate::Error, "Invalid query - be sure to use a date or time column"
else
raise Groupdate::Error, "Database missing time zone support for #{time_zone.tzinfo.name} - see https://github.com/ankane/groupdate#for-mysql"
end
end
end
|
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/groupdate/magic.rb', line 107
def perform(relation, result, default_value:)
multiple_groups = relation.group_values.size > 1
check_nils(result, multiple_groups, relation)
result = cast_result(result, multiple_groups)
series_builder.generate(
result,
default_value: options.key?(:default_value) ? options[:default_value] : default_value,
multiple_groups: multiple_groups,
group_index: group_index
)
end
|
169
170
171
172
173
174
175
176
177
|
# File 'lib/groupdate/magic.rb', line 169
def perform_series_label(relation, result)
label = options[:series_label]
return result unless label.present?
result.map do |r|
r.send("#{label}=", cast_series_label(r.send(label)))
r
end
end
|
#time_zone_support?(relation) ⇒ Boolean
148
149
150
151
152
153
154
155
156
|
# File 'lib/groupdate/magic.rb', line 148
def time_zone_support?(relation)
if relation.connection.adapter_name =~ /mysql/i
sql = relation.klass.send(:sanitize_sql_array, ["SELECT CONVERT_TZ(NOW(), '+00:00', ?)", time_zone.tzinfo.name])
!relation.connection.select_all(sql).first.values.first.nil?
else
true
end
end
|