bmg 0.20.2 → 0.20.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 45a80b1a3fd00fc27f88f37b41816dd11324aa70
4
- data.tar.gz: 9d600dd0619e0d814a07db94c95dc093b61584b9
2
+ SHA256:
3
+ metadata.gz: 0c2ddf234065e92d8491f0efc3e603522c3aabdb43d268a1e6b438f9aa9197ea
4
+ data.tar.gz: d985c466d1b0cc9f9117517f64fb2b00715e2e6cf41e95a10eaa5772e89c2dd3
5
5
  SHA512:
6
- metadata.gz: 38fefe80ca45ddce14d3310621b82b389db5a7c11ab22bb17563c2c6f7dc769f9a54f9a3bebde6c40a2bbecbae215969857a8cf875a7363ad10261fd5b32b75f
7
- data.tar.gz: 91492014f31ff3c540df388cac9e362e16555e373ca59ed178bdf32f7098d176947f7e6432df804a8bb3f34210d8a3762b92ce39d37455ff2ee2e55346bf9bce
6
+ metadata.gz: 13d3dd2a73eb78e4e2344da2af4f6d738c1294f15ec19affa732aad83d2d1e4aa6778e424814a833b3ccdb78f5a6abe55121d75a35448d73ce7f03591abb502f
7
+ data.tar.gz: 27d4c95da2fa998ef36a6fbdc08fdbd8e4cae0735a0b6450008d835a494d82c12566553b50aa222316b8e4e99c145e390e0c3c5148305aeab71c259177dac160
@@ -68,6 +68,20 @@ module Bmg
68
68
 
69
69
  protected ### optimization
70
70
 
71
+ def _allbut(type, butlist)
72
+ new_roots = wrapped_roots!
73
+ separator = @options[:split]
74
+ down = operand.type.attrlist!.select { |attr|
75
+ root = attr.to_s.split(separator).map(&:to_sym).first
76
+ butlist.include?(root)
77
+ }
78
+ r = operand.allbut(down)
79
+ r = r.autowrap(options) unless (butlist & new_roots == new_roots)
80
+ r
81
+ rescue UnknownAttributesError
82
+ super
83
+ end
84
+
71
85
  def _autowrap(type, opts)
72
86
  if same_options?(opts)
73
87
  self
@@ -122,11 +136,12 @@ module Bmg
122
136
  end
123
137
 
124
138
  def _project(type, attrlist)
125
- if (wrapped_roots! & attrlist).empty?
126
- operand.project(attrlist).autowrap(options)
127
- else
128
- super
129
- end
139
+ separator = @options[:split]
140
+ to_keep = operand.type.attrlist!.select { |attr|
141
+ root = attr.to_s.split(separator).map(&:to_sym).first
142
+ attrlist.include?(root)
143
+ }
144
+ operand.project(to_keep).autowrap(options)
130
145
  rescue UnknownAttributesError
131
146
  super
132
147
  end
@@ -169,6 +184,7 @@ module Bmg
169
184
 
170
185
  def wrapped_roots_of!(r, opts)
171
186
  raise UnknownAttributesError unless r.type.knows_attrlist?
187
+
172
188
  Support.wrapped_roots(r.type.to_attrlist, opts[:split])
173
189
  end
174
190
 
@@ -67,6 +67,10 @@ module Bmg
67
67
  operand.restrict(predicate).project(attrlist)
68
68
  end
69
69
 
70
+ def _allbut(type, butlist)
71
+ Project.new(type, @operand, attrlist - butlist)
72
+ end
73
+
70
74
  protected ### inspect
71
75
 
72
76
  def args
@@ -39,7 +39,9 @@ module Bmg
39
39
  private
40
40
 
41
41
  def tuple(row)
42
- row.to_hash.each_with_object({}){|(k,v),h| h[k.to_sym] = v }
42
+ row.to_hash.each_with_object({}){|(k,v),h|
43
+ h[k.to_sym] = v
44
+ }
43
45
  end
44
46
 
45
47
  def handle_type(type)
@@ -2,7 +2,13 @@ module Bmg
2
2
  class Ordering
3
3
 
4
4
  def initialize(attrs)
5
- @attrs = attrs
5
+ @attrs = if attrs.empty?
6
+ []
7
+ elsif attrs.first.is_a?(Symbol)
8
+ attrs.map{|a| [a, :asc] }
9
+ else
10
+ attrs
11
+ end
6
12
  end
7
13
  attr_reader :attrs
8
14
 
@@ -33,5 +39,9 @@ module Bmg
33
39
  0
34
40
  end
35
41
 
42
+ def to_a
43
+ attrs.to_a
44
+ end
45
+
36
46
  end # class Ordering
37
47
  end # module Bmg
@@ -3,6 +3,7 @@ module Bmg
3
3
 
4
4
  DEFAULT_PREFS = {
5
5
  attributes_ordering: nil,
6
+ tuple_ordering: nil,
6
7
  extra_attributes: :after
7
8
  }
8
9
 
@@ -17,6 +18,12 @@ module Bmg
17
18
  new(arg)
18
19
  end
19
20
 
21
+ def tuple_ordering
22
+ return nil unless to = options[:tuple_ordering]
23
+
24
+ @tuple_ordering = Ordering.new(to)
25
+ end
26
+
20
27
  def attributes_ordering
21
28
  options[:attributes_ordering]
22
29
  end
@@ -25,10 +32,29 @@ module Bmg
25
32
  options[:extra_attributes]
26
33
  end
27
34
 
