table_structure 0.3.14 → 0.3.15
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 +5 -0
 - data/Gemfile.lock +2 -2
 - data/README.md +55 -6
 - data/lib/table_structure/csv/writer.rb +34 -40
 - data/lib/table_structure/schema/class_methods.rb +34 -0
 - data/lib/table_structure/schema/column/attrs.rb +7 -7
 - data/lib/table_structure/schema/column/definition/compiler.rb +81 -0
 - data/lib/table_structure/schema/column/definition/error.rb +19 -0
 - data/lib/table_structure/schema/column/definition/validator.rb +35 -0
 - data/lib/table_structure/schema/column/factory.rb +22 -0
 - data/lib/table_structure/schema/column/schema.rb +2 -2
 - data/lib/table_structure/schema/column_converters.rb +9 -8
 - data/lib/table_structure/schema/dsl/column_converter.rb +1 -1
 - data/lib/table_structure/schema/dsl/column_definition.rb +1 -1
 - data/lib/table_structure/schema/dsl/context_builder.rb +1 -1
 - data/lib/table_structure/schema/dsl/option.rb +1 -1
 - data/lib/table_structure/schema/dsl/result_builder.rb +1 -1
 - data/lib/table_structure/schema/result_builders.rb +5 -6
 - data/lib/table_structure/schema/table.rb +3 -7
 - data/lib/table_structure/schema.rb +52 -9
 - data/lib/table_structure/version.rb +1 -1
 - data/lib/table_structure.rb +5 -4
 - metadata +8 -7
 - data/lib/table_structure/schema/definition/compiler.rb +0 -79
 - data/lib/table_structure/schema/definition/error.rb +0 -17
 - data/lib/table_structure/schema/definition/validator.rb +0 -33
 - data/lib/table_structure/schema/definition.rb +0 -63
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 77197fdbfa164e9f532b190b4e94750354595f9e51d155b91ed36ea2f43aeef2
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 52ab0ab962584d0d7e8e10788a6c949369926ec8869577e797a462e90eb76487
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 99774b00f0260b64ed8a3ea670cf24d79e222c8b75fab7545932fbb248516561078f2908a081bae925e7baf44502d115711974d5b7458937e6db1e0961be0152
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: ca70303e5f5ec9ae437e9dccd9554b027c48aa68b7cb9c0f0239f6fa1ca0259321c9ea942310ac7a320e8d80ef6b996ef02a1cfb5ac0afa3a317534b351ecd85
         
     | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -76,7 +76,7 @@ schema = SampleTableSchema.new(context: context) 
     | 
|
| 
       76 
76 
     | 
    
         
             
            Initialize a writer with the schema:
         
     | 
| 
       77 
77 
     | 
    
         
             
            ```ruby
         
     | 
| 
       78 
78 
     | 
    
         
             
            writer = TableStructure::Writer.new(schema)
         
     | 
| 
       79 
     | 
    
         
            -
            ##  
     | 
| 
      
 79 
     | 
    
         
            +
            ## To omit header, write:
         
     | 
| 
       80 
80 
     | 
    
         
             
            # writer = TableStructure::Writer.new(schema, header_omitted: true)
         
     | 
| 
       81 
81 
     | 
    
         
             
            ```
         
     | 
| 
       82 
82 
     | 
    
         | 
| 
         @@ -97,8 +97,9 @@ items = [ 
     | 
|
| 
       97 
97 
     | 
    
         
             
              }
         
     | 
| 
       98 
98 
     | 
    
         
             
            ]
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
       100 
     | 
    
         
            -
            ##  
     | 
| 
      
 100 
     | 
    
         
            +
            ## To use Rails `find_each` method, write:
         
     | 
| 
       101 
101 
     | 
    
         
             
            # items = Item.enum_for(:find_each)
         
     | 
| 
      
 102 
     | 
    
         
            +
            ## or
         
     | 
| 
       102 
103 
     | 
    
         
             
            # items = Enumerator.new { |y| Item.find_each { |item| y << item } }
         
     | 
| 
       103 
104 
     | 
    
         | 
| 
       104 
105 
     | 
    
         
             
            table = []
         
     | 
| 
         @@ -117,7 +118,7 @@ end 
     | 
|
| 
       117 
118 
     | 
    
         | 
| 
       118 
119 
     | 
    
         
             
            Writes the items converted by the schema to stream as CSV with Rails:
         
     | 
| 
       119 
120 
     | 
    
         
             
            ```ruby
         
     | 
| 
       120 
     | 
    
         
            -
            # response.headers['X-Accel-Buffering'] = 'no' #  
     | 
| 
      
 121 
     | 
    
         
            +
            # response.headers['X-Accel-Buffering'] = 'no' # Required if Nginx is used for reverse proxy
         
     | 
| 
       121 
122 
     | 
    
         
             
            response.headers['Cache-Control'] = 'no-cache'
         
     | 
| 
       122 
123 
     | 
    
         
             
            response.headers['Content-Type'] = 'text/csv'
         
     | 
| 
       123 
124 
     | 
    
         
             
            response.headers['Content-Disposition'] = 'attachment; filename="sample.csv"'
         
     | 
| 
         @@ -164,7 +165,7 @@ class SampleTableSchema 
     | 
|
| 
       164 
165 
     | 
    
         
             
                end
         
     | 
| 
       165 
166 
     | 
    
         
             
              }
         
     | 
| 
       166 
167 
     | 
    
         | 
| 
       167 
     | 
    
         
            -
              ##  
     | 
| 
      
 168 
     | 
    
         
            +
              ## If the schemas are nested, :key must be unique in parent and child schemas.
         
     | 
| 
       168 
169 
     | 
    
         
             
              ## This can also be avoided by specifying :key_prefix or :key_suffix option.
         
     | 
| 
       169 
170 
     | 
    
         
             
              # columns ->(table) { NestedSchema.new(context: table, key_prefix: 'foo_', key_suffix: '_bar') }
         
     | 
| 
       170 
171 
     | 
    
         | 
| 
         @@ -318,8 +319,56 @@ context = { 
     | 
|
| 
       318 
319 
     | 
    
         
             
            schema = SampleTableSchema.new(context: context)
         
     | 
| 
       319 
320 
     | 
    
         
             
            ```
         
     | 
| 
       320 
321 
     | 
    
         | 
| 
      
 322 
     | 
    
         
            +
            You can also concatenate schemas.
         
     | 
| 
      
 323 
     | 
    
         
            +
            If there are some definitions of `column_converter` with the same name in the schemas to be concatenated, the one in the schema that is concatenated last will be used.
         
     | 
| 
      
 324 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 325 
     | 
    
         
            +
            class UserTableSchema
         
     | 
| 
      
 326 
     | 
    
         
            +
              include TableStructure::Schema
         
     | 
| 
      
 327 
     | 
    
         
            +
             
     | 
| 
      
 328 
     | 
    
         
            +
              column  name: 'ID',
         
     | 
| 
      
 329 
     | 
    
         
            +
                      value: ->(row, _table) { row[:id] }
         
     | 
| 
      
 330 
     | 
    
         
            +
             
     | 
| 
      
 331 
     | 
    
         
            +
              column  name: 'Name',
         
     | 
| 
      
 332 
     | 
    
         
            +
                      value: ->(row, *) { row[:name] }
         
     | 
| 
      
 333 
     | 
    
         
            +
            end
         
     | 
