table_structure 0.3.16 → 0.3.17

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