active_reporting 0.6.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +81 -31
- data/README.md +139 -43
- data/lib/active_reporting/active_record_adaptor.rb +2 -10
- data/lib/active_reporting/configuration.rb +63 -45
- data/lib/active_reporting/datetime_drill.rb +88 -0
- data/lib/active_reporting/dimension.rb +10 -6
- data/lib/active_reporting/fact_model.rb +15 -10
- data/lib/active_reporting/fact_model_registry.rb +51 -0
- data/lib/active_reporting/metric.rb +7 -5
- data/lib/active_reporting/railtie.rb +9 -0
- data/lib/active_reporting/report.rb +73 -34
- data/lib/active_reporting/reporting_dimension.rb +60 -79
- data/lib/active_reporting/version.rb +1 -1
- data/lib/active_reporting.rb +43 -23
- metadata +20 -122
- data/.github/dependabot.yml +0 -11
- data/.github/workflows/tests.yml +0 -150
- data/.gitignore +0 -12
- data/.rubocop.yml +0 -29
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -17
- data/Rakefile +0 -12
- data/active_reporting.gemspec +0 -37
- data/bin/console +0 -15
- data/bin/setup +0 -8
|
@@ -4,13 +4,17 @@ require 'forwardable'
|
|
|
4
4
|
module ActiveReporting
|
|
5
5
|
class ReportingDimension
|
|
6
6
|
extend Forwardable
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
# Values for the Postgres `date_trunc` method.
|
|
9
|
-
# See https://www.postgresql.org/docs/
|
|
9
|
+
# See https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
|
|
10
10
|
DATETIME_HIERARCHIES = %i[microseconds milliseconds second minute hour day week month quarter year decade
|
|
11
11
|
century millennium date].freeze
|
|
12
|
+
# Column types a datetime drill can be used on. PostgreSQL reports `timestamp with time zone` columns as
|
|
13
|
+
# `timestamptz`, and `timestamp without time zone` columns as `timestamp` when its `datetime_type` is
|
|
14
|
+
# `:timestamptz`.
|
|
15
|
+
DATETIME_DRILL_COLUMN_TYPES = %i[datetime timestamp timestamptz date].freeze
|
|
12
16
|
JOIN_METHODS = { joins: :joins, left_outer_joins: :left_outer_joins }.freeze
|
|
13
|
-
attr_reader :join_method, :label
|
|
17
|
+
attr_reader :join_method, :label, :label_name
|
|
14
18
|
|
|
15
19
|
def_delegators :@dimension, :name, :type, :klass, :association, :model, :hierarchical?
|
|
16
20
|
|
|
@@ -19,15 +23,17 @@ module ActiveReporting
|
|
|
19
23
|
dimension_name, options = dim.is_a?(Hash) ? Array(dim).flatten : [dim, nil]
|
|
20
24
|
found_dimension = fact_model.dimensions[dimension_name.to_sym]
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
if found_dimension.nil?
|
|
27
|
+
raise(UnknownDimension,
|
|
28
|
+
"Dimension '#{dimension_name}' not found on fact model '#{fact_model}'")
|
|
29
|
+
end
|
|
23
30
|
|
|
24
|
-
#
|
|
25
|
-
if !options.is_a?(Hash) && found_dimension.type == Dimension::TYPES[:degenerate]
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
options = { datetime_drill: options }
|
|
31
|
+
# The `{ created_at: :month }` shorthand for datetime drills was removed in 0.7.0
|
|
32
|
+
if options && !options.is_a?(Hash) && found_dimension.type == Dimension::TYPES[:degenerate]
|
|
33
|
+
raise InvalidDimensionLabel,
|
|
34
|
+
"'#{dimension_name}' is not hierarchical. For a datetime drill, use " \
|
|
35
|
+
"`{ #{dimension_name}: { datetime_drill: :#{options} } }` " \
|
|
36
|
+
"instead of `{ #{dimension_name}: :#{options} }`"
|
|
31
37
|
end
|
|
32
38
|
new(found_dimension, **label_config(options))
|
|
33
39
|
end
|
|
@@ -39,9 +45,7 @@ module ActiveReporting
|
|
|
39
45
|
#
|
|
40
46
|
# @param [Symbol|Hash] options
|
|
41
47
|
def self.label_config(options)
|
|
42
|
-
unless options.is_a?(Hash)
|
|
43
|
-
return { label: options }
|
|
44
|
-
end
|
|
48
|
+
return { label: options } unless options.is_a?(Hash)
|
|
45
49
|
|
|
46
50
|
{
|
|
47
51
|
label: options[:field],
|
|
@@ -75,7 +79,7 @@ module ActiveReporting
|
|
|
75
79
|
# @return [Array]
|
|
76
80
|
def select_statement(with_identifier: true)
|
|
77
81
|
ss = ["#{label_fragment} AS #{label_fragment_alias}"]
|
|
78
|
-
ss << "#{identifier_fragment} AS #{identifier_fragment_alias}" if with_identifier &&
|
|
82
|
+
ss << "#{identifier_fragment} AS #{identifier_fragment_alias}" if with_identifier && identifiable?
|
|
79
83
|
ss
|
|
80
84
|
end
|
|
81
85
|
|
|
@@ -84,7 +88,7 @@ module ActiveReporting
|
|
|
84
88
|
# @return [Array]
|
|
85
89
|
def group_by_statement(with_identifier: true)
|
|
86
90
|
group = [label_fragment]
|
|
87
|
-
group << identifier_fragment if with_identifier &&
|
|
91
|
+
group << identifier_fragment if with_identifier && identifiable?
|
|
88
92
|
group
|
|
89
93
|
end
|
|
90
94
|
|
|
@@ -93,36 +97,52 @@ module ActiveReporting
|
|
|
93
97
|
# @return [String]
|
|
94
98
|
def order_by_statement(direction:)
|
|
95
99
|
direction = direction.to_s.upcase
|
|
96
|
-
|
|
100
|
+
unless %w[ASC DESC].include?(direction)
|
|
101
|
+
raise InvalidOrderDirection,
|
|
102
|
+
"Ordering direction for #{name} should be 'asc' or 'desc', got '#{direction.downcase}'"
|
|
103
|
+
end
|
|
104
|
+
|
|
97
105
|
"#{label_fragment} #{direction}"
|
|
98
106
|
end
|
|
99
107
|
|
|
108
|
+
# Tells if the dimension's identifier is included in queries when the report asks for identifiers.
|
|
109
|
+
#
|
|
110
|
+
# Only a standard dimension labeled by its default label has one row per record. Grouping a dimension
|
|
111
|
+
# drilled to a hierarchy level or datetime by its identifier as well would split each roll-up back into one
|
|
112
|
+
# row per record.
|
|
113
|
+
#
|
|
114
|
+
# @return [Boolean]
|
|
115
|
+
def identifiable?
|
|
116
|
+
type == Dimension::TYPES[:standard] && @datetime_drill.nil? && @label == dimension_fact_model.dimension_label
|
|
117
|
+
end
|
|
118
|
+
|
|
100
119
|
# Looks up the dimension label callback for the label
|
|
101
120
|
#
|
|
102
121
|
# @return [Lambda, NilClass]
|
|
103
122
|
def label_callback
|
|
104
|
-
klass.fact_model.dimension_label_callbacks[@label]
|
|
123
|
+
klass.fact_model.dimension_label_callbacks[@label.to_sym]
|
|
105
124
|
end
|
|
106
125
|
|
|
107
126
|
private ####################################################################
|
|
108
127
|
|
|
109
128
|
def determine_label_field(label_field)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
129
|
+
validate_hierarchical_label(label_field) if label_field.present?
|
|
130
|
+
|
|
131
|
+
@label = if type == Dimension::TYPES[:degenerate]
|
|
113
132
|
name
|
|
133
|
+
elsif label_field.present?
|
|
134
|
+
label_field.to_sym
|
|
114
135
|
else
|
|
115
136
|
dimension_fact_model.dimension_label || Configuration.default_dimension_label
|
|
116
137
|
end
|
|
117
138
|
end
|
|
118
139
|
|
|
119
140
|
def determine_label_name(label_name)
|
|
120
|
-
|
|
121
141
|
if label_name
|
|
122
142
|
@label_name = label_name
|
|
123
143
|
else
|
|
124
144
|
@label_name = name
|
|
125
|
-
@label_name += "_#{@label}" if
|
|
145
|
+
@label_name += "_#{@label}" if type == Dimension::TYPES[:standard] && @label != :name
|
|
126
146
|
@label_name += "_#{@datetime_drill}" if @datetime_drill
|
|
127
147
|
end
|
|
128
148
|
@label_name
|
|
@@ -130,6 +150,7 @@ module ActiveReporting
|
|
|
130
150
|
|
|
131
151
|
def determine_datetime_drill(datetime_drill)
|
|
132
152
|
return unless datetime_drill
|
|
153
|
+
|
|
133
154
|
validate_supported_database_for_datetime_hierarchies
|
|
134
155
|
validate_against_datetime_hierarchies(datetime_drill)
|
|
135
156
|
validate_label_is_datetime
|
|
@@ -147,18 +168,19 @@ module ActiveReporting
|
|
|
147
168
|
end
|
|
148
169
|
|
|
149
170
|
def validate_hierarchical_label(hierarchical_label)
|
|
150
|
-
|
|
171
|
+
validate_dimension_is_hierarchical(hierarchical_label)
|
|
151
172
|
validate_against_fact_model_properties(hierarchical_label)
|
|
152
|
-
true
|
|
153
173
|
end
|
|
154
174
|
|
|
155
|
-
def
|
|
175
|
+
def validate_dimension_is_hierarchical(hierarchical_label)
|
|
156
176
|
return if hierarchical?
|
|
177
|
+
|
|
157
178
|
raise InvalidDimensionLabel, "#{name} must be hierarchical to use label #{hierarchical_label}"
|
|
158
179
|
end
|
|
159
180
|
|
|
160
181
|
def validate_supported_database_for_datetime_hierarchies
|
|
161
|
-
return if
|
|
182
|
+
return if datetime_drill_adapter
|
|
183
|
+
|
|
162
184
|
raise InvalidDimensionLabel,
|
|
163
185
|
"Cannot utilize datetime grouping for #{name}; " \
|
|
164
186
|
"database #{model.connection.adapter_name} is not supported"
|
|
@@ -166,67 +188,26 @@ module ActiveReporting
|
|
|
166
188
|
|
|
167
189
|
def validate_against_datetime_hierarchies(hierarchical_label)
|
|
168
190
|
return if DATETIME_HIERARCHIES.include?(hierarchical_label.to_sym)
|
|
191
|
+
|
|
169
192
|
raise InvalidDimensionLabel, "#{hierarchical_label} is not a valid datetime grouping label in #{name}"
|
|
170
193
|
end
|
|
171
194
|
|
|
172
195
|
def validate_label_is_datetime
|
|
173
|
-
return if dimension_fact_model.model.column_for_attribute(@label).type
|
|
174
|
-
|
|
196
|
+
return if DATETIME_DRILL_COLUMN_TYPES.include?(dimension_fact_model.model.column_for_attribute(@label).type)
|
|
197
|
+
|
|
198
|
+
raise InvalidDimensionLabel, "'#{@label}' is not a datetime or date column"
|
|
175
199
|
end
|
|
176
200
|
|
|
177
201
|
def validate_against_fact_model_properties(hierarchical_label)
|
|
178
202
|
return if dimension_fact_model.hierarchical_levels.include?(hierarchical_label.to_sym)
|
|
179
|
-
raise InvalidDimensionLabel, "#{hierarchical_label} is not a hierarchical label in #{name}"
|
|
180
|
-
end
|
|
181
203
|
|
|
182
|
-
|
|
183
|
-
if model.connection.adapter_name == "Mysql2"
|
|
184
|
-
datetime_drill_mysql(column)
|
|
185
|
-
else # Postgress
|
|
186
|
-
datetime_drill_postgress(column)
|
|
187
|
-
end
|
|
204
|
+
raise InvalidDimensionLabel, "#{hierarchical_label} is not a hierarchical label in #{name}"
|
|
188
205
|
end
|
|
189
206
|
|
|
190
|
-
def
|
|
191
|
-
|
|
192
|
-
when :date
|
|
193
|
-
"DATE('#{column}')"
|
|
194
|
-
else
|
|
195
|
-
"DATE_TRUNC('#{@datetime_drill}', #{column})"
|
|
196
|
-
end
|
|
197
|
-
end
|
|
207
|
+
def datetime_drill_adapter
|
|
208
|
+
return @datetime_drill_adapter if defined?(@datetime_drill_adapter)
|
|
198
209
|
|
|
199
|
-
|
|
200
|
-
case @datetime_drill.to_sym
|
|
201
|
-
when :microseconds
|
|
202
|
-
"MICROSECOND(#{column})"
|
|
203
|
-
when :milliseconds
|
|
204
|
-
"MICROSECOND(#{column}) DIV 1000"
|
|
205
|
-
when :second
|
|
206
|
-
"SECOND(#{column})"
|
|
207
|
-
when :minute
|
|
208
|
-
"MINUTE(#{column})"
|
|
209
|
-
when :hour
|
|
210
|
-
"HOUR(#{column})"
|
|
211
|
-
when :day
|
|
212
|
-
"DAY(#{column})"
|
|
213
|
-
when :week
|
|
214
|
-
"WEEKDAY(#{column})"
|
|
215
|
-
when :month
|
|
216
|
-
"MONTH(#{column})"
|
|
217
|
-
when :quarter
|
|
218
|
-
"QUARTER(#{column})"
|
|
219
|
-
when :year
|
|
220
|
-
"YEAR(#{column})"
|
|
221
|
-
when :decade
|
|
222
|
-
"YEAR(#{column}) DIV 10"
|
|
223
|
-
when :century
|
|
224
|
-
"YEAR(#{column}) DIV 100"
|
|
225
|
-
when :millennium
|
|
226
|
-
"YEAR(#{column}) DIV 1000"
|
|
227
|
-
when :date
|
|
228
|
-
"DATE(#{column})"
|
|
229
|
-
end
|
|
210
|
+
@datetime_drill_adapter = DatetimeDrill.adapter_for(model.connection)
|
|
230
211
|
end
|
|
231
212
|
|
|
232
213
|
def identifier_fragment
|
|
@@ -234,17 +215,17 @@ module ActiveReporting
|
|
|
234
215
|
end
|
|
235
216
|
|
|
236
217
|
def identifier_fragment_alias
|
|
237
|
-
|
|
218
|
+
model.connection.quote_column_name("#{name}_identifier").to_s
|
|
238
219
|
end
|
|
239
220
|
|
|
240
221
|
def label_fragment
|
|
241
222
|
fragment = "#{klass.quoted_table_name}.#{model.connection.quote_column_name(@label)}"
|
|
242
|
-
fragment =
|
|
223
|
+
fragment = DatetimeDrill.fragment(datetime_drill_adapter, @datetime_drill, fragment) if @datetime_drill
|
|
243
224
|
fragment
|
|
244
225
|
end
|
|
245
226
|
|
|
246
227
|
def label_fragment_alias
|
|
247
|
-
|
|
228
|
+
model.connection.quote_column_name(@label_name).to_s
|
|
248
229
|
end
|
|
249
230
|
|
|
250
231
|
def dimension_fact_model
|
data/lib/active_reporting.rb
CHANGED
|
@@ -3,43 +3,63 @@
|
|
|
3
3
|
require 'active_record'
|
|
4
4
|
require 'active_reporting/active_record_adaptor'
|
|
5
5
|
require 'active_reporting/configuration'
|
|
6
|
+
require 'active_reporting/datetime_drill'
|
|
6
7
|
require 'active_reporting/dimension'
|
|
7
8
|
require 'active_reporting/dimension_filter'
|
|
8
9
|
require 'active_reporting/metric'
|
|
9
10
|
require 'active_reporting/fact_model'
|
|
11
|
+
require 'active_reporting/fact_model_registry'
|
|
10
12
|
require 'active_reporting/report'
|
|
11
13
|
require 'active_reporting/reporting_dimension'
|
|
12
14
|
require 'active_reporting/version'
|
|
15
|
+
require 'active_reporting/railtie' if defined?(Rails::Railtie)
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
require 'ransack'
|
|
16
|
-
ActiveReporting::Configuration.ransack_available = true
|
|
17
|
-
rescue LoadError, StandardError
|
|
18
|
-
ActiveReporting::Configuration.ransack_available = false
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
ActiveRecord::Base.extend(ActiveReporting::ActiveRecordAdaptor)
|
|
17
|
+
ActiveSupport.on_load(:active_record) { extend ActiveReporting::ActiveRecordAdaptor }
|
|
22
18
|
|
|
23
19
|
module ActiveReporting
|
|
24
20
|
def self.fetch_metric(name)
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
klass_name = Configuration.metric_lookup_class
|
|
22
|
+
klass = klass_name.safe_constantize
|
|
23
|
+
if klass.nil?
|
|
27
24
|
raise BadMetricLookupClass,
|
|
28
|
-
"#{
|
|
29
|
-
'
|
|
25
|
+
"#{klass_name} not defined. Please define a class responsible for looking up a metric by name. " \
|
|
26
|
+
'You may define your own class and set it with `ActiveReporting::Configuration.metric_lookup_class=`.'
|
|
30
27
|
end
|
|
31
|
-
unless klass.
|
|
32
|
-
raise BadMetricLookupClass, "#{
|
|
28
|
+
unless klass.respond_to?(:lookup)
|
|
29
|
+
raise BadMetricLookupClass, "#{klass_name} needs to define a class method called 'lookup'"
|
|
33
30
|
end
|
|
34
|
-
|
|
31
|
+
|
|
32
|
+
klass.lookup(name)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class BadMetricLookupClass < StandardError
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class InvalidDimensionLabel < StandardError
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Subclasses RuntimeError, which was raised for invalid directions before this class existed
|
|
42
|
+
class InvalidOrderDirection < RuntimeError
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class RansackNotAvailable < StandardError
|
|
35
46
|
end
|
|
36
47
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
class UnknownAggregate < StandardError
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class UnknownDimension < StandardError
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class UnknownDimensionFilter < StandardError
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class UnknownMetric < StandardError
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class UnknownMetricFilterOperator < StandardError
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class UnknownJoinMethod < StandardError
|
|
64
|
+
end
|
|
45
65
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_reporting
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tony Drake
|
|
8
|
-
|
|
9
|
-
bindir: exe
|
|
8
|
+
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -16,161 +15,61 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
18
|
+
version: '8.0'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
25
|
+
version: '8.0'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: activesupport
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - ">="
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
32
|
+
version: '8.0'
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - ">="
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
requirements:
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ">="
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: minitest
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '5.0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '5.0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: mysql2
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: pg
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - ">="
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '0'
|
|
90
|
-
type: :development
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - ">="
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: '0'
|
|
97
|
-
- !ruby/object:Gem::Dependency
|
|
98
|
-
name: rake
|
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - ">="
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: '0'
|
|
104
|
-
type: :development
|
|
105
|
-
prerelease: false
|
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
-
requirements:
|
|
108
|
-
- - ">="
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version: '0'
|
|
111
|
-
- !ruby/object:Gem::Dependency
|
|
112
|
-
name: ransack
|
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
|
114
|
-
requirements:
|
|
115
|
-
- - ">="
|
|
116
|
-
- !ruby/object:Gem::Version
|
|
117
|
-
version: '0'
|
|
118
|
-
type: :development
|
|
119
|
-
prerelease: false
|
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
-
requirements:
|
|
122
|
-
- - ">="
|
|
123
|
-
- !ruby/object:Gem::Version
|
|
124
|
-
version: '0'
|
|
125
|
-
- !ruby/object:Gem::Dependency
|
|
126
|
-
name: sqlite3
|
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
|
128
|
-
requirements:
|
|
129
|
-
- - ">="
|
|
130
|
-
- !ruby/object:Gem::Version
|
|
131
|
-
version: '0'
|
|
132
|
-
type: :development
|
|
133
|
-
prerelease: false
|
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
-
requirements:
|
|
136
|
-
- - ">="
|
|
137
|
-
- !ruby/object:Gem::Version
|
|
138
|
-
version: '0'
|
|
139
|
-
description:
|
|
39
|
+
version: '8.0'
|
|
40
|
+
description: ActiveReporting implements ROLAP (Relational Online Analytical Processing)
|
|
41
|
+
concepts such as fact models, dimensions, and metrics on top of ActiveRecord, providing
|
|
42
|
+
a DSL for describing reports and analytics on your data.
|
|
140
43
|
email:
|
|
141
44
|
- t27duck@gmail.com
|
|
142
45
|
executables: []
|
|
143
46
|
extensions: []
|
|
144
47
|
extra_rdoc_files: []
|
|
145
48
|
files:
|
|
146
|
-
- ".github/dependabot.yml"
|
|
147
|
-
- ".github/workflows/tests.yml"
|
|
148
|
-
- ".gitignore"
|
|
149
|
-
- ".rubocop.yml"
|
|
150
49
|
- CHANGELOG.md
|
|
151
|
-
- CODE_OF_CONDUCT.md
|
|
152
|
-
- Gemfile
|
|
153
50
|
- LICENSE.txt
|
|
154
51
|
- README.md
|
|
155
|
-
- Rakefile
|
|
156
|
-
- active_reporting.gemspec
|
|
157
|
-
- bin/console
|
|
158
|
-
- bin/setup
|
|
159
52
|
- lib/active_reporting.rb
|
|
160
53
|
- lib/active_reporting/active_record_adaptor.rb
|
|
161
54
|
- lib/active_reporting/configuration.rb
|
|
55
|
+
- lib/active_reporting/datetime_drill.rb
|
|
162
56
|
- lib/active_reporting/dimension.rb
|
|
163
57
|
- lib/active_reporting/dimension_filter.rb
|
|
164
58
|
- lib/active_reporting/fact_model.rb
|
|
59
|
+
- lib/active_reporting/fact_model_registry.rb
|
|
165
60
|
- lib/active_reporting/metric.rb
|
|
61
|
+
- lib/active_reporting/railtie.rb
|
|
166
62
|
- lib/active_reporting/report.rb
|
|
167
63
|
- lib/active_reporting/reporting_dimension.rb
|
|
168
64
|
- lib/active_reporting/version.rb
|
|
169
65
|
homepage: https://github.com/t27duck/active_reporting
|
|
170
66
|
licenses:
|
|
171
67
|
- MIT
|
|
172
|
-
metadata:
|
|
173
|
-
|
|
68
|
+
metadata:
|
|
69
|
+
bug_tracker_uri: https://github.com/t27duck/active_reporting/issues
|
|
70
|
+
changelog_uri: https://github.com/t27duck/active_reporting/blob/main/CHANGELOG.md
|
|
71
|
+
source_code_uri: https://github.com/t27duck/active_reporting
|
|
72
|
+
rubygems_mfa_required: 'true'
|
|
174
73
|
rdoc_options: []
|
|
175
74
|
require_paths:
|
|
176
75
|
- lib
|
|
@@ -178,15 +77,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
178
77
|
requirements:
|
|
179
78
|
- - ">="
|
|
180
79
|
- !ruby/object:Gem::Version
|
|
181
|
-
version: '
|
|
80
|
+
version: '3.3'
|
|
182
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
82
|
requirements:
|
|
184
83
|
- - ">="
|
|
185
84
|
- !ruby/object:Gem::Version
|
|
186
85
|
version: '0'
|
|
187
86
|
requirements: []
|
|
188
|
-
rubygems_version:
|
|
189
|
-
signing_key:
|
|
87
|
+
rubygems_version: 4.0.20
|
|
190
88
|
specification_version: 4
|
|
191
89
|
summary: Add relational OLAP-like functionality for ActiveRecord
|
|
192
90
|
test_files: []
|
data/.github/dependabot.yml
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
-
# package ecosystems to update and where the package manifests are located.
|
|
3
|
-
# Please see the documentation for all configuration options:
|
|
4
|
-
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
5
|
-
|
|
6
|
-
version: 2
|
|
7
|
-
updates:
|
|
8
|
-
- package-ecosystem: "github-actions"
|
|
9
|
-
directory: "/"
|
|
10
|
-
schedule:
|
|
11
|
-
interval: "weekly"
|