| 
      
 334 
     | 
    
         
            +
             
     | 
| 
      
 335 
     | 
    
         
            +
            class PetTableSchema
         
     | 
| 
      
 336 
     | 
    
         
            +
              include TableStructure::Schema
         
     | 
| 
      
 337 
     | 
    
         
            +
             
     | 
| 
      
 338 
     | 
    
         
            +
              columns name: ['Pet 1', 'Pet 2', 'Pet 3'],
         
     | 
| 
      
 339 
     | 
    
         
            +
                      value: ->(row, *) { row[:pets] }
         
     | 
| 
      
 340 
     | 
    
         
            +
             
     | 
| 
      
 341 
     | 
    
         
            +
              column_converter :same_name, ->(val, *) { 'This definition will not be used.' }
         
     | 
| 
      
 342 
     | 
    
         
            +
            end
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
            class QuestionTableSchema
         
     | 
| 
      
 345 
     | 
    
         
            +
              include TableStructure::Schema
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
      
 347 
     | 
    
         
            +
              columns ->(table) {
         
     | 
| 
      
 348 
     | 
    
         
            +
                table[:questions].map do |question|
         
     | 
| 
      
 349 
     | 
    
         
            +
                  {
         
     | 
| 
      
 350 
     | 
    
         
            +
                    name: question[:id],
         
     | 
| 
      
 351 
     | 
    
         
            +
                    value: ->(row, *) { row[:answers][question[:id]] }
         
     | 
| 
      
 352 
     | 
    
         
            +
                  }
         
     | 
| 
      
 353 
     | 
    
         
            +
                end
         
     | 
| 
      
 354 
     | 
    
         
            +
              }
         
     | 
| 
      
 355 
     | 
    
         
            +
             
     | 
| 
      
 356 
     | 
    
         
            +
              column_converter :same_name, ->(val, *) { 'This definition will be used.' }
         
     | 
| 
      
 357 
     | 
    
         
            +
            end
         
     | 
| 
      
 358 
     | 
    
         
            +
             
     | 
| 
      
 359 
     | 
    
         
            +
            context = {
         
     | 
| 
      
 360 
     | 
    
         
            +
              questions: [
         
     | 
| 
      
 361 
     | 
    
         
            +
                { id: 'Q1', text: 'Do you like sushi?' },
         
     | 
| 
      
 362 
     | 
    
         
            +
                { id: 'Q2', text: 'Do you like yakiniku?' },
         
     | 
| 
      
 363 
     | 
    
         
            +
                { id: 'Q3', text: 'Do you like ramen?' }
         
     | 
| 
      
 364 
     | 
    
         
            +
              ]
         
     | 
| 
      
 365 
     | 
    
         
            +
            }
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
      
 367 
     | 
    
         
            +
            schema = (UserTableSchema + PetTableSchema + QuestionTableSchema).new(context: context)
         
     | 
| 
      
 368 
     | 
    
         
            +
            ```
         
     | 
| 
      
 369 
     | 
    
         
            +
             
     | 
| 
       321 
370 
     | 
    
         
             
            You can also use `context_builder`.
         
     | 
| 
       322 
     | 
    
         
            -
            This may be useful  
     | 
| 
      
 371 
     | 
    
         
            +
            This may be useful if `column(s)` lambda is complicated.
         
     | 
| 
       323 
372 
     | 
    
         
             
            ```ruby
         
     | 
| 
       324 
373 
     | 
    
         
             
            class SampleTableSchema
         
     | 
| 
       325 
374 
     | 
    
         
             
              include TableStructure::Schema
         
     | 
| 
         @@ -359,7 +408,7 @@ If you want to convert CSV character code, you can do so within block of `write` 
     | 
|
| 
       359 
408 
     | 
    
         
             
            ```ruby
         
     | 
| 
       360 
409 
     | 
    
         
             
            File.open('sample.csv', 'w') do |f|
         
     | 
| 
       361 
410 
     | 
    
         
             
              writer.write(items, to: CSV.new(f)) do |row_values|
         
     | 
| 
       362 
     | 
    
         
            -
                row_values.map { |val| val 
     | 
| 
      
 411 
     | 
    
         
            +
                row_values.map { |val| val.to_s.encode('Shift_JIS', invalid: :replace, undef: :replace) }
         
     | 
| 
       363 
412 
     | 
    
         
             
              end
         
     | 
| 
       364 
413 
     | 
    
         
             
            end
         
     | 
| 
       365 
414 
     | 
    
         
             
            ```
         
     | 
| 
         @@ -3,53 +3,47 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module TableStructure
         
     | 
| 
       4 
4 
     | 
    
         
             
              module CSV
         
     | 
| 
       5 
5 
     | 
    
         
             
                class Writer
         
     | 
| 
       6 
     | 
    
         
            -
                  DEFAULT_OPTIONS = {
         
     | 
| 
       7 
     | 
    
         
            -
                    bom: false,
         
     | 
| 
       8 
     | 
    
         
            -
                    csv_options: {}
         
     | 
| 
       9 
     | 
    
         
            -
                  }.freeze
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                  INNER_WRITER_DEFAULT_OPTIONS = ::TableStructure::Writer::DEFAULT_OPTIONS
         
     | 
| 
       12 
     | 
    
         
            -
                  INNER_WRITER_IGNORED_OPTION_KEYS = %i[
         
     | 
| 
       13 
     | 
    
         
            -
                    result_type
         
     | 
| 
       14 
     | 
    
         
            -
                    method
         
     | 
| 
       15 
     | 
    
         
            -
                  ].freeze
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
6 
     | 
    
         
             
                  BOM = "\uFEFF"
         
     | 
| 
       18 
