bmg 0.18.7 → 0.18.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: b7b4d39e83f04ee58369bef32ce396893d5ac98d357fd8c497d309fa17cc93b2
4
- data.tar.gz: b36344887bb1142c4ddd3de0eb4419c0ba1821490a9c8c336668c37008e59156
2
+ SHA1:
3
+ metadata.gz: eda140880e29f5e083ad334176579ed2dfad9090
4
+ data.tar.gz: 444a8cc5f96b80ba3bbf6d807be1438c2d26abd7
5
5
  SHA512:
6
- metadata.gz: c21cc2eb5c0e0e93cb8c4afc823855140051112f6ac5bd896181634edb67f87fca9b88f4a16c0ec70da36c8ce937e3265ade2506e7077f103e4fb46409b8dded
7
- data.tar.gz: b40c206ad43a6ec36e4951c8ff8d531872154e0e855f055f62059ff3af9f0d35e7d96f2443e8046bd107741c4df481aa4ebc2b680ccf1fc88181b988add1d2d6
6
+ metadata.gz: 96ecc393e90d3ae413655d70c4b1676fa2f9831e519ef61cbd25139b873efcd75a825745cce0597e083fc59bc331b08d30b5717b1e5b42adacb5297147a044bd
7
+ data.tar.gz: dc687db5b22f9f3fc53b2ccf0916722065ca7d25b8ad04b0a042c6d79fd66f40c22f2d05461da8019db8b70f54c4c104658f3dce3862f9a37b2af44c6ee25d61
@@ -22,6 +22,7 @@ module Bmg
22
22
 
23
23
  DEFAULT_OPTIONS = {
24
24
  :postprocessor => :none,
25
+ :postprocessor_condition => :all,
25
26
  :split => "_"
26
27
  }
27
28
 
@@ -167,7 +168,7 @@ module Bmg
167
168
 
168
169
  def normalize_options(options)
169
170
  opts = DEFAULT_OPTIONS.merge(options)
170
- opts[:postprocessor] = NoLeftJoinNoise.new(opts[:postprocessor])
171
+ opts[:postprocessor] = NoLeftJoinNoise.new(opts[:postprocessor], opts[:postprocessor_condition])
171
172
  opts
172
173
  end
173
174
 
@@ -209,17 +210,17 @@ module Bmg
209
210
  class NoLeftJoinNoise
210
211
 
211
212
  REMOVERS = {
212
- nil: ->(t,k){ t[k] = nil },
213
- delete: ->(t,k){ t.delete(k) },
214
- none: ->(t,k){ t }
213
+ nil: ->(t,k){ t[k] = nil },
214
+ delete: ->(t,k){ t.delete(k) },
215
+ none: ->(t,k){ t }
215
216
  }
216
217
 
217
- def self.new(remover)
218
+ def self.new(remover, remover_condition = :all)
218
219
  return remover if remover.is_a?(NoLeftJoinNoise)
219
220
  super
220
221
  end
221
222
 
222
- def initialize(remover)
223
+ def initialize(remover, remover_condition = :all)
223
224
  @remover_to_s = remover
224
225
  @remover = case remover
225
226
  when NilClass then REMOVERS[:none]
@@ -229,22 +230,35 @@ module Bmg
229
230
  else
230
231
  raise "Invalid remover `#{remover}`"
231
232
  end
233
+ @remover_condition = case remover_condition
234
+ when :all then ->(tuple){ all_nil?(tuple) }
235
+ when :id then ->(tuple){ id_nil?(tuple) }
236
+ else
237
+ raise "Invalid remover condition `#{remover_condition}`"
238
+ end
232
239
  end
233
240
  attr_reader :remover
234
241
 
235
242
  def call(tuple)
236
243
  tuple.each_key do |k|
237
244
  call(tuple[k]) if tuple[k].is_a?(Hash)
238
- @remover.call(tuple, k) if tuple[k].is_a?(Hash) && all_nil?(tuple[k])
245
+ @remover.call(tuple, k) if tuple[k].is_a?(Hash) && @remover_condition.call(tuple[k])
239
246
  end
240
247
  tuple
241
248
  end
242
249
 
243
250
  def all_nil?(tuple)
244
251
  return false unless tuple.is_a?(Hash)
252
+
245
253
  tuple.all?{|(k,v)| v.nil? || all_nil?(tuple[k]) }
246
254
  end
247
255
 
256
+ def id_nil?(tuple)
257
+ return false unless tuple.is_a?(Hash)
258
+
259
+ tuple[:id].nil?
260
+ end
261
+
248
262
  def inspect
249
263
  @remover_to_s.inspect
250
264
  end
@@ -4,6 +4,7 @@ module Bmg
4
4
  include Reader
5
5
 
6
6
  DEFAULT_OPTIONS = {
7
+ sheet: 0,
7
8
  skip: 0,
8
9
  row_num: true
9
10
  }
