honey_format 0.21.1 → 0.25.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: dd0d06f453986109809c196cef032b5f60233e165a8d5e029162b26b6cc801b2
4
- data.tar.gz: 8f5a15f42e9f2587bc80b7e88d5c929d74a04ef69bd6be272513ba8fc544a22a
3
+ metadata.gz: bba6cf8014cc6cfa59c8519bbb2448d22800e3f5c3699629fd74132f5b615b82
4
+ data.tar.gz: d1e7dc2ed46e061edd4d473a267c5c1a0296fd58f080e7fecd878341364cb90f
5
5
  SHA512:
6
- metadata.gz: 563e6ba6a8ede49e13d15957c12c247b6e26c981afe25b150d6ae8c6c3dab58929c100341dcc0181790a03eabffca5ddd3ac127cf97fcdb4ac76ef04b01c9839
7
- data.tar.gz: 93a08cb9b2683961e80f8f2bb79f763f05fb1401e112458a6188bf86530233e93f9d397b0ee415e4ce9c8b95ff644485e50dc6b52a2c8381aa4379b0bce0e65a
6
+ metadata.gz: d67aad924dd6d89a56a2e36b1eb84ae2a30e68f71d717fc11c8be960fbf154b0061311105d814b8458b794c6f0a6f93d078fa91efd9c3f3845afcf87c9abfaa4
7
+ data.tar.gz: 2981c007e997cad9e8c58e9cdb4b22654b8f0443ef82345355919068b1bd804d278780808ba361f9077cf1e03bad649060b4474fba99de02a999bc9aea3e7efc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # HEAD
2
2
 
3
+ ## v0.25.0
4
+
5
+ * Add support for adding multiple `Rows` together, `Rows#+`
6
+
7
+ ## v0.24.0
8
+
9
+ * Add support for multiple/chained converters. [PR#69](https://github.com/buren/honey_format/pull/69)
10
+ ```ruby
11
+ csv_string = "Id,Username\n1, BuRen "
12
+ type_map = { username: [:strip, :downcase] }
13
+ csv = HoneyFormat::CSV.new(csv_string, type_map: type_map)
14
+ csv.rows.first.username # => "buren"
15
+ ```
16
+ * Add `strip` and `strip!` converter
17
+
18
+ ## v0.23.0
19
+
20
+ * Add `Rows#columns` method that returns header columns
21
+
22
+ ## v0.22.0
23
+
24
+ * 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).
25
+
3
26
  ## v0.21.1
4
27
 
