table_structure 0.3.2 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: edea213f708a84a4bfaf1a149a7c4fd9a78b2c50e36b72b951f6c0bc2b4d3a14
4
- data.tar.gz: 71db859f76a5a55a33772d0764647afcfb0b6fa814705649d26c09f37f3ae35c
3
+ metadata.gz: d2a01593167aa1e2dd8324ca25696bc5a673214eb9659c5ca4643c62e3172cff
4
+ data.tar.gz: f374927b3fdb20eb93b3f0ff88344f9ba55fef1238ada8c8d6c577fc5b0d7484
5
5
  SHA512:
6
- metadata.gz: 72abcf6d37f57322848493cd45e335276dc729524000007385d382dc0cb835fbf6ebe740c970e6de06bd4a78e45b4f63a1858f060bbbbbfc86396a9c2b57d088
7
- data.tar.gz: 9332514abe32694295162c5349d5058e57c1bdf37a9c26eafb83e3bf18d9e01c88a128563f74193aece52fa0158adc6c2d2979fbd2663ad3b380aa17c4c3e03b
6
+ metadata.gz: 69931112fd4a46d250ef0ad1f43a67baebf408dcde70dcc15f153661871a14cb8d91bdec9258ef5ac351af86b40059f35b51ea0c65f1d5e9f4fad19f7529a09b
7
+ data.tar.gz: e615deb857dc78ab84ee643c5f43a629709917e949872a8147fa2625430f9a7a2872523080f3ebb5e31e29a5038cc9ab91123549cd97683c5726a547208d4f3b
data/CHANGELOG.md CHANGED
@@ -1,7 +1,15 @@
1
+ # 0.3.3
2
+ Changes:
3
+ - `TableStructure::Schema`
4
+ - Improve designs and performance. You can ignore the following changes unless you have been using the schema instance method directly.
5
+ - Add `TableStructure::Schema#create_table` method. It returns `TableStructure::Schema::Table` instance.
6
+ - Remove `TableStructure::Schema#header` method. Use `TableStructure::Schema::Table#header` method instead.
7
+ - Remove `TableStructure::Schema#row` method. Use `TableStructure::Schema::Table#row` method instead.
8
+
1
9
  # 0.3.2
2
10
  Changes:
3
- - `TableStructure::Writer`
4
- - When `result_type: :hash` option is specified and `column(s)` key of the schema is undefined, index number is used as the key.
11
+ - `TableStructure::Writer`
12
+ - When `result_type: :hash` option is specified and `column(s)` key of the schema is undefined, index number is used as the key.
5
13
 
6
14
  # 0.3.1
7
15
  Changes:
@@ -15,7 +23,7 @@ Changes:
15
23
  # 0.3.0
16
24
  Changes:
17
25
  - `TableStructure::Schema`
18
- - Add `:omitted` key for column(s) DSL.
26
+ - Add `:omitted` key for `column(s)` DSL.
19
27
  - Support nested schema.
20
28
  - Add following options for schema initialization:
21
29
  - `:key_prefix`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- table_structure (0.3.2)