7 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                  def initialize( 
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(
         
     | 
| 
      
 9 
     | 
    
         
            +
                    schema,
         
     | 
| 
      
 10 
     | 
    
         
            +
                    bom: false,
         
     | 
| 
      
 11 
     | 
    
         
            +
                    csv_options: {},
         
     | 
| 
      
 12 
     | 
    
         
            +
                    header_omitted: false,
         
     | 
| 
      
 13 
     | 
    
         
            +
                    header_context: nil
         
     | 
| 
      
 14 
     | 
    
         
            +
                  )
         
     | 
| 
       20 
15 
     | 
    
         
             
                    require 'csv'
         
     | 
| 
       21 
     | 
    
         
            -
                    @options = DEFAULT_OPTIONS.merge(select_csv_writer_options(options))
         
     | 
| 
       22 
     | 
    
         
            -
                    inner_writer_options = select_inner_writer_options(options)
         
     | 
| 
       23 
     | 
    
         
            -
                    @writer = ::TableStructure::Writer.new(schema, **inner_writer_options)
         
     | 
| 
       24 
     | 
    
         
            -
                  end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  def write(items, to:, **options, &block)
         
     | 
| 
       27 
     | 
    
         
            -
                    csv_writer_options = @options.merge(select_csv_writer_options(options))
         
     | 
| 
       28 
     | 
    
         
            -
                    inner_writer_options = select_inner_writer_options(options)
         
     | 
| 
       29 
     | 
    
         
            -
                    if csv_writer_options[:bom]
         
     | 
| 
       30 
     | 
    
         
            -
                      to.send(INNER_WRITER_DEFAULT_OPTIONS[:method], BOM)
         
     | 
| 
       31 
     | 
    
         
            -
                    end
         
     | 
| 
       32 
     | 
    
         
            -
                    csv = ::CSV.new(to, **csv_writer_options[:csv_options])
         
     | 
| 
       33 
     | 
    
         
            -
                    @writer.write(items, to: csv, **inner_writer_options, &block)
         
     | 
| 
       34 
     | 
    
         
            -
                  end
         
     | 
| 
       35 
16 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 17 
     | 
    
         
            +
                    @options = {
         
     | 
| 
      
 18 
     | 
    
         
            +
                      bom: bom,
         
     | 
| 
      
 19 
     | 
    
         
            +
                      csv_options: csv_options
         
     | 
| 
      
 20 
     | 
    
         
            +
                    }
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @inner_options = {
         
     | 
| 
      
 22 
     | 
    
         
            +
                      header_omitted: header_omitted,
         
     | 
| 
      
 23 
     | 
    
         
            +
                      header_context: header_context
         
     | 
| 
      
 24 
     | 
    
         
            +
                    }
         
     | 
| 
       37 
25 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                    options
         
     | 
| 
       40 
     | 
    
         
            -
                      .select { |k, _v| DEFAULT_OPTIONS.include?(k) }
         
     | 
| 
      
 26 
     | 
    
         
            +
                    @writer = ::TableStructure::Writer.new(schema, **@inner_options)
         
     | 
| 
       41 
27 
     | 
    
         
             
                  end
         
     | 
| 
       42 
28 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                  def  
     | 
| 
       44 
     | 
    
         
            -
                     
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def write(
         
     | 
| 
      
 30 
     | 
    
         
            +
                    items,
         
     | 
| 
      
 31 
     | 
    
         
            +
                    to:,
         
     | 
| 
      
 32 
     | 
    
         
            +
                    bom: @options[:bom],
         
     | 
| 
      
 33 
     | 
    
         
            +
                    csv_options: @options[:csv_options],
         
     | 
| 
      
 34 
     | 
    
         
            +
                    header_omitted: @inner_options[:header_omitted],
         
     | 
| 
      
 35 
     | 
    
         
            +
                    header_context: @inner_options[:header_context],
         
     | 
| 
      
 36 
     | 
    
         
            +
                    &block
         
     | 
| 
      
 37 
     | 
    
         
            +
                  )
         
     | 
| 
      
 38 
     | 
    
         
            +
                    inner_options = {
         
     | 
| 
      
 39 
     | 
    
         
            +
                      header_omitted: header_omitted,
         
     | 
| 
      
 40 
     | 
    
         
            +
                      header_context: header_context
         
     | 
| 
      
 41 
     | 
    
         
            +
                    }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                    to << BOM if bom
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    csv = ::CSV.new(to, **csv_options)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @writer.write(items, to: csv, **inner_options, &block)
         
     | 
| 
       53 
47 
     | 
    
         
             
                  end
         
     | 
| 
       54 
48 
     | 
    
         
             
                end
         
     | 
| 
       55 
49 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TableStructure
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Schema
         
     | 
| 
      
 5 
     | 
    
         
            +
                module ClassMethods
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def +(schema)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    self_schema = self
         
     | 
| 
      
 8 
     | 
    
         
            +
                    Class.new do
         
     | 
| 
      
 9 
     | 
    
         
            +
                      include ::TableStructure::Schema
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                      @__column_definitions__ = [
         
     | 
| 
      
 12 
     | 
    
         
            +
                        self_schema.column_definitions,
         
     | 
| 
      
 13 
     | 
    
         
            +
                        schema.column_definitions
         
     | 
| 
      
 14 
     | 
    
         
            +
                      ].flatten
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                      @__context_builders__ =
         
     | 
| 
      
 17 
     | 
    
         
            +
                        {}
         
     | 
| 
      
 18 
     | 
    
         
            +
                        .merge!(self_schema.context_builders)
         
     | 
| 
      
 19 
     | 
    
         
            +
                        .merge!(schema.context_builders)
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                      @__column_converters__ =
         
     | 
| 
      
 22 
     | 
    
         
            +
                        {}
         
     | 
| 
      
 23 
     | 
    
         
            +
                        .merge!(self_schema.column_converters)
         
     | 
| 
      
 24 
     | 
    
         
            +
                        .merge!(schema.column_converters)
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                      @__result_builders__ =
         
     | 
| 
      
 27 
     | 
    
         
            +
                        {}
         
     | 
| 
      
 28 
     | 
    
         
            +
                        .merge!(self_schema.result_builders)
         
     | 
| 
      
 29 
     | 
    
         
            +
                        .merge!(schema.result_builders)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -6,19 +6,19 @@ module TableStructure 
     | 
|
| 
       6 
6 
     | 
    
         
             
                  class Attrs
         
     | 
| 
       7 
7 
     | 
    
         
             
                    attr_reader :keys, :size
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                    def initialize( 
     | 
| 
       10 
     | 
    
         
            -
                      @name =  
     | 
| 
       11 
     | 
    
         
            -
                      @keys = optimize_size([ 
     | 
| 
       12 
     | 
    
         
            -
                      @value =  
     | 
| 
       13 
     | 
    
         
            -
                      @size =  
     | 
| 
      
 9 
     | 
    
         
            +
                    def initialize(name:, key:, value:, size:)
         
     | 
| 
      
 10 
     | 
    
         
            +
                      @name = name
         
     | 
| 
      
 11 
     | 
    
         
            +
                      @keys = optimize_size([key].flatten, size)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      @value = value
         
     | 
| 
      
 13 
     | 
    
         
            +
                      @size = size
         
     | 
| 
       14 
14 
     | 
    
         
             
                    end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                    def  
     | 
| 
      
 16 
     | 
    
         
            +
                    def names(context, table_context)
         
     | 
| 
       17 
17 
     | 
    
         
             
                      name = Utils.evaluate_callable(@name, context, table_context)
         
     | 
| 
       18 
18 
     | 
    
         
             
                      optimize_size(name, @size)
         
     | 
| 
       19 
19 
     | 
    
         
             
                    end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                    def  
     | 
| 
      
 21 
     | 
    
         
            +
                    def values(context, table_context)
         
     | 
| 
       22 
22 
     | 
    
         
             
                      value = Utils.evaluate_callable(@value, context, table_context)
         
     | 
| 
       23 
23 
     | 
    
         
             
                      optimize_size(value, @size)
         
     | 
| 
       24 
24 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -0,0 +1,81 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TableStructure
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Schema
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Column
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module Definition
         
     | 
| 
      
 7 
     | 
    
         
            +
                    class Compiler
         
     | 
| 
      
 8 
     | 
    
         
            +
                      DEFAULT_ATTRS = {
         
     | 
| 
      
 9 
     | 
    
         
            +
                        name: nil,
         
     | 
| 
      
 10 
     | 
    
         
            +
                        key: nil,
         
     | 
| 
      
 11 
     | 
    
         
            +
                        value: nil,
         
     | 
| 
      
 12 
     | 
    
         
            +
                        size: nil,
         
     | 
| 
      
 13 
     | 
    
         
            +
                        omitted: false
         
     | 
| 
      
 14 
     | 
    
         
            +
                      }.freeze
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                      DEFAULT_SIZE = 1
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                      def initialize(name, definitions, options)
         
     | 
| 
      
 19 
     | 
    
         
            +
                        @name = name
         
     | 
| 
      
 20 
     | 
    
         
            +
                        @definitions = definitions
         
     | 
| 
      
 21 
     | 
    
         
            +
                        @options = options
         
     | 
| 
      
 22 
     | 
    
         
            +
                      end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      def compile(context = nil)
         
     | 
| 
      
 25 
     | 
    
         
            +
                        @definitions
         
     | 
| 
      
 26 
     | 
    
         
            +
                          .map { |definition| Utils.evaluate_callable(definition, context) }
         
     | 
| 
      
 27 
     | 
    
         
            +
                          .map.with_index do |definition, i|
         
     | 
| 
      
 28 
     | 
    
         
            +
                            validator = Validator.new(@name, i)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                            [definition]
         
     | 
| 
      
 31 
     | 
    
         
            +
                              .flatten
         
     | 
| 
      
 32 
     | 
    
         
            +
                              .map do |definition|
         
     | 
| 
      
 33 
     | 
    
         
            +
                                if definition.is_a?(Hash)
         
     | 
| 
      
 34 
     | 
    
         
            +
                                  definition = DEFAULT_ATTRS.merge(definition)
         
     | 
| 
      
 35 
     | 
    
         
            +
                                  omitted = definition.delete(:omitted)
         
     | 
| 
      
 36 
     | 
    
         
            +
                                  next if Utils.evaluate_callable(omitted, context)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                                  definition = evaluate_attrs(definition, context)
         
     | 
| 
      
 39 
     | 
    
         
            +
                                  validator.validate(**definition)
         
     | 
| 
      
 40 
     | 
    
         
            +
                                  definition[:size] = determine_size(**definition)
         
     | 
| 
      
 41 
     | 
    
         
            +
                                  definition
         
     | 
| 
      
 42 
     | 
    
         
            +
                                elsif Utils.schema_instance?(definition)
         
     | 
| 
      
 43 
     | 
    
         
            +
                                  definition
         
     | 
| 
      
 44 
     | 
    
         
            +
                                elsif Utils.schema_class?(definition)
         
     | 
| 
      
 45 
     | 
    
         
            +
                                  definition.new(context: context)
         
     | 
| 
      
 46 
     | 
    
         
            +
                                elsif definition.nil? && @options[:nil_definitions_ignored]
         
     | 
| 
      
 47 
     | 
    
         
            +
                                  next
         
     | 
| 
      
 48 
     | 
    
         
            +
                                else
         
     | 
| 
      
 49 
     | 
    
         
            +
                                  raise Error.new('Invalid definition.', @name, i)
         
     | 
| 
      
 50 
     | 
    
         
            +
                                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                              end
         
     | 
| 
      
 52 
     | 
    
         
            +
                          end
         
     | 
| 
      
 53 
     | 
    
         
            +
                          .flatten
         
     | 
| 
      
 54 
     | 
    
         
            +
                          .compact
         
     | 
| 
      
 55 
     | 
    
         
            +
                      end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                      private
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                      def evaluate_attrs(definition, context)
         
     | 
| 
      
 60 
     | 
    
         
            +
                        size = Utils.evaluate_callable(definition[:size], context)
         
     | 
| 
      
 61 
     | 
    
         
            +
                        definition.merge(size: size)
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                      def determine_size(name:, key:, size:, **)
         
     | 
| 
      
 65 
     | 
    
         
            +
                        return size if size
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                        [calculate_size(name), calculate_size(key)].max
         
     | 
| 
      
 68 
     | 
    
         
            +
                      end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                      def calculate_size(val)
         
     | 
| 
      
 71 
     | 
    
         
            +
                        if val.is_a?(Array)
         
     | 
| 
      
 72 
     | 
    
         
            +
                          return val.empty? ? DEFAULT_SIZE : val.size
         
     | 
| 
      
 73 
     | 
    
         
            +
                        end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                        DEFAULT_SIZE
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TableStructure
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Schema
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Column
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module Definition
         
     | 
| 
      
 7 
     | 
    
         
            +
                    class Error < ::TableStructure::Error
         
     | 
| 
      
 8 
     | 
    
         
            +
                      attr_reader :schema_name, :definition_index
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                      def initialize(error_message, schema_name, definition_index)
         
     | 
| 
      
 11 
     | 
    
         
            +
                        @schema_name = schema_name
         
     | 
| 
      
 12 
     | 
    
         
            +
                        @definition_index = definition_index
         
     | 
| 
      
 13 
     | 
    
         
            +
                        super("#{error_message} [#{schema_name}] defined position of column(s): #{definition_index + 1}")
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TableStructure
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Schema
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Column
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module Definition
         
     | 
| 
      
 7 
     | 
    
         
            +
                    class Validator
         
     | 
| 
      
 8 
     | 
    
         
            +
                      DEFAULT_SIZE = 1
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                      def initialize(name, index)
         
     | 
| 
      
 11 
     | 
    
         
            +
                        @name = name
         
     | 
| 
      
 12 
     | 
    
         
            +
                        @index = index
         
     | 
| 
      
 13 
     | 
    
         
            +
                      end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 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
         
     | 
| 
      
 19 
     | 
    
         
            +
                        if !key && name.respond_to?(:call) && !size
         
     | 
| 
      
 20 
     | 
    
         
            +
                          raise Error.new('"size" must be defined, because column size cannot be determined.', @name, @index)
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end
         
     | 
| 
      
 22 
     | 
    
         
            +
                        if size && size < DEFAULT_SIZE
         
     | 
| 
      
 23 
     | 
    
         
            +
                          raise Error.new('"size" must be positive.', @name, @index)
         
     | 
| 
      
 24 
     | 
    
         
            +
                        end
         
     | 
| 
      
 25 
     | 
    
         
            +
                        if key && size && [key].flatten.size < size
         
     | 
| 
      
 26 
     | 
    
         
            +
                          raise Error.new('"key" size must not be less than specified "size".', @name, @index)
         
     | 
| 
      
 27 
     | 
    
         
            +
                        end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                        true
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TableStructure
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Schema
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Column
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module Factory
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def self.create(name, definitions, context, options)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      Definition::Compiler
         
     | 
| 
      
 9 
     | 
    
         
            +
                        .new(name, definitions, options)
         
     | 
| 
      
 10 
     | 
    
         
            +
                        .compile(context)
         
     | 
| 
      
 11 
     | 
    
         
            +
                        .map do |definition|
         
     | 
| 
      
 12 
     | 
    
         
            +
                          if definition.is_a?(Hash)
         
     | 
| 
      
 13 
     | 
    
         
            +
                            Attrs.new(**definition)
         
     | 
| 
      
 14 
     | 
    
         
            +
                          else
         
     | 
| 
      
 15 
     | 
    
         
            +
                            Schema.new(definition)
         
     | 
| 
      
 16 
     | 
    
         
            +
                          end
         
     | 
| 
      
 17 
     | 
    
         
            +
                        end
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -10,7 +10,7 @@ module TableStructure 
     | 
|
| 
       10 
10 
     | 
    
         
             
                      @table = schema.create_table
         
     | 
| 
       11 
11 
     | 
    
         
             
                    end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                    def  
     | 
| 
      
 13 
     | 
    
         
            +
                    def names(header_context, _table_context)
         
     | 
| 
       14 
14 
     | 
    
         
             
                      @table.header(context: header_context)
         
     | 
| 
       15 
15 
     | 
    
         
             
                    end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
         @@ -18,7 +18,7 @@ module TableStructure 
     | 
|
| 
       18 
18 
     | 
    
         
             
                      @table.send(:keys)
         
     | 
| 
       19 
19 
     | 
    
         
             
                    end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                    def  
     | 
| 
      
 21 
     | 
    
         
            +
                    def values(row_context, _table_context)
         
     | 
| 
       22 
22 
     | 
    
         
             
                      @table.row(context: row_context)
         
     | 
| 
       23 
23 
     | 
    
         
             
                    end
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
         @@ -8,11 +8,12 @@ module TableStructure 
     | 
|
| 
       8 
8 
     | 
    
         
             
                    @row_converters = select_converters_for(:row, converters)
         
     | 
| 
       9 
9 
     | 
    
         
             
                  end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                  def extend_methods_for(table)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def extend_methods_for(table, name_prefix:, name_suffix:)
         
     | 
| 
       12 
12 
     | 
    
         
             
                    table_context = table.instance_variable_get(:@context)
         
     | 
| 
       13 
     | 
    
         
            -
                    table_options = table.instance_variable_get(:@options)
         
     | 
| 
       14 
13 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                    header_converters = @header_converters.merge( 
     | 
| 
      
 14 
     | 
    
         
            +
                    header_converters = @header_converters.merge(
         
     | 
| 
      
 15 
     | 
    
         
            +
                      optional_header_converters(name_prefix: name_prefix, name_suffix: name_suffix)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    )
         
     | 
| 
       16 
17 
     | 
    
         
             
                    row_converters = @row_converters
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
19 
     | 
    
         
             
                    methods = {}
         
     | 
| 
         @@ -37,15 +38,15 @@ module TableStructure 
     | 
|
| 
       37 
38 
     | 
    
         
             
                      .to_h
         
     | 
| 
       38 
39 
     | 
    
         
             
                  end
         
     | 
| 
       39 
40 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                  def optional_header_converters( 
     | 
| 
      
 41 
     | 
    
         
            +
                  def optional_header_converters(name_prefix:, name_suffix:)
         
     | 
| 
       41 
42 
     | 
    
         
             
                    converters = {}
         
     | 
| 
       42 
     | 
    
         
            -
                    if  
     | 
| 
      
 43 
     | 
    
         
            +
                    if name_prefix
         
     | 
| 
       43 
44 
     | 
    
         
             
                      converters[:_prepend_prefix_] =
         
     | 
| 
       44 
     | 
    
         
            -
                        create_prefix_converter( 
     | 
| 
      
 45 
     | 
    
         
            +
                        create_prefix_converter(name_prefix)
         
     | 
| 
       45 
46 
     | 
    
         
             
                    end
         
     | 
| 
       46 
     | 
    
         
            -
                    if  
     | 
| 
      
 47 
     | 
    
         
            +
                    if name_suffix
         
     | 
| 
       47 
48 
     | 
    
         
             
                      converters[:_append_suffix_] =
         
     | 
| 
       48 
     | 
    
         
            -
                        create_suffix_converter( 
     | 
| 
      
 49 
     | 
    
         
            +
                        create_suffix_converter(name_suffix)
         
     | 
| 
       49 
50 
     | 
    
         
             
                    end
         
     | 
| 
       50 
51 
     | 
    
         | 
| 
       51 
52 
     | 
    
         
             
                    converters
         
     | 
| 
         @@ -18,15 +18,14 @@ module TableStructure 
     | 
|
| 
       18 
18 
     | 
    
         
             
                    @builders = builders
         
     | 
| 
       19 
19 
     | 
    
         
             
                  end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                  def extend_methods_for(table)
         
     | 
| 
       22 
     | 
    
         
            -
                     
     | 
| 
       23 
     | 
    
         
            -
                    table_options = table.instance_variable_get(:@options)
         
     | 
| 
       24 
     | 
    
         
            -
                    table_keys = table.send(:keys)
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                    builders = select_builders(table_options[:result_type])
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def extend_methods_for(table, result_type: :array)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    builders = select_builders(result_type)
         
     | 
| 
       27 
23 
     | 
    
         | 
| 
       28 
24 
     | 
    
         
             
                    methods = {}
         
     | 
| 
       29 
25 
     | 
    
         
             
                    unless builders.empty?
         
     | 
| 
      
 26 
     | 
    
         
            +
                      table_context = table.instance_variable_get(:@context)
         
     | 
| 
      
 27 
     | 
    
         
            +
                      table_keys = table.send(:keys)
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       30 
29 
     | 
    
         
             
                      methods[:header] = create_method(builders, table_keys, table_context)
         
     | 
| 
       31 
30 
     | 
    
         
             
                      methods[:row] = create_method(builders, table_keys, table_context)
         
     | 
| 
       32 
31 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -3,10 +3,6 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module TableStructure
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Schema
         
     | 
| 
       5 
5 
     | 
    
         
             
                class Table
         
     | 
| 
       6 
     | 
    
         
            -
                  DEFAULT_OPTIONS = {
         
     | 
| 
       7 
     | 
    
         
            -
                    result_type: :array
         
     | 
| 
       8 
     | 
    
         
            -
                  }.freeze
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
6 
     | 
    
         
             
                  def initialize(
         
     | 
| 
       11 
7 
     | 
    
         
             
                    columns,
         
     | 
| 
       12 
8 
     | 
    
         
             
                    context,
         
     | 
| 
         @@ -14,15 +10,15 @@ module TableStructure 
     | 
|
| 
       14 
10 
     | 
    
         
             
                  )
         
     | 
| 
       15 
11 
     | 
    
         
             
                    @columns = columns
         
     | 
| 
       16 
12 
     | 
    
         
             
                    @context = context
         
     | 
| 
       17 
     | 
    
         
            -
                    @options =  
     | 
| 
      
 13 
     | 
    
         
            +
                    @options = options
         
     | 
| 
       18 
14 
     | 
    
         
             
                  end
         
     | 
| 
       19 
15 
     | 
    
         | 
| 
       20 
16 
     | 
    
         
             
                  def header(context: nil)
         
     | 
| 
       21 
     | 
    
         
            -
                    values(: 
     | 
| 
      
 17 
     | 
    
         
            +
                    values(:names, context)
         
     | 
| 
       22 
18 
     | 
    
         
             
                  end
         
     | 
| 
       23 
19 
     | 
    
         | 
| 
       24 
20 
     | 
    
         
             
                  def row(context: nil)
         
     | 
| 
       25 
     | 
    
         
            -
                    values(: 
     | 
| 
      
 21 
     | 
    
         
            +
                    values(:values, context)
         
     | 
| 
       26 
22 
     | 
    
         
             
                  end
         
     | 
| 
       27 
23 
     | 
    
         | 
| 
       28 
24 
     | 
    
         
             
                  def rows(items)
         
     | 
| 
         @@ -8,8 +8,20 @@ module TableStructure 
     | 
|
| 
       8 
8 
     | 
    
         
             
                  klass.extend(DSL::ContextBuilder)
         
     | 
| 
       9 
9 
     | 
    
         
             
                  klass.extend(DSL::Option)
         
     | 
| 
       10 
10 
     | 
    
         
             
                  klass.extend(DSL::ResultBuilder)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  klass.extend(ClassMethods)
         
     | 
| 
       11 
12 
     | 
    
         
             
                end
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
                Definition = Struct.new(
         
     | 
| 
      
 15 
     | 
    
         
            +
                  'Definition',
         
     | 
| 
      
 16 
     | 
    
         
            +
                  :name,
         
     | 
| 
      
 17 
     | 
    
         
            +
                  :columns,
         
     | 
| 
      
 18 
     | 
    
         
            +
                  :context_builders,
         
     | 
| 
      
 19 
     | 
    
         
            +
                  :column_converters,
         
     | 
| 
      
 20 
     | 
    
         
            +
                  :result_builders,
         
     | 
| 
      
 21 
     | 
    
         
            +
                  :context,
         
     | 
| 
      
 22 
     | 
    
         
            +
                  :options
         
     | 
| 
      
 23 
     | 
    
         
            +
                )
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       13 
25 
     | 
    
         
             
                def initialize(
         
     | 
| 
       14 
26 
     | 
    
         
             
                  name: self.class.name,
         
     | 
| 
       15 
27 
     | 
    
         
             
                  context: nil,
         
     | 
| 
         @@ -23,14 +35,10 @@ module TableStructure 
     | 
|
| 
       23 
35 
     | 
    
         
             
                  unless deprecated_options.empty?
         
     | 
| 
       24 
36 
     | 
    
         
             
                    caller_location = caller_locations(1, 1)
         
     | 
| 
       25 
37 
     | 
    
         
             
                    deprecated_options.keys.each do |k|
         
     | 
| 
       26 
     | 
    
         
            -
                      warn "[TableStructure] Specify  
     | 
| 
      
 38 
     | 
    
         
            +
                      warn "[TableStructure] Specify :#{k} option on the writer or the iterator. #{caller_location}"
         
     | 
| 
       27 
39 
     | 
    
         
             
                    end
         
     | 
| 
       28 
40 
     | 
    
         
             
                  end
         
     | 
| 
       29 
41 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                  column_definitions = [].concat(self.class.column_definitions)
         
     | 
| 
       31 
     | 
    
         
            -
                  context_builders = {}.merge!(self.class.context_builders)
         
     | 
| 
       32 
     | 
    
         
            -
                  column_converters = {}.merge!(self.class.column_converters)
         
     | 
| 
       33 
     | 
    
         
            -
                  result_builders = {}.merge!(self.class.result_builders)
         
     | 
| 
       34 
42 
     | 
    
         
             
                  options = {
         
     | 
| 
       35 
43 
     | 
    
         
             
                    name_prefix: name_prefix,
         
     | 
| 
       36 
44 
     | 
    
         
             
                    name_suffix: name_suffix,
         
     | 
| 
         @@ -39,10 +47,17 @@ module TableStructure 
     | 
|
| 
       39 
47 
     | 
    
         
             
                    nil_definitions_ignored: nil_definitions_ignored
         
     | 
| 
       40 
48 
     | 
    
         
             
                  }.merge!(self.class.options).merge!(deprecated_options)
         
     | 
| 
       41 
49 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
      
 50 
     | 
    
         
            +
                  context_builders = ContextBuilders.new({}.merge!(self.class.context_builders))
         
     | 
| 
      
 51 
     | 
    
         
            +
                  column_converters = ColumnConverters.new({}.merge!(self.class.column_converters))
         
     | 
| 
      
 52 
     | 
    
         
            +
                  result_builders = ResultBuilders.new({}.merge!(self.class.result_builders))
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  context = context_builders.build_for_table(context)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  columns = Column::Factory.create(name, self.class.column_definitions, context, options)
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  @_definition_ =
         
     | 
| 
       43 
58 
     | 
    
         
             
                    Definition.new(
         
     | 
| 
       44 
59 
     | 
    
         
             
                      name,
         
     | 
| 
       45 
     | 
    
         
            -
                       
     | 
| 
      
 60 
     | 
    
         
            +
                      columns,
         
     | 
| 
       46 
61 
     | 
    
         
             
                      context_builders,
         
     | 
| 
       47 
62 
     | 
    
         
             
                      column_converters,
         
     | 
| 
       48 
63 
     | 
    
         
             
                      result_builders,
         
     | 
| 
         @@ -51,8 +66,36 @@ module TableStructure 
     | 
|
| 
       51 
66 
     | 
    
         
             
                    )
         
     | 
| 
       52 
67 
     | 
    
         
             
                end
         
     | 
| 
       53 
68 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
                 
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
      
 69 
     | 
    
         
            +
                # TODO: Specify options using keyword arguments.
         
     | 
| 
      
 70 
     | 
    
         
            +
                def create_table(**options)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  options = @_definition_.options.merge(options)
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  table = Table.new(
         
     | 
| 
      
 74 
     | 
    
         
            +
                    @_definition_.columns,
         
     | 
| 
      
 75 
     | 
    
         
            +
                    @_definition_.context,
         
     | 
| 
      
 76 
     | 
    
         
            +
                    options
         
     | 
| 
      
 77 
     | 
    
         
            +
                  )
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  @_definition_.context_builders.extend_methods_for(table)
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  column_converters_options = {
         
     | 
| 
      
 82 
     | 
    
         
            +
                    name_prefix: options[:name_prefix],
         
     | 
| 
      
 83 
     | 
    
         
            +
                    name_suffix: options[:name_suffix]
         
     | 
| 
      
 84 
     | 
    
         
            +
                  }
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  @_definition_.column_converters.extend_methods_for(table, **column_converters_options)
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  result_builders_options = {
         
     | 
| 
      
 89 
     | 
    
         
            +
                    result_type: options[:result_type]
         
     | 
| 
      
 90 
     | 
    
         
            +
                  }
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  @_definition_.result_builders.extend_methods_for(table, **result_builders_options)
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  if block_given?
         
     | 
| 
      
 95 
     | 
    
         
            +
                    yield table
         
     | 
| 
      
 96 
     | 
    
         
            +
                  else
         
     | 
| 
      
 97 
     | 
    
         
            +
                    table
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
       56 
99 
     | 
    
         
             
                end
         
     | 
| 
       57 
100 
     | 
    
         
             
              end
         
     | 
| 
       58 
101 
     | 
    
         
             
            end
         
     | 
    
        data/lib/table_structure.rb
    CHANGED
    
    | 
         @@ -6,15 +6,12 @@ module TableStructure 
     | 
|
| 
       6 
6 
     | 
    
         
             
              require 'table_structure/version'
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
              require 'table_structure/schema'
         
     | 
| 
      
 9 
     | 
    
         
            +
              require 'table_structure/schema/class_methods'
         
     | 
| 
       9 
10 
     | 
    
         
             
              require 'table_structure/schema/dsl/column_converter'
         
     | 
| 
       10 
11 
     | 
    
         
             
              require 'table_structure/schema/dsl/column_definition'
         
     | 
| 
       11 
12 
     | 
    
         
             
              require 'table_structure/schema/dsl/context_builder'
         
     | 
| 
       12 
13 
     | 
    
         
             
              require 'table_structure/schema/dsl/option'
         
     | 
| 
       13 
14 
     | 
    
         
             
              require 'table_structure/schema/dsl/result_builder'
         
     | 
| 
       14 
     | 
    
         
            -
              require 'table_structure/schema/definition'
         
     | 
| 
       15 
     | 
    
         
            -
              require 'table_structure/schema/definition/compiler'
         
     | 
| 
       16 
     | 
    
         
            -
              require 'table_structure/schema/definition/error'
         
     | 
| 
       17 
     | 
    
         
            -
              require 'table_structure/schema/definition/validator'
         
     | 
| 
       18 
15 
     | 
    
         
             
              require 'table_structure/schema/column_converters'
         
     | 
| 
       19 
16 
     | 
    
         
             
              require 'table_structure/schema/context_builders'
         
     | 
| 
       20 
17 
     | 
    
         
             
              require 'table_structure/schema/result_builders'
         
     | 
| 
         @@ -22,6 +19,10 @@ module TableStructure 
     | 
|
| 
       22 
19 
     | 
    
         
             
              require 'table_structure/schema/table/key_decorator'
         
     | 
| 
       23 
20 
     | 
    
         
             
              require 'table_structure/schema/column/attrs'
         
     | 
| 
       24 
21 
     | 
    
         
             
              require 'table_structure/schema/column/schema'
         
     | 
| 
      
 22 
     | 
    
         
            +
              require 'table_structure/schema/column/factory'
         
     | 
| 
      
 23 
     | 
    
         
            +
              require 'table_structure/schema/column/definition/compiler'
         
     | 
| 
      
 24 
     | 
    
         
            +
              require 'table_structure/schema/column/definition/error'
         
     | 
| 
      
 25 
     | 
    
         
            +
              require 'table_structure/schema/column/definition/validator'
         
     | 
| 
       25 
26 
     | 
    
         
             
              require 'table_structure/schema/utils'
         
     | 
| 
       26 
27 
     | 
    
         
             
              require 'table_structure/writer'
         
     | 
| 
       27 
28 
     | 
    
         
             
              require 'table_structure/csv/writer'
         
     | 
    
        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.3.15
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - jsmmr
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2019-12- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2019-12-27 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: bundler
         
     | 
| 
         @@ -74,14 +74,15 @@ files: 
     | 
|
| 
       74 
74 
     | 
    
         
             
            - lib/table_structure/csv/writer.rb
         
     | 
| 
       75 
75 
     | 
    
         
             
            - lib/table_structure/iterator.rb
         
     | 
| 
       76 
76 
     | 
    
         
             
            - lib/table_structure/schema.rb
         
     | 
| 
      
 77 
     | 
    
         
            +
            - lib/table_structure/schema/class_methods.rb
         
     | 
| 
       77 
78 
     | 
    
         
             
            - lib/table_structure/schema/column/attrs.rb
         
     | 
| 
      
 79 
     | 
    
         
            +
            - lib/table_structure/schema/column/definition/compiler.rb
         
     | 
| 
      
 80 
     | 
    
         
            +
            - lib/table_structure/schema/column/definition/error.rb
         
     | 
| 
      
 81 
     | 
    
         
            +
            - lib/table_structure/schema/column/definition/validator.rb
         
     | 
| 
      
 82 
     | 
    
         
            +
            - lib/table_structure/schema/column/factory.rb
         
     | 
| 
       78 
83 
     | 
    
         
             
            - lib/table_structure/schema/column/schema.rb
         
     | 
| 
       79 
84 
     | 
    
         
             
            - lib/table_structure/schema/column_converters.rb
         
     | 
| 
       80 
85 
     | 
    
         
             
            - lib/table_structure/schema/context_builders.rb
         
     | 
| 
       81 
     | 
    
         
            -
            - lib/table_structure/schema/definition.rb
         
     | 
| 
       82 
     | 
    
         
            -
            - lib/table_structure/schema/definition/compiler.rb
         
     | 
| 
       83 
     | 
    
         
            -
            - lib/table_structure/schema/definition/error.rb
         
     | 
| 
       84 
     | 
    
         
            -
            - lib/table_structure/schema/definition/validator.rb
         
     | 
| 
       85 
86 
     | 
    
         
             
            - lib/table_structure/schema/dsl/column_converter.rb
         
     | 
| 
       86 
87 
     | 
    
         
             
            - lib/table_structure/schema/dsl/column_definition.rb
         
     | 
| 
       87 
88 
     | 
    
         
             
            - lib/table_structure/schema/dsl/context_builder.rb
         
     | 
| 
         @@ -113,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       113 
114 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       114 
115 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       115 
116 
     | 
    
         
             
            requirements: []
         
     | 
| 
       116 
     | 
    
         
            -
            rubygems_version: 3. 
     | 
| 
      
 117 
     | 
    
         
            +
            rubygems_version: 3.1.2
         
     | 
| 
       117 
118 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       118 
119 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       119 
120 
     | 
    
         
             
            summary: Generates and outputs table structured data.
         
     | 
| 
         @@ -1,79 +0,0 @@ 
     | 
|
| 
       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)
         
     | 
| 
       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 
     | 
    
         
            -
                                definition = evaluate_attrs(definition, context)
         
     | 
| 
       38 
     | 
    
         
            -
                                validator.validate(**definition)
         
     | 
| 
       39 
     | 
    
         
            -
                                definition[:size] = determine_size(**definition)
         
     | 
| 
       40 
     | 
    
         
            -
                                definition
         
     | 
| 
       41 
     | 
    
         
            -
                              elsif Utils.schema_instance?(definition)
         
     | 
| 
       42 
     | 
    
         
            -
                                definition
         
     | 
| 
       43 
     | 
    
         
            -
                              elsif Utils.schema_class?(definition)
         
     | 
| 
       44 
     | 
    
         
            -
                                definition.new(context: context)
         
     | 
| 
       45 
     | 
    
         
            -
                              elsif definition.nil? && @options[:nil_definitions_ignored]
         
     | 
| 
       46 
     | 
    
         
            -
                                next
         
     | 
| 
       47 
     | 
    
         
            -
                              else
         
     | 
| 
       48 
     | 
    
         
            -
                                raise Error.new('Invalid definition.', @name, i)
         
     | 
| 
       49 
     | 
    
         
            -
                              end
         
     | 
| 
       50 
     | 
    
         
            -
                            end
         
     | 
| 
       51 
     | 
    
         
            -
                        end
         
     | 
| 
       52 
     | 
    
         
            -
                        .flatten
         
     | 
| 
       53 
     | 
    
         
            -
                        .compact
         
     | 
| 
       54 
     | 
    
         
            -
                    end
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                    private
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                    def evaluate_attrs(definition, context)
         
     | 
| 
       59 
     | 
    
         
            -
                      size = Utils.evaluate_callable(definition[:size], context)
         
     | 
| 
       60 
     | 
    
         
            -
                      definition.merge(size: size)
         
     | 
| 
       61 
     | 
    
         
            -
                    end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                    def determine_size(name:, key:, size:, **)
         
     | 
| 
       64 
     | 
    
         
            -
                      return size if size
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                      [calculate_size(name), calculate_size(key)].max
         
     | 
| 
       67 
     | 
    
         
            -
                    end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                    def calculate_size(val)
         
     | 
| 
       70 
     | 
    
         
            -
                      if val.is_a?(Array)
         
     | 
| 
       71 
     | 
    
         
            -
                        return val.empty? ? DEFAULT_SIZE : val.size
         
     | 
| 
       72 
     | 
    
         
            -
                      end
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
                      DEFAULT_SIZE
         
     | 
| 
       75 
     | 
    
         
            -
                    end
         
     | 
| 
       76 
     | 
    
         
            -
                  end
         
     | 
| 
       77 
     | 
    
         
            -
                end
         
     | 
| 
       78 
     | 
    
         
            -
              end
         
     | 
| 
       79 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,17 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module TableStructure
         
     | 
| 
       4 
     | 
    
         
            -
              module Schema
         
     | 
| 
       5 
     | 
    
         
            -
                class Definition
         
     | 
| 
       6 
     | 
    
         
            -
                  class Error < ::TableStructure::Error
         
     | 
| 
       7 
     | 
    
         
            -
                    attr_reader :schema_name, :definition_index
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                    def initialize(error_message, schema_name, definition_index)
         
     | 
| 
       10 
     | 
    
         
            -
                      @schema_name = schema_name
         
     | 
| 
       11 
     | 
    
         
            -
                      @definition_index = definition_index
         
     | 
| 
       12 
     | 
    
         
            -
                      super("#{error_message} [#{schema_name}] defined position of column(s): #{definition_index + 1}")
         
     | 
| 
       13 
     | 
    
         
            -
                    end
         
     | 
| 
       14 
     | 
    
         
            -
                  end
         
     | 
| 
       15 
     | 
    
         
            -
                end
         
     | 
| 
       16 
     | 
    
         
            -
              end
         
     | 
| 
       17 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,33 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module TableStructure
         
     | 
| 
       4 
     | 
    
         
            -
              module Schema
         
     | 
| 
       5 
     | 
    
         
            -
                class Definition
         
     | 
| 
       6 
     | 
    
         
            -
                  class Validator
         
     | 
| 
       7 
     | 
    
         
            -
                    DEFAULT_SIZE = 1
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                    def initialize(name, index)
         
     | 
| 
       10 
     | 
    
         
            -
                      @name = name
         
     | 
| 
       11 
     | 
    
         
            -
                      @index = index
         
     | 
| 
       12 
     | 
    
         
            -
                    end
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                    def validate(name:, key:, size:, **)
         
     | 
| 
       15 
     | 
    
         
            -
                      if key.respond_to?(:call)
         
     | 
| 
       16 
     | 
    
         
            -
                        raise Error.new('"key" must not be lambda.', @name, @index)
         
     | 
| 
       17 
     | 
    
         
            -
                      end
         
     | 
| 
       18 
     | 
    
         
            -
                      if !key && name.respond_to?(:call) && !size
         
     | 
| 
       19 
     | 
    
         
            -
                        raise Error.new('"size" must be defined, because column size cannot be determined.', @name, @index)
         
     | 
| 
       20 
     | 
    
         
            -
                      end
         
     | 
| 
       21 
     | 
    
         
            -
                      if size && size < DEFAULT_SIZE
         
     | 
| 
       22 
     | 
    
         
            -
                        raise Error.new('"size" must be positive.', @name, @index)
         
     | 
| 
       23 
     | 
    
         
            -
                      end
         
     | 
| 
       24 
     | 
    
         
            -
                      if key && size && [key].flatten.size < size
         
     | 
| 
       25 
     | 
    
         
            -
                        raise Error.new('"key" size must not be less than specified "size".', @name, @index)
         
     | 
| 
       26 
     | 
    
         
            -
                      end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                      true
         
     | 
| 
       29 
     | 
    
         
            -
                    end
         
     | 
| 
       30 
     | 
    
         
            -
                  end
         
     | 
| 
       31 
     | 
    
         
            -
                end
         
     | 
| 
       32 
     | 
    
         
            -
              end
         
     | 
| 
       33 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,63 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module TableStructure
         
     | 
| 
       4 
     | 
    
         
            -
              module Schema
         
     | 
| 
       5 
     | 
    
         
            -
                class Definition
         
     | 
| 
       6 
     | 
    
         
            -
                  attr_reader :options
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                  def initialize(
         
     | 
| 
       9 
     | 
    
         
            -
                    name,
         
     | 
| 
       10 
     | 
    
         
            -
                    column_definitions,
         
     | 
| 
       11 
     | 
    
         
            -
                    context_builders,
         
     | 
| 
       12 
     | 
    
         
            -
                    column_converters,
         
     | 
| 
       13 
     | 
    
         
            -
                    result_builders,
         
     | 
| 
       14 
     | 
    
         
            -
                    context,
         
     | 
| 
       15 
     | 
    
         
            -
                    options
         
     | 
| 
       16 
     | 
    
         
            -
                  )
         
     | 
| 
       17 
     | 
    
         
            -
                    @name = name
         
     | 
| 
       18 
     | 
    
         
            -
                    @context_builders = ContextBuilders.new(context_builders)
         
     | 
| 
       19 
     | 
    
         
            -
                    @column_converters = ColumnConverters.new(column_converters)
         
     | 
| 
       20 
     | 
    
         
            -
                    @result_builders = ResultBuilders.new(result_builders)
         
     | 
| 
       21 
     | 
    
         
            -
                    @context = @context_builders.build_for_table(context)
         
     | 
| 
       22 
     | 
    
         
            -
                    @options = options
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                    @columns = create_columns(@name, column_definitions, @context, @options)
         
     | 
| 
       25 
     | 
    
         
            -
                  end
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                  def create_table(**options)
         
     | 
| 
       28 
     | 
    
         
            -
                    options = @options.merge(options)
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                    table = Table.new(
         
     | 
| 
       31 
     | 
    
         
            -
                      @columns,
         
     | 
| 
       32 
     | 
    
         
            -
                      @context,
         
     | 
| 
       33 
     | 
    
         
            -
                      options
         
     | 
| 
       34 
     | 
    
         
            -
                    )
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                    @context_builders.extend_methods_for(table)
         
     | 
| 
       37 
     | 
    
         
            -
                    @column_converters.extend_methods_for(table)
         
     | 
| 
       38 
     | 
    
         
            -
                    @result_builders.extend_methods_for(table)
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                    if block_given?
         
     | 
| 
       41 
     | 
    
         
            -
                      yield table
         
     | 
| 
       42 
     | 
    
         
            -
                    else
         
     | 
| 
       43 
     | 
    
         
            -
                      table
         
     | 
| 
       44 
     | 
    
         
            -
                    end
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                  private
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                  def create_columns(name, definitions, context, options)
         
     | 
| 
       50 
     | 
    
         
            -
                    Compiler
         
     | 
| 
       51 
     | 
    
         
            -
                      .new(name, definitions, options)
         
     | 
| 
       52 
     | 
    
         
            -
                      .compile(context)
         
     | 
| 
       53 
     | 
    
         
            -
                      .map do |definition|
         
     | 
| 
       54 
     | 
    
         
            -
                        if definition.is_a?(Hash)
         
     | 
| 
       55 
     | 
    
         
            -
                          Column::Attrs.new(definition)
         
     | 
| 
       56 
     | 
    
         
            -
                        else
         
     | 
| 
       57 
     | 
    
         
            -
                          Column::Schema.new(definition)
         
     | 
| 
       58 
     | 
    
         
            -
                        end
         
     | 
| 
       59 
     | 
    
         
            -
                      end
         
     | 
| 
       60 
     | 
    
         
            -
                  end
         
     | 
| 
       61 
     | 
    
         
            -
                end
         
     | 
| 
       62 
     | 
    
         
            -
              end
         
     | 
| 
       63 
     | 
    
         
            -
            end
         
     |