5
28
  * Closes [issue #58](https://github.com/buren/honey_format/issues/58). [PR #62](https://github.com/buren/honey_format/pull/62)
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Jacob Burenstam Linder
3
+ Copyright (c) 2021 Jacob Burenstam Linder
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -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|
@@ -315,6 +323,13 @@ user.public_send(:"first^name") # => "Jacob"
315
323
  user['first^name'] # => "Jacob"
316
324
  ```
317
325
 
326
+ Emoji characters
327
+ ```ruby
328
+ csv_string = "😎⛷\nEmoji characters"
329
+ csv = HoneyFormat::CSV.new(csv_string)
330
+ csv.rows.first.😎⛷ # => Emoji characters
331
+ ```
332
+
318
333
  __Errors__
319
334
 
320
335
  > When you need to be extra safe.
@@ -376,6 +391,74 @@ matrix.to_csv # => "name,id\nJACOB,1\n"
376
391
 
377
392
  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
393
 
394
+
395
+ __SQL example__
396
+
397
+ When you want the result as an object, with certain columns converted to objects.
398
+
399
+ ```ruby
400
+ require 'mysql2'
401
+
402
+ class DBClient
403
+ def initialize(host:, username:, password:, port: 3306)
404
+ @client = Mysql2::Client.new(
405
+ host: host,
406
+ username: username,
407
+ password: password,
408
+ port: port
409
+ )
410
+ end
411
+
412
+ def query(sql, type_map: {})
413
+ result = @client.query(sql)
414
+ return if result.first.nil?
415
+
416
+ matrix = HoneyFormat::Matrix.new(
417
+ result.map(&:values),
418
+ header: result.first.keys,
419
+ type_map: type_map
420
+ )
421
+ matrix.rows
422
+ end
423
+ end
424
+ ```
425
+
426
+ Usage example with a fictional "users" database table (schema: `name`, `created_at`)
427
+ ```ruby
428
+ client = DbClient.new(host: '127.0.0.1', username: 'root', password: nil)
429
+ users = client.query(
430
+ 'SELECT * FROM users',
431
+ type_map: { created_at: :datetime! }
432
+ )
433
+ user = users.first
434
+ user.name # => buren
435
+ user.created_at.class # => Time
436
+ ```
437
+
438
+ ## Configuration
439
+
440
+ Configuration is optional
441
+ ```ruby
442
+ HoneyFormat.configure do |config|
443
+ config.header_converter = proc { |column| column.downcase }
444
+ config.delimiter = ";"
445
+ config.row_delimiter = "|"
446
+ config.quote_character = "'"
447
+ config.skip_lines = %r{\A#} # Match all lines that start with "#"
448
+ end
449
+ ```
450
+
451
+ Default configuration values
452
+ ```ruby
453
+ HoneyFormat.configure do |config|
454
+ config.header_converter = HoneyFormat::Registry.new(Converters::DEFAULT)[:header_column]
455
+ config.delimiter = ","
456
+ config.row_delimiter = :auto
457
+ config.quote_character = "\""
458
+ config.skip_lines = nil
459
+ end
460
+ ```
461
+
379
462
  ## CLI
380
463
 
381
464
  > Perfect when you want to get something simple done quickly.
@@ -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
@@ -20,6 +20,7 @@ module HoneyFormat
20
20
  symbol!: StrictConvertSymbol,
21
21
  downcase!: StrictConvertDowncase,
22
22
  upcase!: StrictConvertUpcase,
23
+ strip!: StrictConvertStrip,
23
24
  boolean!: StrictConvertBoolean,
24
25
  # safe variants
25
26
  decimal: ConvertDecimal,
@@ -31,6 +32,7 @@ module HoneyFormat
31
32
  symbol: ConvertSymbol,
32
33
  downcase: ConvertDowncase,
33
34
  upcase: ConvertUpcase,
35
+ strip: ConvertStrip,
34
36
  boolean: ConvertBoolean,
35
37
  md5: ConvertMD5,
36
38
  hex: ConvertHex,
@@ -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
@@ -12,12 +12,24 @@ module HoneyFormat
12
12
  # @param [Array] rows the array of rows.
13
13
  # @param [Array<Symbol>] columns the array of column symbols.
14
14
  # @param type_map [Hash] map of column_name => type conversion to perform.
15
+ # @param pre_built_rows [boolean] whether the rows come pre-built
15
16
  # @raise [RowError] super class of errors raised when there is a row error.
16
17
  # @raise [EmptyRowColumnsError] raised when there are no columns.
17
18
  # @raise [InvalidRowLengthError] raised when row has more columns than header columns.
18
- def initialize(rows, columns, builder: nil, type_map: {})
19
- builder = RowBuilder.new(columns, builder: builder, type_map: type_map)
20
- @rows = prepare_rows(builder, rows)
19
+ def initialize(rows, columns, builder: nil, type_map: {}, pre_built_rows: false)
20
+ @columns = columns
21
+ if pre_built_rows
22
+ @rows = rows
23
+ else
24
+ builder = RowBuilder.new(@columns, builder: builder, type_map: type_map)
25
+ @rows = prepare_rows(builder, rows)
26
+ end
27
+ end
28
+
29
+ # Row columns
30
+ # @return [Array<Symbol>] of column identifiers.
31
+ def columns
32
+ @columns
21
33
  end
22
34
 
23
35
  # Returns true if rows contains no elements.
@@ -26,6 +38,18 @@ module HoneyFormat
26
38
  @rows.empty?
27
39
  end
28
40
 
41
+ # Returns the rows added together.
42
+ # @return [Rows] the two sets of Rows added together.
43
+ # @param [Rows] the other Rows object.
44
+ def +(other)
45
+ if columns != columns.union(other.columns)
46
+ raise ArgumentError, "can't added two sets of rows with different columns"
47
+ end
48
+
49
+ rows = @rows + other.rows_data
50
+ self.class.new(rows, columns, pre_built_rows: true)
51
+ end
52
+
29
53
  # @yield [row] The given block will be passed for every row.
30
54
  # @yieldparam [Row] a row in the CSV file.
31
55
  # @return [Enumerator]
@@ -42,6 +66,7 @@ module HoneyFormat
42
66
 
43
67
  # Return element at given position.
44
68
  # @return [Row] of rows.
69
+ # @param [Integer] the index to return.
45
70
  def [](index)
46
71
  @rows[index]
47
72
  end
@@ -77,6 +102,12 @@ module HoneyFormat
77
102
  csv_rows.join
78
103
  end
79
104
 
105
+ protected
106
+
107
+ def rows_data
108
+ @rows
109
+ end
110
+
80
111
  private
81
112
 
82
113
  def prepare_rows(builder, rows)
@@ -4,7 +4,7 @@ module HoneyFormat
4
4
  # Gem version
5
5
  VERSION = [
6
6
  MAJOR_VERSION = 0,
7
- MINOR_VERSION = 21,
8
- PATCH_VERSION = 1,
7
+ MINOR_VERSION = 25,
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.21.1
4
+ version: 0.25.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: 2020-09-14 00:00:00.000000000 Z
11
+ date: 2021-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -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.