table_structure 0.3.2 → 0.3.3

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