bmg 0.18.2 → 0.18.3

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
2
  SHA256:
3
- metadata.gz: 2c9b490328160c9816102f7dd34b3ee46207ab4362cd2af6d8623c9fc5d4b87a
4
- data.tar.gz: d113dc14ae1811f2b5565af9e84a0ffbc82b7842c46284af7fcad3bc9f3b7470
3
+ metadata.gz: 340efbb84309b24fd818bd8ff0c0f40b1f2ba3b3f087e3af0ea574fbd1f7c4ef
4
+ data.tar.gz: d7c6af70390c893f6e198f89a019141b4d5727326183f1663aa7d2e15a7ef694
5
5
  SHA512:
6
- metadata.gz: fd42b8787cc093c6452386760744d7480c64c8be186ab73b87a548a1b853643b46a6ad48cf019da9d77fddbb38c824eb0e0bef3ef5fa2f333f1d1240f5a0bd84
7
- data.tar.gz: 7bd0cd32a28963123b03b59152fa03d6470bbdf1a3c6cfe0b17a6667a80d97e65d5309def4e31ec9cbb47353d409ad9ad2a6d1fbc9c2ec10797460852836ce35
6
+ metadata.gz: 69562558e784e35f6c8a81bf8b32f8f1a24bbabc176ca8fc109e8151ad324d15dece34d58cf44196a78387b645ae21ec2cb361cc71e11f93b14fd0c916bd1573
7
+ data.tar.gz: c25d6966c201c265d2b42dd976e29faf075a8ea285d609883f1f4a9d3c52c941e4c690741e5e277bd4ea8a7d8cfefa4d9adea3a575e2c6006b6993ad767351fb
@@ -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)
@@ -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)
@@ -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
@@ -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
@@ -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
@@ -32,6 +32,7 @@ module Bmg
32
32
  public
33
33
 
34
34
  def each(&bl)
35
+ return to_enum unless block_given?
35
36
  index = Hash.new{|h,k| h[k] = k.merge(as => empty_group) }
36
37
  operand.each do |tuple|
37
38
  key = TupleAlgebra.allbut(tuple, attrs)
@@ -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
 
@@ -25,6 +25,7 @@ module Bmg
25
25
  public
26
26
 
27
27
  def each
28
+ return to_enum unless block_given?
28
29
  index = Hash.new
29
30
  right.each_with_object(index) do |t, index|
30
31
  key = tuple_project(t, on)
@@ -23,6 +23,7 @@ module Bmg
23
23
  public
24
24
 
25
25
  def each
26
+ return to_enum unless block_given?
26
27
  index = Hash.new
27
28
  right.each_with_object(index) do |t, index|
28
29
  key = tuple_project(t, on)
@@ -23,6 +23,7 @@ module Bmg
23
23
  public
24
24
 
25
25
  def each
26
+ return to_enum unless block_given?
26
27
  index = Hash.new
27
28
  right.each_with_object(index) do |t, index|
28
29
  key = tuple_project(t, on)
@@ -30,6 +30,7 @@ module Bmg
30
30
  public
31
31
 
32
32
  def each(&bl)
33
+ return to_enum unless block_given?
33
34
  page_size = options[:page_size]
34
35
  @operand.to_a
35
36
  .sort(&comparator)
@@ -29,6 +29,7 @@ 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
35
  projected = tuple_project(tuple)
@@ -29,6 +29,7 @@ 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
34
  yield rename(tuple, renaming)
34
35
  end
@@ -26,6 +26,7 @@ module Bmg
26
26
  end
27
27
 
28
28
  def each
29
+ return to_enum unless block_given?
29
30
  @operand.each do |tuple|
30
31
  yield(tuple) if @predicate.evaluate(tuple)
31
32
  end
@@ -32,6 +32,7 @@ module Bmg
32
32
  public
33
33
 
34
34
  def each
35
+ return to_enum unless block_given?
35
36
  @operand.each do |tuple|
36
37
  against = attrs.map{|a| tuple[a] }.join(" ")
37
38
  matcher = self.matcher
@@ -13,7 +13,7 @@ module Bmg
13
13
  @type = type
14
14
  @operand = operand
15
15
  @by = by
