table_structure 0.3.16 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -3
  3. data/Gemfile.lock +5 -5
  4. data/README.md +44 -38
  5. data/lib/table_structure.rb +15 -10
  6. data/lib/table_structure/schema.rb +43 -22
  7. data/lib/table_structure/schema/class_methods.rb +2 -2
  8. data/lib/table_structure/schema/column_converters.rb +40 -44
  9. data/lib/table_structure/schema/{column/attrs.rb → columns/attributes.rb} +7 -2
  10. data/lib/table_structure/schema/{column → columns}/schema.rb +6 -4
  11. data/lib/table_structure/schema/context_builders.rb +12 -4
  12. data/lib/table_structure/schema/definition/column_converter.rb +31 -0
  13. data/lib/table_structure/schema/definition/columns/attributes.rb +55 -0
  14. data/lib/table_structure/schema/definition/columns/compiler.rb +45 -0
  15. data/lib/table_structure/schema/{column/definition → definition/columns}/error.rb +2 -2
  16. data/lib/table_structure/schema/definition/columns/schema_class.rb +24 -0
  17. data/lib/table_structure/schema/definition/columns/schema_instance.rb +23 -0
  18. data/lib/table_structure/schema/{column/definition → definition/columns}/validator.rb +2 -2
  19. data/lib/table_structure/schema/definition/context_builder.rb +17 -0
  20. data/lib/table_structure/schema/definition/row_builder.rb +25 -0
  21. data/lib/table_structure/schema/dsl/column_converter.rb +16 -9
  22. data/lib/table_structure/schema/dsl/context_builder.rb +4 -1
  23. data/lib/table_structure/schema/dsl/row_builder.rb +26 -0
  24. data/lib/table_structure/schema/keys_generator.rb +29 -0
  25. data/lib/table_structure/schema/row_builders.rb +58 -0
  26. data/lib/table_structure/schema/table.rb +24 -16
  27. data/lib/table_structure/schema/utils.rb +5 -1
  28. data/lib/table_structure/version.rb +1 -1
  29. data/lib/table_structure/writer.rb +1 -1
  30. metadata +16 -11
  31. data/lib/table_structure/schema/column/definition/compiler.rb +0 -81
  32. data/lib/table_structure/schema/column/factory.rb +0 -22
  33. data/lib/table_structure/schema/dsl/result_builder.rb +0 -27
  34. data/lib/table_structure/schema/result_builders.rb +0 -67
  35. data/lib/table_structure/schema/table/key_decorator.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8794a66493988290a6ddeea36604322559a519ba3f0f261af4243fd56687663
4
- data.tar.gz: 57f9279940767cc9c0612a9ffda469711ac070d086a8780aeef4a23c8dafef7d
3
+ metadata.gz: 15d536a6af5a6f759f6e2460568aa1822edc3b15812b4d84c821a5d9750e4275
4
+ data.tar.gz: d12f7463aa3b5ee12cfe8023ef77f0ef0ccf1f2d59692f392696ceeef47dc948
5
5
  SHA512:
6
- metadata.gz: e906e4e3bdb277218db13fc90b028470f794ae9f346de456a84c524219aeaf63a184d9a8e4802ed3cc0dab55f7891fe0b6a5012144b236d6da1f3a02c3abebe0
7
- data.tar.gz: c68e1178bce24e496b77ab1b3cb3674120129b86b1e352ef6233f29504b11e7355d93a4975c3e3445fd88e03ed19ac1bf05f4f86dc38331a8e256a2d273356f2
6
+ metadata.gz: 5f8008644303fdea9135a1d1a6d7e26cac50c388062982723c7e9564589c96d3eb70346a2a12a216c2fc2c13abe52e4f0d8b7860fbc652ff1878cce70b505b74
7
+ data.tar.gz: 719615ac3af76a63c0fa616f4fc2e8195d806dd4e773987ce0f4274eff58647ddab6b460b6a13fbfb72d7709d93e26ca30f427202132e8ab4ddd13cedf7f9c3d
@@ -1,3 +1,15 @@
1
+ # 0.3.17
2
+ Changes:
3
+ - `TableStructure::Schema`
4
+ - `:row` option for `column_converter` DSL has been deprecated. Use `:body` option instead.
5
+ - `:result_type` option of `create_table` method has been deprecated. Use `:row_type` option instead.
6
+ - `TableStructure::Schema::Table`
7
+ - `rows` method has been deprecated. Use `body` method instead.
8
+ - `TableStructure::Writer`
9
+ - `:result_type` option has been deprecated. Use `:row_type` option instead.
10
+ - `TableStructure::Iterator`
11
+ - `:result_type` option has been deprecated. Use `:row_type` option instead.
12
+
1
13
  # 0.3.16
