table_structure 0.3.16 → 0.3.17

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -3
  3. data/Gemfile.lock +5 -5
  4. data/README.md +44 -38
  5. data/lib/table_structure.rb +15 -10
  6. data/lib/table_structure/schema.rb +43 -22
  7. data/lib/table_structure/schema/class_methods.rb +2 -2
  8. data/lib/table_structure/schema/column_converters.rb +40 -44
  9. data/lib/table_structure/schema/{column/attrs.rb → columns/attributes.rb} +7 -2
  10. data/lib/table_structure/schema/{column → columns}/schema.rb +6 -4
  11. data/lib/table_structure/schema/context_builders.rb +12 -4
  12. data/lib/table_structure/schema/definition/column_converter.rb +31 -0
  13. data/lib/table_structure/schema/definition/columns/attributes.rb +55 -0
  14. data/lib/table_structure/schema/definition/columns/compiler.rb +45 -0
  15. data/lib/table_structure/schema/{column/definition → definition/columns}/error.rb +2 -2
  16. data/lib/table_structure/schema/definition/columns/schema_class.rb +24 -0
  17. data/lib/table_structure/schema/definition/columns/schema_instance.rb +23 -0
  18. data/lib/table_structure/schema/{column/definition → definition/columns}/validator.rb +2 -2
  19. data/lib/table_structure/schema/definition/context_builder.rb +17 -0
  20. data/lib/table_structure/schema/definition/row_builder.rb +25 -0
  21. data/lib/table_structure/schema/dsl/column_converter.rb +16 -9
  22. data/lib/table_structure/schema/dsl/context_builder.rb +4 -1
  23. data/lib/table_structure/schema/dsl/row_builder.rb +26 -0
  24. data/lib/table_structure/schema/keys_generator.rb +29 -0
  25. data/lib/table_structure/schema/row_builders.rb +58 -0
  26. data/lib/table_structure/schema/table.rb +24 -16
  27. data/lib/table_structure/schema/utils.rb +5 -1
  28. data/lib/table_structure/version.rb +1 -1
  29. data/lib/table_structure/writer.rb +1 -1
  30. metadata +16 -11
  31. data/lib/table_structure/schema/column/definition/compiler.rb +0 -81
  32. data/lib/table_structure/schema/column/factory.rb +0 -22
  33. data/lib/table_structure/schema/dsl/result_builder.rb +0 -27
  34. data/lib/table_structure/schema/result_builders.rb +0 -67
  35. data/lib/table_structure/schema/table/key_decorator.rb +0 -32
@@ -2,8 +2,8 @@
2
2
 
3
3
  module TableStructure
4
4
  module Schema
5
- module Column
6
- class Attrs
5
+ module Columns
6
+ class Attributes
7
7
  attr_reader :keys, :size
8
8
 
9
9
  def initialize(name:, key:, value:, size:)
@@ -23,6 +23,11 @@ module TableStructure
23
23
  optimize_size(value, @size)
24
24
  end
25
25
 
26
+ def contain_callable?(attribute)
27
+ val = instance_variable_get("@#{attribute}")
28
+ Utils.callable?(val)
29
+ end
30
+
26
31
  private
27
32
 
28
33
  def optimize_size(value, expected_size)
@@ -2,10 +2,8 @@
2
2
 
3
3
  module TableStructure
4
4
  module Schema
5
- module Column
5
+ module Columns
6
6
  class Schema
7
- attr_reader :table
8
-
9
7
  def initialize(schema)
10
8
  @table = schema.create_table
11
9
  end
@@ -19,12 +17,16 @@ module TableStructure
19
17
  end
20
18
 
21
19
  def values(row_context, _table_context)
22
- @table.row(context: row_context)
20
+ @table.send(:data, context: row_context)
23
21
  end
24
22
 
25
23
  def size
26
24
  @table.send(:size)
27
25
  end
26
+
27
+ def contain_callable?(attribute)
28
+ @table.send(:contain_callable?, attribute)
29
+ end
28
30
  end
29
31
  end
30
32
  end
@@ -19,24 +19,32 @@ module TableStructure
19
19
 
20
20
  def extend_methods_for(table)
21
21
  methods = {}
