table_structure 0.3.22 → 0.4.3
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/.travis.yml +1 -1
- data/CHANGELOG.md +33 -0
- data/Gemfile.lock +7 -7
- data/README.md +30 -31
- data/lib/table_structure.rb +6 -12
- data/lib/table_structure/csv/writer.rb +4 -41
- data/lib/table_structure/iterator.rb +48 -89
- data/lib/table_structure/schema.rb +63 -76
- data/lib/table_structure/schema/class_methods.rb +9 -28
- data/lib/table_structure/schema/column_builder_factory.rb +75 -0
- data/lib/table_structure/schema/columns/attributes.rb +14 -9
- data/lib/table_structure/schema/columns/schema.rb +14 -9
- data/lib/table_structure/schema/composite_class.rb +40 -0
- data/lib/table_structure/schema/definition/columns/compiler.rb +7 -3
- data/lib/table_structure/schema/definition/columns/validator.rb +2 -6
- data/lib/table_structure/schema/dsl/column_builder.rb +29 -0
- data/lib/table_structure/schema/dsl/column_definition.rb +12 -2
- data/lib/table_structure/schema/dsl/context_builder.rb +2 -11
- data/lib/table_structure/schema/dsl/row_builder.rb +2 -9
- data/lib/table_structure/schema/{key_converter.rb → keys_builder.rb} +2 -2
- data/lib/table_structure/schema/row_context_builder_factory.rb +26 -0
- data/lib/table_structure/table.rb +31 -56
- data/lib/table_structure/utils.rb +40 -0
- data/lib/table_structure/version.rb +1 -1
- data/lib/table_structure/writer.rb +7 -54
- metadata +8 -14
- data/lib/table_structure/schema/column_converter.rb +0 -46
- data/lib/table_structure/schema/definition/column_converter.rb +0 -31
- data/lib/table_structure/schema/definition/context_builder.rb +0 -17
- data/lib/table_structure/schema/definition/row_builder.rb +0 -25
- data/lib/table_structure/schema/dsl/column_converter.rb +0 -41
- data/lib/table_structure/schema/dsl/option.rb +0 -19
- data/lib/table_structure/schema/row_builder.rb +0 -21
- data/lib/table_structure/table/column_converter.rb +0 -46
- data/lib/table_structure/table/context_builder.rb +0 -49
- data/lib/table_structure/table/iterator.rb +0 -22
- data/lib/table_structure/table/row_builder.rb +0 -38
@@ -13,15 +13,11 @@ module TableStructure
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def validate(name:, key:, size:, **)
|
16
|
-
if key.respond_to?(:call)
|
17
|
-
raise Error.new('"key" must not be lambda.', @name, @index)
|
18
|
-
end
|
16
|
+
raise Error.new('"key" must not be callable.', @name, @index) if key.respond_to?(:call)
|
19
17
|
if !key && name.respond_to?(:call) && !size
|
20
18
|
raise Error.new('"size" must be defined, because column size cannot be determined.', @name, @index)
|
21
19
|
end
|
22
|
-
if size && size < DEFAULT_SIZE
|
23
|
-
raise Error.new('"size" must be positive.', @name, @index)
|
24
|
-
end
|
20
|
+
raise Error.new('"size" must be positive.', @name, @index) if size && size < DEFAULT_SIZE
|
25
21
|
if key && size && [key].flatten.size < size
|
26
22
|
raise Error.new('"key" size must not be less than specified "size".', @name, @index)
|
27
23
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableStructure
|
4
|
+
module Schema
|
5
|
+
module DSL
|
6
|
+
module ColumnBuilder
|
7
|
+
def column_builder(
|
8
|
+
name,
|
9
|
+
header: true,
|
10
|
+
body: true,
|
11
|
+
&block
|
12
|
+
)
|
13
|
+
column_builders[name] =
|
14
|
+
::TableStructure::Utils::TypedProc.new(
|
15
|
+
types: { header: !!header, body: !!body }.select { |_k, v| v }.keys,
|
16
|
+
&block
|
17
|
+
)
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def column_builders
|
22
|
+
@__column_builders__ ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
alias column_converter column_builder
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -5,12 +5,22 @@ module TableStructure
|
|
5
5
|
module DSL
|
6
6
|
module ColumnDefinition
|
7
7
|
def column(definition)
|
8
|
+
unless definition.is_a?(Hash)
|
9
|
+
warn "[TableStructure] Use `columns` instead of `column`.", uplevel: 1
|
10
|
+
end
|
8
11
|
column_definitions << definition
|
9
12
|
nil
|
10
13
|
end
|
11
14
|
|
12
|
-
def columns(definition)
|
13
|
-
|
15
|
+
def columns(definition = nil, &block)
|
16
|
+
if definition.is_a?(Hash)
|
17
|
+
warn "[TableStructure] Use `column` instead of `columns`.", uplevel: 1
|
18
|
+
end
|
19
|
+
if Utils.callable?(definition)
|
20
|
+
warn "[TableStructure] Use `block` instead of `lambda` or `proc`.", uplevel: 1
|
21
|
+
end
|
22
|
+
column_definitions << (block || definition)
|
23
|
+
nil
|
14
24
|
end
|
15
25
|
|
16
26
|
def column_definitions
|
@@ -5,17 +5,8 @@ module TableStructure
|
|
5
5
|
module DSL
|
6
6
|
module ContextBuilder
|
7
7
|
# TODO: Change definition style
|
8
|
-
def context_builder(name,
|
9
|
-
|
10
|
-
warn "[TableStructure] Use `block` instead of #{callable}."
|
11
|
-
end
|
12
|
-
|
13
|
-
block ||= callable
|
14
|
-
|
15
|
-
context_builders[name] =
|
16
|
-
::TableStructure::Schema::Definition::ContextBuilder.new(
|
17
|
-
&block
|
18
|
-
)
|
8
|
+
def context_builder(name, &block)
|
9
|
+
context_builders[name] = block
|
19
10
|
nil
|
20
11
|
end
|
21
12
|
|
@@ -6,19 +6,12 @@ module TableStructure
|
|
6
6
|
module RowBuilder
|
7
7
|
def row_builder(
|
8
8
|
name,
|
9
|
-
callable = nil,
|
10
9
|
enabled_row_types: %i[array hash],
|
11
10
|
&block
|
12
11
|
)
|
13
|
-
if callable
|
14
|
-
warn "[TableStructure] Use `block` instead of #{callable}."
|
15
|
-
end
|
16
|
-
|
17
|
-
block ||= callable
|
18
|
-
|
19
12
|
row_builders[name] =
|
20
|
-
::TableStructure::
|
21
|
-
|
13
|
+
::TableStructure::Utils::TypedProc.new(
|
14
|
+
types: enabled_row_types,
|
22
15
|
&block
|
23
16
|
)
|
24
17
|
nil
|
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
module TableStructure
|
4
4
|
module Schema
|
5
|
-
class
|
5
|
+
class KeysBuilder
|
6
6
|
def initialize(prefix: nil, suffix: nil)
|
7
7
|
@prefix = prefix
|
8
8
|
@suffix = suffix
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def build(keys)
|
12
12
|
return keys unless has_any_options?
|
13
13
|
|
14
14
|
keys.map do |key|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableStructure
|
4
|
+
module Schema
|
5
|
+
class RowContextBuilderFactory
|
6
|
+
def initialize(schema, builders)
|
7
|
+
@schema = schema
|
8
|
+
@builders = builders
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_header_builder
|
12
|
+
return unless @schema.contain_name_callable?
|
13
|
+
return unless @builders.key?(:header)
|
14
|
+
|
15
|
+
proc { |context| @builders[:header].call(context) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_data_builder
|
19
|
+
return unless @schema.contain_value_callable?
|
20
|
+
return unless @builders.key?(:row)
|
21
|
+
|
22
|
+
proc { |context| @builders[:row].call(context) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -2,71 +2,46 @@
|
|
2
2
|
|
3
3
|
module TableStructure
|
4
4
|
class Table
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
apply_to_name: schema.contain_callable?(:name),
|
13
|
-
apply_to_value: schema.contain_callable?(:value),
|
14
|
-
context: schema.context
|
15
|
-
) { |mod| extend mod }
|
16
|
-
|
17
|
-
ColumnConverter.create_module(
|
18
|
-
schema.column_converters,
|
19
|
-
context: schema.context
|
20
|
-
) { |mod| extend mod }
|
5
|
+
DEFAULT_ROW_BUILDERS = {
|
6
|
+
_to_hash_: Utils::TypedProc.new(
|
7
|
+
types: :hash
|
8
|
+
) do |values, keys|
|
9
|
+
keys.map.with_index { |key, i| [key || i, values[i]] }.to_h
|
10
|
+
end
|
11
|
+
}.freeze
|
21
12
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
13
|
+
def initialize(schema, row_type: :array)
|
14
|
+
@header_row_generator = schema.create_header_row_generator
|
15
|
+
@data_row_generator = schema.create_data_row_generator
|
16
|
+
|
17
|
+
row_builders =
|
18
|
+
DEFAULT_ROW_BUILDERS
|
19
|
+
.merge(schema.row_builders)
|
20
|
+
.select { |_k, v| v.typed?(row_type) }
|
21
|
+
.values
|
22
|
+
|
23
|
+
unless row_builders.empty?
|
24
|
+
row_build_task = proc do |row|
|
25
|
+
row.values = row_builders.reduce(row.values) do |values, builder|
|
26
|
+
builder.call(values, row.keys, row.context, schema.context)
|
27
|
+
end
|
28
|
+
row
|
29
|
+
end
|
30
|
+
@header_row_generator.compose(row_build_task)
|
31
|
+
@data_row_generator.compose(row_build_task)
|
32
|
+
end
|
28
33
|
|
29
34
|
yield self if block_given?
|
30
35
|
end
|
31
36
|
|
32
37
|
def header(context: nil)
|
33
|
-
|
38
|
+
@header_row_generator.call(context).values
|
34
39
|
end
|
35
40
|
|
36
|
-
def body(
|
37
|
-
Enumerator.new do |y|
|
38
|
-
|
41
|
+
def body(contexts)
|
42
|
+
::Enumerator.new do |y|
|
43
|
+
contexts.each { |context| y << @data_row_generator.call(context).values }
|
39
44
|
end
|
40
45
|
end
|
41
|
-
|
42
|
-
def rows(items)
|
43
|
-
warn '[TableStructure] `TableStructure::Table#rows(items)` has been deprecated. Use `TableStructure::Table#body(items)` instead.'
|
44
|
-
body(items)
|
45
|
-
end
|
46
|
-
|
47
|
-
def row(context: nil)
|
48
|
-
warn '[TableStructure] `TableStructure::Table#row(context: ...)` has been deprecated. Use `TableStructure::Table#body(items)` instead.'
|
49
|
-
data(context: context)
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def data(context: nil)
|
55
|
-
row_values(:values, context)
|
56
|
-
end
|
57
|
-
|
58
|
-
def keys
|
59
|
-
@keys ||= @key_converter.convert(@columns.map(&:keys).flatten)
|
60
|
-
end
|
61
|
-
|
62
|
-
def size
|
63
|
-
@size ||= @columns.map(&:size).reduce(0, &:+)
|
64
|
-
end
|
65
|
-
|
66
|
-
def row_values(method, context)
|
67
|
-
@columns
|
68
|
-
.map { |column| column.send(method, context, @context) }
|
69
|
-
.flatten
|
70
|
-
end
|
71
46
|
end
|
72
47
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableStructure
|
4
|
+
module Utils
|
5
|
+
class Proc < ::Proc
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def initialize(**options, &block)
|
9
|
+
@options = options
|
10
|
+
super(&block)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class TypedProc < Proc
|
15
|
+
def initialize(types:, **options, &block)
|
16
|
+
@types = [types].flatten.compact
|
17
|
+
super(**options, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def typed?(type)
|
21
|
+
@types.include?(type)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class CompositeCallable
|
26
|
+
def initialize
|
27
|
+
@callables = []
|
28
|
+
end
|
29
|
+
|
30
|
+
def compose(*callables)
|
31
|
+
@callables.concat(callables.flatten.compact)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(source)
|
36
|
+
@callables.reduce(source) { |memo, callable| callable.call(memo) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -4,28 +4,10 @@ module TableStructure
|
|
4
4
|
class Writer
|
5
5
|
def initialize(
|
6
6
|
schema,
|
7
|
-
header: { context: nil },
|
7
|
+
header: { context: nil, step: nil },
|
8
8
|
method: :<<,
|
9
|
-
row_type: :array
|
10
|
-
**deprecated_options
|
9
|
+
row_type: :array
|
11
10
|
)
|
12
|
-
if deprecated_options.key?(:header_omitted)
|
13
|
-
header_omitted = deprecated_options[:header_omitted]
|
14
|
-
warn "[TableStructure] `header_omitted: #{!!header_omitted}` option has been deprecated. Use `header: #{!header_omitted}` option instead."
|
15
|
-
header = !header_omitted
|
16
|
-
end
|
17
|
-
|
18
|
-
if deprecated_options.key?(:header_context)
|
19
|
-
header_context = deprecated_options[:header_context]
|
20
|
-
warn '[TableStructure] `:header_context` option has been deprecated. Use `header: { context: ... }` option instead.'
|
21
|
-
header = { context: header_context }
|
22
|
-
end
|
23
|
-
|
24
|
-
if deprecated_options.key?(:result_type)
|
25
|
-
warn '[TableStructure] `:result_type` option has been deprecated. Use `:row_type` option instead.'
|
26
|
-
row_type = deprecated_options[:result_type]
|
27
|
-
end
|
28
|
-
|
29
11
|
@schema = schema
|
30
12
|
@options = {
|
31
13
|
header: header,
|
@@ -38,51 +20,22 @@ module TableStructure
|
|
38
20
|
items,
|
39
21
|
to:,
|
40
22
|
method: @options[:method],
|
41
|
-
**deprecated_options,
|
42
23
|
&block
|
43
24
|
)
|
44
|
-
header = @options[:header]
|
45
|
-
row_type = @options[:row_type]
|
46
|
-
|
47
|
-
if deprecated_options.key?(:header)
|
48
|
-
header = deprecated_options[:header]
|
49
|
-
warn '[TableStructure] Use :header option on initialize method.'
|
50
|
-
end
|
51
|
-
|
52
|
-
if deprecated_options.key?(:header_omitted)
|
53
|
-
header_omitted = deprecated_options[:header_omitted]
|
54
|
-
warn "[TableStructure] `header_omitted: #{!!header_omitted}` option has been deprecated. Use `header: #{!header_omitted}` option instead."
|
55
|
-
header = !header_omitted
|
56
|
-
end
|
57
|
-
|
58
|
-
if deprecated_options.key?(:header_context)
|
59
|
-
header_context = deprecated_options[:header_context]
|
60
|
-
warn '[TableStructure] `:header_context` option has been deprecated. Use `header: { context: ... }` option instead.'
|
61
|
-
header = { context: header_context }
|
62
|
-
end
|
63
|
-
|
64
|
-
if deprecated_options.key?(:row_type)
|
65
|
-
row_type = deprecated_options[:row_type]
|
66
|
-
warn '[TableStructure] Use :row_type option on initialize method.'
|
67
|
-
end
|
68
|
-
|
69
|
-
if deprecated_options.key?(:result_type)
|
70
|
-
warn '[TableStructure] `:result_type` option has been deprecated. Use `:row_type` option instead.'
|
71
|
-
row_type = deprecated_options[:result_type]
|
72
|
-
end
|
73
|
-
|
74
25
|
output = Output.new(to, method: method)
|
75
26
|
|
76
27
|
Iterator
|
77
|
-
.new(
|
28
|
+
.new(
|
29
|
+
@schema,
|
30
|
+
header: @options[:header],
|
31
|
+
row_type: @options[:row_type]
|
32
|
+
)
|
78
33
|
.iterate(items, &block)
|
79
34
|
.each { |row| output.write(row) }
|
80
35
|
|
81
36
|
nil
|
82
37
|
end
|
83
38
|
|
84
|
-
private
|
85
|
-
|
86
39
|
class Output
|
87
40
|
def initialize(output, method: :<<)
|
88
41
|
@output = output
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: table_structure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jsmmr
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -75,31 +75,25 @@ files:
|
|
75
75
|
- lib/table_structure/iterator.rb
|
76
76
|
- lib/table_structure/schema.rb
|
77
77
|
- lib/table_structure/schema/class_methods.rb
|
78
|
-
- lib/table_structure/schema/
|
78
|
+
- lib/table_structure/schema/column_builder_factory.rb
|
79
79
|
- lib/table_structure/schema/columns/attributes.rb
|
80
80
|
- lib/table_structure/schema/columns/schema.rb
|
81
|
-
- lib/table_structure/schema/
|
81
|
+
- lib/table_structure/schema/composite_class.rb
|
82
82
|
- lib/table_structure/schema/definition/columns/attributes.rb
|
83
83
|
- lib/table_structure/schema/definition/columns/compiler.rb
|
84
84
|
- lib/table_structure/schema/definition/columns/error.rb
|
85
85
|
- lib/table_structure/schema/definition/columns/schema_class.rb
|
86
86
|
- lib/table_structure/schema/definition/columns/schema_instance.rb
|
87
87
|
- lib/table_structure/schema/definition/columns/validator.rb
|
88
|
-
- lib/table_structure/schema/
|
89
|
-
- lib/table_structure/schema/definition/row_builder.rb
|
90
|
-
- lib/table_structure/schema/dsl/column_converter.rb
|
88
|
+
- lib/table_structure/schema/dsl/column_builder.rb
|
91
89
|
- lib/table_structure/schema/dsl/column_definition.rb
|
92
90
|
- lib/table_structure/schema/dsl/context_builder.rb
|
93
|
-
- lib/table_structure/schema/dsl/option.rb
|
94
91
|
- lib/table_structure/schema/dsl/row_builder.rb
|
95
|
-
- lib/table_structure/schema/
|
96
|
-
- lib/table_structure/schema/
|
92
|
+
- lib/table_structure/schema/keys_builder.rb
|
93
|
+
- lib/table_structure/schema/row_context_builder_factory.rb
|
97
94
|
- lib/table_structure/schema/utils.rb
|
98
95
|
- lib/table_structure/table.rb
|
99
|
-
- lib/table_structure/
|
100
|
-
- lib/table_structure/table/context_builder.rb
|
101
|
-
- lib/table_structure/table/iterator.rb
|
102
|
-
- lib/table_structure/table/row_builder.rb
|
96
|
+
- lib/table_structure/utils.rb
|
103
97
|
- lib/table_structure/version.rb
|
104
98
|
- lib/table_structure/writer.rb
|
105
99
|
- table_structure.gemspec
|