2
14
  Changes:
3
15
  - `TableStructure::Schema`
@@ -12,11 +24,11 @@ Changes:
12
24
 
13
25
  # 0.3.14
14
26
  Changes:
15
- - Support Ruby 2.7.
27
+ - Support Ruby 2.7.
16
28
 
17
29
  # 0.3.13
18
30
  Changes:
19
- - Minor improvements.
31
+ - Minor improvements.
20
32
 
21
33
  # 0.3.12
22
34
  Changes:
@@ -67,7 +79,7 @@ Changes:
67
79
  - `column_converter`
68
80
  - Add `:header` and `:row` options.
69
81
  - If `header: false`, the converter is not applied to header values.
70
- - If `row: false`, the converter is not applied to row values.
82
+ - If `row: false`, the converter is not applied to body values.
71
83
  - Both options default to `true`, which is same behavior as before.
72
84
 
73
85
  # 0.3.4
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- table_structure (0.3.16)
4
+ table_structure (0.3.17)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -12,15 +12,15 @@ GEM
12
12
  rspec-core (~> 3.9.0)
13
13
  rspec-expectations (~> 3.9.0)
14
14
  rspec-mocks (~> 3.9.0)
15
- rspec-core (3.9.0)
16
- rspec-support (~> 3.9.0)
15
+ rspec-core (3.9.1)
16
+ rspec-support (~> 3.9.1)
17
17
  rspec-expectations (3.9.0)
18
18
  diff-lcs (>= 1.2.0, < 2.0)
19
19
  rspec-support (~> 3.9.0)
20
- rspec-mocks (3.9.0)
20
+ rspec-mocks (3.9.1)
21
21
  diff-lcs (>= 1.2.0, < 2.0)
22
22
  rspec-support (~> 3.9.0)
23
- rspec-support (3.9.0)
23
+ rspec-support (3.9.2)
24
24
 
25
25
  PLATFORMS
26
26
  ruby
data/README.md CHANGED
@@ -5,9 +5,9 @@
5
5
  - `TableStructure::Schema`
6
6
  - Defines columns of a table using DSL.
7
7
  - `TableStructure::Writer`
8
- - Converts data with the schema, and outputs it.
8
+ - Converts data with the schema, and outputs table structured data.
9
9
  - `TableStructure::Iterator`
10
- - Converts data with the schema, and enumerates it.
10
+ - Converts data with the schema, and enumerates table structured data.
11
11
 
12
12
  ## Installation
13
13
 
@@ -129,6 +129,15 @@ end
129
129
  ```
130
130
  [Sample with docker](https://github.com/jsmmr/ruby_table_structure_sample)
131
131
 
132
+ You can also convert CSV character code:
133
+ ```ruby
134
+ File.open('sample.csv', 'w') do |f|
135
+ writer.write(items, to: CSV.new(f)) do |row_values|
136
+ row_values.map { |val| val.to_s.encode('Shift_JIS', invalid: :replace, undef: :replace) }
137
+ end
138
+ end
139
+ ```
140
+
132
141
  You can also use `TableStructure::CSV::Writer` instead:
133
142
  ```ruby
134
143
  writer = TableStructure::CSV::Writer.new(schema)