@@ -19,7 +20,7 @@ module Bmg
19
20
  require 'roo'
20
21
  xlsx = Roo::Spreadsheet.open(@path, @options)
21
22
  headers = nil
22
- xlsx.sheet(0)
23
+ xlsx.sheet(@options[:sheet])
23
24
  .each
24
25
  .drop(@options[:skip])
25
26
  .each_with_index
@@ -90,11 +90,17 @@ module Bmg
90
90
  end
91
91
 
92
92
  def on_summarizer(sexpr)
93
- if sexpr.summary_expr
94
- ::Sequel.function(sexpr.summary_func, apply(sexpr.summary_expr))
93
+ func, distinct = if sexpr.summary_func == :distinct_count
94
+ [:count, true]
95
95
  else
96
- ::Sequel.function(sexpr.summary_func).*
96
+ [sexpr.summary_func, false]
97
97
  end
98
+ f = if sexpr.summary_expr
99
+ ::Sequel.function(func, apply(sexpr.summary_expr))
100
+ else
101
+ ::Sequel.function(func).*
102
+ end
103
+ distinct ? f.distinct : f
98
104
  end
99
105
 
100
106
  def on_qualified_name(sexpr)
@@ -36,10 +36,10 @@ module Bmg
36
36
  [:select_item,
37
37
  [ :summarizer,
38
38
  summarizer.to_summarizer_name,
39
- sexpr.desaliaser[attr] ],
39
+ sexpr.desaliaser[summarizer.functor] ],
40
40
  [:column_name, attr.to_s] ]
41
41
  }
42
- [:select_list] + by_list + group_list
42
+ ([:select_list] + by_list + group_list)
43
43
  end
44
44
 
45
45
  end # class Summarize
@@ -160,7 +160,7 @@ module Bmg
160
160
 
161
161
  def can_compile_summarization?(summarization)
162
162
  summarization.values.all?{|s|
163
- [:avg, :count, :max, :min, :sum].include?(s.to_summarizer_name)
163
+ [:avg, :count, :max, :min, :sum, :distinct_count].include?(s.to_summarizer_name)
164
164
  }
165
165
  end
166
166
 
@@ -213,8 +213,7 @@ module Bmg
213
213
  def _collect_joins(sexpr, joins)
214
214
  case sexpr.first
215
215
  when :and
216
- _collect_joins(sexpr[1], joins)
217
- _collect_joins(sexpr[2], joins)
216
+ sexpr[1..-1].each{ |term| _collect_joins(term, joins) }
218
217
  when :eq
219
218
  joins << sexpr
220
219
  else
@@ -0,0 +1,36 @@
1
+ module Bmg
2
+ class Summarizer
3
+ #
4
+ # Collect the count of distinct values.
5
+ #
6
+ # Example:
7
+ #
8
+ # # direct ruby usage
9
+ # Bmg::Summarizer.distinct_count(:qty).summarize(...)
10
+ #
11
+ class DistinctCount < Summarizer
12
+
13
+ # Returns [] as least value.
14
+ def least()
15
+ {}
16
+ end
17
+
18
+ # Adds val to the memo array
19
+ def _happens(memo, val)
20
+ memo[val] = true
21
+ memo
22
+ end
23
+
24
+ def finalize(memo)
25
+ memo.keys.size
26
+ end
27
+
28
+ end # class DistinctCount
29
+
30
+ # Factors a distinct count summarizer
31
+ def self.distinct_count(*args, &bl)
32
+ DistinctCount.new(*args, &bl)
33
+ end
34
+
35
+ end # class Summarizer
36
+ end # module Bmg
@@ -0,0 +1,25 @@
1
+ module Bmg
2
+ class Summarizer
3
+ #
4
+ # First summarizer.
5
+ #
6
+ # Example:
7
+ #
8
+ # # direct ruby usage
9
+ # Bmg::Summarizer.first(:qty, :order => [:id]).summarize(...)
10
+ #
11
+ class First < Positional
12
+
13
+ def choose(t1, t2)
14
+ t1
15
+ end
16
+
17
+ end # class First
18
+
19
+ # Factors a first summarizer
20
+ def self.first(*args, &bl)
21
+ First.new(*args, &bl)
22
+ end
23
+
24
+ end # class Summarizer
25
+ end # module Bmg
@@ -0,0 +1,25 @@
1
+ module Bmg
2
+ class Summarizer
3
+ #
4
+ # Last summarizer.
5
+ #
6
+ # Example:
7
+ #
8
+ # # direct ruby usage
9
+ # Bmg::Summarizer.last(:qty, :order => [:id]).summarize(...)
10
+ #
11
+ class Last < Positional
12
+
13
+ def choose(t1, t2)
14
+ t2
15
+ end
16
+
17
+ end # class Last
18
+
19
+ # Factors a last summarizer
20
+ def self.last(*args, &bl)
21
+ Last.new(*args, &bl)
22
+ end
23
+
24
+ end # class Summarizer
25
+ end # module Bmg
@@ -0,0 +1,33 @@
1
+ module Bmg
2
+ class Summarizer
3
+ # See First and Last
4
+ class Positional < Summarizer
5
+
6
+ def initialize(*args, &block)
7
+ super
8
+ raise ArgumentError, "Missing order" unless options[:order]
9
+ @ordering = Ordering.new(options[:order])
10
+ end
11
+ attr_reader :ordering
12
+
13
+ def least
14
+ nil
15
+ end
16
+
17
+ def happens(memo, tuple)
18
+ if memo.nil?
19
+ tuple
20
+ else
21
+ c = ordering.call(memo, tuple)
22
+ c <= 0 ? choose(memo, tuple) : choose(tuple, memo)
23
+ end
24
+ end
25
+
26
+ def finalize(memo)
27
+ return nil if memo.nil?
28
+ extract_value(memo)
29
+ end
30
+
31
+ end # class Positional
32
+ end # class Summarizer
33
+ end # module Bmg
@@ -131,7 +131,10 @@ module Bmg
131
131
 
