mongoid-report 0.0.10 → 0.0.11
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 +8 -8
- data/Gemfile.lock +1 -1
- data/lib/mongoid/report/attach_proxy.rb +17 -2
- data/lib/mongoid/report/queries_builder.rb +12 -4
- data/lib/mongoid/report/scope.rb +3 -1
- data/lib/mongoid/report/version.rb +1 -1
- data/lib/mongoid/report.rb +29 -34
- data/spec/mongoid/report/aggregation_spec.rb +45 -0
- data/spec/mongoid/report/queries_builder_spec.rb +4 -4
- data/spec/mongoid/report_spec.rb +15 -17
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjViNTY5ZjMxOWYzYWU5ZmY3NGNlMGJkZTVkMjFkZmY5ZGUxMTEyZA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjhiZDUzNWIwNGYxYWI3OGQ4MjJhMDRkYWFmNjVkMmZhNjBlZmY4Zg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MjFhMWU4YWI4YzExYzUyYmI3ZWM4Yzk5OGE3NGJlOWE0OTcyNjY4NmMwODRj
|
10
|
+
ZDQ0NWViMDk4MTk3MWZmODBkZmYwZGQzMjgzNjU4M2VjN2M5ZmQ1MWEwYTZl
|
11
|
+
MTBmMjhjMDIxYzJiNTJkMTAxNzVmYjM1MjUzOTBlMWE3YWU4OTA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2E4NzQzMDJkZGIyOTBmZDJkY2IyNWM3NmUyZGQ0Y2U5YWRiMDM4MGMzOTli
|
14
|
+
Mzg5MDRhZjUwNWVmZTZmMTNlZGY0MTM0N2Y2ZDM4MDI0ZjQ1MjE2ZWYzMjg3
|
15
|
+
ODdjMTA4NDBiMmM2MjhkMzhjZjI2MGM0ZWI0ZWViYjcwYTIyOGU=
|
data/Gemfile.lock
CHANGED
@@ -2,12 +2,27 @@ module Mongoid
|
|
2
2
|
module Report
|
3
3
|
|
4
4
|
AttachProxy = Struct.new(:context, :collection, :options) do
|
5
|
+
attr_reader :attach_name
|
6
|
+
|
7
|
+
def initialize(context, collection, options)
|
8
|
+
# Lets remove as option because of passing to the next blocks options
|
9
|
+
@attach_name = options.delete(:as) || collection
|
10
|
+
options = options.merge(attach_name: attach_name, for: collection)
|
11
|
+
super(context, collection, options)
|
12
|
+
end
|
13
|
+
|
5
14
|
def aggregation_field(*fields)
|
6
|
-
|
15
|
+
field_options = fields.extract_options!
|
16
|
+
field_options.merge!(options)
|
17
|
+
|
18
|
+
context.aggregation_field(*fields, field_options)
|
7
19
|
end
|
8
20
|
|
9
21
|
def group_by(*fields)
|
10
|
-
|
22
|
+
group_options = fields.extract_options!
|
23
|
+
group_options.merge!(options)
|
24
|
+
|
25
|
+
context.group_by(*fields, group_options)
|
11
26
|
end
|
12
27
|
end
|
13
28
|
|
@@ -26,9 +26,17 @@ module Mongoid
|
|
26
26
|
@fields ||= settings[:fields]
|
27
27
|
end
|
28
28
|
|
29
|
+
def in_fields
|
30
|
+
@in_fields ||= fields.keys
|
31
|
+
end
|
32
|
+
|
33
|
+
def output_fields
|
34
|
+
@output_fields ||= fields.values
|
35
|
+
end
|
36
|
+
|
29
37
|
def all_fields
|
30
38
|
[:_id]
|
31
|
-
.concat(
|
39
|
+
.concat(in_fields)
|
32
40
|
.concat(groups)
|
33
41
|
end
|
34
42
|
|
@@ -48,7 +56,7 @@ module Mongoid
|
|
48
56
|
hash.merge!(group => GROUP_TEMPLATE % group)
|
49
57
|
end
|
50
58
|
|
51
|
-
|
59
|
+
in_fields.inject(query) do |hash, field|
|
52
60
|
hash.merge!(field => { '$sum' => GROUP_TEMPLATE % field })
|
53
61
|
end
|
54
62
|
end
|
@@ -67,8 +75,8 @@ module Mongoid
|
|
67
75
|
end
|
68
76
|
end
|
69
77
|
|
70
|
-
fields.inject(query) do |hash, field|
|
71
|
-
hash.merge!(
|
78
|
+
fields.inject(query) do |hash, (field, name)|
|
79
|
+
hash.merge!(name => "$#{field}")
|
72
80
|
end
|
73
81
|
end
|
74
82
|
end
|
data/lib/mongoid/report/scope.rb
CHANGED
@@ -37,7 +37,9 @@ module Mongoid
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def fields
|
40
|
-
|
40
|
+
# We need to use here only output field names it could be different
|
41
|
+
# than defined colunms, Example: field1: 'report-field-name'
|
42
|
+
context.class.settings_property(report_name, :fields).values
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
data/lib/mongoid/report.rb
CHANGED
@@ -49,40 +49,43 @@ module Mongoid
|
|
49
49
|
end
|
50
50
|
|
51
51
|
module ClassMethods
|
52
|
+
def report(name, &block)
|
53
|
+
proxy = ReportProxy.new(self, name)
|
54
|
+
proxy.instance_eval(&block)
|
55
|
+
end
|
56
|
+
|
52
57
|
def attach_to(collection, options = {}, &block)
|
53
58
|
proxy = AttachProxy.new(self, collection, options)
|
54
59
|
proxy.instance_eval(&block)
|
55
60
|
end
|
56
61
|
|
57
62
|
def group_by(*fields)
|
58
|
-
define_report_method(*fields) do |groups, report_name|
|
63
|
+
define_report_method(*fields) do |groups, report_name, _|
|
59
64
|
settings[report_name][:group_by] = groups
|
60
65
|
end
|
61
66
|
end
|
62
67
|
|
63
68
|
def aggregation_field(*fields)
|
64
|
-
define_report_method(*fields) do |columns, report_name|
|
69
|
+
define_report_method(*fields) do |columns, report_name, options|
|
65
70
|
columns.each do |column|
|
66
|
-
|
71
|
+
name = options.fetch(:as) { column }
|
72
|
+
add_field(report_name, column, name)
|
67
73
|
end
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
71
|
-
def report(name, &block)
|
72
|
-
proxy = ReportProxy.new(self, name)
|
73
|
-
proxy.instance_eval(&block)
|
74
|
-
end
|
75
|
-
|
76
77
|
def fields(collection)
|
77
|
-
settings_property(collection, :fields)
|
78
|
+
settings_property(collection, :fields, {})
|
78
79
|
end
|
79
80
|
|
80
81
|
def groups(collection)
|
81
|
-
settings_property(collection, :group_by)
|
82
|
+
settings_property(collection, :group_by, [])
|
82
83
|
end
|
83
84
|
|
84
|
-
def settings_property(collection, key)
|
85
|
-
settings
|
85
|
+
def settings_property(collection, key, default = [])
|
86
|
+
settings
|
87
|
+
.fetch(collection) { {} }
|
88
|
+
.fetch(key) { default }
|
86
89
|
end
|
87
90
|
|
88
91
|
private
|
@@ -90,41 +93,33 @@ module Mongoid
|
|
90
93
|
def define_report_method(*fields)
|
91
94
|
options = fields.extract_options!
|
92
95
|
|
93
|
-
# We should always have for option
|
94
|
-
report_name = initialize_settings_by(options)
|
95
|
-
|
96
|
-
# Because of modifying fields(usign exract options method of
|
97
|
-
# ActiveSupport) lets pass fields to the next block with collection.
|
98
|
-
yield fields, report_name
|
99
|
-
end
|
100
|
-
|
101
|
-
def initialize_settings_by(options)
|
102
96
|
# We should always specify model to attach fields, groups
|
103
97
|
collection = options.fetch(:for)
|
104
98
|
|
105
99
|
# If user didn't pass as option to name the report we are using
|
106
100
|
# collection class as key for settings.
|
107
|
-
|
101
|
+
attach_name = options.fetch(:attach_name) { collection }
|
102
|
+
|
103
|
+
# We should always have for option
|
104
|
+
initialize_settings_by(attach_name, collection)
|
105
|
+
|
106
|
+
# Because of modifying fields(usign exract options method of
|
107
|
+
# ActiveSupport) lets pass fields to the next block with collection.
|
108
|
+
yield fields, attach_name, options || {}
|
109
|
+
end
|
108
110
|
|
109
|
-
|
111
|
+
def initialize_settings_by(attach_name, collection)
|
112
|
+
settings[attach_name] ||= settings.fetch(attach_name) do
|
110
113
|
{
|
111
114
|
for: collection,
|
112
|
-
fields:
|
115
|
+
fields: {},
|
113
116
|
group_by: [],
|
114
117
|
}
|
115
118
|
end
|
116
|
-
|
117
|
-
report_name
|
118
119
|
end
|
119
120
|
|
120
|
-
def add_field(
|
121
|
-
settings[
|
122
|
-
|
123
|
-
class_eval <<-FIELD
|
124
|
-
def #{field}
|
125
|
-
@#{field} ||= 0
|
126
|
-
end
|
127
|
-
FIELD
|
121
|
+
def add_field(attach_name, field, name)
|
122
|
+
settings[attach_name][:fields][field] = name
|
128
123
|
end
|
129
124
|
|
130
125
|
end
|
@@ -166,6 +166,51 @@ describe Mongoid::Report do
|
|
166
166
|
expect(rows[1]['field2']).to eq(2)
|
167
167
|
expect(rows[1]['day']).to eq(yesterday)
|
168
168
|
end
|
169
|
+
|
170
|
+
class Report11
|
171
|
+
include Mongoid::Report
|
172
|
+
|
173
|
+
report 'example' do
|
174
|
+
attach_to Model, as: 'model1' do
|
175
|
+
group_by :day
|
176
|
+
aggregation_field :field1, as: 'new-field1'
|
177
|
+
end
|
178
|
+
|
179
|
+
attach_to Model, as: 'model2' do
|
180
|
+
group_by :day
|
181
|
+
aggregation_field :field2
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should still aggregate with combined report and project using the new names' do
|
187
|
+
klass.create(day: today , field1: 1 , field2: 2)
|
188
|
+
klass.create(day: today , field1: 1 , field2: 2)
|
189
|
+
klass.create(day: yesterday , field1: 1 , field2: 2)
|
190
|
+
klass.create(day: two_days_ago , field1: 1 , field2: 2)
|
191
|
+
|
192
|
+
example = Report11.new
|
193
|
+
scope = example.aggregate
|
194
|
+
scope
|
195
|
+
.query('$match' => { :day => { '$gte' => yesterday.mongoize, '$lte' => today.mongoize } })
|
196
|
+
.yield
|
197
|
+
.query('$sort' => { day: -1 })
|
198
|
+
scope = scope.all
|
199
|
+
|
200
|
+
rows = scope['example-model1']
|
201
|
+
expect(rows.size).to eq(2)
|
202
|
+
expect(rows[0]['new-field1']).to eq(2)
|
203
|
+
expect(rows[0]['day']).to eq(today)
|
204
|
+
expect(rows[1]['new-field1']).to eq(1)
|
205
|
+
expect(rows[1]['day']).to eq(yesterday)
|
206
|
+
|
207
|
+
rows = scope['example-model2']
|
208
|
+
expect(rows.size).to eq(2)
|
209
|
+
expect(rows[0]['field2']).to eq(4)
|
210
|
+
expect(rows[0]['day']).to eq(today)
|
211
|
+
expect(rows[1]['field2']).to eq(2)
|
212
|
+
expect(rows[1]['day']).to eq(yesterday)
|
213
|
+
end
|
169
214
|
end
|
170
215
|
|
171
216
|
end
|
@@ -19,7 +19,7 @@ describe Mongoid::Report::QueriesBuilder do
|
|
19
19
|
expect(queries[2]).to eq(
|
20
20
|
'$project' => {
|
21
21
|
:_id => '$_id',
|
22
|
-
:field1 =>
|
22
|
+
:field1 => '$field1',
|
23
23
|
})
|
24
24
|
end
|
25
25
|
|
@@ -41,7 +41,7 @@ describe Mongoid::Report::QueriesBuilder do
|
|
41
41
|
'$project' => {
|
42
42
|
:_id => 0,
|
43
43
|
:day => '$_id.day',
|
44
|
-
:field1 =>
|
44
|
+
:field1 => '$field1',
|
45
45
|
})
|
46
46
|
end
|
47
47
|
|
@@ -77,8 +77,8 @@ describe Mongoid::Report::QueriesBuilder do
|
|
77
77
|
:_id => 0,
|
78
78
|
:day => '$_id.day',
|
79
79
|
:field2 => '$_id.field2',
|
80
|
-
:field1 =>
|
81
|
-
:field3 =>
|
80
|
+
:field1 => '$field1',
|
81
|
+
:field3 => '$field3',
|
82
82
|
})
|
83
83
|
end
|
84
84
|
end
|
data/spec/mongoid/report_spec.rb
CHANGED
@@ -3,28 +3,13 @@ require 'spec_helper'
|
|
3
3
|
describe Mongoid::Report do
|
4
4
|
|
5
5
|
describe '.aggregation_field' do
|
6
|
-
it 'defines field for aggregation using class method' do
|
7
|
-
example = Report1.new
|
8
|
-
expect(example).to be_respond_to(:field1)
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'defines as reader only' do
|
12
|
-
example = Report1.new
|
13
|
-
expect{ example.field1 = 'value' }.to raise_error
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'defines field with 0 by default' do
|
17
|
-
example = Report1.new
|
18
|
-
expect(example.field1).to eq(0)
|
19
|
-
end
|
20
|
-
|
21
6
|
it 'defines aggegration settings' do
|
22
7
|
expect(Report1).to be_respond_to(:settings)
|
23
8
|
end
|
24
9
|
|
25
10
|
it 'defines aggregation field for specific model to make queries' do
|
26
11
|
fields = Report1.fields(Model)
|
27
|
-
expect(fields).to eq(
|
12
|
+
expect(fields).to eq({ field1: :field1 })
|
28
13
|
end
|
29
14
|
end
|
30
15
|
|
@@ -35,7 +20,7 @@ describe Mongoid::Report do
|
|
35
20
|
|
36
21
|
it 'defines field in terms of attached model' do
|
37
22
|
fields = Report2.fields(Model)
|
38
|
-
expect(fields).to eq(
|
23
|
+
expect(fields).to eq({ field1: :field1 })
|
39
24
|
end
|
40
25
|
end
|
41
26
|
|
@@ -89,4 +74,17 @@ describe Mongoid::Report do
|
|
89
74
|
expect(Report7.settings).to have_key("example-#{Model.collection.name}")
|
90
75
|
end
|
91
76
|
end
|
77
|
+
|
78
|
+
class Report10
|
79
|
+
include Mongoid::Report
|
80
|
+
|
81
|
+
aggregation_field :field1, for: Model, as: 'field-name'
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '.aggregation_field `as` option' do
|
85
|
+
it 'creates settings with report-<attached-model-name' do
|
86
|
+
expect(Report10.fields(Model).keys).to eq([:field1])
|
87
|
+
expect(Report10.fields(Model).values).to eq(['field-name'])
|
88
|
+
end
|
89
|
+
end
|
92
90
|
end
|