@@ -138,7 +147,7 @@ end
138
147
  ```
139
148
 
140
149
  #### TableStructure::Iterator
141
- Specifying `result_type: :hash` option works well.
150
+ Specifying `row_type: :hash` option works well.
142
151
  To use this option, define `column(s)` with `:key`.
143
152
 
144
153
  Define a schema:
@@ -167,9 +176,7 @@ class SampleTableSchema
167
176
 
168
177
  ## If the schemas are nested, :key must be unique in parent and child schemas.
169
178
  ## This can also be avoided by specifying :key_prefix or :key_suffix option.
170
- # columns ->(table) { NestedSchema.new(context: table, key_prefix: 'foo_', key_suffix: '_bar') }
171
-
172
- column_converter :to_s, ->(val, *) { val.to_s }
179
+ # columns ->(table) { NestedTableSchema.new(context: table, key_prefix: 'foo_', key_suffix: '_bar') }
173
180
  end
174
181
  ```
175
182
 
@@ -184,7 +191,7 @@ context = {
184
191
  }
185
192
 
186
193
  schema = SampleTableSchema.new(context: context)
187
- iterator = TableStructure::Iterator.new(schema, result_type: :hash, header_omitted: true)
194
+ iterator = TableStructure::Iterator.new(schema, row_type: :hash, header_omitted: true)
188
195
  ```
189
196
 
190
197
  Enumerate the items converted by the schema:
@@ -220,9 +227,26 @@ enum.lazy.select { |item| item[:q1] == '⭕️' }.take(1).force
220
227
 
221
228
  ### Advanced
222
229
 
230
+ You can add definitions when initializing the schema.
231
+ ```ruby
232
+ class UserTableSchema
233
+ include TableStructure::Schema
234
+
235
+ column name: 'ID',
236
+ value: ->(row, *) { row[:id] }
237
+
238
+ column name: 'Name',
239
+ value: ->(row, *) { row[:name] }
240
+ end
241
+
242
+ schema = UserTableSchema.new do
243
+ column_converter :to_s, ->(val, *) { val.to_s }
244
+ end
245
+ ```
246
+
223
247
  You can also omit columns by defining `:omitted`.
224
248
  ```ruby
225
- class SampleTableSchema
249
+ class UserTableSchema
226
250
  include TableStructure::Schema
227
251
 
228
252
  column name: 'ID',
@@ -238,7 +262,7 @@ end
238
262
 
239
263
  context = { admin: true }
240
264
 
241
- schema = SampleTableSchema.new(context: context)
265
+ schema = UserTableSchema.new(context: context)
242
266
  ```
243
267
 
244
268
  You can also omit columns by specifying `nil_definitions_ignored: true`.
@@ -268,25 +292,18 @@ context = { pet_num: 0 }
268
292
  schema = SampleTableSchema.new(context: context, nil_definitions_ignored: true)
269
293
  ```
270
294
 
271
- You can add definitions when initializing the schema.
295
+ You can also nest the schemas.
272
296
  ```ruby
273
297
  class UserTableSchema
274
298
  include TableStructure::Schema
275
299
 
276
300
  column name: 'ID',
277
- value: ->(row, _table) { row[:id] }
301
+ value: ->(row, *) { row[:id] }
278
302
 
279
303
  column name: 'Name',
280
304
  value: ->(row, *) { row[:name] }
281
305
  end
282
306
 
283
- schema = UserTableSchema.new do
284
- column_converter :to_s, ->(val, *) { val.to_s }
285
- end
286
- ```
287
-
288
- You can also nest the schemas.
289
- ```ruby
290
307
  class PetTableSchema
291
308
  include TableStructure::Schema
292
309
 
@@ -307,14 +324,12 @@ class QuestionTableSchema
307
324
  }
308
325
  end
309
326
 
310
- class UserTableSchema
327
+ class SampleTableSchema
311
328
  include TableStructure::Schema
312
329
 
313
- column name: 'ID',
314
- value: ->(row, *) { row[:id] }
315
-
316
- column name: 'Name',
317
- value: ->(row, *) { row[:name] }
330
+ columns ->(table) { UserTableSchema.new(context: table) }
331
+ ## or
332
+ # columns UserTableSchema
318
333
 
319
334
  columns ->(table) { PetTableSchema.new(context: table) }
320
335
  ## or
@@ -333,7 +348,7 @@ context = {
333
348
  ]
334
349
  }
335
350
 
336
- schema = UserTableSchema.new(context: context)
351
+ schema = SampleTableSchema.new(context: context)
337
352
  ```
