slyce 1.5.2 → 1.7.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/README.md +3 -2
- data/bin/slyce +15 -11
- data/bin/slyce3 +1 -1
- data/bin/slyced +59 -29
- data/slyce.gemspec +18 -16
- metadata +22 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9494f3b07aa6625fdb858913588120801e41f7abde508c7b46c6dcd7f40a35c9
|
|
4
|
+
data.tar.gz: c27456ca335865f82c2b0f3fa3aeb9d64c8c0c4ea44c065f481da61f780a7a27
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d13d4ab7c55da6c48e9849afe5e1306bca6058632e90dc88037805932725eca680052d4a0ee0372f38430d19619c62532c863b5d4572ce269c8b12931a6ce22
|
|
7
|
+
data.tar.gz: 5b62b195a2b9af14a80779902cd3304583971225e0b5d22c7f8fa6d01d713f47013f11ac6ba8c631cfad7813b606fd8c2d9497c9c0a124ff9a7f36d401aa9b06
|
data/README.md
CHANGED
|
@@ -16,9 +16,10 @@ usage: slyce [options] <database> <table>
|
|
|
16
16
|
-a, --ascii Convert data to ASCII using AnyAscii
|
|
17
17
|
-c, --columns Display column names and quit
|
|
18
18
|
-h, --help Show help and command usage
|
|
19
|
+
-H, --headerless Do not show headers when exporting delimited files
|
|
19
20
|
-n, --natural Sort naturally, not numerically
|
|
20
|
-
-
|
|
21
|
-
-
|
|
21
|
+
-s, --show <count> Show this many values
|
|
22
|
+
-t, --tables Display table names and quit
|
|
22
23
|
-v, --version Show version number
|
|
23
24
|
-w, --where <cond> Where clause (eg - 'age>50 and state='AZ')
|
|
24
25
|
-x, --extract <col1,col2,...> Comma separated list of columns to extract
|
data/bin/slyce
CHANGED
|
@@ -36,7 +36,7 @@ end
|
|
|
36
36
|
# ==[ Options ]==
|
|
37
37
|
|
|
38
38
|
OptionParser.new.instance_eval do
|
|
39
|
-
@version = "1.
|
|
39
|
+
@version = "1.7.0"
|
|
40
40
|
@banner = "usage: #{program_name} [options] <database> <table>"
|
|
41
41
|
|
|
42
42
|
on "--csv" , "Output comma separated values"
|
|
@@ -57,14 +57,6 @@ OptionParser.new.instance_eval do
|
|
|
57
57
|
self
|
|
58
58
|
end.parse!(into: opts={}) rescue abort($!.message)
|
|
59
59
|
|
|
60
|
-
dbas = nil
|
|
61
|
-
tabl = nil
|
|
62
|
-
|
|
63
|
-
xcsv = opts[:csv]
|
|
64
|
-
xpsv = opts[:psv]
|
|
65
|
-
xtsv = opts[:tsv]
|
|
66
|
-
xprt = xcsv || xpsv || xtsv and require "censive"
|
|
67
|
-
|
|
68
60
|
asky = opts[:ascii ] and require "any_ascii"
|
|
69
61
|
dump = opts[:dump ]
|
|
70
62
|
want = opts[:extract ].to_s.downcase.split(",")
|
|
@@ -73,11 +65,23 @@ show = opts[:show ]
|
|
|
73
65
|
hide = opts[:headerless]
|
|
74
66
|
filt = opts[:where ] and filt = "\nwhere\n #{filt}"
|
|
75
67
|
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
# ==[ Export ]==
|
|
69
|
+
|
|
70
|
+
xcsv = opts[:csv]
|
|
71
|
+
xpsv = opts[:psv]
|
|
72
|
+
xtsv = opts[:tsv]
|
|
73
|
+
xprt = xcsv || xpsv || xtsv and require "censive"
|
|
78
74
|
|
|
79
75
|
[xcsv, xpsv, xtsv].compact.size > 1 and abort "only one of csv, psv, or tsv allowed"
|
|
80
76
|
|
|
77
|
+
# ==[ Source ]==
|
|
78
|
+
|
|
79
|
+
dbas = nil
|
|
80
|
+
tabl = nil
|
|
81
|
+
|
|
82
|
+
dbas ||= ARGV.shift or abort "no database given"
|
|
83
|
+
tabl ||= ARGV.shift or opts[:tables] or !want.empty? or abort "no table given"
|
|
84
|
+
|
|
81
85
|
# ==[ Let 'er rip! ]==
|
|
82
86
|
|
|
83
87
|
# get database connection
|
data/bin/slyce3
CHANGED
data/bin/slyced
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
STDOUT.sync = true
|
|
4
4
|
|
|
5
|
+
require "bigdecimal"
|
|
5
6
|
require "duckdb"
|
|
6
7
|
require "optparse"
|
|
7
8
|
|
|
@@ -9,8 +10,6 @@ trap("INT" ) { abort "\n" }
|
|
|
9
10
|
|
|
10
11
|
# ==[ Helpers ]==
|
|
11
12
|
|
|
12
|
-
DuckDB::Result.use_chunk_each = true
|
|
13
|
-
|
|
14
13
|
class DuckDB::Connection
|
|
15
14
|
alias_method :sql, :query
|
|
16
15
|
|
|
@@ -38,33 +37,26 @@ end
|
|
|
38
37
|
# ==[ Options ]==
|
|
39
38
|
|
|
40
39
|
OptionParser.new.instance_eval do
|
|
41
|
-
@version = "1.
|
|
40
|
+
@version = "1.7.0"
|
|
42
41
|
@banner = "usage: #{program_name} [options] <database> <table>"
|
|
43
42
|
|
|
44
|
-
on "--csv"
|
|
45
|
-
on "--psv"
|
|
46
|
-
on "--tsv"
|
|
47
|
-
on "-a", "--ascii"
|
|
48
|
-
on "-c", "--columns"
|
|
49
|
-
on "-h", "--help"
|
|
50
|
-
on "-H", "--headerless"
|
|
51
|
-
on "-n", "--natural"
|
|
52
|
-
on "-s", "--show <count>"
|
|
53
|
-
on "-
|
|
54
|
-
on "-
|
|
55
|
-
on "-
|
|
43
|
+
on "--csv" , "Output comma separated values"
|
|
44
|
+
on "--psv" , "Output pipe separated values"
|
|
45
|
+
on "--tsv" , "Output tab separated values"
|
|
46
|
+
on "-a", "--ascii" , "Convert data to ASCII using AnyAscii"
|
|
47
|
+
on "-c", "--columns" , "Display column names and quit"
|
|
48
|
+
on "-h", "--help" , "Show help and command usage" do Kernel.abort to_s; end
|
|
49
|
+
on "-H", "--headerless" , "Do not show headers when exporting delimited files"
|
|
50
|
+
on "-n", "--natural" , "Sort naturally, not numerically"
|
|
51
|
+
on "-s", "--show <count>" , "Show this many values", Integer
|
|
52
|
+
on "-t", "--tables" , "Display table names and quit"
|
|
53
|
+
on "-v", "--version" , "Show version number" do Kernel.abort "#{program_name} #{@version}"; end
|
|
54
|
+
on "-w", "--where <cond>" , "Where clause (eg - 'age>50 and state='AZ')"
|
|
55
|
+
on "-x", "--extract <a,b,c...>", "Comma separated list of columns or tables to extract"
|
|
56
56
|
|
|
57
57
|
self
|
|
58
58
|
end.parse!(into: opts={}) rescue abort($!.message)
|
|
59
59
|
|
|
60
|
-
dbas = nil
|
|
61
|
-
tabl = nil
|
|
62
|
-
|
|
63
|
-
xcsv = opts[:csv]
|
|
64
|
-
xpsv = opts[:psv]
|
|
65
|
-
xtsv = opts[:tsv]
|
|
66
|
-
xprt = xcsv || xpsv || xtsv and require "censive"
|
|
67
|
-
|
|
68
60
|
asky = opts[:ascii ] and require "any_ascii"
|
|
69
61
|
want = opts[:extract ].to_s.downcase.split(",")
|
|
70
62
|
natu = opts[:natural ]
|
|
@@ -72,14 +64,51 @@ show = opts[:show ]
|
|
|
72
64
|
hide = opts[:headerless]
|
|
73
65
|
filt = opts[:where ] and filt = "\nwhere\n #{filt}"
|
|
74
66
|
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
# ==[ Export ]==
|
|
68
|
+
|
|
69
|
+
xcsv = opts[:csv]
|
|
70
|
+
xpsv = opts[:psv]
|
|
71
|
+
xtsv = opts[:tsv]
|
|
72
|
+
xprt = xcsv || xpsv || xtsv and require "censive"
|
|
77
73
|
|
|
78
74
|
[xcsv, xpsv, xtsv].compact.size > 1 and abort "only one of csv, psv, or tsv allowed"
|
|
79
75
|
|
|
76
|
+
# ==[ Source ]==
|
|
77
|
+
|
|
78
|
+
file = '/dev/stdin'
|
|
79
|
+
dbas = ':memory:'
|
|
80
|
+
tabl = '_memory_'
|
|
81
|
+
|
|
82
|
+
if ARGV.size == 1
|
|
83
|
+
if opts[:tables]
|
|
84
|
+
dbas = ARGV.shift
|
|
85
|
+
else
|
|
86
|
+
file = ARGV.shift
|
|
87
|
+
File.readable?(file) or abort "#{file.inspect} is unreadable"
|
|
88
|
+
end
|
|
89
|
+
elsif ARGV.size > 1
|
|
90
|
+
dbas = ARGV.shift
|
|
91
|
+
tabl = ARGV.shift
|
|
92
|
+
end
|
|
93
|
+
|
|
80
94
|
# ==[ Let 'er rip! ]==
|
|
81
95
|
|
|
82
96
|
conn = DuckDB::Database.open(dbas).connect
|
|
97
|
+
|
|
98
|
+
if dbas && opts[:tables]
|
|
99
|
+
resu = conn.sql("show tables")
|
|
100
|
+
tbls = resu.to_a.flatten
|
|
101
|
+
want = want.empty? ? tbls : want & tbls
|
|
102
|
+
puts want
|
|
103
|
+
exit
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
conn.sql(<<~end) if file rescue exit
|
|
107
|
+
create temporary table "#{tabl}" as
|
|
108
|
+
select *
|
|
109
|
+
from read_csv("#{file}", all_varchar=true)
|
|
110
|
+
end
|
|
111
|
+
|
|
83
112
|
resu = conn.sql(<<~end)
|
|
84
113
|
select column_name
|
|
85
114
|
from information_schema.columns
|
|
@@ -116,6 +145,7 @@ if xprt
|
|
|
116
145
|
csv << want unless hide
|
|
117
146
|
data.each do |row|
|
|
118
147
|
csv << row.map {|e| asky ? AnyAscii.transliterate(e.to_s) : e.to_s }
|
|
148
|
+
# csv << row.map {|e| asky ? AnyAscii.transliterate(e.to_s) : e.nil? ? nil : e.to_s }
|
|
119
149
|
end
|
|
120
150
|
end
|
|
121
151
|
|
|
@@ -127,8 +157,8 @@ want.each do |name|
|
|
|
127
157
|
limt = show ? "limit #{show}" : ""
|
|
128
158
|
like = <<~"".gsub(/(.)^/m, '\1 ').rstrip
|
|
129
159
|
if(regexp_matches("#{name}", '^[-+]?((0|([1-9]\\d*)(\\.\\d*)?)|((0|([1-9]\\d*))\\.\\d+))$'),cast("#{name}" as double),null) nulls last,
|
|
130
|
-
if(regexp_matches("#{name}", '^0\\d*$'),length("#{name}"),null)
|
|
131
|
-
if(regexp_matches("#{name}", '^\\d+\\D'),length(regexp_extract("#{name}",'^(\\d+)',1)),null)
|
|
160
|
+
if(regexp_matches("#{name}", '^0\\d*$'),length("#{name}"),null) nulls last,
|
|
161
|
+
if(regexp_matches("#{name}", '^\\d+\\D'),length(regexp_extract("#{name}",'^(\\d+)',1)),null) nulls last,
|
|
132
162
|
|
|
133
163
|
data = conn.sql(<<~"".rstrip).to_a
|
|
134
164
|
select
|
|
@@ -145,8 +175,8 @@ want.each do |name|
|
|
|
145
175
|
|
|
146
176
|
uniq, tots = conn.sql(<<~"".rstrip).to_a[0]
|
|
147
177
|
select
|
|
148
|
-
count(distinct(ifnull("#{name}",
|
|
149
|
-
count(ifnull("#{name}",
|
|
178
|
+
count(distinct(ifnull("#{name}",''))),
|
|
179
|
+
count(ifnull("#{name}",''))
|
|
150
180
|
from
|
|
151
181
|
"#{tabl}"
|
|
152
182
|
#{filt}
|
data/slyce.gemspec
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
|
|
3
|
-
Gem::Specification.new do |
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
Gem::Specification.new do |gem|
|
|
4
|
+
gem.name = "slyce"
|
|
5
|
+
gem.version = `grep -m 1 '^\s*@version' bin/slyce | cut -f 2 -d '"'`
|
|
6
|
+
gem.author = "Steve Shreeve"
|
|
7
|
+
gem.email = "steve.shreeve@gmail.com"
|
|
8
|
+
gem.summary = "A " +
|
|
9
|
+
gem.description = "Ruby utility to show statistics for databases or csv files"
|
|
10
|
+
gem.homepage = "https://github.com/shreeve/slyce"
|
|
11
|
+
gem.license = "MIT"
|
|
12
|
+
gem.files = `git ls-files`.split("\n") - %w[.gitignore]
|
|
13
|
+
gem.executables = `cd bin && git ls-files .`.split("\n")
|
|
14
|
+
gem.required_ruby_version = Gem::Requirement.new(">= 3.0") if gem.respond_to? :required_ruby_version=
|
|
15
|
+
gem.add_runtime_dependency "any_ascii", "~> 0.3.2"
|
|
16
|
+
gem.add_runtime_dependency "bigdecimal", "~> 3.1.0"
|
|
17
|
+
gem.add_runtime_dependency "censive", "~> 1.1.0"
|
|
18
|
+
gem.add_runtime_dependency "duckdb", "~> 1.1.2"
|
|
19
|
+
gem.add_runtime_dependency "extralite-bundle", "~> 2.1"
|
|
20
|
+
gem.add_runtime_dependency "mysql2", "~> 0.5"
|
|
19
21
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: slyce
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Steve Shreeve
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2025-02-06 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: any_ascii
|
|
@@ -24,6 +23,20 @@ dependencies:
|
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: 0.3.2
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: bigdecimal
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 3.1.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 3.1.0
|
|
27
40
|
- !ruby/object:Gem::Dependency
|
|
28
41
|
name: censive
|
|
29
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -44,14 +57,14 @@ dependencies:
|
|
|
44
57
|
requirements:
|
|
45
58
|
- - "~>"
|
|
46
59
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
60
|
+
version: 1.1.2
|
|
48
61
|
type: :runtime
|
|
49
62
|
prerelease: false
|
|
50
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
64
|
requirements:
|
|
52
65
|
- - "~>"
|
|
53
66
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
67
|
+
version: 1.1.2
|
|
55
68
|
- !ruby/object:Gem::Dependency
|
|
56
69
|
name: extralite-bundle
|
|
57
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,7 +93,7 @@ dependencies:
|
|
|
80
93
|
- - "~>"
|
|
81
94
|
- !ruby/object:Gem::Version
|
|
82
95
|
version: '0.5'
|
|
83
|
-
description: Ruby utility to show
|
|
96
|
+
description: Ruby utility to show statistics for databases or csv files
|
|
84
97
|
email: steve.shreeve@gmail.com
|
|
85
98
|
executables:
|
|
86
99
|
- slyce
|
|
@@ -100,7 +113,6 @@ homepage: https://github.com/shreeve/slyce
|
|
|
100
113
|
licenses:
|
|
101
114
|
- MIT
|
|
102
115
|
metadata: {}
|
|
103
|
-
post_install_message:
|
|
104
116
|
rdoc_options: []
|
|
105
117
|
require_paths:
|
|
106
118
|
- lib
|
|
@@ -108,15 +120,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
108
120
|
requirements:
|
|
109
121
|
- - ">="
|
|
110
122
|
- !ruby/object:Gem::Version
|
|
111
|
-
version: '0'
|
|
123
|
+
version: '3.0'
|
|
112
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
125
|
requirements:
|
|
114
126
|
- - ">="
|
|
115
127
|
- !ruby/object:Gem::Version
|
|
116
128
|
version: '0'
|
|
117
129
|
requirements: []
|
|
118
|
-
rubygems_version: 3.
|
|
119
|
-
signing_key:
|
|
130
|
+
rubygems_version: 3.6.3
|
|
120
131
|
specification_version: 4
|
|
121
|
-
summary: Ruby utility to show
|
|
132
|
+
summary: A Ruby utility to show statistics for databases or csv files
|
|
122
133
|
test_files: []
|