22
- methods[:header] = create_method(@header_builder) if @header_builder
23
- methods[:row] = create_method(@row_builder) if @row_builder
24
22
 
23
+ if table.send(:contain_callable?, :name)
24
+ methods[:header] = create_method(@header_builder)
25
+ end
26
+ if table.send(:contain_callable?, :value)
27
+ methods[:data] = create_method(@row_builder)
28
+ end
29
+
30
+ methods.reject! { |_k, v| v.nil? }
25
31
  return if methods.empty?
26
32
 
27
- table.extend ContextBuilder.new(methods)
33
+ table.extend ContextBuildable.new(methods)
28
34
  end
29
35
 
30
36
  private
31
37
 
32
38
  def create_method(builder)
39
+ return if builder.nil?
40
+
33
41
  proc do |context: nil|
34
42
  super(context: builder.call(context))
35
43
  end
36
44
  end
37
45
  end
38
46
 
39
- class ContextBuilder < Module
47
+ class ContextBuildable < Module
40
48
  def initialize(methods)
41
49
  methods.each do |name, method|
42
50
  define_method(name, &method)
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module Definition
6
+ class ColumnConverter
7
+ extend Forwardable
8
+
9
+ def_delegator :@callable, :call
10
+
11
+ def initialize(
12
+ callable,
13
+ header: true,
14
+ body: true
15
+ )
16
+ @callable = callable
17
+ @applicable_to_header = header
18
+ @applicable_to_body = body
19
+ end
20
+
21
+ def applicable_to_header?
22
+ !!@applicable_to_header
23
+ end
24
+
25
+ def applicable_to_body?
26
+ !!@applicable_to_body
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module Definition
6
+ module Columns
7
+ class Attributes
8
+ DEFAULT_SIZE = 1
9
+
10
+ def initialize(
11
+ name: nil,
12
+ key: nil,
13
+ value: nil,
14
+ size: nil,
15
+ omitted: false,
16
+ validator:
17
+ )
18
+ @name = name
19
+ @key = key
20
+ @value = value
21
+ @size = size
22
+ @omitted = omitted
23
+ @validator = validator
24
+ end
25
+
26
+ def omitted?(context:)
27
+ Utils.evaluate_callable(@omitted, context)
28
+ end
29
+
30
+ def compile(context:)
31
+ size = Utils.evaluate_callable(@size, context)
32
+ @validator.validate(name: @name, key: @key, size: size)
33
+ size ||= [calculate_size(@name), calculate_size(@key)].max
34
+ ::TableStructure::Schema::Columns::Attributes.new(
35
+ name: @name,
36
+ key: @key,
37
+ value: @value,
38
+ size: size
39
+ )
40
+ end
41
+
42
+ private
43
+
44
+ def calculate_size(val)
45
+ if val.is_a?(Array)
46
+ return val.empty? ? DEFAULT_SIZE : val.size
47
+ end
48
+
49
+ DEFAULT_SIZE
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module Definition
6
+ module Columns
7
+ class Compiler
8
+ def initialize(schema_name, definitions, options)
9
+ @schema_name = schema_name
10
+ @definitions = definitions
11
+ @options = options
12
+ end
13
+
14
+ def compile(context = nil)
15
+ @definitions
16
+ .map { |definition| Utils.evaluate_callable(definition, context) }
17
+ .map.with_index do |definitions, i|
18
+ validator = Validator.new(@schema_name, i)
19
+
20
+ [definitions]
21
+ .flatten
22
+ .map do |definition|
23
+ if definition.is_a?(Hash)
24
+ Attributes.new(**definition, validator: validator)
25
+ elsif Utils.schema_instance?(definition)
26
+ SchemaInstance.new(definition)
27
+ elsif Utils.schema_class?(definition)
28
+ SchemaClass.new(definition)
29
+ elsif definition.nil? && @options[:nil_definitions_ignored]
30
+ next
31
+ else
32
+ raise Error.new('Invalid definition.', @schema_name, i)
33
+ end
34
+ end
35
+ end
36
+ .flatten
37
+ .compact
38
+ .reject { |column| column.omitted?(context: context) }
39
+ .map { |column| column.compile(context: context) }
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module TableStructure
4
4
  module Schema
5
- module Column
6
- module Definition
5
+ module Definition
6
+ module Columns
7
7
  class Error < ::TableStructure::Error
