honey_format 0.20.0 → 0.24.0
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/CHANGELOG.md +27 -0
- data/README.md +54 -2
- data/honey_format.gemspec +1 -1
- data/lib/honey_format/configuration.rb +1 -28
- data/lib/honey_format/converters/convert_boolean.rb +2 -2
- data/lib/honey_format/converters/convert_date_and_time.rb +2 -2
- data/lib/honey_format/converters/convert_string.rb +9 -1
- data/lib/honey_format/converters/converters.rb +33 -0
- data/lib/honey_format/matrix/matrix.rb +8 -1
- data/lib/honey_format/matrix/row_builder.rb +5 -1
- data/lib/honey_format/matrix/rows.rb +14 -1
- data/lib/honey_format/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e7b05a5cbde9ef4df67f043ff78e75c545563faa02333c57c97f70f1adec0f9
|
4
|
+
data.tar.gz: 91275865eabfd283c22ef0507a76b0c433d64a36c2ab68d92501548b982a00c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5904b276f295163855c1d74f7afa27568572e50583ec54532e571f70eb59ce06648e60a0e0d29806289d7126b8d0a9351acdd746967c247db03004cec3c4356
|
7
|
+
data.tar.gz: e498be3c0e31e594cc42d2186404d367564111d70d2fffbe0011d0ea208e5f217ff8416061f12cbdff5137b3075e1f09d857b2dd189d785b865381d02c429d07
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# HEAD
|
2
2
|
|
3
|
+
## v0.24.0
|
4
|
+
|
5
|
+
* Add support for multiple/chained converters. [PR#69](https://github.com/buren/honey_format/pull/69)
|
6
|
+
```ruby
|
7
|
+
csv_string = "Id,Username\n1, BuRen "
|
8
|
+
type_map = { username: [:strip, :downcase] }
|
9
|
+
csv = HoneyFormat::CSV.new(csv_string, type_map: type_map)
|
10
|
+
csv.rows.first.username # => "buren"
|
11
|
+
```
|
12
|
+
* Add `strip` and `strip!` converter
|
13
|
+
|
14
|
+
## v0.23.0
|
15
|
+
|
16
|
+
* Add `Rows#columns` method that returns header columns
|
17
|
+
|
18
|
+
## v0.22.0
|
19
|
+
|
20
|
+
* Add `Matrix#type_map` and ignore non-existing column in the type map. [PR#64](https://github.com/buren/honey_format/pull/64). Thank you [@prem-prakash](https://github.com/prem-prakash).
|
21
|
+
|
22
|
+
## v0.21.1
|
23
|
+
|
24
|
+
* Closes [issue #58](https://github.com/buren/honey_format/issues/58). [PR #62](https://github.com/buren/honey_format/pull/62)
|
25
|
+
|
26
|
+
## v0.21.0
|
27
|
+
|
28
|
+
* Add `Rows#[]` method
|
29
|
+
|
3
30
|
## v0.20.0
|
4
31
|
|
5
32
|
* Support additional header variant, pass hash with `String => Symbol` and/or `String => #call` (callable object). Unmapped keys are converted using the default header converter.
|
data/README.md
CHANGED
@@ -91,7 +91,7 @@ __Type converters__
|
|
91
91
|
|
92
92
|
> Type converters are great if you want to convert column values, like numbers and dates.
|
93
93
|
|
94
|
-
There are a
|
94
|
+
There are a bunch of [default type converters](https://github.com/buren/honey_format/blob/master/lib/honey_format/converters/converters.rb)
|
95
95
|
```ruby
|
96
96
|
csv_string = "Id,Username\n1,buren"
|
97
97
|
type_map = { id: :integer }
|
@@ -107,6 +107,14 @@ csv = HoneyFormat::CSV.new(csv_string, type_map: type_map)
|
|
107
107
|
csv.rows.first.username # => "BUREN"
|
108
108
|
```
|
109
109
|
|
110
|
+
Combine multiple converters
|
111
|
+
```ruby
|
112
|
+
csv_string = "Id,Username\n1, BuRen "
|
113
|
+
type_map = { username: [:strip, :downcase] }
|
114
|
+
csv = HoneyFormat::CSV.new(csv_string, type_map: type_map)
|
115
|
+
csv.rows.first.username # => "buren"
|
116
|
+
```
|
117
|
+
|
110
118
|
Register your own converter
|
111
119
|
```ruby
|
112
120
|
HoneyFormat.configure do |config|
|
@@ -139,7 +147,7 @@ Default converter names
|
|
139
147
|
HoneyFormat.config.default_converters.keys
|
140
148
|
```
|
141
149
|
|
142
|
-
See [`
|
150
|
+
See [`Converters::DEFAULT`](https://github.com/buren/honey_format/blob/master/lib/honey_format/converters.rb) for a complete list of the default converter names.
|
143
151
|
|
144
152
|
__Row builder__
|
145
153
|
|
@@ -376,6 +384,50 @@ matrix.to_csv # => "name,id\nJACOB,1\n"
|
|
376
384
|
|
377
385
|
If you want to see more usage examples check out the [`examples/`](https://github.com/buren/honey_format/tree/master/examples) and [`spec/`](https://github.com/buren/honey_format/tree/master/spec) directories and of course [on RubyDoc](https://www.rubydoc.info/gems/honey_format/).
|
378
386
|
|
387
|
+
|
388
|
+
__SQL example__
|
389
|
+
|
390
|
+
When you want the result as an object, with certain columns converted to objects.
|
391
|
+
|
392
|
+
```ruby
|
393
|
+
require 'mysql2'
|
394
|
+
|
395
|
+
class DBClient
|
396
|
+
def initialize(host:, username:, password:, port: 3306)
|
397
|
+
@client = Mysql2::Client.new(
|
398
|
+
host: host,
|
399
|
+
username: username,
|
400
|
+
password: password,
|
401
|
+
port: port
|
402
|
+
)
|
403
|
+
end
|
404
|
+
|
405
|
+
def query(sql, type_map: {})
|
406
|
+
result = @client.query(sql)
|
407
|
+
return if result.first.nil?
|
408
|
+
|
409
|
+
matrix = HoneyFormat::Matrix.new(
|
410
|
+
result.map(&:values),
|
411
|
+
header: result.first.keys,
|
412
|
+
type_map: type_map
|
413
|
+
)
|
414
|
+
matrix.rows
|
415
|
+
end
|
416
|
+
end
|
417
|
+
```
|
418
|
+
|
419
|
+
Usage example with a fictional "users" database table (schema: `name`, `created_at`)
|
420
|
+
```ruby
|
421
|
+
client = DbClient.new(host: '127.0.0.1', username: 'root', password: nil)
|
422
|
+
users = client.query(
|
423
|
+
'SELECT * FROM users',
|
424
|
+
type_map: { created_at: :datetime! }
|
425
|
+
)
|
426
|
+
user = users.first
|
427
|
+
user.name # => buren
|
428
|
+
user.created_at.class # => Time
|
429
|
+
```
|
430
|
+
|
379
431
|
## CLI
|
380
432
|
|
381
433
|
> Perfect when you want to get something simple done quickly.
|
data/honey_format.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency 'benchmark-ips'
|
26
26
|
spec.add_development_dependency 'bundler', '> 1.10', '< 3'
|
27
27
|
spec.add_development_dependency 'byebug'
|
28
|
-
spec.add_development_dependency 'rake', '~>
|
28
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
29
29
|
spec.add_development_dependency 'rspec'
|
30
30
|
spec.add_development_dependency 'simplecov'
|
31
31
|
end
|
@@ -97,34 +97,7 @@ module HoneyFormat
|
|
97
97
|
# Default converter registry
|
98
98
|
# @return [Hash] hash with default converters
|
99
99
|
def default_converters
|
100
|
-
@default_converters ||=
|
101
|
-
# strict variants
|
102
|
-
decimal!: StrictConvertDecimal,
|
103
|
-
integer!: StrictConvertInteger,
|
104
|
-
date!: StrictConvertDate,
|
105
|
-
datetime!: StrictConvertDatetime,
|
106
|
-
symbol!: StrictConvertSymbol,
|
107
|
-
downcase!: StrictConvertDowncase,
|
108
|
-
upcase!: StrictConvertUpcase,
|
109
|
-
boolean!: StrictConvertBoolean,
|
110
|
-
# safe variants
|
111
|
-
decimal: ConvertDecimal,
|
112
|
-
decimal_or_zero: ConvertDecimalOrZero,
|
113
|
-
integer: ConvertInteger,
|
114
|
-
integer_or_zero: ConvertIntegerOrZero,
|
115
|
-
date: ConvertDate,
|
116
|
-
datetime: ConvertDatetime,
|
117
|
-
symbol: ConvertSymbol,
|
118
|
-
downcase: ConvertDowncase,
|
119
|
-
upcase: ConvertUpcase,
|
120
|
-
boolean: ConvertBoolean,
|
121
|
-
md5: ConvertMD5,
|
122
|
-
hex: ConvertHex,
|
123
|
-
nil: ConvertNil,
|
124
|
-
blank: ConvertBlank,
|
125
|
-
header_column: ConvertHeaderColumn,
|
126
|
-
method_name: ConvertHeaderColumn,
|
127
|
-
}.freeze
|
100
|
+
@default_converters ||= Converters::DEFAULT
|
128
101
|
end
|
129
102
|
end
|
130
103
|
end
|
@@ -4,9 +4,9 @@ require 'set'
|
|
4
4
|
|
5
5
|
module HoneyFormat
|
6
6
|
# String values considered truthy
|
7
|
-
TRUTHY = Set.new(%w[t T 1 y Y true TRUE]).freeze
|
7
|
+
TRUTHY = Set.new(%w[t T 1 y Y true TRUE] + [true]).freeze
|
8
8
|
# String values considered falsy
|
9
|
-
FALSY = Set.new(%w[f F 0 n N false FALSE]).freeze
|
9
|
+
FALSY = Set.new(%w[f F 0 n N false FALSE] + [false]).freeze
|
10
10
|
|
11
11
|
# Tries to convert value boolean to, returns nil if it can't convert
|
12
12
|
ConvertBoolean = proc do |v|
|
@@ -23,8 +23,8 @@ module HoneyFormat
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# Convert to date or raise error
|
26
|
-
StrictConvertDate = proc { |v| Date.parse(v) }
|
26
|
+
StrictConvertDate = proc { |v| v.is_a?(Date) ? v : Date.parse(v) }
|
27
27
|
|
28
28
|
# Convert to datetime or raise error
|
29
|
-
StrictConvertDatetime = proc { |v| Time.parse(v) }
|
29
|
+
StrictConvertDatetime = proc { |v| v.is_a?(Time) ? v : Time.parse(v) }
|
30
30
|
end
|
@@ -10,6 +10,9 @@ module HoneyFormat
|
|
10
10
|
# Convert to upcase or nil
|
11
11
|
ConvertUpcase = proc { |v| v&.upcase }
|
12
12
|
|
13
|
+
# Convert to stripped string
|
14
|
+
ConvertStrip = proc { |v| v&.strip }
|
15
|
+
|
13
16
|
# Convert to symbol or nil
|
14
17
|
ConvertSymbol = proc { |v| v&.to_sym }
|
15
18
|
|
@@ -35,8 +38,13 @@ module HoneyFormat
|
|
35
38
|
ConvertDowncase.call(v) || raise(ArgumentError, "can't convert nil to downcased string")
|
36
39
|
end
|
37
40
|
|
41
|
+
# Convert to downcase or raise error
|
42
|
+
StrictConvertStrip = proc do |v|
|
43
|
+
ConvertStrip.call(v) || raise(ArgumentError, "can't convert nil to downcased string")
|
44
|
+
end
|
45
|
+
|
38
46
|
# Convert to symbol or raise error
|
39
47
|
StrictConvertSymbol = proc do |v|
|
40
|
-
ConvertSymbol.call(v) || raise(ArgumentError, "can't convert nil to
|
48
|
+
ConvertSymbol.call(v) || raise(ArgumentError, "can't convert nil to stripped string")
|
41
49
|
end
|
42
50
|
end
|
@@ -9,4 +9,37 @@ require 'honey_format/converters/convert_string'
|
|
9
9
|
module HoneyFormat
|
10
10
|
# Convert to nil
|
11
11
|
ConvertNil = proc {}
|
12
|
+
|
13
|
+
module Converters
|
14
|
+
DEFAULT = {
|
15
|
+
# strict variants
|
16
|
+
decimal!: StrictConvertDecimal,
|
17
|
+
integer!: StrictConvertInteger,
|
18
|
+
date!: StrictConvertDate,
|
19
|
+
datetime!: StrictConvertDatetime,
|
20
|
+
symbol!: StrictConvertSymbol,
|
21
|
+
downcase!: StrictConvertDowncase,
|
22
|
+
upcase!: StrictConvertUpcase,
|
23
|
+
strip!: StrictConvertStrip,
|
24
|
+
boolean!: StrictConvertBoolean,
|
25
|
+
# safe variants
|
26
|
+
decimal: ConvertDecimal,
|
27
|
+
decimal_or_zero: ConvertDecimalOrZero,
|
28
|
+
integer: ConvertInteger,
|
29
|
+
integer_or_zero: ConvertIntegerOrZero,
|
30
|
+
date: ConvertDate,
|
31
|
+
datetime: ConvertDatetime,
|
32
|
+
symbol: ConvertSymbol,
|
33
|
+
downcase: ConvertDowncase,
|
34
|
+
upcase: ConvertUpcase,
|
35
|
+
strip: ConvertStrip,
|
36
|
+
boolean: ConvertBoolean,
|
37
|
+
md5: ConvertMD5,
|
38
|
+
hex: ConvertHex,
|
39
|
+
nil: ConvertNil,
|
40
|
+
blank: ConvertBlank,
|
41
|
+
header_column: ConvertHeaderColumn,
|
42
|
+
method_name: ConvertHeaderColumn,
|
43
|
+
}.freeze
|
44
|
+
end
|
12
45
|
end
|
@@ -51,7 +51,8 @@ module HoneyFormat
|
|
51
51
|
converter: header_converter,
|
52
52
|
deduplicator: header_deduplicator
|
53
53
|
)
|
54
|
-
@
|
54
|
+
@type_map = type_map.select { |key, _v| @header.columns.include?(key) }.to_h
|
55
|
+
@rows = Rows.new(matrix, columns, builder: row_builder, type_map: @type_map)
|
55
56
|
end
|
56
57
|
|
57
58
|
# Original matrix header
|
@@ -66,6 +67,12 @@ module HoneyFormat
|
|
66
67
|
@header.to_a
|
67
68
|
end
|
68
69
|
|
70
|
+
# Matrix type map used
|
71
|
+
# @return [Hash<Symbol, Symbol>] the type map used.
|
72
|
+
def type_map
|
73
|
+
@type_map
|
74
|
+
end
|
75
|
+
|
69
76
|
# Return rows
|
70
77
|
# @return [Rows] rows.
|
71
78
|
def rows
|
@@ -57,7 +57,11 @@ module HoneyFormat
|
|
57
57
|
|
58
58
|
# Convert values
|
59
59
|
@type_map.each do |column, type|
|
60
|
-
|
60
|
+
types = type.respond_to?(:each) ? type : [type]
|
61
|
+
value = row[column]
|
62
|
+
types.each { |t| value = @converter.call(value, t) }
|
63
|
+
|
64
|
+
row[column] = value
|
61
65
|
end
|
62
66
|
|
63
67
|
return row unless @builder
|
@@ -16,10 +16,17 @@ module HoneyFormat
|
|
16
16
|
# @raise [EmptyRowColumnsError] raised when there are no columns.
|
17
17
|
# @raise [InvalidRowLengthError] raised when row has more columns than header columns.
|
18
18
|
def initialize(rows, columns, builder: nil, type_map: {})
|
19
|
-
|
19
|
+
@columns = columns
|
20
|
+
builder = RowBuilder.new(@columns, builder: builder, type_map: type_map)
|
20
21
|
@rows = prepare_rows(builder, rows)
|
21
22
|
end
|
22
23
|
|
24
|
+
# Row columns
|
25
|
+
# @return [Array<Symbol>] of column identifiers.
|
26
|
+
def columns
|
27
|
+
@columns
|
28
|
+
end
|
29
|
+
|
23
30
|
# Returns true if rows contains no elements.
|
24
31
|
# @return [true, false] true if rows contains no elements.
|
25
32
|
def empty?
|
@@ -40,6 +47,12 @@ module HoneyFormat
|
|
40
47
|
@rows
|
41
48
|
end
|
42
49
|
|
50
|
+
# Return element at given position.
|
51
|
+
# @return [Row] of rows.
|
52
|
+
def [](index)
|
53
|
+
@rows[index]
|
54
|
+
end
|
55
|
+
|
43
56
|
# Return the number of rows
|
44
57
|
# @return [Integer] the number of rows
|
45
58
|
def length
|
data/lib/honey_format/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: honey_format
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Burenstam
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|
@@ -64,14 +64,14 @@ dependencies:
|
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
67
|
+
version: '12.3'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
74
|
+
version: '12.3'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: rspec
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
168
|
- !ruby/object:Gem::Version
|
169
169
|
version: '0'
|
170
170
|
requirements: []
|
171
|
-
rubygems_version: 3.
|
171
|
+
rubygems_version: 3.1.4
|
172
172
|
signing_key:
|
173
173
|
specification_version: 4
|
174
174
|
summary: Makes working with CSVs as smooth as honey.
|