4
+ table_structure (0.3.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -305,9 +305,10 @@ end
305
305
  You can also use only `TableStructure::Schema`.
306
306
  ```ruby
307
307
  schema = SampleTableSchema.new
308
- header = schema.header
308
+ table = schema.create_table
309
+ header = table.header
309
310
  items.each do |item|
310
- row = schema.row(context: item)
311
+ row = table.row(context: item)
311
312
  ...
312
313
  end
313
314
  ```
@@ -4,7 +4,7 @@ module TableStructure
4
4
  module Schema
5
5
  module Column
6
6
  class Attrs
7
- attr_reader :name, :key, :vlaue, :size
7
+ attr_reader :keys, :size
8
8
 
9
9
  def initialize(definition, options)
10
10
  @name = definition[:name]
@@ -19,14 +19,6 @@ module TableStructure
19
19
  optimize_size(name, @size)
20
20
  end
21
21
 
22
- def key
23
- if @options[:key_prefix] || @options[:key_suffix]
24
- decorate_keys
25
- else
26
- @keys
27
- end
28
- end
29
-
30
22
  def value(row_context, table_context)
31
23
  value = Utils.evaluate_callable(@value, row_context, table_context)
32
24
  optimize_size(value, @size)
@@ -47,16 +39,6 @@ module TableStructure
47
39
  values
48
40
  end
49
41
  end
50
-
51
- def decorate_keys
52
- @keys.map do |key|
53
- next key unless key
54
-
55
- decorated_key = "#{@options[:key_prefix]}#{key}#{@options[:key_suffix]}"
56
- decorated_key = decorated_key.to_sym if key.is_a?(Symbol)
57
- decorated_key
58
- end
59
- end
60
42
  end
61
43
  end
62
44
  end
@@ -4,32 +4,26 @@ module TableStructure
4
4
  module Schema
5
5
  module Column
6
6
  class Schema
7
- attr_reader :schema
7
+ attr_reader :table
8
8
 
9
9
  def initialize(schema)
10
- @schema = schema
10
+ @table = schema.create_table
11
11
  end
12
12
 
13
13
  def name(header_context, _table_context)
14
- @schema.header(context: header_context)
14
+ @table.header(context: header_context)
15
15
  end
16
16
 
17
- def key
18
- table.send(:keys)
17
+ def keys
18
+ @table.send(:keys)
19
19
  end
20
20
 
21
21
  def value(row_context, _table_context)
22
- @schema.row(context: row_context)
22
+ @table.row(context: row_context)
23
23
  end
24
24
 
25
25
  def size
26
- table.send(:size)
27
- end
28
-
29
- private
30
-
31
- def table
32
- @schema.instance_variable_get(:@table_structure_schema_table_)
26
+ @table.send(:size)
33
27
  end
34
28
  end
35
29
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ class Definition
6
+ class Compiler
7
+ DEFAULT_ATTRS = {
8
+ name: nil,
9
+ key: nil,
10
+ value: nil,
11
+ size: nil,
12
+ omitted: false
13
+ }.freeze
14
+
15
+ DEFAULT_SIZE = 1
16
+
17
+ def initialize(name, definitions, options)
18
+ @name = name
19
+ @definitions = definitions
20
+ @options = options
21
+ end
22
+
23
+ def compile(context = nil)
24
+ @definitions
25
+ .map { |definition| Utils.evaluate_callable(definition, context) }
26
+ .map.with_index do |definition, i|
27
+ validator = Validator.new(@name, i, @options)
28
+
29
+ [definition]
30
+ .flatten
31
+ .map do |definition|
32
+ if definition.is_a?(Hash)
33
+ definition = DEFAULT_ATTRS.merge(definition)
34
+ omitted = definition.delete(:omitted)
35
+ next if Utils.evaluate_callable(omitted, context)
36
+
37
+ validator.validate(definition)
38
+ definition[:size] = determine_size(definition)
39
+ definition
40
+ elsif Utils.schema_instance?(definition)
41
+ definition
42
+ elsif Utils.schema_class?(definition)
43
+ definition.new(context: context)
44
+ else
45
+ raise Error.new('Invalid definition.', @name, i)
46
+ end
47
+ end
48
+ end
49
+ .flatten
50
+ .compact
51
+ end
52
+
53
+ private
54
+
55
+ def determine_size(name:, key:, size:, **)
56
+ return size if size
57
+
58
+ [calculate_size(name), calculate_size(key)].max
59
+ end
60
+
61
+ def calculate_size(val)
62
+ if val.is_a?(Array)
63
+ return val.empty? ? DEFAULT_SIZE : val.size
64
+ end
65
+
66
+ DEFAULT_SIZE
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -3,66 +3,59 @@
3
3
  module TableStructure
4
4
  module Schema
5
5
  class Definition
6
- DEFAULT_ATTRS = {
7
- name: nil,
8
- key: nil,
9
- value: nil,
10
- size: nil,
11
- omitted: false
6
+ RESULT_BUILDERS = {
7
+ hash: lambda { |values, keys, *|
8
+ keys.map.with_index { |key, i| [key || i, values[i]] }.to_h
9
+ }
12
10
  }.freeze
13
11
 
14
- DEFAULT_SIZE = 1
12
+ attr_reader :columns, :options
13
+
14
+ def initialize(
15
+ name,
16
+ column_definitions,
17
+ context_builders,
18
+ column_converters,
19
+ result_builders,
20
+ context,
21
+ options
22
+ )
23
+ table_context_builder = context_builders.delete(:table)
24
+ context = table_context_builder.call(context) if table_context_builder
15
25
 
16
- def initialize(name, definitions, options)
17
26
  @name = name
18
- @definitions = definitions
27
+ @columns = create_columns(name, column_definitions, context, options)
28
+ @context_builders = context_builders
29
+ @column_converters = column_converters
30
+ @result_builders = result_builders
31
+ @context = context
19
32
  @options = options
20
33
  end
21
34
 
22
- def compile(context = nil)
23
- @definitions
24
- .map { |definition| Utils.evaluate_callable(definition, context) }
25
- .map.with_index do |definition, i|
26
- validator = Validator.new(@name, i, @options)
27
-
28
- [definition]
29
- .flatten
30
- .map do |definition|
31
- if definition.is_a?(Hash)
32
- definition = DEFAULT_ATTRS.merge(definition)
33
- omitted = definition.delete(:omitted)
34
- next if Utils.evaluate_callable(omitted, context)
35
-
36
- validator.validate(definition)
37
- definition[:size] = determine_size(definition)
38
- definition
39
- elsif Utils.schema_instance?(definition)
40
- definition
41
- elsif Utils.schema_class?(definition)
42
- definition.new(context: context)
43
- else
44
- raise Error.new('Invalid definition.', @name, i)
45
- end
46
- end
47
- end
48
- .flatten
49
- .compact
35
+ def create_table(result_type: :array, **options)
36
+ options = @options.merge(options)
37
+ result_builders =
38
+ RESULT_BUILDERS
39
+ .select { |k, _v| k == result_type }
40
+ .merge(@result_builders)
41
+
42
+ Table.new(
43
+ @columns,
44
+ @context_builders,
45
+ @column_converters,
46
+ result_builders,
47
+ @context,
48
+ options
49
+ )
50
50
  end
51
51
 
52
52
  private
53
53
 
54
- def determine_size(name:, key:, size:, **)
55
- return size if size
56
-
57
- [calculate_size(name), calculate_size(key)].max
58
- end
59
-
60
- def calculate_size(val)
61
- if val.is_a?(Array)
62
- return val.empty? ? DEFAULT_SIZE : val.size
63
- end
64
-
65
- DEFAULT_SIZE
54
+ def create_columns(name, definitions, context, options)
55
+ Compiler
56
+ .new(name, definitions, options)
57
+ .compile(context)
58
+ .map { |definition| Column.create(definition, options) }
66
59
  end
67
60
  end
68
61
  end
@@ -10,7 +10,7 @@ module TableStructure
10
10
  end
11
11
 
12
12
  def context_builders
13
- @table_structure_schema_context_builders__ ||= Hash.new(->(val) { val })
13
+ @table_structure_schema_context_builders__ ||= {}
14
14
  end
15
15
  end
16
16
  end
@@ -3,49 +3,67 @@
3
3
  module TableStructure
4
4
  module Schema
5
5
  class Table
6
- RESULT_BUILDERS = {
7
- hash: lambda { |values, keys, *|
8
- keys.map.with_index { |key, i| [key || i, values[i]] }.to_h
9
- }
10
- }.freeze
6
+ attr_reader :column_converters, :result_builders
11
7
 
12
- attr_reader :columns, :column_converters, :result_builders, :options
13
-
14
- def initialize(name, column_definitions, column_converters, result_builders, context, options)
15
- @name = name
16
- @columns = build_columns(name, column_definitions, context, options)
8
+ def initialize(
9
+ columns,
10
+ context_builders,
11
+ column_converters,
12
+ result_builders,
13
+ context,
14
+ options
15
+ )
16
+ @columns = columns
17
+ @header_context_builder = context_builders[:header]
18
+ @row_context_builder = context_builders[:row]
17
19
  @column_converters = column_converters
18
20
  @result_builders = result_builders
19
21
  @context = context
20
22
  @options = options
21
23
  end
22
24
 
23
- def header_values(context, result_type = nil) # TODO
24
- values(:name, result_type, context)
25
+ def header(context: nil)
26
+ if @header_context_builder
27
+ context = @header_context_builder.call(context)
28
+ end
29
+ values(:name, context)
25
30
  end
26
31
 
27
- def row_values(context, result_type = nil) # TODO
28
- values(:value, result_type, context)
32
+ def row(context: nil)
33
+ context = @row_context_builder.call(context) if @row_context_builder
34
+ values(:value, context)
29
35
  end
30
36
 
37
+ private
38
+
31
39
  def keys
32
- @keys ||= @columns.map(&:key).flatten
40
+ @keys ||= obtain_keys
33
41
  end
34
42
 
35
- def size
36
- @size ||= @columns.map(&:size).reduce(0) { |memo, size| memo + size }
43
+ def obtain_keys
44
+ keys = @columns.map(&:keys).flatten
45
+ has_key_options? ? decorate_keys(keys) : keys
37
46
  end
38
47
 
39
- private
48
+ def has_key_options?
49
+ @options[:key_prefix] || @options[:key_suffix]
50
+ end
51
+
52
+ def decorate_keys(keys)
53
+ keys.map do |key|
54
+ next key unless key
55
+
56
+ decorated_key = "#{@options[:key_prefix]}#{key}#{@options[:key_suffix]}"
57
+ decorated_key = decorated_key.to_sym if key.is_a?(Symbol)
58
+ decorated_key
59
+ end
60
+ end
40
61
 
41
- def build_columns(name, definitions, context, options)
42
- Definition
43
- .new(name, definitions, options)
44
- .compile(context)
45
- .map { |definition| Column.create(definition, options) }
62
+ def size
63
+ @size ||= @columns.map(&:size).reduce(0) { |memo, size| memo + size }
46
64
  end
47
65
 
48
- def values(method, result_type, context)
66
+ def values(method, context)
49
67
  columns =
50
68
  @columns
51
69
  .map { |column| column.send(method, context, @context) }
@@ -56,9 +74,7 @@ module TableStructure
56
74
  end
57
75
  end
58
76
 
59
- RESULT_BUILDERS
60
- .select { |k, _v| k == result_type }
61
- .merge(@result_builders)
77
+ @result_builders
62
78
  .reduce(columns) do |columns, (_, result_builder)|
63
79
  result_builder.call(columns, keys, context, @context)
64
80
  end
@@ -17,15 +17,16 @@ module TableStructure
17
17
  }.freeze
18
18
 
19
19
  def initialize(context: nil, name: self.class.name, **options)
20
- column_definitions = self.class.column_definitions
21
- column_converters = self.class.column_converters
22
- result_builders = self.class.result_builders
23
- context = self.class.context_builders[:table].call(context)
20
+ column_definitions = [].concat(self.class.column_definitions)
21
+ context_builders = {}.merge!(self.class.context_builders)
22
+ column_converters = {}.merge!(self.class.column_converters)
23
+ result_builders = {}.merge!(self.class.result_builders)
24
24
  options = DEFAULT_OPTIONS.merge(self.class.options).merge(options)
25
- @table_structure_schema_table_ =
26
- Table.new(
25
+ @table_structure_schema_definition_ =
26
+ Definition.new(
27
27
  name,
28
28
  column_definitions,
29
+ context_builders,
29
30
  column_converters,
30
31
  result_builders,
31
32
  context,
@@ -33,26 +34,10 @@ module TableStructure
33
34
  )
34
35
  end
35
36
 
36
- def header(context: nil, result_type: nil)
37
- # TODO
38
- result_type ||= @table_structure_schema_table_.options[:result_type]
39
- context = self.class.context_builders[:header].call(context)
40
- @table_structure_schema_table_.header_values(context, result_type)
41
- end
42
-
43
- def row(context: nil, result_type: nil)
44
- # TODO
45
- result_type ||= @table_structure_schema_table_.options[:result_type]
46
- context = self.class.context_builders[:row].call(context)
47
- @table_structure_schema_table_.row_values(context, result_type)
48
- end
49
-
50
- def column_converters
51
- @table_structure_schema_table_.column_converters
52
- end
53
-
54
- def result_builders
55
- @table_structure_schema_table_.result_builders
37
+ def create_table(result_type: nil, **options)
38
+ options = @table_structure_schema_definition_.options.merge(options)
39
+ result_type ||= options[:result_type] # TODO: remove
40
+ @table_structure_schema_definition_.create_table(result_type: result_type, **options)
56
41
  end
57
42
  end
58
43
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TableStructure
4
- VERSION = '0.3.2'
4
+ VERSION = '0.3.3'
5
5
  end
@@ -16,19 +16,16 @@ module TableStructure
16
16
 
17
17
  def write(items, to:, **options)
18
18
  options = @options.merge(options)
19
+ table = @schema.create_table(options)
19
20
  unless options[:header_omitted]
20
- header = @schema.header(
21
- context: options[:header_context],
22
- result_type: options[:result_type]
21
+ header = table.header(
22
+ context: options[:header_context]
23
23
  )
24
24
  header = yield header if block_given?
25
25
  to.send(options[:method], header)
26
26
  end
27
27
  enumerize(items).each do |item|
28
- row = @schema.row(
29
- context: item,
30
- result_type: options[:result_type]
31
- )
28
+ row = table.row(context: item)
32
29
  row = yield row if block_given?
33
30
  to.send(options[:method], row)
34
31
  end
@@ -12,6 +12,7 @@ module TableStructure
12
12
  require 'table_structure/schema/dsl/option'
13
13
  require 'table_structure/schema/dsl/result_builder'
14
14
  require 'table_structure/schema/definition'
15
+ require 'table_structure/schema/definition/compiler'
15
16
  require 'table_structure/schema/definition/error'
16
17
  require 'table_structure/schema/definition/validator'
17
18
  require 'table_structure/schema/table'
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.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - jsmmr
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-02 00:00:00.000000000 Z
11
+ date: 2019-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -77,6 +77,7 @@ files:
77
77
  - lib/table_structure/schema/column/attrs.rb
78
78
  - lib/table_structure/schema/column/schema.rb
79
79
  - lib/table_structure/schema/definition.rb
80
+ - lib/table_structure/schema/definition/compiler.rb
80
81
  - lib/table_structure/schema/definition/error.rb
81
82
  - lib/table_structure/schema/definition/validator.rb
82
83
  - lib/table_structure/schema/dsl/column_converter.rb