honey_format 0.21.1 → 0.25.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 +23 -0
- data/LICENSE.txt +1 -1
- data/README.md +83 -0
- data/lib/honey_format/converters/convert_string.rb +9 -1
- data/lib/honey_format/converters/converters.rb +2 -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 +34 -3
- data/lib/honey_format/version.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bba6cf8014cc6cfa59c8519bbb2448d22800e3f5c3699629fd74132f5b615b82
|
4
|
+
data.tar.gz: d1e7dc2ed46e061edd4d473a267c5c1a0296fd58f080e7fecd878341364cb90f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
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
|
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
|
-
@
|
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
|
@@ -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
|
-
|
20
|
-
|
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)
|
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.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:
|
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.
|
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.
|