fat_table 0.3.0 → 0.4.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/.rubocop.yml +16 -3
- data/.travis.yml +1 -1
- data/Gemfile +2 -0
- data/README.org +22 -18
- data/fat_table.gemspec +3 -3
- data/lib/fat_table/column.rb +59 -23
- data/lib/fat_table/db_handle.rb +2 -0
- data/lib/fat_table/errors.rb +2 -0
- data/lib/fat_table/evaluator.rb +2 -0
- data/lib/fat_table/formatters/aoa_formatter.rb +2 -0
- data/lib/fat_table/formatters/aoh_formatter.rb +2 -0
- data/lib/fat_table/formatters/formatter.rb +53 -47
- data/lib/fat_table/formatters/org_formatter.rb +2 -0
- data/lib/fat_table/formatters/term_formatter.rb +17 -15
- data/lib/fat_table/formatters/text_formatter.rb +2 -0
- data/lib/fat_table/formatters.rb +2 -0
- data/lib/fat_table/patches.rb +2 -0
- data/lib/fat_table/table.rb +55 -22
- data/lib/fat_table/version.rb +3 -1
- data/lib/fat_table.rb +5 -3
- metadata +23 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dea0adf5d428fa875a7dda51538a79e514b9095b167d392ef06eae849e563a9f
|
|
4
|
+
data.tar.gz: d5ac2784c1f569fc1677f596278af3c6a00b1b5736ea1a080667f8a0f0acdd16
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7ea35509645ae4c11c8f7fd61157fe5057cf5d11237d888b9e5cfcbab437ff5fd90a3d3cffa9bd6d53038406138b12a890c65a72a59ac0b9542c1a90a979158c
|
|
7
|
+
data.tar.gz: 04eaf2e05b452efc8f25c14ab51b069d09dd9c548983481731562883d8866beac555a4a48a85b3352d408736c1b22d90881c0a23fab273fd78b459f31f704988
|
data/.rubocop.yml
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
-
inherit_from:
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
inherit_from:
|
|
2
|
+
- ~/.rubocop.yml
|
|
3
|
+
|
|
4
|
+
AllCops:
|
|
5
|
+
Exclude:
|
|
6
|
+
- 'test/tmp/**/*'
|
|
7
|
+
- 'vendor/bundle/**/*'
|
|
8
|
+
|
|
9
|
+
Style/MethodCallWithArgsParentheses:
|
|
10
|
+
Exclude:
|
|
11
|
+
- '**/Gemfile'
|
|
12
|
+
- '*_spec.rb'
|
|
13
|
+
|
|
14
|
+
Style/ClassAndModuleChildren:
|
|
15
|
+
Exclude:
|
|
16
|
+
- 'test/**/*'
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.org
CHANGED
|
@@ -481,7 +481,7 @@ This example illustrates several things:
|
|
|
481
481
|
A second ruby data structure that can be used to initialize a ~FatTable~ table
|
|
482
482
|
is an array of ruby Hashes. Each hash represents a row of the table, and the
|
|
483
483
|
headers of the table are taken from the keys of the hashes. Accordingly, all the
|
|
484
|
-
hashes
|
|
484
|
+
hashes must have the same keys.
|
|
485
485
|
|
|
486
486
|
This same method can in fact take an array of any objects that can be converted
|
|
487
487
|
to a Hash with the ~#to_h~ method, so you can use an array of your own objects
|
|
@@ -768,17 +768,18 @@ symbol representing an existing column, which has the effect of renaming an
|
|
|
768
768
|
existing column, or (2) a string representing a ruby expression for the value of
|
|
769
769
|
a new column.
|
|
770
770
|
|
|
771
|
-
Within the string expression, the names of existing or already-specified
|
|
772
|
-
are available as local variables
|
|
773
|
-
'@
|
|
774
|
-
|
|
771
|
+
Within the string expression, the names of existing or already-specified
|
|
772
|
+
columns are available as local variables. In addition the instance variables
|
|
773
|
+
'@row' and '@group' are available as the row number and group number of the
|
|
774
|
+
new value. So for our example table, the string expressions for new columns
|
|
775
|
+
have access to local variables ~ref~, ~date~, ~code~, ~price~, ~g10~, ~qp10~,
|
|
775
776
|
~shares~, ~lp~, ~qp~, ~iplp~, and ~ipqp~ as well as the instance variables
|
|
776
777
|
~@row~ and ~@group~. The local variables are set to the values of the cell in
|
|
777
|
-
their respective columns for each row in the input table and the instance
|
|
778
|
-
variables are set the number of the current row and group respectively.
|
|
778
|
+
their respective columns for each row in the input table, and the instance
|
|
779
|
+
variables are set the number of the current row and group number respectively.
|
|
779
780
|
|
|
780
|
-
For example, if we want to rename the ~:date~
|
|
781
|
-
compute the cost of shares, we could do the following:
|
|
781
|
+
For example, if we want to rename the ~traded_on~ column to ~:date~ and add a
|
|
782
|
+
new column to compute the cost of shares, we could do the following:
|
|
782
783
|
|
|
783
784
|
#+HEADER: :colnames no :session readme :hlines yes :wrap EXAMPLE :exports both
|
|
784
785
|
#+BEGIN_SRC ruby
|
|
@@ -1041,8 +1042,10 @@ the value is a symbol for one of several aggregating methods that
|
|
|
1041
1042
|
to the :price column so that the output shows the average price in each group.
|
|
1042
1043
|
The ~:shares~, ~:lp~, and ~:qp~ columns are summed, and the ~:any?~ aggregate is
|
|
1043
1044
|
applied to one of the boolean fields, that is, it is ~true~ if any of the values
|
|
1044
|
-
in that column are ~true~.
|
|
1045
|
-
|
|
1045
|
+
in that column are ~true~.
|
|
1046
|
+
|
|
1047
|
+
Note that the column names in the output of the aggregated columns have the
|
|
1048
|
+
name of the aggregating method pre-pended to the column name.
|
|
1046
1049
|
|
|
1047
1050
|
Here is a list of all the aggregate methods available. If the description
|
|
1048
1051
|
restricts the aggregate to particular column types, applying it to other types
|
|
@@ -1311,6 +1314,7 @@ table where the join expression is satisfied and augmented with nils otherwise.
|
|
|
1311
1314
|
Finally, a cross join outputs every row of ~tab_a~ augmented with every row of
|
|
1312
1315
|
~tab_b~, in other words, the Cartesian product of the two tables. If ~tab_a~ has
|
|
1313
1316
|
~N~ rows and ~tab_b~ has ~M~ rows, the output table will have ~N * M~ rows.
|
|
1317
|
+
So be careful lest you consume all your computer's memory.
|
|
1314
1318
|
|
|
1315
1319
|
#+HEADER: :colnames no :session readme :hlines yes :wrap EXAMPLE :exports both
|
|
1316
1320
|
#+BEGIN_SRC ruby
|
|
@@ -1348,10 +1352,10 @@ Finally, a cross join outputs every row of ~tab_a~ augmented with every row of
|
|
|
1348
1352
|
|
|
1349
1353
|
*** Set Operations
|
|
1350
1354
|
|
|
1351
|
-
~FatTable~ can perform several set operations on tables. In order for
|
|
1352
|
-
to be used this way, they must have the same number of columns with
|
|
1353
|
-
types or an exception will be raised. We'll call two tables that
|
|
1354
|
-
combining with set operations "set-compatible."
|
|
1355
|
+
~FatTable~ can perform several set operations on pairs of tables. In order for
|
|
1356
|
+
two tables to be used this way, they must have the same number of columns with
|
|
1357
|
+
the same types or an exception will be raised. We'll call two tables that
|
|
1358
|
+
qualify for combining with set operations "set-compatible."
|
|
1355
1359
|
|
|
1356
1360
|
We'll use the following two set-compatible tables in the examples. They each
|
|
1357
1361
|
have some duplicates and some group boundaries so you can see the effect of the
|
|
@@ -1763,9 +1767,9 @@ but ruby data structures, and for them, things such as alignment are irrelevant.
|
|
|
1763
1767
|
array of array,
|
|
1764
1768
|
|
|
1765
1769
|
These are all implemented by classes that inherit from ~FatTable::Formatter~
|
|
1766
|
-
class by defining about a dozen methods that get called at various places
|
|
1767
|
-
the construction of the output table. The idea is that more
|
|
1768
|
-
defined by adding additional classes.
|
|
1770
|
+
class by defining about a dozen methods that get called at various places
|
|
1771
|
+
during the construction of the output table. The idea is that more output
|
|
1772
|
+
formats can be defined by adding additional classes.
|
|
1769
1773
|
|
|
1770
1774
|
*** Table Locations
|
|
1771
1775
|
|
data/fat_table.gemspec
CHANGED
|
@@ -64,19 +64,19 @@ Gem::Specification.new do |spec|
|
|
|
64
64
|
spec.metadata['yard.run'] = 'yri' # use "yard" to build full HTML docs.
|
|
65
65
|
|
|
66
66
|
spec.add_development_dependency 'bundler'
|
|
67
|
-
spec.add_development_dependency '
|
|
67
|
+
spec.add_development_dependency 'debug', '>= 1.0.0'
|
|
68
68
|
spec.add_development_dependency 'pry'
|
|
69
|
-
spec.add_development_dependency 'pry-byebug'
|
|
70
69
|
spec.add_development_dependency 'pry-doc'
|
|
71
70
|
spec.add_development_dependency 'rake', '~> 13.0'
|
|
72
71
|
spec.add_development_dependency 'redcarpet'
|
|
72
|
+
spec.add_development_dependency 'pg'
|
|
73
73
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
74
74
|
spec.add_development_dependency 'rubocop-rspec'
|
|
75
75
|
spec.add_development_dependency 'rubocop-performance'
|
|
76
76
|
spec.add_development_dependency 'simplecov'
|
|
77
77
|
|
|
78
78
|
spec.add_runtime_dependency 'activesupport', '>3.0'
|
|
79
|
-
spec.add_runtime_dependency 'fat_core', '>= 4.
|
|
79
|
+
spec.add_runtime_dependency 'fat_core', '>= 4.9.0'
|
|
80
80
|
spec.add_runtime_dependency 'rainbow'
|
|
81
81
|
spec.add_runtime_dependency 'sequel'
|
|
82
82
|
spec.add_runtime_dependency 'gem-path'
|
data/lib/fat_table/column.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FatTable
|
|
2
4
|
# Column objects are a thin wrapper around an Array to allow columns to be
|
|
3
5
|
# summed and have other aggregate operations performed on them, but compacting
|
|
@@ -81,7 +83,7 @@ module FatTable
|
|
|
81
83
|
# col.type #=> 'Numeric'
|
|
82
84
|
# col.header #=> :prices
|
|
83
85
|
# col.sum #=> 18376.75
|
|
84
|
-
def initialize(header:, items: [])
|
|
86
|
+
def initialize(header:, items: [], type: 'NilClass')
|
|
85
87
|
@raw_header = header
|
|
86
88
|
@header =
|
|
87
89
|
if @raw_header.is_a?(Symbol)
|
|
@@ -89,7 +91,7 @@ module FatTable
|
|
|
89
91
|
else
|
|
90
92
|
@raw_header.to_s.as_sym
|
|
91
93
|
end
|
|
92
|
-
@type =
|
|
94
|
+
@type = type
|
|
93
95
|
msg = "unknown column type '#{type}"
|
|
94
96
|
raise UserError, msg unless TYPES.include?(@type.to_s)
|
|
95
97
|
|
|
@@ -137,6 +139,19 @@ module FatTable
|
|
|
137
139
|
size - 1
|
|
138
140
|
end
|
|
139
141
|
|
|
142
|
+
# :category: Attributes
|
|
143
|
+
|
|
144
|
+
# Force the column to have String type and then convert all items to
|
|
145
|
+
# strings.
|
|
146
|
+
def force_to_string_type
|
|
147
|
+
# msg = "Can only force an empty column to String type"
|
|
148
|
+
# raise UserError, msg unless empty?
|
|
149
|
+
@type = 'String'
|
|
150
|
+
unless empty?
|
|
151
|
+
@items = items.map(&:to_s)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
140
155
|
##########################################################################
|
|
141
156
|
# Enumerable
|
|
142
157
|
##########################################################################
|
|
@@ -483,34 +498,55 @@ module FatTable
|
|
|
483
498
|
end
|
|
484
499
|
end
|
|
485
500
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
501
|
+
ISO_DATE_RE = %r{(?<yr>\d\d\d\d)[-\/]
|
|
502
|
+
(?<mo>\d\d?)[-\/]
|
|
503
|
+
(?<dy>\d\d?)\s*
|
|
504
|
+
(T?\s*\d\d:\d\d(:\d\d)?
|
|
505
|
+
([-+](\d\d?)(:\d\d?))?)?}x
|
|
506
|
+
|
|
507
|
+
AMR_DATE_RE = %r{(?<dy>\d\d?)[-/](?<mo>\d\d?)[-/](?<yr>\d\d\d\d)\s*
|
|
508
|
+
(?<tm>T\d\d:\d\d:\d\d(\+\d\d:\d\d)?)?}x
|
|
509
|
+
|
|
510
|
+
# A Date like 'Tue, 01 Nov 2016' or 'Tue 01 Nov 2016' or '01 Nov 2016'.
|
|
511
|
+
# These are emitted by Postgresql, so it makes from_sql constructor
|
|
512
|
+
# possible without special formatting of the dates.
|
|
513
|
+
INV_DATE_RE = %r{((mon|tue|wed|thu|fri|sat|sun)[a-zA-z]*,?)?\s+ # looks like dow
|
|
514
|
+
(?<dy>\d\d?)\s+ # one or two-digit day
|
|
515
|
+
(?<mo_name>[jfmasondJFMASOND][A-Za-z]{2,})\s+ # looks like a month name
|
|
516
|
+
(?<yr>\d\d\d\d) # and a 4-digit year
|
|
517
|
+
}xi
|
|
518
|
+
|
|
519
|
+
# Convert the val to a DateTime if it is either a DateTime, a Date, a Time, or a
|
|
492
520
|
# String that can be parsed as a DateTime, otherwise return nil. It only
|
|
493
|
-
# recognizes strings that contain a something like '2016-01-14' or
|
|
494
|
-
#
|
|
495
|
-
#
|
|
496
|
-
#
|
|
521
|
+
# recognizes strings that contain a something like '2016-01-14' or '2/12/1985'
|
|
522
|
+
# within them, otherwise DateTime.parse would treat many bare numbers as dates,
|
|
523
|
+
# such as '2841381', which it would recognize as a valid date, but the user
|
|
524
|
+
# probably does not intend it to be so treated.
|
|
497
525
|
def convert_to_date_time(val)
|
|
498
526
|
return val if val.is_a?(DateTime)
|
|
499
527
|
return val if val.is_a?(Date)
|
|
528
|
+
return val.to_datetime if val.is_a?(Time)
|
|
500
529
|
begin
|
|
501
|
-
|
|
502
|
-
return nil if
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
530
|
+
str = val.to_s.clean
|
|
531
|
+
return nil if str.blank?
|
|
532
|
+
|
|
533
|
+
if str.match(ISO_DATE_RE)
|
|
534
|
+
date = DateTime.parse(val)
|
|
535
|
+
elsif str =~ AMR_DATE_RE
|
|
536
|
+
date = DateTime.new(Regexp.last_match[:yr].to_i,
|
|
537
|
+
Regexp.last_match[:mo].to_i,
|
|
538
|
+
Regexp.last_match[:dy].to_i)
|
|
539
|
+
elsif str =~ INV_DATE_RE
|
|
540
|
+
mo = Date.mo_name_to_num(last_match[:mo_name])
|
|
541
|
+
date = DateTime.new(Regexp.last_match[:yr].to_i, mo,
|
|
542
|
+
Regexp.last_match[:dy].to_i)
|
|
507
543
|
else
|
|
508
544
|
return nil
|
|
509
545
|
end
|
|
510
|
-
val = val.to_date if
|
|
511
|
-
|
|
546
|
+
# val = val.to_date if
|
|
547
|
+
date.seconds_since_midnight.zero? ? date.to_date : date
|
|
512
548
|
rescue ArgumentError
|
|
513
|
-
|
|
549
|
+
nil
|
|
514
550
|
end
|
|
515
551
|
end
|
|
516
552
|
|
|
@@ -530,8 +566,8 @@ module FatTable
|
|
|
530
566
|
BigDecimal(val.to_s.clean)
|
|
531
567
|
when /\A[-+]?[\d]+\z/
|
|
532
568
|
val.to_i
|
|
533
|
-
when %r{\A([-+]?\d+)\s*[:/]\s*([-+]?\d+)\z}
|
|
534
|
-
Rational(
|
|
569
|
+
when %r{\A(?<nm>[-+]?\d+)\s*[:/]\s*(?<dn>[-+]?\d+)\z}
|
|
570
|
+
Rational(Regexp.last_match[:nm], Regexp.last_match[:dn])
|
|
535
571
|
end
|
|
536
572
|
end
|
|
537
573
|
|
data/lib/fat_table/db_handle.rb
CHANGED
data/lib/fat_table/errors.rb
CHANGED
data/lib/fat_table/evaluator.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FatTable
|
|
2
4
|
# A Formatter is for use in Table output routines, and provides methods for
|
|
3
5
|
# adding group and table footers to the output and instructions for how the
|
|
@@ -73,7 +75,7 @@ module FatTable
|
|
|
73
75
|
false_color: 'none',
|
|
74
76
|
false_bgcolor: 'none',
|
|
75
77
|
underline: false,
|
|
76
|
-
blink: false
|
|
78
|
+
blink: false,
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
class_attribute :valid_colors
|
|
@@ -577,9 +579,9 @@ module FatTable
|
|
|
577
579
|
# parse, we remove the matched construct from fmt. At the end, any
|
|
578
580
|
# remaining characters in fmt should be invalid.
|
|
579
581
|
fmt_hash = {}
|
|
580
|
-
if fmt =~ /c\[(
|
|
581
|
-
fmt_hash[:color] =
|
|
582
|
-
fmt_hash[:bgcolor] =
|
|
582
|
+
if fmt =~ /c\[(?<co>#{CLR_RE})(\.(?<bg>#{CLR_RE}))?\]/
|
|
583
|
+
fmt_hash[:color] = Regexp.last_match[:co] unless Regexp.last_match[:co].blank?
|
|
584
|
+
fmt_hash[:bgcolor] = Regexp.last_match[:bg] unless Regexp.last_match[:bg].blank?
|
|
583
585
|
validate_color(fmt_hash[:color])
|
|
584
586
|
validate_color(fmt_hash[:bgcolor])
|
|
585
587
|
fmt = fmt.sub($&, '')
|
|
@@ -599,12 +601,12 @@ module FatTable
|
|
|
599
601
|
fmt_hash[:case] = :title
|
|
600
602
|
fmt = fmt.sub($&, '')
|
|
601
603
|
end
|
|
602
|
-
if fmt =~ /(
|
|
603
|
-
fmt_hash[:bold] =
|
|
604
|
+
if fmt =~ /(?<neg>~\s*)?B/
|
|
605
|
+
fmt_hash[:bold] = !Regexp.last_match[:neg]
|
|
604
606
|
fmt = fmt.sub($&, '')
|
|
605
607
|
end
|
|
606
|
-
if fmt =~ /(
|
|
607
|
-
fmt_hash[:italic] =
|
|
608
|
+
if fmt =~ /(?<neg>~\s*)?I/
|
|
609
|
+
fmt_hash[:italic] = !Regexp.last_match[:neg]
|
|
608
610
|
fmt = fmt.sub($&, '')
|
|
609
611
|
end
|
|
610
612
|
if fmt =~ /R/
|
|
@@ -619,12 +621,12 @@ module FatTable
|
|
|
619
621
|
fmt_hash[:alignment] = :left
|
|
620
622
|
fmt = fmt.sub($&, '')
|
|
621
623
|
end
|
|
622
|
-
if fmt =~ /(
|
|
623
|
-
fmt_hash[:underline] =
|
|
624
|
+
if fmt =~ /(?<neg>~\s*)?_/
|
|
625
|
+
fmt_hash[:underline] = !Regexp.last_match[:neg]
|
|
624
626
|
fmt = fmt.sub($&, '')
|
|
625
627
|
end
|
|
626
|
-
if fmt =~ /(
|
|
627
|
-
fmt_hash[:blink] =
|
|
628
|
+
if fmt =~ /(?<neg>~\s*)?\*/
|
|
629
|
+
fmt_hash[:blink] = !Regexp.last_match[:neg]
|
|
628
630
|
fmt = fmt.sub($&, '')
|
|
629
631
|
end
|
|
630
632
|
[fmt_hash, fmt]
|
|
@@ -639,9 +641,9 @@ module FatTable
|
|
|
639
641
|
# parse, we remove the matched construct from fmt. At the end, any
|
|
640
642
|
# remaining characters in fmt should be invalid.
|
|
641
643
|
fmt_hash = {}
|
|
642
|
-
if fmt =~ /n\[\s*([^\]]*)\s*\]/
|
|
643
|
-
fmt_hash[:nil_text] =
|
|
644
|
-
fmt = fmt.sub(
|
|
644
|
+
if fmt =~ /n\[\s*(?<bdy>[^\]]*)\s*\]/
|
|
645
|
+
fmt_hash[:nil_text] = Regexp.last_match[:bdy].clean
|
|
646
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
645
647
|
end
|
|
646
648
|
[fmt_hash, fmt]
|
|
647
649
|
end
|
|
@@ -655,22 +657,22 @@ module FatTable
|
|
|
655
657
|
# parse, we remove the matched construct from fmt. At the end, any
|
|
656
658
|
# remaining characters in fmt should be invalid.
|
|
657
659
|
fmt_hash, fmt = parse_str_fmt(fmt)
|
|
658
|
-
if fmt =~ /(
|
|
659
|
-
fmt_hash[:pre_digits] =
|
|
660
|
-
fmt_hash[:post_digits] =
|
|
661
|
-
fmt = fmt.sub(
|
|
660
|
+
if fmt =~ /(?<pre>\d+).(?<post>\d+)/
|
|
661
|
+
fmt_hash[:pre_digits] = Regexp.last_match[:pre].to_i
|
|
662
|
+
fmt_hash[:post_digits] = Regexp.last_match[:post].to_i
|
|
663
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
662
664
|
end
|
|
663
|
-
if fmt =~ /(
|
|
664
|
-
fmt_hash[:commas] =
|
|
665
|
-
fmt = fmt.sub(
|
|
665
|
+
if fmt =~ /(?<neg>~\s*)?,/
|
|
666
|
+
fmt_hash[:commas] = !Regexp.last_match[:neg]
|
|
667
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
666
668
|
end
|
|
667
|
-
if fmt =~ /(
|
|
668
|
-
fmt_hash[:currency] =
|
|
669
|
-
fmt = fmt.sub(
|
|
669
|
+
if fmt =~ /(?<neg>~\s*)?\$/
|
|
670
|
+
fmt_hash[:currency] = !Regexp.last_match[:neg]
|
|
671
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
670
672
|
end
|
|
671
|
-
if fmt =~ /(
|
|
672
|
-
fmt_hash[:hms] =
|
|
673
|
-
fmt = fmt.sub(
|
|
673
|
+
if fmt =~ /(?<neg>~\s*)?H/
|
|
674
|
+
fmt_hash[:hms] = !Regexp.last_match[:neg]
|
|
675
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
674
676
|
end
|
|
675
677
|
unless fmt.blank? || !strict
|
|
676
678
|
raise UserError, "unrecognized numeric formatting instructions '#{fmt}'"
|
|
@@ -688,13 +690,13 @@ module FatTable
|
|
|
688
690
|
# parse, we remove the matched construct from fmt. At the end, any
|
|
689
691
|
# remaining characters in fmt should be invalid.
|
|
690
692
|
fmt_hash, fmt = parse_str_fmt(fmt)
|
|
691
|
-
if fmt =~ /d\[([^\]]*)\]/
|
|
692
|
-
fmt_hash[:date_fmt] =
|
|
693
|
-
fmt = fmt.sub(
|
|
693
|
+
if fmt =~ /d\[(?<bdy>[^\]]*)\]/
|
|
694
|
+
fmt_hash[:date_fmt] = Regexp.last_match[:bdy]
|
|
695
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
694
696
|
end
|
|
695
|
-
if fmt =~ /D\[([^\]]*)\]/
|
|
696
|
-
fmt_hash[:date_fmt] =
|
|
697
|
-
fmt = fmt.sub(
|
|
697
|
+
if fmt =~ /D\[(?<bdy>[^\]]*)\]/
|
|
698
|
+
fmt_hash[:date_fmt] = Regexp.last_match[:bdy]
|
|
699
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
698
700
|
end
|
|
699
701
|
unless fmt.blank? || !strict
|
|
700
702
|
msg = "unrecognized datetime formatting instructions '#{fmt}'"
|
|
@@ -712,37 +714,38 @@ module FatTable
|
|
|
712
714
|
# parse, we remove the matched construct from fmt. At the end, any
|
|
713
715
|
# remaining characters in fmt should be invalid.
|
|
714
716
|
fmt_hash = {}
|
|
715
|
-
if fmt =~ /b\[\s*([^\],]*),([^\]]*)\s*\]/
|
|
716
|
-
fmt_hash[:true_text] =
|
|
717
|
-
fmt_hash[:false_text] =
|
|
718
|
-
fmt = fmt.sub(
|
|
717
|
+
if fmt =~ /b\[\s*(?<t>[^\],]*),(?<f>[^\]]*)\s*\]/
|
|
718
|
+
fmt_hash[:true_text] = Regexp.last_match[:t].clean
|
|
719
|
+
fmt_hash[:false_text] = Regexp.last_match[:f].clean
|
|
720
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
719
721
|
end
|
|
720
722
|
# Since true_text, false_text and nil_text may want to have internal
|
|
721
723
|
# spaces, defer removing extraneous spaces until after they are parsed.
|
|
722
724
|
if fmt =~ /c\[(#{CLR_RE})(\.(#{CLR_RE}))?,
|
|
723
725
|
\s*(#{CLR_RE})(\.(#{CLR_RE}))?\]/x
|
|
724
|
-
|
|
725
|
-
fmt_hash[:
|
|
726
|
-
fmt_hash[:
|
|
727
|
-
fmt_hash[:
|
|
728
|
-
|
|
726
|
+
tco, _, tbg, fco, _, fbg = Regexp.last_match.captures
|
|
727
|
+
fmt_hash[:true_color] = tco unless tco.blank?
|
|
728
|
+
fmt_hash[:true_bgcolor] = tbg unless tbg.blank?
|
|
729
|
+
fmt_hash[:false_color] = fco unless fco.blank?
|
|
730
|
+
fmt_hash[:false_bgcolor] = fbg unless fbg.blank?
|
|
731
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
729
732
|
end
|
|
730
733
|
str_fmt_hash, fmt = parse_str_fmt(fmt)
|
|
731
734
|
fmt_hash = fmt_hash.merge(str_fmt_hash)
|
|
732
735
|
if fmt =~ /Y/
|
|
733
736
|
fmt_hash[:true_text] = 'Y'
|
|
734
737
|
fmt_hash[:false_text] = 'N'
|
|
735
|
-
fmt = fmt.sub(
|
|
738
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
736
739
|
end
|
|
737
740
|
if fmt =~ /T/
|
|
738
741
|
fmt_hash[:true_text] = 'T'
|
|
739
742
|
fmt_hash[:false_text] = 'F'
|
|
740
|
-
fmt = fmt.sub(
|
|
743
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
741
744
|
end
|
|
742
745
|
if fmt =~ /X/
|
|
743
746
|
fmt_hash[:true_text] = 'X'
|
|
744
747
|
fmt_hash[:false_text] = ''
|
|
745
|
-
fmt = fmt.sub(
|
|
748
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
|
746
749
|
end
|
|
747
750
|
unless fmt.blank? || !strict
|
|
748
751
|
raise UserError, "unrecognized boolean formatting instructions '#{fmt}'"
|
|
@@ -1072,7 +1075,10 @@ module FatTable
|
|
|
1072
1075
|
:body
|
|
1073
1076
|
end
|
|
1074
1077
|
table.headers.each do |h|
|
|
1075
|
-
|
|
1078
|
+
# We set the column type here in case the column type was forced
|
|
1079
|
+
# to String.
|
|
1080
|
+
# grp_col[h] ||= Column.new(header: h)
|
|
1081
|
+
grp_col[h] ||= Column.new(header: h, type: table.type(h))
|
|
1076
1082
|
grp_col[h] << row[h]
|
|
1077
1083
|
istruct = format_at[location][h]
|
|
1078
1084
|
new_row[h] = [row[h], format_cell(row[h], istruct,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'rainbow'
|
|
2
4
|
|
|
3
5
|
module FatTable
|
|
@@ -26,10 +28,10 @@ module FatTable
|
|
|
26
28
|
super
|
|
27
29
|
@options[:unicode] = options.fetch(:unicode, true)
|
|
28
30
|
@options[:framecolor] = options.fetch(:framecolor, 'none.none')
|
|
29
|
-
return unless @options[:framecolor] =~ /([-_a-zA-Z]*)(\.([-_a-zA-Z]*))/
|
|
31
|
+
return unless @options[:framecolor] =~ /(?<co>[-_a-zA-Z]*)(\.(?<bg>[-_a-zA-Z]*))/
|
|
30
32
|
|
|
31
|
-
@options[:frame_fg] =
|
|
32
|
-
@options[:frame_bg] =
|
|
33
|
+
@options[:frame_fg] = Regexp.last_match[:co].downcase unless Regexp.last_match[:co].blank?
|
|
34
|
+
@options[:frame_bg] = Regexp.last_match[:bg].downcase unless Regexp.last_match[:bg].blank?
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
# Valid colors for ANSI terminal using the rainbow gem's X11ColorNames.
|
|
@@ -101,18 +103,18 @@ module FatTable
|
|
|
101
103
|
# Unicode line-drawing characters. We use double lines before and after the
|
|
102
104
|
# table and single lines for the sides and hlines between groups and
|
|
103
105
|
# footers.
|
|
104
|
-
UPPER_LEFT = "\u2552"
|
|
105
|
-
UPPER_RIGHT = "\u2555"
|
|
106
|
-
DOUBLE_RULE = "\u2550"
|
|
107
|
-
UPPER_TEE = "\u2564"
|
|
108
|
-
VERTICAL_RULE = "\u2502"
|
|
109
|
-
LEFT_TEE = "\u251C"
|
|
110
|
-
HORIZONTAL_RULE = "\u2500"
|
|
111
|
-
SINGLE_CROSS = "\u253C"
|
|
112
|
-
RIGHT_TEE = "\u2524"
|
|
113
|
-
LOWER_LEFT = "\u2558"
|
|
114
|
-
LOWER_RIGHT = "\u255B"
|
|
115
|
-
LOWER_TEE = "\u2567"
|
|
106
|
+
UPPER_LEFT = "\u2552"
|
|
107
|
+
UPPER_RIGHT = "\u2555"
|
|
108
|
+
DOUBLE_RULE = "\u2550"
|
|
109
|
+
UPPER_TEE = "\u2564"
|
|
110
|
+
VERTICAL_RULE = "\u2502"
|
|
111
|
+
LEFT_TEE = "\u251C"
|
|
112
|
+
HORIZONTAL_RULE = "\u2500"
|
|
113
|
+
SINGLE_CROSS = "\u253C"
|
|
114
|
+
RIGHT_TEE = "\u2524"
|
|
115
|
+
LOWER_LEFT = "\u2558"
|
|
116
|
+
LOWER_RIGHT = "\u255B"
|
|
117
|
+
LOWER_TEE = "\u2567"
|
|
116
118
|
# :startdoc:
|
|
117
119
|
|
|
118
120
|
def upper_left
|
data/lib/fat_table/formatters.rb
CHANGED
data/lib/fat_table/patches.rb
CHANGED
data/lib/fat_table/table.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FatTable
|
|
2
4
|
# A container for a two-dimensional table. All cells in the table must be a
|
|
3
5
|
# String, a DateTime (or Date), a Numeric (Bignum, Integer, or BigDecimal), or
|
|
@@ -156,7 +158,8 @@ module FatTable
|
|
|
156
158
|
raise UserError, msg if FatTable.db.nil?
|
|
157
159
|
|
|
158
160
|
result = Table.new
|
|
159
|
-
FatTable.db[query]
|
|
161
|
+
rows = FatTable.db[query]
|
|
162
|
+
rows.each do |h|
|
|
160
163
|
result << h
|
|
161
164
|
end
|
|
162
165
|
result
|
|
@@ -295,6 +298,8 @@ module FatTable
|
|
|
295
298
|
# :category: Attributes
|
|
296
299
|
|
|
297
300
|
# Return the table's Column with the given +key+ as its header.
|
|
301
|
+
# @param key [Symbol] symbol for header of column to return
|
|
302
|
+
# @return [FatTable::Column]
|
|
298
303
|
def column(key)
|
|
299
304
|
columns.detect { |c| c.header == key.as_sym }
|
|
300
305
|
end
|
|
@@ -309,6 +314,15 @@ module FatTable
|
|
|
309
314
|
|
|
310
315
|
# :category: Attributes
|
|
311
316
|
|
|
317
|
+
# Set the column type for Column with the given +key+ as a String type,
|
|
318
|
+
# but only if empty. Otherwise, we would have to worry about converting
|
|
319
|
+
# existing items in the column to String. Perhaps that's a TODO.
|
|
320
|
+
def set_column_to_string_type(key)
|
|
321
|
+
column(key).force_to_string_type
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# :category: Attributes
|
|
325
|
+
|
|
312
326
|
# Return the array of items of the column with the given header symbol
|
|
313
327
|
# +key+, or if +key+ is an Integer, return that row at that index. So a
|
|
314
328
|
# table's rows can be accessed by number, and its columns can be accessed by
|
|
@@ -880,10 +894,7 @@ module FatTable
|
|
|
880
894
|
# Apply the set operation given by ~oper~ between this table and the other
|
|
881
895
|
# table given in the first argument. If distinct is true, eliminate
|
|
882
896
|
# duplicates from the result.
|
|
883
|
-
def set_operation(other, oper = :+,
|
|
884
|
-
distinct: true,
|
|
885
|
-
add_boundaries: true,
|
|
886
|
-
inherit_boundaries: false)
|
|
897
|
+
def set_operation(other, oper = :+, distinct: true, add_boundaries: true, inherit_boundaries: false)
|
|
887
898
|
unless columns.size == other.columns.size
|
|
888
899
|
msg = "can't apply set ops to tables with a different number of columns"
|
|
889
900
|
raise UserError, msg
|
|
@@ -981,6 +992,11 @@ module FatTable
|
|
|
981
992
|
#
|
|
982
993
|
# Any groups present in either Table are eliminated in the output Table. See
|
|
983
994
|
# the README for examples.
|
|
995
|
+
# @param other [FatTable::Table] table to join with self
|
|
996
|
+
# @param exps [Array<String>, Array<Symbol>] table to join with self
|
|
997
|
+
# @param join_type [Array<String>, Array<Symbol>] type of join :inner, :left, :right, :full, :cross
|
|
998
|
+
# @return [FatTable::Table] result of joining self to other
|
|
999
|
+
#
|
|
984
1000
|
def join(other, *exps, join_type: :inner)
|
|
985
1001
|
unless other.is_a?(Table)
|
|
986
1002
|
raise UserError, 'need other table as first argument to join'
|
|
@@ -1083,10 +1099,10 @@ module FatTable
|
|
|
1083
1099
|
# Translate any remaining row_b heads to append '_b' if they have the
|
|
1084
1100
|
# same name as a row_a key.
|
|
1085
1101
|
a_heads = row_a.keys
|
|
1086
|
-
row_b = row_b.to_a.each.map
|
|
1102
|
+
row_b = row_b.to_a.each.map do |k, v|
|
|
1087
1103
|
[a_heads.include?(k) ? "#{k}_b".to_sym : k, v]
|
|
1088
|
-
|
|
1089
|
-
row_a.merge(row_b)
|
|
1104
|
+
end
|
|
1105
|
+
row_a.merge(row_b.to_h)
|
|
1090
1106
|
end
|
|
1091
1107
|
|
|
1092
1108
|
# Return a hash for the local variables of a join expression in which all
|
|
@@ -1125,7 +1141,7 @@ module FatTable
|
|
|
1125
1141
|
[nat_exp, common_heads]
|
|
1126
1142
|
end
|
|
1127
1143
|
else
|
|
1128
|
-
# We have expressions to evaluate
|
|
1144
|
+
# We have join expressions to evaluate
|
|
1129
1145
|
and_conds = []
|
|
1130
1146
|
partial_result = nil
|
|
1131
1147
|
last_sym = nil
|
|
@@ -1133,8 +1149,8 @@ module FatTable
|
|
|
1133
1149
|
case exp
|
|
1134
1150
|
when Symbol
|
|
1135
1151
|
case exp.to_s.clean
|
|
1136
|
-
when /\A(
|
|
1137
|
-
a_head =
|
|
1152
|
+
when /\A(?<sy>.*)_a\z/
|
|
1153
|
+
a_head = Regexp.last_match[:sy].to_sym
|
|
1138
1154
|
unless a_heads.include?(a_head)
|
|
1139
1155
|
raise UserError, "no column '#{a_head}' in table"
|
|
1140
1156
|
end
|
|
@@ -1149,11 +1165,11 @@ module FatTable
|
|
|
1149
1165
|
partial_result = nil
|
|
1150
1166
|
else
|
|
1151
1167
|
# First of a pair of _a or _b
|
|
1152
|
-
partial_result = "(#{a_head}_a == "
|
|
1168
|
+
partial_result = String.new("(#{a_head}_a == ")
|
|
1153
1169
|
end
|
|
1154
1170
|
last_sym = a_head
|
|
1155
|
-
when /\A(
|
|
1156
|
-
b_head =
|
|
1171
|
+
when /\A(?<sy>.*)_b\z/
|
|
1172
|
+
b_head = Regexp.last_match[:sy].to_sym
|
|
1157
1173
|
unless b_heads.include?(b_head)
|
|
1158
1174
|
raise UserError, "no column '#{b_head}' in second table"
|
|
1159
1175
|
end
|
|
@@ -1168,7 +1184,7 @@ module FatTable
|
|
|
1168
1184
|
partial_result = nil
|
|
1169
1185
|
else
|
|
1170
1186
|
# First of a pair of _a or _b
|
|
1171
|
-
partial_result = "(#{b_head}_b == "
|
|
1187
|
+
partial_result = String.new("(#{b_head}_b == ")
|
|
1172
1188
|
end
|
|
1173
1189
|
b_common_heads << b_head
|
|
1174
1190
|
last_sym = b_head
|
|
@@ -1275,16 +1291,33 @@ module FatTable
|
|
|
1275
1291
|
|
|
1276
1292
|
# :category: Constructors
|
|
1277
1293
|
|
|
1294
|
+
# Add a group boundary mark at the given row, or at the end of the table
|
|
1295
|
+
# by default.
|
|
1296
|
+
def add_boundary(at_row = nil)
|
|
1297
|
+
row = at_row || (size - 1)
|
|
1298
|
+
@boundaries << row
|
|
1299
|
+
end
|
|
1300
|
+
|
|
1301
|
+
# :category: Constructors
|
|
1302
|
+
|
|
1278
1303
|
# Add a +row+ represented by a Hash having the headers as keys. If +mark:+
|
|
1279
1304
|
# is set true, mark this row as a boundary. All tables should be built
|
|
1280
1305
|
# ultimately using this method as a primitive.
|
|
1281
1306
|
def add_row(row, mark: false)
|
|
1282
|
-
row.
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1307
|
+
row.transform_keys!(&:as_sym)
|
|
1308
|
+
# Make sure there is a column for each known header and each new key
|
|
1309
|
+
# present in row.
|
|
1310
|
+
new_heads = row.keys - headers
|
|
1311
|
+
new_heads.each do |h|
|
|
1312
|
+
# This column is new, so it needs nil items for all prior rows lest
|
|
1313
|
+
# the value be added to a prior row.
|
|
1314
|
+
items = Array.new(size, nil)
|
|
1315
|
+
columns << Column.new(header: h, items: items)
|
|
1316
|
+
end
|
|
1317
|
+
headers.each do |h|
|
|
1318
|
+
# NB: This adds a nil if h is not in row.
|
|
1319
|
+
column(h) << row[h]
|
|
1286
1320
|
end
|
|
1287
|
-
@boundaries << (size - 1) if mark
|
|
1288
1321
|
self
|
|
1289
1322
|
end
|
|
1290
1323
|
|
|
@@ -1353,9 +1386,9 @@ module FatTable
|
|
|
1353
1386
|
|
|
1354
1387
|
method = "to_#{fmt}"
|
|
1355
1388
|
if block_given?
|
|
1356
|
-
send
|
|
1389
|
+
send(method, options, &Proc.new)
|
|
1357
1390
|
else
|
|
1358
|
-
send
|
|
1391
|
+
send(method, options)
|
|
1359
1392
|
end
|
|
1360
1393
|
end
|
|
1361
1394
|
|
data/lib/fat_table/version.rb
CHANGED
data/lib/fat_table.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# This module provides objects for treating tables as a data type on which you
|
|
2
4
|
# can (1) perform operations, such as select, where, join, and others and (2)
|
|
3
5
|
# output the tables in several formats, including text, ANSI terminal, LaTeX,
|
|
@@ -29,7 +31,7 @@ module FatTable
|
|
|
29
31
|
path = Dir.glob("#{ENV['GEM_HOME']}/gems/#{gem_name}*").sort.last
|
|
30
32
|
if path
|
|
31
33
|
path = File.join(path, 'lib')
|
|
32
|
-
|
|
34
|
+
$LOAD_PATH << path unless $LOAD_PATH.include?(path)
|
|
33
35
|
end
|
|
34
36
|
end
|
|
35
37
|
|
|
@@ -158,9 +160,9 @@ module FatTable
|
|
|
158
160
|
raise UserError, "unknown format '#{fmt}'" unless FORMATS.include?(fmt)
|
|
159
161
|
method = "to_#{fmt}"
|
|
160
162
|
if block_given?
|
|
161
|
-
send
|
|
163
|
+
send(method, table, options, &Proc.new)
|
|
162
164
|
else
|
|
163
|
-
send
|
|
165
|
+
send(method, table, options)
|
|
164
166
|
end
|
|
165
167
|
end
|
|
166
168
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fat_table
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel E. Doherty
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-01-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -25,19 +25,19 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: debug
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 1.0.0
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 1.0.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: pry
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -53,7 +53,7 @@ dependencies:
|
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '0'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: pry-
|
|
56
|
+
name: pry-doc
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - ">="
|
|
@@ -67,35 +67,35 @@ dependencies:
|
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
70
|
+
name: rake
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- - "
|
|
73
|
+
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
75
|
+
version: '13.0'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- - "
|
|
80
|
+
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
82
|
+
version: '13.0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: redcarpet
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- - "
|
|
87
|
+
- - ">="
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
89
|
+
version: '0'
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
|
-
- - "
|
|
94
|
+
- - ">="
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
96
|
+
version: '0'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
98
|
+
name: pg
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
101
|
- - ">="
|
|
@@ -184,14 +184,14 @@ dependencies:
|
|
|
184
184
|
requirements:
|
|
185
185
|
- - ">="
|
|
186
186
|
- !ruby/object:Gem::Version
|
|
187
|
-
version:
|
|
187
|
+
version: 4.9.0
|
|
188
188
|
type: :runtime
|
|
189
189
|
prerelease: false
|
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
191
|
requirements:
|
|
192
192
|
- - ">="
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
|
-
version:
|
|
194
|
+
version: 4.9.0
|
|
195
195
|
- !ruby/object:Gem::Dependency
|
|
196
196
|
name: rainbow
|
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -306,7 +306,7 @@ licenses: []
|
|
|
306
306
|
metadata:
|
|
307
307
|
allowed_push_host: https://rubygems.org
|
|
308
308
|
yard.run: yri
|
|
309
|
-
post_install_message:
|
|
309
|
+
post_install_message:
|
|
310
310
|
rdoc_options: []
|
|
311
311
|
require_paths:
|
|
312
312
|
- lib
|
|
@@ -321,8 +321,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
321
321
|
- !ruby/object:Gem::Version
|
|
322
322
|
version: '0'
|
|
323
323
|
requirements: []
|
|
324
|
-
rubygems_version: 3.
|
|
325
|
-
signing_key:
|
|
324
|
+
rubygems_version: 3.3.3
|
|
325
|
+
signing_key:
|
|
326
326
|
specification_version: 4
|
|
327
327
|
summary: Provides tools for working with tables as a data type.
|
|
328
328
|
test_files: []
|