338
353
 
339
354
  You can also concatenate or merge the schema classes.
@@ -349,7 +364,7 @@ class UserTableSchema
349
364
  include TableStructure::Schema
350
365
 
351
366
  column name: 'ID',
352
- value: ->(row, _table) { row[:id] }
367
+ value: ->(row, *) { row[:id] }
353
368
 
354
369
  column name: 'Name',
355
370
  value: ->(row, *) { row[:name] }
@@ -429,18 +444,9 @@ class SampleTableSchema
429
444
  end
430
445
  ```
431
446
 
432
- If you want to convert CSV character code, you can do so in a block of `write` method.
433
- ```ruby
434
- File.open('sample.csv', 'w') do |f|
435
- writer.write(items, to: CSV.new(f)) do |row_values|
436
- row_values.map { |val| val.to_s.encode('Shift_JIS', invalid: :replace, undef: :replace) }
437
- end
438
- end
439
- ```
440
-
441
- You can also use only `TableStructure::Schema`.
447
+ You can also use only `TableStructure::Schema` instance.
442
448
  ```erb
443
- <% @schema.create_table(result_type: :array) do |table| %>
449
+ <% @schema.create_table(row_type: :array) do |table| %>
444
450
  <table>
445
451
  <thead>
446
452
  <tr>
@@ -451,7 +457,7 @@ You can also use only `TableStructure::Schema`.
451
457
  </thead>
452
458
 
453
459
  <tbody>
454
- <% table.rows(@items).each do |row| %>
460
+ <% table.body(@items).each do |row| %>
455
461
  <tr>
456
462
  <% row.each do |val| %>
457
463
  <td><%= val %></td>
@@ -4,25 +4,30 @@ module TableStructure
4
4
  class Error < StandardError; end
5
5
 
6
6
  require 'table_structure/version'
7
-
7
+ require 'forwardable'
8
8
  require 'table_structure/schema'
9
9
  require 'table_structure/schema/class_methods'
10
10
  require 'table_structure/schema/dsl/column_converter'
11
11
  require 'table_structure/schema/dsl/column_definition'
12
12
  require 'table_structure/schema/dsl/context_builder'
13
13
  require 'table_structure/schema/dsl/option'
14
- require 'table_structure/schema/dsl/result_builder'
14
+ require 'table_structure/schema/dsl/row_builder'
15
+ require 'table_structure/schema/definition/column_converter'
16
+ require 'table_structure/schema/definition/context_builder'
17
+ require 'table_structure/schema/definition/row_builder'
18
+ require 'table_structure/schema/definition/columns/compiler'
19
+ require 'table_structure/schema/definition/columns/error'
20
+ require 'table_structure/schema/definition/columns/validator'
21
+ require 'table_structure/schema/definition/columns/attributes'
22
+ require 'table_structure/schema/definition/columns/schema_class'
23
+ require 'table_structure/schema/definition/columns/schema_instance'
15
24
  require 'table_structure/schema/column_converters'
16
25
  require 'table_structure/schema/context_builders'
17
- require 'table_structure/schema/result_builders'
26
+ require 'table_structure/schema/row_builders'
18
27
  require 'table_structure/schema/table'
19
- require 'table_structure/schema/table/key_decorator'
20
- require 'table_structure/schema/column/attrs'
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'
28
+ require 'table_structure/schema/keys_generator'
29
+ require 'table_structure/schema/columns/attributes'
30
+ require 'table_structure/schema/columns/schema'
26
31
  require 'table_structure/schema/utils'
27
32
  require 'table_structure/writer'
28
33
  require 'table_structure/csv/writer'
@@ -7,7 +7,7 @@ module TableStructure
7
7
  klass.extend(DSL::ColumnDefinition)
8
8
  klass.extend(DSL::ContextBuilder)
9
9
  klass.extend(DSL::Option)
