bmg 0.18.1 → 0.18.6
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/README.md +4 -0
- data/lib/bmg/algebra.rb +18 -0
- data/lib/bmg/algebra/shortcuts.rb +8 -0
- data/lib/bmg/error.rb +3 -0
- data/lib/bmg/operator.rb +2 -0
- data/lib/bmg/operator/allbut.rb +9 -4
- data/lib/bmg/operator/autosummarize.rb +7 -0
- data/lib/bmg/operator/autowrap.rb +19 -0
- data/lib/bmg/operator/constants.rb +7 -0
- data/lib/bmg/operator/extend.rb +7 -0
- data/lib/bmg/operator/group.rb +1 -0
- data/lib/bmg/operator/image.rb +15 -0
- data/lib/bmg/operator/join.rb +1 -0
- data/lib/bmg/operator/matching.rb +1 -0
- data/lib/bmg/operator/not_matching.rb +1 -0
- data/lib/bmg/operator/page.rb +1 -0
- data/lib/bmg/operator/project.rb +3 -2
- data/lib/bmg/operator/rename.rb +12 -5
- data/lib/bmg/operator/restrict.rb +1 -0
- data/lib/bmg/operator/rxmatch.rb +1 -0
- data/lib/bmg/operator/summarize.rb +2 -17
- data/lib/bmg/operator/transform.rb +1 -0
- data/lib/bmg/operator/ungroup.rb +61 -0
- data/lib/bmg/operator/union.rb +1 -0
- data/lib/bmg/operator/unwrap.rb +47 -0
- data/lib/bmg/reader/csv.rb +29 -10
- data/lib/bmg/reader/excel.rb +23 -4
- data/lib/bmg/relation.rb +18 -0
- data/lib/bmg/relation/empty.rb +4 -0
- data/lib/bmg/relation/in_memory.rb +10 -1
- data/lib/bmg/relation/materialized.rb +6 -0
- data/lib/bmg/relation/spied.rb +5 -0
- data/lib/bmg/sequel/relation.rb +5 -0
- data/lib/bmg/sql/relation.rb +2 -2
- data/lib/bmg/summarizer.rb +36 -1
- data/lib/bmg/summarizer/avg.rb +3 -3
- data/lib/bmg/summarizer/by_proc.rb +41 -0
- data/lib/bmg/summarizer/distinct.rb +36 -0
- data/lib/bmg/summarizer/multiple.rb +46 -0
- data/lib/bmg/summarizer/percentile.rb +79 -0
- data/lib/bmg/summarizer/value_by.rb +62 -0
- data/lib/bmg/support/keys.rb +5 -0
- data/lib/bmg/support/tuple_transformer.rb +10 -1
- data/lib/bmg/type.rb +19 -1
- data/lib/bmg/version.rb +1 -1
- data/lib/bmg/writer.rb +16 -0
- data/lib/bmg/writer/csv.rb +2 -12
- data/lib/bmg/writer/xlsx.rb +68 -0
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 482e0bb06c06e4afc620696491cf75f788902240c75f9c82d71ce9b0db4deee1
|
4
|
+
data.tar.gz: f49609c7cf929149d91bb1c29703fd4e5fb7d861073b38ad916a851214ec20b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4068309c373faa50bfc4549648ee26e3220187192a529ee8c6c890424c52b4d05103c2ebf7b137354c1c8a82a756eafbdb5c6b266f489c3c6e0a0b9923a4d15
|
7
|
+
data.tar.gz: ba7a0046919e2d796c58cae326f3d4cf7b86f6d577e34f79395c04286c4bf463cb4c349cb2a5ce4611fbd6e310ebf521736fb190bcc1d1c2c42c51ccc175fb2e
|
data/README.md
CHANGED
@@ -234,7 +234,11 @@ t.transform(:to_s) # all-attrs transformation
|
|
234
234
|
t.transform(&:to_s) # similar, but Proc-driven
|
235
235
|
t.transform(:foo => :upcase, ...) # specific-attrs tranformation
|
236
236
|
t.transform([:to_s, :upcase]) # chain-transformation
|
237
|
+
r.ungroup([:a, :b, ...]) # ungroup relation-valued attributes within parent tuple
|
238
|
+
r.ungroup(:a) # shortcut over ungroup([:a])
|
237
239
|
r.union(right) # relational union
|
240
|
+
r.unwrap([:a, :b, ...]) # merge tuple-valued attributes within parent tuple
|
241
|
+
r.unwrap(:a) # shortcut over unwrap([:a])
|
238
242
|
r.where(predicate) # alias for restrict(predicate)
|
239
243
|
```
|
240
244
|
|
data/lib/bmg/algebra.rb
CHANGED
@@ -183,6 +183,15 @@ module Bmg
|
|
183
183
|
end
|
184
184
|
protected :_transform
|
185
185
|
|
186
|
+
def ungroup(attrs)
|
187
|
+
_ungroup self.type.ungroup(attrs), attrs
|
188
|
+
end
|
189
|
+
|
190
|
+
def _ungroup(type, attrs)
|
191
|
+
Operator::Ungroup.new(type, self, attrs)
|
192
|
+
end
|
193
|
+
protected :_ungroup
|
194
|
+
|
186
195
|
def union(other, options = {})
|
187
196
|
return self if other.is_a?(Relation::Empty)
|
188
197
|
_union self.type.union(other.type), other, options
|
@@ -193,6 +202,15 @@ module Bmg
|
|
193
202
|
end
|
194
203
|
protected :_union
|
195
204
|
|
205
|
+
def unwrap(attrs)
|
206
|
+
_unwrap self.type.unwrap(attrs), attrs
|
207
|
+
end
|
208
|
+
|
209
|
+
def _unwrap(type, attrs)
|
210
|
+
Operator::Unwrap.new(type, self, attrs)
|
211
|
+
end
|
212
|
+
protected :_unwrap
|
213
|
+
|
196
214
|
def spied(spy)
|
197
215
|
return self if spy.nil?
|
198
216
|
Relation::Spied.new(self, spy)
|
@@ -69,6 +69,14 @@ module Bmg
|
|
69
69
|
self.not_matching(right.rename(renaming), on.keys)
|
70
70
|
end
|
71
71
|
|
72
|
+
def ungroup(attr)
|
73
|
+
super(attr.is_a?(Symbol) ? [attr] : attr)
|
74
|
+
end
|
75
|
+
|
76
|
+
def unwrap(attr)
|
77
|
+
super(attr.is_a?(Symbol) ? [attr] : attr)
|
78
|
+
end
|
79
|
+
|
72
80
|
end # module Shortcuts
|
73
81
|
end # module Algebra
|
74
82
|
end # module Bmg
|
data/lib/bmg/error.rb
CHANGED
data/lib/bmg/operator.rb
CHANGED
@@ -47,4 +47,6 @@ require_relative 'operator/restrict'
|
|
47
47
|
require_relative 'operator/rxmatch'
|
48
48
|
require_relative 'operator/summarize'
|
49
49
|
require_relative 'operator/transform'
|
50
|
+
require_relative 'operator/ungroup'
|
50
51
|
require_relative 'operator/union'
|
52
|
+
require_relative 'operator/unwrap'
|
data/lib/bmg/operator/allbut.rb
CHANGED
@@ -30,6 +30,7 @@ module Bmg
|
|
30
30
|
public
|
31
31
|
|
32
32
|
def each
|
33
|
+
return to_enum unless block_given?
|
33
34
|
seen = {}
|
34
35
|
@operand.each do |tuple|
|
35
36
|
allbuted = tuple_allbut(tuple)
|
@@ -74,15 +75,19 @@ module Bmg
|
|
74
75
|
operand.matching(right, on).allbut(butlist)
|
75
76
|
end
|
76
77
|
|
77
|
-
def _restrict(type, predicate)
|
78
|
-
operand.restrict(predicate).allbut(butlist)
|
79
|
-
end
|
80
|
-
|
81
78
|
def _page(type, ordering, page_index, options)
|
82
79
|
return super unless self.preserving_key?
|
83
80
|
operand.page(ordering, page_index, options).allbut(butlist)
|
84
81
|
end
|
85
82
|
|
83
|
+
def _project(type, attrlist)
|
84
|
+
operand.project(attrlist)
|
85
|
+
end
|
86
|
+
|
87
|
+
def _restrict(type, predicate)
|
88
|
+
operand.restrict(predicate).allbut(butlist)
|
89
|
+
end
|
90
|
+
|
86
91
|
protected ### inspect
|
87
92
|
|
88
93
|
def preserving_key?
|
@@ -41,6 +41,7 @@ module Bmg
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def each(&bl)
|
44
|
+
return to_enum unless block_given?
|
44
45
|
h = {}
|
45
46
|
@operand.each do |tuple|
|
46
47
|
key = key(tuple)
|
@@ -57,6 +58,12 @@ module Bmg
|
|
57
58
|
[:autosummarize, operand.to_ast, by.dup, sums.dup]
|
58
59
|
end
|
59
60
|
|
61
|
+
public ### for internal reasons
|
62
|
+
|
63
|
+
def _count
|
64
|
+
operand._count
|
65
|
+
end
|
66
|
+
|
60
67
|
protected
|
61
68
|
|
62
69
|
def _restrict(type, predicate)
|
@@ -43,6 +43,7 @@ module Bmg
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def each
|
46
|
+
return to_enum unless block_given?
|
46
47
|
@operand.each do |tuple|
|
47
48
|
yield autowrap_tuple(tuple)
|
48
49
|
end
|
@@ -52,6 +53,12 @@ module Bmg
|
|
52
53
|
[ :autowrap, operand.to_ast, @original_options.dup ]
|
53
54
|
end
|
54
55
|
|
56
|
+
public ### for internal reasons
|
57
|
+
|
58
|
+
def _count
|
59
|
+
operand._count
|
60
|
+
end
|
61
|
+
|
55
62
|
protected ### optimization
|
56
63
|
|
57
64
|
def _autowrap(type, opts)
|
@@ -92,6 +99,8 @@ module Bmg
|
|
92
99
|
else
|
93
100
|
super
|
94
101
|
end
|
102
|
+
rescue UnknownAttributesError
|
103
|
+
super
|
95
104
|
end
|
96
105
|
|
97
106
|
def _page(type, ordering, page_index, opts)
|
@@ -105,6 +114,16 @@ module Bmg
|
|
105
114
|
super
|
106
115
|
end
|
107
116
|
|
117
|
+
def _project(type, attrlist)
|
118
|
+
if (wrapped_roots! & attrlist).empty?
|
119
|
+
operand.project(attrlist).autowrap(options)
|
120
|
+
else
|
121
|
+
super
|
122
|
+
end
|
123
|
+
rescue UnknownAttributesError
|
124
|
+
super
|
125
|
+
end
|
126
|
+
|
108
127
|
def _rename(type, renaming)
|
109
128
|
# 1. Can't optimize if renaming applies to a wrapped one
|
110
129
|
return super unless (wrapped_roots! & renaming.keys).empty?
|
@@ -23,6 +23,7 @@ module Bmg
|
|
23
23
|
public
|
24
24
|
|
25
25
|
def each
|
26
|
+
return to_enum unless block_given?
|
26
27
|
@operand.each do |tuple|
|
27
28
|
yield extend_it(tuple)
|
28
29
|
end
|
@@ -54,6 +55,12 @@ module Bmg
|
|
54
55
|
[ :constants, operand.to_ast, constants.dup ]
|
55
56
|
end
|
56
57
|
|
58
|
+
public ### for internal reasons
|
59
|
+
|
60
|
+
def _count
|
61
|
+
operand._count
|
62
|
+
end
|
63
|
+
|
57
64
|
protected ### optimization
|
58
65
|
|
59
66
|
def _page(type, ordering, page_index, options)
|
data/lib/bmg/operator/extend.rb
CHANGED
@@ -26,6 +26,7 @@ module Bmg
|
|
26
26
|
public
|
27
27
|
|
28
28
|
def each
|
29
|
+
return to_enum unless block_given?
|
29
30
|
@operand.each do |tuple|
|
30
31
|
yield extend_it(tuple)
|
31
32
|
end
|
@@ -53,6 +54,12 @@ module Bmg
|
|
53
54
|
[ :extend, operand.to_ast, extension.dup ]
|
54
55
|
end
|
55
56
|
|
57
|
+
public ### for internal reasons
|
58
|
+
|
59
|
+
def _count
|
60
|
+
operand._count
|
61
|
+
end
|
62
|
+
|
56
63
|
protected ### optimization
|
57
64
|
|
58
65
|
def _allbut(type, butlist)
|
data/lib/bmg/operator/group.rb
CHANGED
data/lib/bmg/operator/image.rb
CHANGED
@@ -46,6 +46,7 @@ module Bmg
|
|
46
46
|
public
|
47
47
|
|
48
48
|
def each(*args, &bl)
|
49
|
+
return to_enum unless block_given?
|
49
50
|
(options[:jit_optimized] ? self : jit_optimize)._each(*args, &bl)
|
50
51
|
end
|
51
52
|
|
@@ -155,6 +156,12 @@ module Bmg
|
|
155
156
|
end
|
156
157
|
end
|
157
158
|
|
159
|
+
public ### for internal reasons
|
160
|
+
|
161
|
+
def _count
|
162
|
+
left._count
|
163
|
+
end
|
164
|
+
|
158
165
|
protected ### optimization
|
159
166
|
|
160
167
|
def _allbut(type, butlist)
|
@@ -185,6 +192,14 @@ module Bmg
|
|
185
192
|
end
|
186
193
|
end
|
187
194
|
|
195
|
+
def _project(type, attrlist)
|
196
|
+
if attrlist.include?(as)
|
197
|
+
super
|
198
|
+
else
|
199
|
+
left.project(attrlist)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
188
203
|
def _restrict(type, predicate)
|
189
204
|
on_as, rest = predicate.and_split([as])
|
190
205
|
if rest.tautology?
|
data/lib/bmg/operator/join.rb
CHANGED
data/lib/bmg/operator/page.rb
CHANGED
data/lib/bmg/operator/project.rb
CHANGED
@@ -29,9 +29,10 @@ module Bmg
|
|
29
29
|
public
|
30
30
|
|
31
31
|
def each
|
32
|
+
return to_enum unless block_given?
|
32
33
|
seen = {}
|
33
34
|
@operand.each do |tuple|
|
34
|
-
projected =
|
35
|
+
projected = tuple_project(tuple)
|
35
36
|
unless seen.has_key?(projected)
|
36
37
|
yield(projected)
|
37
38
|
seen[projected] = true
|
@@ -74,7 +75,7 @@ module Bmg
|
|
74
75
|
|
75
76
|
private
|
76
77
|
|
77
|
-
def
|
78
|
+
def tuple_project(tuple)
|
78
79
|
tuple.dup.delete_if{|k,_| !@attrlist.include?(k) }
|
79
80
|
end
|
80
81
|
|
data/lib/bmg/operator/rename.rb
CHANGED
@@ -29,16 +29,17 @@ module Bmg
|
|
29
29
|
public
|
30
30
|
|
31
31
|
def each
|
32
|
+
return to_enum unless block_given?
|
32
33
|
@operand.each do |tuple|
|
33
|
-
yield
|
34
|
+
yield rename_tuple(tuple, renaming)
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
38
|
def insert(arg)
|
38
39
|
case arg
|
39
|
-
when Hash then operand.insert(
|
40
|
+
when Hash then operand.insert(rename_tuple(arg, reverse_renaming))
|
40
41
|
when Relation then operand.insert(arg.rename(reverse_renaming))
|
41
|
-
when Enumerable then operand.insert(arg.map{|t|
|
42
|
+
when Enumerable then operand.insert(arg.map{|t| rename_tuple(t, reverse_renaming) })
|
42
43
|
else
|
43
44
|
super
|
44
45
|
end
|
@@ -46,7 +47,7 @@ module Bmg
|
|
46
47
|
|
47
48
|
def update(arg)
|
48
49
|
case arg
|
49
|
-
when Hash then operand.update(
|
50
|
+
when Hash then operand.update(rename_tuple(arg, reverse_renaming))
|
50
51
|
else
|
51
52
|
super
|
52
53
|
end
|
@@ -60,6 +61,12 @@ module Bmg
|
|
60
61
|
[ :rename, operand.to_ast, renaming.dup ]
|
61
62
|
end
|
62
63
|
|
64
|
+
public ### for internal reasons
|
65
|
+
|
66
|
+
def _count
|
67
|
+
operand._count
|
68
|
+
end
|
69
|
+
|
63
70
|
protected ### optimization
|
64
71
|
|
65
72
|
def _page(type, ordering, page_index, options)
|
@@ -82,7 +89,7 @@ module Bmg
|
|
82
89
|
|
83
90
|
private
|
84
91
|
|
85
|
-
def
|
92
|
+
def rename_tuple(tuple, renaming)
|
86
93
|
tuple.each_with_object({}){|(k,v),h|
|
87
94
|
h[renaming[k] || k] = v
|
88
95
|
h
|
data/lib/bmg/operator/rxmatch.rb
CHANGED
@@ -13,7 +13,7 @@ module Bmg
|
|
13
13
|
@type = type
|
14
14
|
@operand = operand
|
15
15
|
@by = by
|
16
|
-
@summarization =
|
16
|
+
@summarization = Summarizer.summarization(summarization)
|
17
17
|
end
|
18
18
|
|
19
19
|
protected
|
@@ -23,6 +23,7 @@ module Bmg
|
|
23
23
|
public
|
24
24
|
|
25
25
|
def each
|
26
|
+
return to_enum unless block_given?
|
26
27
|
# summary key => summarization memo, starting with least
|
27
28
|
result = Hash.new{|h,k|
|
28
29
|
h[k] = Hash[@summarization.map{|k,v|
|
@@ -56,22 +57,6 @@ module Bmg
|
|
56
57
|
[ by, summarization ]
|
57
58
|
end
|
58
59
|
|
59
|
-
private
|
60
|
-
|
61
|
-
# Compile a summarization hash so that every value is a Summarizer
|
62
|
-
# instance
|
63
|
-
def self.compile(summarization)
|
64
|
-
Hash[summarization.map{|k,v|
|
65
|
-
summarizer = case v
|
66
|
-
when Summarizer then v
|
67
|
-
when Symbol then Summarizer.send(v, k)
|
68
|
-
else
|
69
|
-
raise ArgumentError, "Unexpected summarizer #{k} => #{v}"
|
70
|
-
end
|
71
|
-
[ k, summarizer ]
|
72
|
-
}]
|
73
|
-
end
|
74
|
-
|
75
60
|
end # class Summarize
|
76
61
|
end # module Operator
|
77
62
|
end # module Bmg
|