8
8
  attr_reader :schema_name, :definition_index
9
9
 
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module Definition
6
+ module Columns
7
+ class SchemaClass
8
+ def initialize(definition)
9
+ @definition = definition
10
+ end
11
+
12
+ def omitted?(**)
13
+ false
14
+ end
15
+
16
+ def compile(context:)
17
+ instance = @definition.new(context: context)
18
+ ::TableStructure::Schema::Columns::Schema.new(instance)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module Definition
6
+ module Columns
7
+ class SchemaInstance
8
+ def initialize(definition)
9
+ @definition = definition
10
+ end
11
+
12
+ def omitted?(**)
13
+ false
14
+ end
15
+
16
+ def compile(**)
17
+ ::TableStructure::Schema::Columns::Schema.new(@definition)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module TableStructure
4
4
  module Schema
5
- module Column
6
- module Definition
5
+ module Definition
6
+ module Columns
7
7
  class Validator
8
8
  DEFAULT_SIZE = 1
9
9
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module Definition
6
+ class ContextBuilder
7
+ extend Forwardable
8
+
9
+ def_delegator :@callable, :call
10
+
11
+ def initialize(callable)
12
+ @callable = callable
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module Definition
6
+ class RowBuilder
7
+ extend Forwardable
8
+
9
+ def_delegator :@callable, :call
10
+
11
+ def initialize(
12
+ callable,
13
+ enabled_row_types: %i[array hash]
14
+ )
15
+ @callable = callable
16
+ @enabled_row_types = [enabled_row_types].flatten
17
+ end
18
+
19
+ def enabled?(row_type)
20
+ @enabled_row_types.include?(row_type)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -4,17 +4,24 @@ module TableStructure
4
4
  module Schema
5
5
  module DSL
6
6
  module ColumnConverter
7
- DEFAULT_OPTIONS = {
7
+ def column_converter(
8
+ name,
9
+ callable,
8
10
  header: true,
9
- row: true
10
- }.freeze
11
+ body: true,
12
+ **deprecated_options
13
+ )
14
+ if deprecated_options.key?(:row)
15
+ warn '[TableStructure] `:row` option has been deprecated. Use `:body` option instead.'
16
+ body = deprecated_options[:row]
17
+ end
11
18
 
12
- def column_converter(name, callable, **options)
13
- options = DEFAULT_OPTIONS.merge(options)
14
- column_converters[name] = {
15
- callable: callable,
16
- options: options
17
- }
19
+ column_converters[name] =
20
+ ::TableStructure::Schema::Definition::ColumnConverter.new(
21
+ callable,
22
+ header: header,
23
+ body: body
24
+ )
18
25
  nil
19
26
  end
20
27
 
@@ -5,7 +5,10 @@ module TableStructure
5
5
  module DSL
6
6
  module ContextBuilder
7
7
  def context_builder(name, callable)
8
- context_builders[name] = callable
8
+ context_builders[name] =
9
+ ::TableStructure::Schema::Definition::ContextBuilder.new(
10
+ callable
11
+ )
9
12
  nil
10
13
  end
11
14
 
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ module DSL
6
+ module RowBuilder
7
+ def row_builder(
8
+ name,
9
+ callable,
10
+ enabled_row_types: %i[array hash]
11
+ )
12
+ row_builders[name] =
13
+ ::TableStructure::Schema::Definition::RowBuilder.new(
14
+ callable,
15
+ enabled_row_types: enabled_row_types
16
+ )
17
+ nil
18
+ end
19
+
20
+ def row_builders
21
+ @__row_builders__ ||= {}
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableStructure
4
+ module Schema
5
+ class KeysGenerator
6
+ def initialize(prefix: nil, suffix: nil)
7
+ @prefix = prefix
8
+ @suffix = suffix
9
+ end
10
+
11
+ def generate(keys)
12
+ return keys unless has_any_options?
13
+
14
+ keys.map do |key|
15
+ next key unless key
16
+
17
+ decorated_key = "#{@prefix}#{key}#{@suffix}"
18
+ key.is_a?(Symbol) ? decorated_key.to_sym : decorated_key
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def has_any_options?
25
+ @prefix || @suffix
26
+ end
27
+ end
28
+ end
29
+ end