16
- @summarization = Summarize.compile(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
@@ -28,6 +28,7 @@ module Bmg
28
28
  public
29
29
 
30
30
  def each
31
+ return to_enum unless block_given?
31
32
  t = transformer
32
33
  @operand.each do |tuple|
33
34
  yield t.call(tuple)
@@ -37,6 +37,7 @@ module Bmg
37
37
  end
38
38
 
39
39
  def each(&bl)
40
+ return to_enum unless block_given?
40
41
  if all?
41
42
  operands.each do |op|
42
43
  op.each(&bl)
@@ -5,30 +5,36 @@ module Bmg
5
5
 
6
6
  DEFAULT_OPTIONS = {
7
7
  :headers => true,
8
- :return_headers => false
8
+ :return_headers => false,
9
+ :smart => true
9
10
  }
10
11
 
11
- def initialize(type, path, options = {})
12
+ def initialize(type, path_or_io, options = {})
12
13
  @type = type
13
- @path = path
14
+ @path_or_io = path_or_io
14
15
  @options = DEFAULT_OPTIONS.merge(options)
15
- @options[:col_sep] ||= infer_col_sep
16
- @options[:quote_char] ||= infer_quote_char
16
+ if @options[:smart] && !@path_or_io.is_a?(IO)
17
+ @options[:col_sep] ||= infer_col_sep
18
+ @options[:quote_char] ||= infer_quote_char
19
+ end
17
20
  end
18
21
 
19
22
  def each
23
+ return to_enum unless block_given?
20
24
  require 'csv'
21
- ::CSV.foreach(@path, @options) do |row|
22
- yield tuple(row)
25
+ with_io do |io|
26
+ ::CSV.new(io, csv_options).each do |row|
27
+ yield tuple(row)
28
+ end
23
29
  end
24
30
  end
25
31
 
26
32
  def to_ast
27
- [ :csv, @path, @options ]
33
+ [ :csv, @path_or_io, @options ]
28
34
  end
29
35
 
30
36
  def to_s
31
- "(csv #{path})"
37
+ "(csv #{@path_or_io})"
32
38
  end
33
39
  alias :inspect :to_s
34
40
 
@@ -47,7 +53,16 @@ module Bmg
47
53
  end
48
54
 
49
55
  def text_portion
50
- @text_portion ||= File.foreach(@path).first(10).join("\n")
56
+ @text_portion ||= with_io{|io| io.readlines(10).join("\n") }
57
+ end
58
+
59
+ def with_io(&bl)
60
+ case @path_or_io
61
+ when IO, StringIO
62
+ bl.call(@path_or_io)
63
+ else
64
+ File.open(@path_or_io, "r", &bl)
65
+ end
51
66
  end
52
67
 
53
68
  # Finds the best candidate among `candidates` for a separator
@@ -61,6 +76,10 @@ module Bmg
61
76
  snif.size > 0 ? snif[0][0] : default
62
77
  end
63
78
 
79
+ def csv_options
80
+ @csv_options ||= @options.dup.tap{|opts| opts.delete(:smart) }
81
+ end
82
+
64
83
  end # class Csv
65
84
  end # module Reader
66
85
  end # module Bmg
@@ -4,7 +4,8 @@ module Bmg
4
4
  include Reader
5
5
 
6
6
  DEFAULT_OPTIONS = {
7
- skip: 0
7
+ skip: 0,
8
+ row_num: true
8
9
  }
9
10
 
10
11
  def initialize(type, path, options = {})
@@ -14,6 +15,7 @@ module Bmg
14
15
  end
15
16
 
16
17
  def each
18
+ return to_enum unless block_given?
17
19
  require 'roo'
18
20
  xlsx = Roo::Spreadsheet.open(@path, @options)
19
21
  headers = nil
@@ -25,7 +27,11 @@ module Bmg
25
27
  if i==0
26
28
  headers = row.map(&:to_sym)
27
29
  else
28
- tuple = (0...headers.size).each_with_object({}){|i,t| t[headers[i]] = row[i] }
30
+ init = init_tuple(i)
31
+ tuple = (0...headers.size)
32
+ .each_with_object(init){|i,t|
33
+ t[headers[i]] = row[i]
34
+ }
29
35
  yield(tuple)
30
36
  end
31
37
  end
@@ -36,10 +42,23 @@ module Bmg
36
42
  end
37
43
 
38
44
  def to_s
39
- "(excel #{path})"
45
+ "(excel #{@path})"
40
46
  end
41
47
  alias :inspect :to_s
42
48
 
49
+ private
50
+
51
+ def init_tuple(i)
52
+ case as = @options[:row_num]
53
+ when TrueClass
54
+ { :row_num => i }
55
+ when FalseClass
56
+ {}
57
+ when Symbol
58
+ { :"#{as}" => i }
59
+ end
60
+ end
61
+
43
62
  end # class Excel
44
63
  end # module Reader
45
64
  end # module Bmg
data/lib/bmg/relation.rb CHANGED
@@ -27,6 +27,12 @@ module Bmg
27
27
  }
