honey_format 0.20.0 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c0136727f1cf1e473ac8a517105158a9c927c5988f525b1640ffced32c5a2fd
4
- data.tar.gz: d26d86cd08edbc33f2f9b8399ef2f7c5aade4b35ca4ea7617dc6a21415b72c9a
3
+ metadata.gz: 4e7b05a5cbde9ef4df67f043ff78e75c545563faa02333c57c97f70f1adec0f9
4
+ data.tar.gz: 91275865eabfd283c22ef0507a76b0c433d64a36c2ab68d92501548b982a00c8
5
5
  SHA512:
6
- metadata.gz: 6ec8850e11d3ae4039b748738641bacd19ea3ffe9f437e2d93eb407e9d7e7cb2dcc669116f04f2a175855fbc121bad62228dc6dbd022163d033a52e89af6e8e7
7
- data.tar.gz: 9ec609fe969d26348c1be54458a79ea24a199085381e82c3bc79d58b5054bb02300759946f520c7b29eb0273e56db290375c791ee4fb2c5fecf10da65954e54b
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 few default type converters
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 [`Configuration#default_converters`](https://github.com/buren/honey_format/blob/master/lib/honey_format/configuration.rb#L99) for a complete list of the default ones.
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', '~> 10.0'
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 symbol")
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
- @rows = Rows.new(matrix, columns, builder: row_builder, type_map: type_map)
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
- row[column] = @converter.call(row[column], type)
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
- builder = RowBuilder.new(columns, builder: builder, type_map: type_map)
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
@@ -4,7 +4,7 @@ module HoneyFormat
4
4
  # Gem version
5
5
  VERSION = [
6
6
  MAJOR_VERSION = 0,
7
- MINOR_VERSION = 20,
7
+ MINOR_VERSION = 24,
8
8
  PATCH_VERSION = 0,
9
9
  ].join('.')
10
10
  end
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.20.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: 2019-12-16 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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.0.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.