bmg 0.23.5 → 0.23.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/lib/bmg/database/data_folder.rb +14 -6
- data/lib/bmg/database/xlsx.rb +5 -2
- data/lib/bmg/database.rb +5 -0
- data/lib/bmg/reader/xlsx.rb +12 -2
- data/lib/bmg/support/output_preferences.rb +9 -2
- data/lib/bmg/version.rb +1 -1
- data/lib/bmg/writer/xlsx.rb +26 -9
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4cb86461e5f53734d08dcb3668bd2a99630680d7213bb946fa5a13cbf0f86f2
|
4
|
+
data.tar.gz: f9a80e014cb2769d6d8da8cea581b18c7601c2d1015db18e1eac6333f8e08876
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7621e13e58615206096b3f2d2799a79aa4e662592688b295329bf09626efe86b9a8f4f6f01aba5432513e6054c7568894f13dfccd86d8932f28fa1e9b0892a28
|
7
|
+
data.tar.gz: 9cfc8e393267db43d44764db894b47639d6cfc445b3e7d80e1287929e02cf8ec4d7e541432f52905002953ac727770b5c30b3c4c850ff1a039d98beba2811469
|
@@ -3,7 +3,9 @@ module Bmg
|
|
3
3
|
class DataFolder < Database
|
4
4
|
|
5
5
|
DEFAULT_OPTIONS = {
|
6
|
-
data_extensions: ['json', 'yml', 'yaml', 'csv']
|
6
|
+
data_extensions: ['json', 'yml', 'yaml', 'csv'],
|
7
|
+
relname_from_file: ->(file) { file.basename.rm_ext.to_sym },
|
8
|
+
filename_from_relname: ->(relname) { relname },
|
7
9
|
}
|
8
10
|
|
9
11
|
def initialize(folder, options = {})
|
@@ -25,15 +27,21 @@ module Bmg
|
|
25
27
|
next unless @options[:data_extensions].find {|ext|
|
26
28
|
path.ext == ".#{ext}" || path.ext == ext
|
27
29
|
}
|
28
|
-
yield(path
|
30
|
+
yield(@options[:relname_from_file].call(path), read_file(path))
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
def self.dump(database, path, ext = :json)
|
34
|
+
def self.dump(database, path, ext = :json, options = DEFAULT_OPTIONS)
|
35
|
+
options = DEFAULT_OPTIONS.merge(options)
|
33
36
|
path = Path(path)
|
34
37
|
path.mkdir_p
|
35
38
|
database.each_relation_pair do |name, rel|
|
36
|
-
(
|
39
|
+
filename = options[:filename_from_relname].call(name)
|
40
|
+
if ext === :json
|
41
|
+
(path/"#{filename}.#{ext}").write(JSON.pretty_generate(rel))
|
42
|
+
else
|
43
|
+
(path/"#{filename}.#{ext}").write(rel.public_send(:"to_#{ext}"))
|
44
|
+
end
|
37
45
|
end
|
38
46
|
path
|
39
47
|
end
|
@@ -56,8 +64,8 @@ module Bmg
|
|
56
64
|
def find_file(name)
|
57
65
|
exts = @options[:data_extensions]
|
58
66
|
exts.each do |ext|
|
59
|
-
target = @folder
|
60
|
-
return target if target
|
67
|
+
target = @folder.glob("*#{name}.#{ext}")
|
68
|
+
return target.first if target&.first&.file?
|
61
69
|
end
|
62
70
|
raise NotSuchRelationError, "#{@folder}/#{name}.#{exts.join(',')}"
|
63
71
|
end
|
data/lib/bmg/database/xlsx.rb
CHANGED
@@ -3,12 +3,13 @@ module Bmg
|
|
3
3
|
class Xlsx < Database
|
4
4
|
|
5
5
|
DEFAULT_OPTIONS = {
|
6
|
+
reader_options: {}
|
6
7
|
}
|
7
8
|
|
8
9
|
def initialize(path, options = {})
|
9
10
|
path = Path(path) if path.is_a?(String)
|
10
11
|
@path = path
|
11
|
-
@options =
|
12
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
12
13
|
end
|
13
14
|
|
14
15
|
def method_missing(name, *args, &bl)
|
@@ -33,7 +34,9 @@ module Bmg
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def rel_for(sheet_name)
|
36
|
-
Bmg.excel(@path,
|
37
|
+
Bmg.excel(@path, @options[:reader_options].merge({
|
38
|
+
sheet: sheet_name.to_s
|
39
|
+
}))
|
37
40
|
end
|
38
41
|
|
39
42
|
end # class Sequel
|
data/lib/bmg/database.rb
CHANGED
@@ -24,6 +24,7 @@ module Bmg
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def to_data_folder(*args)
|
27
|
+
require_relative 'database/data_folder'
|
27
28
|
DataFolder.dump(self, *args)
|
28
29
|
end
|
29
30
|
|
@@ -31,5 +32,9 @@ module Bmg
|
|
31
32
|
raise NotImplementedError
|
32
33
|
end
|
33
34
|
|
35
|
+
def output_preferences_for(name)
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
34
39
|
end # class Database
|
35
40
|
end # module Bmg
|
data/lib/bmg/reader/xlsx.rb
CHANGED
@@ -6,7 +6,8 @@ module Bmg
|
|
6
6
|
DEFAULT_OPTIONS = {
|
7
7
|
sheet: 0,
|
8
8
|
skip: 0,
|
9
|
-
row_num: true
|
9
|
+
row_num: true,
|
10
|
+
grouping_character: nil,
|
10
11
|
}
|
11
12
|
|
12
13
|
def initialize(type, path, options = {})
|
@@ -23,13 +24,16 @@ module Bmg
|
|
23
24
|
headers = headers[1..-1] if generate_row_num?
|
24
25
|
start_at = @options[:skip] + 2
|
25
26
|
end_at = spreadsheet.last_row
|
27
|
+
|
28
|
+
previous = {}
|
26
29
|
(start_at..end_at).each do |i|
|
27
30
|
row = spreadsheet.row(i)
|
28
31
|
init = init_tuple(i - start_at + 1)
|
29
32
|
tuple = (0...headers.size).each_with_object(init){|i,t|
|
30
|
-
t[headers[i]] = row[i]
|
33
|
+
t[headers[i]] = extract_value(headers[i], row[i], previous)
|
31
34
|
}
|
32
35
|
yield(tuple)
|
36
|
+
previous = tuple
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
@@ -75,6 +79,12 @@ module Bmg
|
|
75
79
|
{ row_num_name => i }
|
76
80
|
end
|
77
81
|
|
82
|
+
def extract_value(attribute, value, previous)
|
83
|
+
return value unless c = @options[:grouping_character]
|
84
|
+
|
85
|
+
value == c ? previous[attribute] : value
|
86
|
+
end
|
87
|
+
|
78
88
|
end # class Excel
|
79
89
|
end # module Reader
|
80
90
|
end # module Bmg
|
@@ -4,6 +4,7 @@ module Bmg
|
|
4
4
|
DEFAULT_PREFS = {
|
5
5
|
attributes_ordering: nil,
|
6
6
|
tuple_ordering: nil,
|
7
|
+
grouping_attributes: nil,
|
7
8
|
extra_attributes: :after
|
8
9
|
}
|
9
10
|
|
@@ -36,14 +37,20 @@ module Bmg
|
|
36
37
|
options[:grouping_attributes]
|
37
38
|
end
|
38
39
|
|
40
|
+
def grouping_character
|
41
|
+
options[:grouping_character]
|
42
|
+
end
|
43
|
+
|
39
44
|
def erase_redundance_in_group(before, current)
|
40
45
|
return [nil, current] unless ga = grouping_attributes
|
41
46
|
return [current, current] unless before
|
42
47
|
|
43
48
|
new_before, new_current = current.dup, current.dup
|
44
49
|
ga.each do |attr|
|
45
|
-
|
46
|
-
|
50
|
+
unless before[attr] == current[attr]
|
51
|
+
return [new_before, new_current]
|
52
|
+
end
|
53
|
+
new_current[attr] = grouping_character
|
47
54
|
end
|
48
55
|
[new_before, new_current]
|
49
56
|
end
|
data/lib/bmg/version.rb
CHANGED
data/lib/bmg/writer/xlsx.rb
CHANGED
@@ -25,7 +25,7 @@ module Bmg
|
|
25
25
|
rel.to_xlsx({
|
26
26
|
workbook: workbook,
|
27
27
|
worksheet: worksheet,
|
28
|
-
})
|
28
|
+
}, nil, database.output_preferences_for(name))
|
29
29
|
end
|
30
30
|
workbook.close
|
31
31
|
end
|
@@ -39,31 +39,48 @@ module Bmg
|
|
39
39
|
@worksheet = workbook.add_worksheet(@worksheet) if @worksheet.is_a?(String)
|
40
40
|
|
41
41
|
headers = infer_headers(relation.type)
|
42
|
+
max_widths = Hash.new{|h,k| h[k] = 5 }
|
42
43
|
before = nil
|
44
|
+
|
45
|
+
write_headers(headers, worksheet, max_widths) unless headers.nil?
|
46
|
+
|
43
47
|
each_tuple(relation) do |tuple,i|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
+
if headers.nil?
|
49
|
+
headers = infer_headers(tuple)
|
50
|
+
write_headers(headers, worksheet, max_widths)
|
51
|
+
end
|
48
52
|
before, tuple = output_preferences.erase_redundance_in_group(before, tuple)
|
49
53
|
headers.each_with_index do |h,j|
|
50
|
-
meth,
|
54
|
+
meth, args, approx_width = write_pair(tuple[h])
|
51
55
|
worksheet.send(meth, 1+i, j, *args)
|
56
|
+
max_widths[j] = [max_widths[j], approx_width].max
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
60
|
+
max_widths.each_pair do |col, width|
|
61
|
+
worksheet.set_column(col, col, [1+width, 100].min)
|
62
|
+
end
|
63
|
+
worksheet.freeze_panes(1, 0)
|
55
64
|
workbook.close unless xlsx_options[:workbook]
|
56
65
|
path
|
57
66
|
end
|
58
67
|
|
68
|
+
def write_headers(headers, worksheet, max_widths)
|
69
|
+
header_format = workbook.add_format(bold: true)
|
70
|
+
headers.each_with_index do |h,i|
|
71
|
+
worksheet.write_string(0, i, h, header_format)
|
72
|
+
max_widths[i] = [max_widths[i], h.to_s.size].max
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
59
76
|
def write_pair(value)
|
60
77
|
case value
|
61
78
|
when Numeric
|
62
|
-
[:write_number, value]
|
79
|
+
[:write_number, [value], value.to_s.size]
|
63
80
|
when Date
|
64
|
-
[:write_date_time, value, date_format]
|
81
|
+
[:write_date_time, [value, date_format], value.to_s.size]
|
65
82
|
else
|
66
|
-
[:write_string, value.to_s]
|
83
|
+
[:write_string, [value.to_s], value.to_s.size]
|
67
84
|
end
|
68
85
|
end
|
69
86
|
|
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.23.
|
4
|
+
version: 0.23.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: predicate
|
@@ -347,7 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
347
347
|
- !ruby/object:Gem::Version
|
348
348
|
version: '0'
|
349
349
|
requirements: []
|
350
|
-
rubygems_version: 3.
|
350
|
+
rubygems_version: 3.4.19
|
351
351
|
signing_key:
|
352
352
|
specification_version: 4
|
353
353
|
summary: Bmg is Alf's successor.
|