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