35
+ def grouping_attributes
36
+ options[:grouping_attributes]
37
+ end
38
+
39
+ def erase_redundance_in_group(before, current)
40
+ return [nil, current] unless ga = grouping_attributes
41
+ return [current, current] unless before
42
+
43
+ new_before, new_current = current.dup, current.dup
44
+ ga.each do |attr|
45
+ return [new_before, new_current] unless before[attr] == current[attr]
46
+ new_current[attr] = nil
47
+ end
48
+ [new_before, new_current]
49
+ end
50
+
28
51
  def order_attrlist(attrlist)
29
52
  return attrlist if attributes_ordering.nil?
53
+
30
54
  index = Hash[attributes_ordering.each_with_index.to_a]
31
- attrlist.sort{|a,b|
55
+ base = attrlist
56
+ base = attrlist & attributes_ordering if extra_attributes == :ignored
57
+ base.sort{|a,b|
32
58
  ai, bi = index[a], index[b]
33
59
  if ai && bi
34
60
  ai <=> bi
data/lib/bmg/type.rb CHANGED
@@ -46,6 +46,11 @@ module Bmg
46
46
  attr_accessor :attrlist
47
47
  protected :attrlist=
48
48
 
49
+ def attrlist!
50
+ knows_attrlist!
51
+ attrlist
52
+ end
53
+
49
54
  def with_attrlist(attrlist)
50
55
  dup.tap{|x|
51
56
  x.attrlist = attrlist
data/lib/bmg/version.rb CHANGED
@@ -2,7 +2,7 @@ module Bmg
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 20
5
- TINY = 2
5
+ TINY = 5
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
@@ -16,12 +16,14 @@ module Bmg
16
16
  require 'csv'
17
17
  string_or_io, to_s = string_or_io.nil? ? [StringIO.new, true] : [string_or_io, false]
18
18
  headers, csv = infer_headers(relation.type), nil
19
- relation.each do |tuple|
19
+ previous = nil
20
+ each_tuple(relation) do |tuple,i|
20
21
  if csv.nil?
21
22
  headers = infer_headers(tuple) if headers.nil?
22
23
  csv_opts = csv_options.merge(headers: headers)
23
24
  csv = CSV.new(string_or_io, **csv_opts)
24
25
  end
26
+ previous, tuple = output_preferences.erase_redundance_in_group(previous, tuple)
25
27
  csv << headers.map{|h| tuple[h] }
26
28
  end
27
29
  to_s ? string_or_io.string : string_or_io
@@ -6,11 +6,11 @@ module Bmg
6
6
  DEFAULT_OPTIONS = {
7
7
  }
8
8
 
9
- def initialize(csv_options, output_preferences = nil)
10
- @csv_options = DEFAULT_OPTIONS.merge(csv_options)
9
+ def initialize(xlsx_options, output_preferences = nil)
10
+ @xlsx_options = DEFAULT_OPTIONS.merge(xlsx_options)
11
11
  @output_preferences = OutputPreferences.dress(output_preferences)
12
12
  end
13
- attr_reader :csv_options, :output_preferences
13
+ attr_reader :xlsx_options, :output_preferences
14
14
 
15
15
  def call(relation, path)
16
16
  require 'write_xlsx'
@@ -21,22 +21,24 @@ module Bmg
21
21
  attr_reader :workbook, :worksheet
22
22
 
23
23
  def _call(relation, path)
24
- @workbook = WriteXLSX.new(path)
25
- @worksheet = workbook.add_worksheet
24
+ @workbook = xlsx_options[:workbook] || WriteXLSX.new(path)
25
+ @worksheet = xlsx_options[:worksheet] || workbook.add_worksheet
26
26
 
27
27
  headers = infer_headers(relation.type)
28
- relation.each_with_index do |tuple,i|
28
+ before = nil
29
+ each_tuple(relation) do |tuple,i|
29
30
  headers = infer_headers(tuple) if headers.nil?
30
31
  headers.each_with_index do |h,i|
31
32
  worksheet.write_string(0, i, h)
32
33
  end if i == 0
34
+ before, tuple = output_preferences.erase_redundance_in_group(before, tuple)
33
35
  headers.each_with_index do |h,j|
34
36
  meth, *args = write_pair(tuple[h])
35
37
  worksheet.send(meth, 1+i, j, *args)
36
38
  end
37
39
  end
38
40
 
39
- workbook.close
41
+ workbook.close unless xlsx_options[:workbook]
40
42
  path
41
43
  end
42
44
 
data/lib/bmg/writer.rb CHANGED
@@ -12,6 +12,17 @@ module Bmg
12
12
  attrlist ? output_preferences.order_attrlist(attrlist) : nil
13
13
  end
14
14
 
15
+ def each_tuple(relation, &bl)
16
+ if ordering = output_preferences.tuple_ordering
17
+ relation
18
+ .to_a
19
+ .sort{|t1,t2| ordering.compare_attrs(t1, t2) }
20
+ .each_with_index(&bl)
21
+ else
22
+ relation.each_with_index(&bl)
23
+ end
24
+ end
25
+
15
26
  end # module Writer
16
27
  end # module Bmg
17
28
  require_relative 'writer/csv'
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.20.2
4
+ version: 0.20.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-01 00:00:00.000000000 Z
11
+ date: 2024-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: predicate
@@ -320,8 +320,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
320
320
  - !ruby/object:Gem::Version
321
321
  version: '0'
322
322
  requirements: []
323
- rubyforge_project:
324
- rubygems_version: 2.6.14.4
323
+ rubygems_version: 3.1.6
325
324
  signing_key:
326
325
  specification_version: 4
327
326
  summary: Bmg is Alf's successor.