132
132
  # Returns the canonical summarizer name
133
133
  def to_summarizer_name
134
- self.class.name.downcase[/::([a-z]+)$/, 1].to_sym
134
+ self.class.name
135
+ .gsub(/[a-z][A-Z]/){|x| x.split('').join('_') }
136
+ .downcase[/::([a-z_]+)$/, 1]
137
+ .to_sym
135
138
  end
136
139
 
137
140
  protected
@@ -161,7 +164,11 @@ require_relative 'summarizer/stddev'
161
164
  require_relative 'summarizer/percentile'
162
165
  require_relative 'summarizer/collect'
163
166
  require_relative 'summarizer/distinct'
167
+ require_relative 'summarizer/distinct_count'
164
168
  require_relative 'summarizer/concat'
165
169
  require_relative 'summarizer/by_proc'
166
170
  require_relative 'summarizer/multiple'
167
171
  require_relative 'summarizer/value_by'
172
+ require_relative 'summarizer/positional'
173
+ require_relative 'summarizer/first'
174
+ require_relative 'summarizer/last'
@@ -6,8 +6,12 @@ module Bmg
6
6
  end
7
7
  attr_reader :attrs
8
8
 
9
+ def call(t1, t2)
10
+ comparator.call(t1, t2)
11
+ end
12
+
9
13
  def comparator
10
- ->(t1, t2) {
14
+ @comparator ||= ->(t1, t2) {
11
15
  attrs.each do |(attr,direction)|
12
16
  c = t1[attr] <=> t2[attr]
13
17
  return (direction == :desc ? -c : c) unless c==0
data/lib/bmg/version.rb CHANGED
@@ -2,7 +2,7 @@ module Bmg
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 18
5
- TINY = 7
5
+ TINY = 11
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
metadata CHANGED
@@ -1,35 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bmg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.7
4
+ version: 0.18.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-14 00:00:00.000000000 Z
11
+ date: 2021-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: predicate
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 2.5.0
20
17
  - - "~>"
21
18
  - !ruby/object:Gem::Version
22
- version: '2.5'
19
+ version: '2.6'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.6.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 2.5.0
30
27
  - - "~>"
31
28
  - !ruby/object:Gem::Version
32
- version: '2.5'
29
+ version: '2.6'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.6.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: path
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -273,10 +273,14 @@ files:
273
273
  - lib/bmg/summarizer/concat.rb
274
274
  - lib/bmg/summarizer/count.rb
275
275
  - lib/bmg/summarizer/distinct.rb
276
+ - lib/bmg/summarizer/distinct_count.rb
277
+ - lib/bmg/summarizer/first.rb
278
+ - lib/bmg/summarizer/last.rb
276
279
  - lib/bmg/summarizer/max.rb
277
280
  - lib/bmg/summarizer/min.rb
278
281
  - lib/bmg/summarizer/multiple.rb
279
282
  - lib/bmg/summarizer/percentile.rb
283
+ - lib/bmg/summarizer/positional.rb
280
284
  - lib/bmg/summarizer/stddev.rb
281
285
  - lib/bmg/summarizer/sum.rb
282
286
  - lib/bmg/summarizer/value_by.rb
@@ -313,7 +317,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
313
317
  - !ruby/object:Gem::Version
314
318
  version: '0'
315
319
  requirements: []
316
- rubygems_version: 3.0.8
320
+ rubyforge_project:
321
+ rubygems_version: 2.6.14.4
317
322
  signing_key:
318
323
  specification_version: 4
319
324
  summary: Bmg is Alf's successor.