table_structure 0.3.22 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|