10
- klass.extend(DSL::ResultBuilder)
10
+ klass.extend(DSL::RowBuilder)
11
11
  klass.extend(ClassMethods)
12
12
  end
13
13
 
@@ -21,13 +21,12 @@ module TableStructure
21
21
  end
22
22
  end
23
23
 
24
- Definition = Struct.new(
25
- 'Definition',
24
+ MyDefinition = Struct.new(
26
25
  :name,
27
26
  :columns,
28
27
  :context_builders,
29
28
  :column_converters,
30
- :result_builders,
29
+ :row_builders,
31
30
  :context,
32
31
  :options
33
32
  )
@@ -72,24 +71,26 @@ module TableStructure
72
71
  schema_classes.map(&:column_converters).reduce({}, &:merge!)
73
72
  )
74
73
 
75
- result_builders = ResultBuilders.new(
76
- schema_classes.map(&:result_builders).reduce({}, &:merge!)
74
+ row_builders = RowBuilders.new(
75
+ schema_classes.map(&:row_builders).reduce({}, &:merge!)
77
76
  )
78
77
 
79
- columns = Column::Factory.create(
80
- name,
81
- schema_classes.map(&:column_definitions).reduce([], &:concat),
82
- context_builders.build_for_table(context),
83
- options
84
- )
78
+ columns =
79
+ Definition::Columns::Compiler
80
+ .new(
81
+ name,
82
+ schema_classes.map(&:column_definitions).reduce([], &:concat),
83
+ options
84
+ )
85
+ .compile(context_builders.build_for_table(context))
85
86
 
86
87
  @_definition_ =
87
- Definition.new(
88
+ MyDefinition.new(
88
89
  name,
89
90
  columns,
90
91
  context_builders,
91
92
  column_converters,
92
- result_builders,
93
+ row_builders,
93
94
  context,
94
95
  options
95
96
  )
@@ -99,26 +100,46 @@ module TableStructure
99
100
  def create_table(**options)
100
101
  options = @_definition_.options.merge(options)
101
102
 
103
+ if options.key?(:result_type)
104
+ warn '[TableStructure] `:result_type` option has been deprecated. Use `:row_type` option instead.'
105
+ options[:row_type] = options[:result_type]
106
+ end
107
+
108
+ keys_generator_options = {
109
+ prefix: options[:key_prefix],
110
+ suffix: options[:key_suffix]
111
+ }
112
+
113
+ keys_generator = KeysGenerator.new(
114
+ **keys_generator_options
115
+ )
116
+
102
117
  table = Table.new(
103
- @_definition_.columns,
104
- @_definition_.context,
105
- options
118
+ columns: @_definition_.columns,
119
+ context: @_definition_.context,
120
+ keys_generator: keys_generator
106
121
  )
107
122
 
108
- @_definition_.context_builders.extend_methods_for(table)
123
+ @_definition_
124
+ .context_builders
125
+ .extend_methods_for(table)
109
126
 
110
127
  column_converters_options = {
111
128
  name_prefix: options[:name_prefix],
112
129
  name_suffix: options[:name_suffix]
113
130
  }
114
131
 
115
- @_definition_.column_converters.extend_methods_for(table, **column_converters_options)
132
+ @_definition_
133
+ .column_converters
134
+ .extend_methods_for(table, **column_converters_options)
116
135
 
117
- result_builders_options = {
118
- result_type: options[:result_type]
136
+ row_builders_options = {
137
+ row_type: options[:row_type]
119
138
  }
120
139
 
121
- @_definition_.result_builders.extend_methods_for(table, **result_builders_options)
140
+ @_definition_
141
+ .row_builders
142
+ .extend_methods_for(table, **row_builders_options)
122
143
 
123
144
  if block_given?
124
145
  yield table
@@ -41,9 +41,9 @@ module TableStructure
41
41
  .map(&:column_converters)
42
42
  .reduce({}, &:merge!)
43
43
 
44
- @__result_builders__ =
44
+ @__row_builders__ =
45
45
  schema_classes
46
- .map(&:result_builders)
46
+ .map(&:row_builders)
47
47
  .reduce({}, &:merge!)
48
48
  end
49
49
  end
@@ -4,70 +4,66 @@ module TableStructure
4
4
  module Schema
5
5
  class ColumnConverters
6
6
  def initialize(converters)
7
- @header_converters = select_converters_for(:header, converters)
8
- @row_converters = select_converters_for(:row, converters)
7
+ @header_converters = converters.select { |_k, v| v.applicable_to_header? }
8
+ @body_converterss = converters.select { |_k, v| v.applicable_to_body? }
9
9
  end
10
10
 
11
11
  def extend_methods_for(table, name_prefix:, name_suffix:)
12
12
  table_context = table.instance_variable_get(:@context)
13
13
 
14
- header_converters = @header_converters.merge(
15
- optional_header_converters(name_prefix: name_prefix, name_suffix: name_suffix)
16
- )
17
- row_converters = @row_converters
14
+ header_converters =
15
+ @header_converters
16
+ .merge(
17
+ _prepend_prefix_: create_prepender(name_prefix),
18
+ _append_suffix_: create_appender(name_suffix)
19
+ )
20
+ .reject { |_k, v| v.nil? }
18
21
 
19
- methods = {}
20
- unless header_converters.empty?
21
- methods[:header] = create_method(header_converters, table_context)
22
- end
23
- unless row_converters.empty?
24
- methods[:row] = create_method(row_converters, table_context)
25
- end
22
+ body_converterss = @body_converterss
23
+
24
+ methods =
25
+ {
26
+ header: create_method(header_converters, table_context),
27
+ data: create_method(body_converterss, table_context)
28
+ }
29
+ .reject { |_k, v| v.nil? }
26
30
 
27
31
  return if methods.empty?
28
32
 
29
- table.extend ColumnConverter.new(methods)
33
+ table.extend ColumnConvertible.new(methods)
30
34
  end
31
35
 
32
36
  private
33
37
 
34
- def select_converters_for(method, converters)
35
- converters
36
- .select { |_k, v| v[:options][method] }
37
- .map { |k, v| [k, v[:callable]] }
38
- .to_h
39
- end
40
-
41
- def optional_header_converters(name_prefix:, name_suffix:)
42
- converters = {}
43
- if name_prefix
44
- converters[:_prepend_prefix_] =
45
- create_prefix_converter(name_prefix)
46
- end
47
- if name_suffix
48
- converters[:_append_suffix_] =
49
- create_suffix_converter(name_suffix)
50
- end
38
+ def create_prepender(prefix)
39
+ return unless prefix
51
40
 
52
- converters
41
+ Definition::ColumnConverter.new(
42
+ lambda { |val, *|
43
+ val.nil? ? val : "#{prefix}#{val}"
44
+ },
45
+ header: true,
46
+ body: false
47
+ )
53
48
  end
54
49
 
55
- def create_prefix_converter(prefix)
56
- lambda { |val, *|
57
- val.nil? ? val : "#{prefix}#{val}"
58
- }
59
- end
50
+ def create_appender(suffix)
51
+ return unless suffix
60
52
 
61
- def create_suffix_converter(suffix)
62
- lambda { |val, *|
63
- val.nil? ? val : "#{val}#{suffix}"
64
- }
53
+ Definition::ColumnConverter.new(
54
+ lambda { |val, *|
55
+ val.nil? ? val : "#{val}#{suffix}"
56
+ },
57
+ header: true,
58
+ body: false
59
+ )
65
60
  end
66
61
 
67
62
  def create_method(converters, table_context)
63
+ return if converters.empty?
64
+
68
65
  proc do |context: nil|
69
- values = super(context: context)
70
- values.map do |val|
66
+ super(context: context).map do |val|
71
67
  converters.reduce(val) do |val, (_, converter)|
72
68
  converter.call(val, context, table_context)
73
69
  end
@@ -76,7 +72,7 @@ module TableStructure
76
72
  end
77
73
  end
78
74
 
79
- class ColumnConverter < Module
75
+ class ColumnConvertible < Module
80
76
  def initialize(methods)
81
77
  methods.each do |name, method|
82
78
  define_method(name, &method)