table_structure 0.3.21 → 0.4.2
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 +37 -0
- data/Gemfile.lock +7 -7
- data/README.md +84 -78
- data/lib/table_structure.rb +6 -12
- data/lib/table_structure/csv/writer.rb +4 -41
- data/lib/table_structure/iterator.rb +48 -89
- data/lib/table_structure/schema.rb +63 -76
- data/lib/table_structure/schema/class_methods.rb +2 -2
- data/lib/table_structure/schema/column_builder_factory.rb +75 -0
- data/lib/table_structure/schema/columns/attributes.rb +14 -9
- data/lib/table_structure/schema/columns/schema.rb +14 -9
- data/lib/table_structure/schema/composite_class.rb +40 -0
- data/lib/table_structure/schema/definition/columns/compiler.rb +7 -3
- data/lib/table_structure/schema/definition/columns/validator.rb +2 -6
- data/lib/table_structure/schema/dsl/column_builder.rb +29 -0
- data/lib/table_structure/schema/dsl/context_builder.rb +3 -5
- data/lib/table_structure/schema/dsl/row_builder.rb +5 -5
- data/lib/table_structure/schema/{key_converter.rb → keys_builder.rb} +2 -2
- data/lib/table_structure/schema/row_context_builder_factory.rb +30 -0
- data/lib/table_structure/table.rb +31 -56
- data/lib/table_structure/utils.rb +40 -0
- data/lib/table_structure/version.rb +1 -1
- data/lib/table_structure/writer.rb +7 -54
- metadata +8 -14
- data/lib/table_structure/schema/column_converter.rb +0 -48
- data/lib/table_structure/schema/definition/column_converter.rb +0 -31
- data/lib/table_structure/schema/definition/context_builder.rb +0 -17
- data/lib/table_structure/schema/definition/row_builder.rb +0 -25
- data/lib/table_structure/schema/dsl/column_converter.rb +0 -34
- data/lib/table_structure/schema/dsl/option.rb +0 -19
- data/lib/table_structure/schema/row_builder.rb +0 -22
- data/lib/table_structure/table/column_converter.rb +0 -46
- data/lib/table_structure/table/context_builder.rb +0 -49
- data/lib/table_structure/table/iterator.rb +0 -22
- data/lib/table_structure/table/row_builder.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06f36abaa1bc4478901ea51a27e0e22b00ecf70ecbfd18b4c785c2e86e08ca1d
|
4
|
+
data.tar.gz: 26990e2f8ac30764a3d571dbf8a35e422ce163989f9eda5e92aa3c2b9e5cf498
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 288ea6944e5efa303a3c39e4502dce7b0d2994504796a7de0b69b28d8b0cd91f878670db9846a51cbb57d16797bb8124e50f2162db00ec89b49d83de3a345030
|
7
|
+
data.tar.gz: 72d983aef1de40282befe38d230806b1fb3deec4ecf08801822867d43ea656a6a307ad53c46ae87f2661bcc90ef5c6f0b3d8c5ea515eb80ddeb78e559b552585
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,40 @@
|
|
1
|
+
# 0.4.2
|
2
|
+
Changes:
|
3
|
+
- `TableStructure::Schema`
|
4
|
+
- Improve performance.
|
5
|
+
- `TableStructure::Iterator`
|
6
|
+
- `TableStructure::Writer`
|
7
|
+
- `TableStructure::CSV::Writer`
|
8
|
+
- Add validation for `header: { step: n }` option.
|
9
|
+
- `n` is allowed positive number or `nil`(default).
|
10
|
+
|
11
|
+
# 0.4.1
|
12
|
+
Changes:
|
13
|
+
- `TableStructure::Iterator`
|
14
|
+
- `TableStructure::Writer`
|
15
|
+
- `TableStructure::CSV::Writer`
|
16
|
+
- Add `header: { step: n }` option. Header rows are output at intervals of step number.
|
17
|
+
- e.g. `TableStructure::Iterator.new(schema, header: { step: 10 })`
|
18
|
+
|
19
|
+
# 0.4.0
|
20
|
+
Changes:
|
21
|
+
- Remove deprecated methods, arguments and options.
|
22
|
+
- It is recommended that you update to `0.3.23` first. If you get warnings or errors, fix them and then update to `0.4.0`.
|
23
|
+
|
24
|
+
# 0.3.23
|
25
|
+
Changes:
|
26
|
+
- `TableStructure::CSV::Writer`
|
27
|
+
- Fix not to output wrong warning.
|
28
|
+
|
29
|
+
# 0.3.22
|
30
|
+
Changes:
|
31
|
+
- `TableStructure::Schema`
|
32
|
+
- DSL
|
33
|
+
- `column_converter`
|
34
|
+
- Using `lambda` has been deprecated. Use `block` instead.
|
35
|
+
- `context_builder`
|
36
|
+
- Using `lambda` has been deprecated. Use `block` instead.
|
37
|
+
|
1
38
|
# 0.3.21
|
2
39
|
Changes:
|
3
40
|
- Add `TableStructure::Table`
|
data/Gemfile.lock
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
table_structure (0.
|
4
|
+
table_structure (0.4.2)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
diff-lcs (1.
|
9
|
+
diff-lcs (1.4.4)
|
10
10
|
rake (13.0.1)
|
11
11
|
rspec (3.9.0)
|
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.
|
16
|
-
rspec-support (~> 3.9.
|
17
|
-
rspec-expectations (3.9.
|
15
|
+
rspec-core (3.9.2)
|
16
|
+
rspec-support (~> 3.9.3)
|
17
|
+
rspec-expectations (3.9.2)
|
18
18
|
diff-lcs (>= 1.2.0, < 2.0)
|
19
19
|
rspec-support (~> 3.9.0)
|
20
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.
|
23
|
+
rspec-support (3.9.3)
|
24
24
|
|
25
25
|
PLATFORMS
|
26
26
|
ruby
|
@@ -32,4 +32,4 @@ DEPENDENCIES
|
|
32
32
|
table_structure!
|
33
33
|
|
34
34
|
BUNDLED WITH
|
35
|
-
2.1.
|
35
|
+
2.1.4
|
data/README.md
CHANGED
@@ -56,7 +56,9 @@ class SampleTableSchema
|
|
56
56
|
end
|
57
57
|
}
|
58
58
|
|
59
|
-
column_converter :to_s
|
59
|
+
column_converter :to_s do |val, _row, _table|
|
60
|
+
val.to_s
|
61
|
+
end
|
60
62
|
end
|
61
63
|
```
|
62
64
|
|
@@ -104,10 +106,10 @@ items = [
|
|
104
106
|
## or
|
105
107
|
# items = Enumerator.new { |y| Item.find_each { |item| y << item } }
|
106
108
|
|
107
|
-
|
108
|
-
writer.write(items, to:
|
109
|
+
array = []
|
110
|
+
writer.write(items, to: array)
|
109
111
|
|
110
|
-
#
|
112
|
+
# array
|
111
113
|
# => [["ID", "Name", "Pet 1", "Pet 2", "Pet 3", "Q1", "Q2", "Q3"], ["1", "Taro", "🐱", "🐶", "", "⭕️", "❌", "⭕️"], ["2", "Hanako", "🐇", "🐢", "🐿", "⭕️", "⭕️", "❌"]]
|
112
114
|
```
|
113
115
|
|
@@ -124,6 +126,7 @@ Write the items converted by the schema to stream as CSV with Rails:
|
|
124
126
|
response.headers['Cache-Control'] = 'no-cache'
|
125
127
|
response.headers['Content-Type'] = 'text/csv'
|
126
128
|
response.headers['Content-Disposition'] = 'attachment; filename="sample.csv"'
|
129
|
+
response.headers['Last-Modified'] = Time.now.ctime.to_s # Required if Rack >= 2.2.0
|
127
130
|
response_body = Enumerator.new do |y|
|
128
131
|
# y << "\uFEFF" # BOM (Prevent garbled characters for Excel)
|
129
132
|
writer.write(items, to: CSV.new(y))
|
@@ -133,8 +136,8 @@ end
|
|
133
136
|
You can also convert CSV character code:
|
134
137
|
```ruby
|
135
138
|
File.open('sample.csv', 'w') do |f|
|
136
|
-
writer.write(items, to: CSV.new(f)) do |
|
137
|
-
|
139
|
+
writer.write(items, to: CSV.new(f)) do |row|
|
140
|
+
row.map { |val| val.to_s.encode('Shift_JIS', invalid: :replace, undef: :replace) }
|
138
141
|
end
|
139
142
|
end
|
140
143
|
```
|
@@ -178,10 +181,6 @@ class SampleTableSchema
|
|
178
181
|
}
|
179
182
|
end
|
180
183
|
}
|
181
|
-
|
182
|
-
## If the schemas are nested, :key must be unique in parent and child schemas.
|
183
|
-
## This can also be avoided by using :key_prefix or :key_suffix option.
|
184
|
-
# columns ->(table) { NestedTableSchema.new(context: table, key_prefix: 'foo_', key_suffix: '_bar') }
|
185
184
|
end
|
186
185
|
```
|
187
186
|
|
@@ -257,6 +256,10 @@ Initialize a table with the schema and render the table:
|
|
257
256
|
<% end %>
|
258
257
|
```
|
259
258
|
|
259
|
+
### Sample with docker
|
260
|
+
|
261
|
+
https://github.com/jsmmr/ruby_table_structure_sample
|
262
|
+
|
260
263
|
### Advanced
|
261
264
|
|
262
265
|
You can add definitions when initializing the schema.
|
@@ -272,7 +275,9 @@ class UserTableSchema
|
|
272
275
|
end
|
273
276
|
|
274
277
|
schema = UserTableSchema.new do
|
275
|
-
column_converter :to_s
|
278
|
+
column_converter :to_s do |val, *|
|
279
|
+
val.to_s
|
280
|
+
end
|
276
281
|
end
|
277
282
|
```
|
278
283
|
|
@@ -324,53 +329,91 @@ context = { pet_num: 0 }
|
|
324
329
|
schema = SampleTableSchema.new(context: context, nil_definitions_ignored: true)
|
325
330
|
```
|
326
331
|
|
327
|
-
You can also
|
332
|
+
You can also use `context_builder` to change the context object that the `lambda` receives.
|
328
333
|
```ruby
|
329
|
-
class
|
334
|
+
class SampleTableSchema
|
330
335
|
include TableStructure::Schema
|
331
336
|
|
337
|
+
TableContext = Struct.new(:questions, keyword_init: true)
|
338
|
+
|
339
|
+
RowContext = Struct.new(:id, :name, :pets, :answers, keyword_init: true) do
|
340
|
+
def increase_pets
|
341
|
+
pets + pets
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
context_builder :table do |context|
|
346
|
+
TableContext.new(**context)
|
347
|
+
end
|
348
|
+
|
349
|
+
context_builder :row, :value do |context|
|
350
|
+
RowContext.new(**context)
|
351
|
+
end
|
352
|
+
|
332
353
|
column name: 'ID',
|
333
|
-
value: ->(row, *) { row
|
354
|
+
value: ->(row, *) { row.id }
|
334
355
|
|
335
356
|
column name: 'Name',
|
336
|
-
value: ->(row, *) { row
|
337
|
-
end
|
338
|
-
|
339
|
-
class PetTableSchema
|
340
|
-
include TableStructure::Schema
|
357
|
+
value: ->(row, *) { row.name }
|
341
358
|
|
342
359
|
columns name: ['Pet 1', 'Pet 2', 'Pet 3'],
|
343
|
-
value: ->(row, *) { row
|
344
|
-
end
|
345
|
-
|
346
|
-
class QuestionTableSchema
|
347
|
-
include TableStructure::Schema
|
360
|
+
value: ->(row, *) { row.increase_pets }
|
348
361
|
|
349
362
|
columns ->(table) {
|
350
|
-
table
|
363
|
+
table.questions.map do |question|
|
351
364
|
{
|
352
365
|
name: question[:id],
|
353
|
-
value: ->(row, *) { row
|
366
|
+
value: ->(row, *) { row.answers[question[:id]] }
|
354
367
|
}
|
355
368
|
end
|
356
369
|
}
|
357
370
|
end
|
371
|
+
```
|
372
|
+
|
373
|
+
You can also nest the schemas.
|
374
|
+
If you nest the schemas and use `row_type: :hash`, `:key` must be unique in the schemas.
|
375
|
+
You can also use `:key_prefix` or `:key_suffix` option to keep uniqueness of the keys.
|
376
|
+
|
377
|
+
```ruby
|
378
|
+
class UserTableSchema
|
379
|
+
include TableStructure::Schema
|
380
|
+
|
381
|
+
column name: 'ID',
|
382
|
+
key: :id,
|
383
|
+
value: ->(row, *) { row[:id] }
|
384
|
+
|
385
|
+
column name: 'Name',
|
386
|
+
key: :name,
|
387
|
+
value: ->(row, *) { row[:name] }
|
388
|
+
end
|
358
389
|
|
359
390
|
class SampleTableSchema
|
360
391
|
include TableStructure::Schema
|
361
392
|
|
362
393
|
columns UserTableSchema
|
363
|
-
## or
|
364
|
-
# columns ->(table) { UserTableSchema.new(context: table) }
|
365
394
|
|
366
|
-
columns
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
395
|
+
columns ->(table) {
|
396
|
+
UserTableSchema.new(context: table, name_prefix: 'Friend ', key_prefix: 'friend_') do
|
397
|
+
context_builder :row do |context|
|
398
|
+
context[:friend]
|
399
|
+
end
|
400
|
+
end
|
401
|
+
}
|
373
402
|
end
|
403
|
+
|
404
|
+
items = [
|
405
|
+
{
|
406
|
+
id: 1,
|
407
|
+
name: 'Taro',
|
408
|
+
friend: {
|
409
|
+
id: 2,
|
410
|
+
name: 'Hanako'
|
411
|
+
}
|
412
|
+
}
|
413
|
+
]
|
414
|
+
|
415
|
+
schema = SampleTableSchema.new(context: {})
|
416
|
+
TableStructure::Iterator.new(schema, row_type: :hash).iterate(items)
|
374
417
|
```
|
375
418
|
|
376
419
|
You can also concatenate or merge the schema classes.
|
@@ -398,7 +441,9 @@ class PetTableSchema
|
|
398
441
|
columns name: ['Pet 1', 'Pet 2', 'Pet 3'],
|
399
442
|
value: ->(row, *) { row[:pets] }
|
400
443
|
|
401
|
-
column_converter :same_name
|
444
|
+
column_converter :same_name do |val, *|
|
445
|
+
"pet: #{val}"
|
446
|
+
end
|
402
447
|
end
|
403
448
|
|
404
449
|
class QuestionTableSchema
|
@@ -413,7 +458,9 @@ class QuestionTableSchema
|
|
413
458
|
end
|
414
459
|
}
|
415
460
|
|
416
|
-
column_converter :same_name
|
461
|
+
column_converter :same_name do |val, *|
|
462
|
+
"question: #{val}"
|
463
|
+
end
|
417
464
|
end
|
418
465
|
|
419
466
|
context = {
|
@@ -429,47 +476,6 @@ concatenated_schema = (UserTableSchema + PetTableSchema + QuestionTableSchema).n
|
|
429
476
|
merged_schema = UserTableSchema.merge(PetTableSchema, QuestionTableSchema).new(context: context)
|
430
477
|
```
|
431
478
|
|
432
|
-
You can also use `context_builder`.
|
433
|
-
This may be useful if `column(s)` lambda is complicated.
|
434
|
-
```ruby
|
435
|
-
class SampleTableSchema
|
436
|
-
include TableStructure::Schema
|
437
|
-
|
438
|
-
TableContext = Struct.new(:questions, keyword_init: true)
|
439
|
-
|
440
|
-
RowContext = Struct.new(:id, :name, :pets, :answers, keyword_init: true) do
|
441
|
-
def more_pets
|
442
|
-
pets + pets
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
|
-
context_builder :table, ->(context) { TableContext.new(**context) }
|
447
|
-
context_builder :row, ->(context) { RowContext.new(**context) }
|
448
|
-
|
449
|
-
column name: 'ID',
|
450
|
-
value: ->(row, *) { row.id }
|
451
|
-
|
452
|
-
column name: 'Name',
|
453
|
-
value: ->(row, *) { row.name }
|
454
|
-
|
455
|
-
columns name: ['Pet 1', 'Pet 2', 'Pet 3'],
|
456
|
-
value: ->(row, *) { row.more_pets }
|
457
|
-
|
458
|
-
columns ->(table) {
|
459
|
-
table.questions.map do |question|
|
460
|
-
{
|
461
|
-
name: question[:id],
|
462
|
-
value: ->(row, *) { row.answers[question[:id]] }
|
463
|
-
}
|
464
|
-
end
|
465
|
-
}
|
466
|
-
end
|
467
|
-
```
|
468
|
-
|
469
|
-
## Sample with docker
|
470
|
-
|
471
|
-
https://github.com/jsmmr/ruby_table_structure_sample
|
472
|
-
|
473
479
|
## Contributing
|
474
480
|
|
475
481
|
Bug reports and pull requests are welcome on GitHub at https://github.com/jsmmr/ruby_table_structure.
|
data/lib/table_structure.rb
CHANGED
@@ -5,33 +5,27 @@ module TableStructure
|
|
5
5
|
|
6
6
|
require 'table_structure/version'
|
7
7
|
require 'forwardable'
|
8
|
+
require 'table_structure/utils'
|
8
9
|
require 'table_structure/schema'
|
9
10
|
require 'table_structure/schema/class_methods'
|
10
|
-
require 'table_structure/schema/
|
11
|
+
require 'table_structure/schema/composite_class'
|
12
|
+
require 'table_structure/schema/dsl/column_builder'
|
11
13
|
require 'table_structure/schema/dsl/column_definition'
|
12
14
|
require 'table_structure/schema/dsl/context_builder'
|
13
|
-
require 'table_structure/schema/dsl/option'
|
14
15
|
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
16
|
require 'table_structure/schema/definition/columns/compiler'
|
19
17
|
require 'table_structure/schema/definition/columns/error'
|
20
18
|
require 'table_structure/schema/definition/columns/validator'
|
21
19
|
require 'table_structure/schema/definition/columns/attributes'
|
22
20
|
require 'table_structure/schema/definition/columns/schema_class'
|
23
21
|
require 'table_structure/schema/definition/columns/schema_instance'
|
24
|
-
require 'table_structure/schema/
|
25
|
-
require 'table_structure/schema/
|
26
|
-
require 'table_structure/schema/
|
22
|
+
require 'table_structure/schema/column_builder_factory'
|
23
|
+
require 'table_structure/schema/keys_builder'
|
24
|
+
require 'table_structure/schema/row_context_builder_factory'
|
27
25
|
require 'table_structure/schema/columns/attributes'
|
28
26
|
require 'table_structure/schema/columns/schema'
|
29
27
|
require 'table_structure/schema/utils'
|
30
28
|
require 'table_structure/table'
|
31
|
-
require 'table_structure/table/column_converter'
|
32
|
-
require 'table_structure/table/context_builder'
|
33
|
-
require 'table_structure/table/row_builder'
|
34
|
-
require 'table_structure/table/iterator'
|
35
29
|
require 'table_structure/writer'
|
36
30
|
require 'table_structure/csv/writer'
|
37
31
|
require 'table_structure/iterator'
|
@@ -9,32 +9,19 @@ module TableStructure
|
|
9
9
|
schema,
|
10
10
|
bom: false,
|
11
11
|
csv_options: {},
|
12
|
-
header: { context: nil }
|
13
|
-
**deprecated_options
|
12
|
+
header: { context: nil, step: nil }
|
14
13
|
)
|
15
|
-
if deprecated_options.key?(:header_omitted)
|
16
|
-
header_omitted = deprecated_options[:header_omitted]
|
17
|
-
warn "[TableStructure] `header_omitted: #{!!header_omitted}` option has been deprecated. Use `header: #{!header_omitted}` option instead."
|
18
|
-
header = !header_omitted
|
19
|
-
end
|
20
|
-
|
21
|
-
if deprecated_options.key?(:header_context)
|
22
|
-
header_context = deprecated_options[:header_context]
|
23
|
-
warn '[TableStructure] `:header_context` option has been deprecated. Use `header: { context: ... }` option instead.'
|
24
|
-
header = { context: header_context }
|
25
|
-
end
|
26
|
-
|
27
14
|
require 'csv'
|
28
15
|
|
29
16
|
@options = {
|
30
17
|
bom: bom,
|
31
18
|
csv_options: csv_options
|
32
19
|
}
|
33
|
-
|
20
|
+
inner_options = {
|
34
21
|
header: header
|
35
22
|
}
|
36
23
|
|
37
|
-
@writer = ::TableStructure::Writer.new(schema,
|
24
|
+
@writer = ::TableStructure::Writer.new(schema, **inner_options)
|
38
25
|
end
|
39
26
|
|
40
27
|
def write(
|
@@ -42,36 +29,12 @@ module TableStructure
|
|
42
29
|
to:,
|
43
30
|
bom: @options[:bom],
|
44
31
|
csv_options: @options[:csv_options],
|
45
|
-
**deprecated_options,
|
46
32
|
&block
|
47
33
|
)
|
48
|
-
header = @inner_options[:header]
|
49
|
-
|
50
|
-
if deprecated_options.key?(:header)
|
51
|
-
header = deprecated_options[:header]
|
52
|
-
warn '[TableStructure] Specify :header option as an argument for initialize method.'
|
53
|
-
end
|
54
|
-
|
55
|
-
if deprecated_options.key?(:header_omitted)
|
56
|
-
header_omitted = deprecated_options[:header_omitted]
|
57
|
-
warn "[TableStructure] `header_omitted: #{!!header_omitted}` option has been deprecated. Use `header: #{!header_omitted}` option instead."
|
58
|
-
header = !header_omitted
|
59
|
-
end
|
60
|
-
|
61
|
-
if deprecated_options.key?(:header_context)
|
62
|
-
header_context = deprecated_options[:header_context]
|
63
|
-
warn '[TableStructure] `:header_context` option has been deprecated. Use `header: { context: ... }` option instead.'
|
64
|
-
header = { context: header_context }
|
65
|
-
end
|
66
|
-
|
67
|
-
inner_options = {
|
68
|
-
header: header
|
69
|
-
}
|
70
|
-
|
71
34
|
to << BOM if bom
|
72
35
|
|
73
36
|
csv = ::CSV.new(to, **csv_options)
|
74
|
-
@writer.write(items, to: csv,
|
37
|
+
@writer.write(items, to: csv, &block)
|
75
38
|
end
|
76
39
|
end
|
77
40
|
end
|