table_structure 0.3.21 → 0.3.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +2 -2
- data/README.md +77 -71
- data/lib/table_structure/schema/column_converter.rb +6 -8
- data/lib/table_structure/schema/definition/column_converter.rb +3 -3
- data/lib/table_structure/schema/definition/context_builder.rb +2 -2
- data/lib/table_structure/schema/definition/row_builder.rb +3 -3
- data/lib/table_structure/schema/dsl/column_converter.rb +11 -4
- data/lib/table_structure/schema/dsl/context_builder.rb +9 -2
- data/lib/table_structure/schema/dsl/row_builder.rb +11 -4
- data/lib/table_structure/schema/row_builder.rb +3 -4
- data/lib/table_structure/table/context_builder.rb +1 -1
- data/lib/table_structure/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae9b604db5214e4001824da3583481ad03b93e22785b6c7819874cd546b65025
|
4
|
+
data.tar.gz: 5883b75571629c06eb71f7b06ffb0923c1ce2660113f9804eaeaf0ecd8d94ce6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2839f25ac4d152627f70dd733a01f49b92a8c07bfcdf43c0b67fcc2891a105f136570e272c93580c5f68c869b20808c92edc56bb4c5aa836f07288dea9eac75a
|
7
|
+
data.tar.gz: 1e49f3a7400bb993eafd7c24fa2622ece9aa1edb480b921179c92d4579f65e5316579c9606f522d9cdfc7d8e9f38b4e71693fd9edc52788996b8ba9f24af2122
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# 0.3.22
|
2
|
+
Changes:
|
3
|
+
- `TableStructure::Schema`
|
4
|
+
- DSL
|
5
|
+
- `column_converter`
|
6
|
+
- Using `lambda` has been deprecated. Use `block` instead.
|
7
|
+
- `context_builder`
|
8
|
+
- Using `lambda` has been deprecated. Use `block` instead.
|
9
|
+
|
1
10
|
# 0.3.21
|
2
11
|
Changes:
|
3
12
|
- Add `TableStructure::Table`
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
table_structure (0.3.
|
4
|
+
table_structure (0.3.22)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -14,7 +14,7 @@ GEM
|
|
14
14
|
rspec-mocks (~> 3.9.0)
|
15
15
|
rspec-core (3.9.1)
|
16
16
|
rspec-support (~> 3.9.1)
|
17
|
-
rspec-expectations (3.9.
|
17
|
+
rspec-expectations (3.9.1)
|
18
18
|
diff-lcs (>= 1.2.0, < 2.0)
|
19
19
|
rspec-support (~> 3.9.0)
|
20
20
|
rspec-mocks (3.9.1)
|
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
|
|
@@ -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
|
|
@@ -272,7 +271,9 @@ class UserTableSchema
|
|
272
271
|
end
|
273
272
|
|
274
273
|
schema = UserTableSchema.new do
|
275
|
-
column_converter :to_s
|
274
|
+
column_converter :to_s do |val, *|
|
275
|
+
val.to_s
|
276
|
+
end
|
276
277
|
end
|
277
278
|
```
|
278
279
|
|
@@ -324,53 +325,91 @@ context = { pet_num: 0 }
|
|
324
325
|
schema = SampleTableSchema.new(context: context, nil_definitions_ignored: true)
|
325
326
|
```
|
326
327
|
|
327
|
-
You can also
|
328
|
+
You can also use `context_builder` to change the context object that the `lambda` receives.
|
328
329
|
```ruby
|
329
|
-
class
|
330
|
+
class SampleTableSchema
|
330
331
|
include TableStructure::Schema
|
331
332
|
|
333
|
+
TableContext = Struct.new(:questions, keyword_init: true)
|
334
|
+
|
335
|
+
RowContext = Struct.new(:id, :name, :pets, :answers, keyword_init: true) do
|
336
|
+
def increase_pets
|
337
|
+
pets + pets
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
context_builder :table do |context|
|
342
|
+
TableContext.new(**context)
|
343
|
+
end
|
344
|
+
|
345
|
+
context_builder :row, :value do |context|
|
346
|
+
RowContext.new(**context)
|
347
|
+
end
|
348
|
+
|
332
349
|
column name: 'ID',
|
333
|
-
value: ->(row, *) { row
|
350
|
+
value: ->(row, *) { row.id }
|
334
351
|
|
335
352
|
column name: 'Name',
|
336
|
-
value: ->(row, *) { row
|
337
|
-
end
|
338
|
-
|
339
|
-
class PetTableSchema
|
340
|
-
include TableStructure::Schema
|
353
|
+
value: ->(row, *) { row.name }
|
341
354
|
|
342
355
|
columns name: ['Pet 1', 'Pet 2', 'Pet 3'],
|
343
|
-
value: ->(row, *) { row
|
344
|
-
end
|
345
|
-
|
346
|
-
class QuestionTableSchema
|
347
|
-
include TableStructure::Schema
|
356
|
+
value: ->(row, *) { row.increase_pets }
|
348
357
|
|
349
358
|
columns ->(table) {
|
350
|
-
table
|
359
|
+
table.questions.map do |question|
|
351
360
|
{
|
352
361
|
name: question[:id],
|
353
|
-
value: ->(row, *) { row
|
362
|
+
value: ->(row, *) { row.answers[question[:id]] }
|
354
363
|
}
|
355
364
|
end
|
356
365
|
}
|
357
366
|
end
|
367
|
+
```
|
368
|
+
|
369
|
+
You can also nest the schemas.
|
370
|
+
If you nest the schemas and use `row_type: :hash`, `:key` must be unique in the schemas.
|
371
|
+
You can also use `:key_prefix` or `:key_suffix` option to keep uniqueness of the keys.
|
372
|
+
|
373
|
+
```ruby
|
374
|
+
class UserTableSchema
|
375
|
+
include TableStructure::Schema
|
376
|
+
|
377
|
+
column name: 'ID',
|
378
|
+
key: :id,
|
379
|
+
value: ->(row, *) { row[:id] }
|
380
|
+
|
381
|
+
column name: 'Name',
|
382
|
+
key: :name,
|
383
|
+
value: ->(row, *) { row[:name] }
|
384
|
+
end
|
358
385
|
|
359
386
|
class SampleTableSchema
|
360
387
|
include TableStructure::Schema
|
361
388
|
|
362
389
|
columns UserTableSchema
|
363
|
-
## or
|
364
|
-
# columns ->(table) { UserTableSchema.new(context: table) }
|
365
|
-
|
366
|
-
columns PetTableSchema
|
367
|
-
## or
|
368
|
-
# columns ->(table) { PetTableSchema.new(context: table) }
|
369
390
|
|
370
|
-
columns
|
371
|
-
|
372
|
-
|
391
|
+
columns ->(table) {
|
392
|
+
UserTableSchema.new(context: table, name_prefix: 'Friend ', key_prefix: 'friend_') do
|
393
|
+
context_builder :row do |context|
|
394
|
+
context[:friend]
|
395
|
+
end
|
396
|
+
end
|
397
|
+
}
|
373
398
|
end
|
399
|
+
|
400
|
+
items = [
|
401
|
+
{
|
402
|
+
id: 1,
|
403
|
+
name: 'Taro',
|
404
|
+
friend: {
|
405
|
+
id: 2,
|
406
|
+
name: 'Hanako'
|
407
|
+
}
|
408
|
+
}
|
409
|
+
]
|
410
|
+
|
411
|
+
schema = SampleTableSchema.new(context: {})
|
412
|
+
TableStructure::Iterator.new(schema, row_type: :hash).iterate(items)
|
374
413
|
```
|
375
414
|
|
376
415
|
You can also concatenate or merge the schema classes.
|
@@ -398,7 +437,9 @@ class PetTableSchema
|
|
398
437
|
columns name: ['Pet 1', 'Pet 2', 'Pet 3'],
|
399
438
|
value: ->(row, *) { row[:pets] }
|
400
439
|
|
401
|
-
column_converter :same_name
|
440
|
+
column_converter :same_name do |val, *|
|
441
|
+
"pet: #{val}"
|
442
|
+
end
|
402
443
|
end
|
403
444
|
|
404
445
|
class QuestionTableSchema
|
@@ -413,7 +454,9 @@ class QuestionTableSchema
|
|
413
454
|
end
|
414
455
|
}
|
415
456
|
|
416
|
-
column_converter :same_name
|
457
|
+
column_converter :same_name do |val, *|
|
458
|
+
"question: #{val}"
|
459
|
+
end
|
417
460
|
end
|
418
461
|
|
419
462
|
context = {
|
@@ -429,43 +472,6 @@ concatenated_schema = (UserTableSchema + PetTableSchema + QuestionTableSchema).n
|
|
429
472
|
merged_schema = UserTableSchema.merge(PetTableSchema, QuestionTableSchema).new(context: context)
|
430
473
|
```
|
431
474
|
|
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
475
|
## Sample with docker
|
470
476
|
|
471
477
|
https://github.com/jsmmr/ruby_table_structure_sample
|
@@ -27,20 +27,18 @@ module TableStructure
|
|
27
27
|
|
28
28
|
def create_prepender(string, **options)
|
29
29
|
Definition::ColumnConverter.new(
|
30
|
-
lambda { |val, *|
|
31
|
-
val.nil? ? val : "#{string}#{val}"
|
32
|
-
},
|
33
30
|
**options
|
34
|
-
)
|
31
|
+
) do |val, *|
|
32
|
+
val.nil? ? val : "#{string}#{val}"
|
33
|
+
end
|
35
34
|
end
|
36
35
|
|
37
36
|
def create_appender(string, **options)
|
38
37
|
Definition::ColumnConverter.new(
|
39
|
-
lambda { |val, *|
|
40
|
-
val.nil? ? val : "#{val}#{string}"
|
41
|
-
},
|
42
38
|
**options
|
43
|
-
)
|
39
|
+
) do |val, *|
|
40
|
+
val.nil? ? val : "#{val}#{string}"
|
41
|
+
end
|
44
42
|
end
|
45
43
|
end
|
46
44
|
end
|
@@ -9,13 +9,13 @@ module TableStructure
|
|
9
9
|
def_delegator :@callable, :call
|
10
10
|
|
11
11
|
def initialize(
|
12
|
-
callable,
|
13
12
|
header: true,
|
14
|
-
body: true
|
13
|
+
body: true,
|
14
|
+
&block
|
15
15
|
)
|
16
|
-
@callable = callable
|
17
16
|
@applicable_to_header = header
|
18
17
|
@applicable_to_body = body
|
18
|
+
@callable = block
|
19
19
|
end
|
20
20
|
|
21
21
|
def applicable_to_header?
|
@@ -9,11 +9,11 @@ module TableStructure
|
|
9
9
|
def_delegator :@callable, :call
|
10
10
|
|
11
11
|
def initialize(
|
12
|
-
|
13
|
-
|
12
|
+
enabled_row_types: %i[array hash],
|
13
|
+
&block
|
14
14
|
)
|
15
|
-
@callable = callable
|
16
15
|
@enabled_row_types = [enabled_row_types].flatten
|
16
|
+
@callable = block
|
17
17
|
end
|
18
18
|
|
19
19
|
def enabled?(row_type)
|
@@ -6,21 +6,28 @@ module TableStructure
|
|
6
6
|
module ColumnConverter
|
7
7
|
def column_converter(
|
8
8
|
name,
|
9
|
-
callable,
|
9
|
+
callable = nil,
|
10
10
|
header: true,
|
11
11
|
body: true,
|
12
|
-
**deprecated_options
|
12
|
+
**deprecated_options,
|
13
|
+
&block
|
13
14
|
)
|
14
15
|
if deprecated_options.key?(:row)
|
15
16
|
warn '[TableStructure] `:row` option has been deprecated. Use `:body` option instead.'
|
16
17
|
body = deprecated_options[:row]
|
17
18
|
end
|
18
19
|
|
20
|
+
if callable
|
21
|
+
warn "[TableStructure] Use `block` instead of #{callable}."
|
22
|
+
end
|
23
|
+
|
24
|
+
block ||= callable
|
25
|
+
|
19
26
|
column_converters[name] =
|
20
27
|
::TableStructure::Schema::Definition::ColumnConverter.new(
|
21
|
-
callable,
|
22
28
|
header: header,
|
23
|
-
body: body
|
29
|
+
body: body,
|
30
|
+
&block
|
24
31
|
)
|
25
32
|
nil
|
26
33
|
end
|
@@ -4,10 +4,17 @@ module TableStructure
|
|
4
4
|
module Schema
|
5
5
|
module DSL
|
6
6
|
module ContextBuilder
|
7
|
-
|
7
|
+
# TODO: Change definition style
|
8
|
+
def context_builder(name, callable = nil, &block)
|
9
|
+
if callable
|
10
|
+
warn "[TableStructure] Use `block` instead of #{callable}."
|
11
|
+
end
|
12
|
+
|
13
|
+
block ||= callable
|
14
|
+
|
8
15
|
context_builders[name] =
|
9
16
|
::TableStructure::Schema::Definition::ContextBuilder.new(
|
10
|
-
|
17
|
+
&block
|
11
18
|
)
|
12
19
|
nil
|
13
20
|
end
|
@@ -6,13 +6,20 @@ module TableStructure
|
|
6
6
|
module RowBuilder
|
7
7
|
def row_builder(
|
8
8
|
name,
|
9
|
-
callable,
|
10
|
-
enabled_row_types: %i[array hash]
|
9
|
+
callable = nil,
|
10
|
+
enabled_row_types: %i[array hash],
|
11
|
+
&block
|
11
12
|
)
|
13
|
+
if callable
|
14
|
+
warn "[TableStructure] Use `block` instead of #{callable}."
|
15
|
+
end
|
16
|
+
|
17
|
+
block ||= callable
|
18
|
+
|
12
19
|
row_builders[name] =
|
13
20
|
::TableStructure::Schema::Definition::RowBuilder.new(
|
14
|
-
|
15
|
-
|
21
|
+
enabled_row_types: enabled_row_types,
|
22
|
+
&block
|
16
23
|
)
|
17
24
|
nil
|
18
25
|
end
|
@@ -5,11 +5,10 @@ module TableStructure
|
|
5
5
|
module RowBuilder
|
6
6
|
DEFAULT_ROW_BUILDERS = {
|
7
7
|
_to_hash_: Definition::RowBuilder.new(
|
8
|
-
lambda { |values, keys, *|
|
9
|
-
keys.map.with_index { |key, i| [key || i, values[i]] }.to_h
|
10
|
-
},
|
11
8
|
enabled_row_types: [:hash]
|
12
|
-
)
|
9
|
+
) do |values, keys, *|
|
10
|
+
keys.map.with_index { |key, i| [key || i, values[i]] }.to_h
|
11
|
+
end
|
13
12
|
}.freeze
|
14
13
|
|
15
14
|
class << self
|
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.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jsmmr
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|