28
28
  end
29
29
 
30
+ def with_type_attrlist
31
+ return self if type.knows_attrlist?
32
+ attrs = self.first.keys
33
+ with_type(type.with_attrlist(attrs))
34
+ end
35
+
30
36
  def with_typecheck
31
37
  dup.tap{|r|
32
38
  r.type = r.type.with_typecheck
@@ -8,7 +8,6 @@ module Bmg
8
8
  @type = type
9
9
  end
10
10
  attr_accessor :type
11
- protected :type=
12
11
  attr_reader :operand
13
12
 
14
13
  public
@@ -9,6 +9,7 @@ module Bmg
9
9
  attr_reader :sequel_db
10
10
 
11
11
  def each(&bl)
12
+ return to_enum unless block_given?
12
13
  dataset.each(&bl)
13
14
  end
14
15
 
@@ -133,8 +133,8 @@ module Bmg
133
133
  _instance(type, builder, expr)
134
134
  end
135
135
 
136
- def _summarize(type, by, summarization)
137
- summarization = Operator::Summarize.compile(summarization)
136
+ def _summarize(type, by, defs)
137
+ summarization = ::Bmg::Summarizer.summarization(defs)
138
138
  if can_compile_summarization?(summarization)
139
139
  expr = before_use(self.expr)
140
140
  expr = Processor::Summarize.new(by, summarization, builder).call(self.expr)
@@ -50,6 +50,21 @@ module Bmg
50
50
  end
51
51
  end
52
52
 
53
+ # Converts some summarization definitions to a Hash of
54
+ # summarizers.
55
+ def self.summarization(defs)
56
+ Hash[defs.map{|k,v|
57
+ summarizer = case v
58
+ when Summarizer then v
59
+ when Symbol then Summarizer.send(v, k)
60
+ when Proc then Summarizer.by_proc(&v)
61
+ else
62
+ raise ArgumentError, "Unexpected summarizer #{k} => #{v}"
63
+ end
64
+ [ k, summarizer ]
65
+ }]
66
+ end
67
+
53
68
  # Returns the default options to use
54
69
  #
55
70
  # @return the default aggregation options
@@ -80,7 +95,16 @@ module Bmg
80
95
  # @param the current iterated tuple
81
96
  # @return updated memo value
82
97
  def happens(memo, tuple)
83
- value = @functor.is_a?(Proc) ? @functor.call(tuple) : tuple[@functor]
98
+ value = case @functor
99
+ when Proc
100
+ @functor.call(tuple)
101
+ when NilClass
102
+ tuple
103
+ when Symbol
104
+ tuple[@functor]
105
+ else
106
+ tuple[@functor]
107
+ end
84
108
  _happens(memo, value)
85
109
  end
86
110
 
@@ -128,5 +152,9 @@ require_relative 'summarizer/max'
128
152
  require_relative 'summarizer/avg'
129
153
  require_relative 'summarizer/variance'
130
154
  require_relative 'summarizer/stddev'
155
+ require_relative 'summarizer/percentile'
131
156
  require_relative 'summarizer/collect'
157
+ require_relative 'summarizer/distinct'
132
158
  require_relative 'summarizer/concat'
159
+ require_relative 'summarizer/by_proc'
160
+ require_relative 'summarizer/multiple'
@@ -16,13 +16,13 @@ module Bmg
16
16
  end
17
17
 
18
18
  # Collects one more value + the sum of all
19
- def _happens(memo, val)
19
+ def _happens(memo, val)
20
20
  [memo.first + val, memo.last + 1]
21
21
  end
22
22
 
23
23
  # Finalizes the computation.
24
- def finalize(memo)
25
- memo.first / memo.last
24
+ def finalize(memo)
25
+ memo.first / memo.last
26
26
  end
27
27
 
28
28
  end # class Avg
@@ -0,0 +1,41 @@
1
+ module Bmg
2
+ class Summarizer
3
+ #
4
+ # Generic summarizer that takes a Proc àla each_with_object.
5
+ #
6
+ # Example:
7
+ #
8
+ # # direct ruby usage
9
+ # Bmg::Summarizer.by_proc{|t,memo| ... }.summarize(...)
10
+ #
11
+ class ByProc < Summarizer
12
+
13
+ def initialize(least, by_proc)
14
+ @least = least
15
+ @by_proc = by_proc
16
+ end
17
+
18
+ # Returns [] as least value.
19
+ def least()
20
+ @least
21
+ end
22
+
23
+ # Adds val to the memo array
24
+ def happens(memo, val)
25
+ @by_proc.call(val, memo)
26
+ end
27
+
28
+ def finalize(memo)
29
+ memo
30
+ end
31
+
32
+ end # class ByProc
33
+
34
+ # Factors a distinct summarizer
35
+ def self.by_proc(least = nil, proc = nil, &bl)
36
+ least, proc = nil, least if least.is_a?(Proc)
37
+ ByProc.new(least, proc || bl)
38
+ end
39
+
40
+ end # class Summarizer
41
+ end # module Bmg
@@ -0,0 +1,36 @@
1
+ module Bmg
2
+ class Summarizer
3
+ #
4
+ # Collect the distinct values as an array.
5
+ #
6
+ # Example:
7
+ #
8
+ # # direct ruby usage
9
+ # Bmg::Summarizer.distinct(:qty).summarize(...)
10
+ #
11
+ class Distinct < 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
26
+ end
27
+
28
+ end # class Distinct
29
+
30
+ # Factors a distinct summarizer
31
+ def self.distinct(*args, &bl)
32
+ Distinct.new(*args, &bl)
33
+ end
34
+
35
+ end # class Summarizer
36
+ end # module Bmg
@@ -0,0 +1,46 @@
1
+ module Bmg
2
+ class Summarizer
3
+ #
4
+ # A summarizer that collects multiple summarization as a wrapped
5
+ # tuple.
6
+ #
7
+ # Example:
8
+ #
9
+ # # direct ruby usage
10
+ # Bmg::Summarizer.multiple(x: ..., y: ...).summarize(...)
11
+ #
12
+ class Multiple < Summarizer
13
+
14
+ def initialize(defs)
15
+ @summarization = Summarizer.summarization(defs)
16
+ end
17
+
18
+ # Returns [] as least value.
19
+ def least()
20
+ @summarization.each_pair.each_with_object({}){|(k,v),memo|
21
+ memo[k] = v.least
22
+ }
23
+ end
24
+
25
+ # Adds val to the memo array
26
+ def happens(memo, val)
27
+ @summarization.each_pair.each_with_object({}){|(k,v),memo2|
28
+ memo2[k] = v.happens(memo[k], val)
29
+ }
30
+ end
31
+
32
+ def finalize(memo)
33
+ @summarization.each_pair.each_with_object({}){|(k,v),memo2|
34
+ memo2[k] = v.finalize(memo[k])
35
+ }
36
+ end
37
+
38
+ end # class Multiple
39
+
40
+ # Factors a distinct summarizer
41
+ def self.multiple(defs)
42
+ Multiple.new(defs)
43
+ end
44
+
45
+ end # class Summarizer
46
+ end # module Bmg
@@ -0,0 +1,47 @@
1
+ module Bmg
2
+ class Summarizer
3
+ #
4
+ # Percentile summarizer.
5
+ #
6
+ # Example:
7
+ #
8
+ # # direct ruby usage
9
+ # Bmg::Summarizer.percentile(:qty, 50).summarize(...)
10
+ #
11
+ class Percentile < Summarizer
12
+
13
+ def initialize(attribute = nil, nth = 50, &bl)
14
+ attribute, nth = nil, attribute if attribute.is_a?(Integer)
15
+ super(*[attribute].compact, &bl)
16
+ @nth = nth
17
+ end
18
+
19
+ # Returns [] as least value.
20
+ def least()
21
+ []
22
+ end
23
+
24
+ # Collects the value
25
+ def _happens(memo, val)
26
+ memo << val
27
+ end
28
+
29
+ # Finalizes the computation.
30
+ def finalize(memo)
31
+ return nil if memo.empty?
32
+ index = memo.size * (@nth / 100.0)
33
+ above = [[index.ceil - 1, memo.size - 1].min, 0].max
34
+ below = [index.floor - 1, 0].max
35
+ sorted = memo.sort
36
+ (sorted[above] + sorted[below]) / 2
37
+ end
38
+
39
+ end # class Avg
40
+
41
+ # Factors an average summarizer
42
+ def self.percentile(*args, &bl)
43
+ Percentile.new(*args, &bl)
44
+ end
45
+
46
+ end # class Summarizer
47
+ end # module Bmg
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 = 2
5
+ TINY = 3
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
data/lib/bmg/writer.rb CHANGED
@@ -1 +1,17 @@
1
+ module Bmg
2
+ module Writer
3
+
4
+ protected
5
+
6
+ def infer_headers(from)
7
+ attrlist = if from.is_a?(Type) && from.knows_attrlist?
8
+ from.to_attrlist
9
+ elsif from.is_a?(Hash)
10
+ from.keys
11
+ end
12
+ attrlist ? output_preferences.order_attrlist(attrlist) : nil
13
+ end
14
+
15
+ end # module Writer
16
+ end # module Bmg
1
17
  require_relative 'writer/csv'
@@ -26,17 +26,6 @@ module Bmg
26
26
  to_s ? string_or_io.string : string_or_io
27
27
  end
28
28
 
29
- private
30
-
31
- def infer_headers(from)
32
- attrlist = if from.is_a?(Type) && from.knows_attrlist?
33
- from.to_attrlist
34
- elsif from.is_a?(Hash)
35
- from.keys
36
- end
37
- attrlist ? output_preferences.order_attrlist(attrlist) : nil
38
- end
39
-
40
29
  end # class Csv
41
30
  end # module Writer
42
31
  end # module Bmg
@@ -0,0 +1,68 @@
1
+ module Bmg
2
+ module Writer
3
+ class Xlsx
4
+ include Writer
5
+
6
+ DEFAULT_OPTIONS = {
7
+ }
8
+
9
+ def initialize(csv_options, output_preferences = nil)
10
+ @csv_options = DEFAULT_OPTIONS.merge(csv_options)
11
+ @output_preferences = OutputPreferences.dress(output_preferences)
12
+ end
13
+ attr_reader :csv_options, :output_preferences
14
+
15
+ def call(relation, path)
16
+ require 'write_xlsx'
17
+ dup._call(relation, path)
18
+ end
19
+
20
+ protected
21
+ attr_reader :workbook, :worksheet
22
+
23
+ def _call(relation, path)
24
+ @workbook = WriteXLSX.new(path)
25
+ @worksheet = workbook.add_worksheet
26
+
27
+ headers = infer_headers(relation.type)
28
+ relation.each_with_index do |tuple,i|
29
+ headers = infer_headers(tuple) if headers.nil?
30
+ headers.each_with_index do |h,i|
31
+ worksheet.write_string(0, i, h)
32
+ end if i == 0
33
+ headers.each_with_index do |h,j|
34
+ meth, *args = write_pair(tuple[h])
35
+ worksheet.send(meth, 1+i, j, *args)
36
+ end
37
+ end
38
+
39
+ workbook.close
40
+ path
41
+ end
42
+
43
+ def write_pair(value)
44
+ case value
45
+ when Numeric
46
+ [:write_number, value]
47
+ when Date
48
+ [:write_date_time, value, date_format]
49
+ else
50
+ [:write_string, value.to_s]
51
+ end
52
+ end
53
+
54
+ def date_format
55
+ @date_format ||= workbook.add_format(:num_format => 'yyyy-mm-dd')
56
+ end
57
+
58
+ end # class Xlsx
59
+ end # module Writer
60
+ module Relation
61
+
62
+ def to_xlsx(options = {}, path = nil, preferences = nil)
63
+ options, path = {}, options unless options.is_a?(Hash)
64
+ Writer::Xlsx.new(options, preferences).call(self, path)
65
+ end
66
+
67
+ end # module Relation
68
+ end # module Bmg
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bmg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.2
4
+ version: 0.18.3
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-04-16 00:00:00.000000000 Z
11
+ date: 2021-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: predicate
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '2.8'
89
+ - !ruby/object:Gem::Dependency
90
+ name: write_xlsx
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.0'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: sequel
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -251,11 +265,15 @@ files:
251
265
  - lib/bmg/sql/version.rb
252
266
  - lib/bmg/summarizer.rb
253
267
  - lib/bmg/summarizer/avg.rb
268
+ - lib/bmg/summarizer/by_proc.rb
254
269
  - lib/bmg/summarizer/collect.rb
255
270
  - lib/bmg/summarizer/concat.rb
256
271
  - lib/bmg/summarizer/count.rb
272
+ - lib/bmg/summarizer/distinct.rb
257
273
  - lib/bmg/summarizer/max.rb
258
274
  - lib/bmg/summarizer/min.rb
275
+ - lib/bmg/summarizer/multiple.rb
276
+ - lib/bmg/summarizer/percentile.rb
259
277
  - lib/bmg/summarizer/stddev.rb
260
278
  - lib/bmg/summarizer/sum.rb
261
279
  - lib/bmg/summarizer/variance.rb
@@ -269,6 +287,7 @@ files:
269
287
  - lib/bmg/version.rb
270
288
  - lib/bmg/writer.rb
271
289
  - lib/bmg/writer/csv.rb
290
+ - lib/bmg/writer/xlsx.rb
272
291
  - tasks/gem.rake
273
292
  - tasks/test.rake
274
293
  homepage: http://github.com/enspirit/bmg