slyce 0.9.2 → 0.9.7
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/bin/slyce +18 -10
- data/bin/slyce3 +127 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 380c2147a52bd30761850468c1a06b6f041523d66ed513912a0756a51d80d7d5
|
4
|
+
data.tar.gz: 1f306e010169260bc76a5bfb7200d2c9c0ca87ca76fc27b143b9e61e6310ef14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33369805c3929785f1709b567484d35ceaeb2d0502c5db8db8c1a26ea50e31f43dd39d48f6ac605e4cf294e8ea727fa3f9c5977091c3c48e25c68a4080c6e444
|
7
|
+
data.tar.gz: ef9ca1f35c4f6c172f231b9609fc72968e393ffbf45005973a4918e293af59ca53d82dbd8d7788f829a783213c70a020b88640939c64fbc1db5395659272507e
|
data/bin/slyce
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
3
|
+
VERSION="0.9.7"
|
4
4
|
|
5
|
-
|
5
|
+
STDOUT.sync = true
|
6
6
|
|
7
7
|
require "mysql2"
|
8
8
|
require "optparse"
|
@@ -27,19 +27,23 @@ OptionParser.new.instance_eval do
|
|
27
27
|
end.parse!(into: opts={}) rescue abort($!.message)
|
28
28
|
|
29
29
|
abcd = opts[:alpha]
|
30
|
+
filt = opts[:where] and filt = "where\n #{filt}"
|
30
31
|
show = opts[:show]
|
31
32
|
want = opts[:extract].to_s.downcase.split(",")
|
32
|
-
filt = opts[:where] and filt = "where\n #{filt}"
|
33
33
|
|
34
|
-
dbas ||= ARGV.shift or
|
35
|
-
tabl ||= ARGV.shift or
|
34
|
+
dbas ||= ARGV.shift or abort "no database given"
|
35
|
+
tabl ||= ARGV.shift or abort "no table given"
|
36
36
|
|
37
37
|
# ==[ Helpers ]==
|
38
38
|
|
39
39
|
class Mysql2::Client
|
40
|
-
def
|
40
|
+
def sql(...)
|
41
|
+
query(...)
|
42
|
+
end
|
43
|
+
|
44
|
+
def sql!(stmt, *args, **, &)
|
41
45
|
puts "\n==[ SQL statement ]==\n\n", stmt.strip, ";"
|
42
|
-
|
46
|
+
sql(stmt, *args, **, &)
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
@@ -69,10 +73,14 @@ if opts[:columns]
|
|
69
73
|
exit
|
70
74
|
end
|
71
75
|
|
76
|
+
if want.empty?
|
77
|
+
abort "no columns are selected"
|
78
|
+
end
|
79
|
+
|
72
80
|
want.each do |name|
|
73
81
|
sort = abcd ? "" : "cnt desc,"
|
74
82
|
stmt = show ? "limit #{show}" : ""
|
75
|
-
data = conn.
|
83
|
+
data = conn.sql(<<~"" + stmt).to_a
|
76
84
|
select
|
77
85
|
count(*) as cnt,
|
78
86
|
`#{name}` as val
|
@@ -87,14 +95,14 @@ want.each do |name|
|
|
87
95
|
-if(regexp_like(`#{name}`, '^\\\\d'), regexp_instr(`#{name}`, '[^\\\\d]'), null) desc,
|
88
96
|
`#{name}` is null, `#{name}`
|
89
97
|
|
90
|
-
uniq = conn.
|
98
|
+
uniq = conn.sql(<<~"").to_a[0][0]
|
91
99
|
select
|
92
100
|
count(distinct(ifnull(`#{name}`,0)))
|
93
101
|
from
|
94
102
|
`#{tabl}`
|
95
103
|
#{filt}
|
96
104
|
|
97
|
-
tots = conn.
|
105
|
+
tots = conn.sql(<<~"").to_a[0][0]
|
98
106
|
select
|
99
107
|
count(ifnull(`#{name}`,0))
|
100
108
|
from
|
data/bin/slyce3
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# NOTE: Requires the 'regexp' sqlite3 extension from https://github.com/nalgeon/sqlean
|
4
|
+
#
|
5
|
+
# Downloads from https://github.com/nalgeon/sqlean/releases/latest
|
6
|
+
#
|
7
|
+
# For example, on Apple Silicon with macOS with an M1 you can use:
|
8
|
+
#
|
9
|
+
# wget https://github.com/nalgeon/sqlean/releases/download/0.19.3/sqlean-macos-arm64.zip
|
10
|
+
# unzip sqlean-macos-arm64.zip regexp.dylib
|
11
|
+
|
12
|
+
VERSION="0.9.7"
|
13
|
+
|
14
|
+
STDOUT.sync = true
|
15
|
+
|
16
|
+
require "extralite"
|
17
|
+
require "optparse"
|
18
|
+
|
19
|
+
trap("INT" ) { abort "\n" }
|
20
|
+
|
21
|
+
dbas = nil
|
22
|
+
tabl = nil
|
23
|
+
|
24
|
+
OptionParser.new.instance_eval do
|
25
|
+
@banner = "usage: #{program_name} [options] <database> <table>"
|
26
|
+
|
27
|
+
on "-a", "--alpha" , "Sort alphabetically, not numerically"
|
28
|
+
on "-c", "--columns" , "Display column names and quit"
|
29
|
+
on "-h", "--help" , "Show help and command usage" do Kernel.abort to_s; end
|
30
|
+
on "-r", "--regexp <path>" , "Path to the sqlean/regexp extension"
|
31
|
+
on "-s", "--show <count>" , "Show this many values", Integer
|
32
|
+
on "-v", "--version" , "Show version number" do Kernel.abort "#{program_name} #{VERSION}"; end
|
33
|
+
on "-w", "--where <cond>" , "Filter rows (eg - 'age=33,Name=/[BW]ill/i,color=\"\"'"
|
34
|
+
on "-x", "--extract <col1,col2,...>", "Comma separated list of columns to extract"
|
35
|
+
|
36
|
+
self
|
37
|
+
end.parse!(into: opts={}) rescue abort($!.message)
|
38
|
+
|
39
|
+
abcd = opts[:alpha]
|
40
|
+
filt = opts[:where] and filt = "where\n #{filt}"
|
41
|
+
regx = opts[:regexp] || Dir["{,sqlean}/regexp.{dll,dylib,so}"].first
|
42
|
+
show = opts[:show]
|
43
|
+
want = opts[:extract].to_s.downcase.split(",")
|
44
|
+
|
45
|
+
dbas ||= ARGV.shift or abort "no database given"
|
46
|
+
tabl ||= ARGV.shift or abort "no table given"
|
47
|
+
|
48
|
+
regx && File.exist?(regx) or abort "no regexp extension found#{regx ? " at '#{regx}'" : ''}"
|
49
|
+
|
50
|
+
# ==[ Helpers ]==
|
51
|
+
|
52
|
+
class Extralite::Database
|
53
|
+
def sql(...)
|
54
|
+
query_ary(...)
|
55
|
+
end
|
56
|
+
|
57
|
+
def sql!(stmt, *args, **, &)
|
58
|
+
puts "\n==[ SQL statement ]==\n\n", stmt.strip, ";"
|
59
|
+
sql(stmt, *args, **, &)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def display(name, data, show, uniq, tots)
|
64
|
+
seen = data.inject(0) {|seen, coun| seen += coun[0] }
|
65
|
+
rows = [data.size, seen].min
|
66
|
+
wide = tots.to_s.size
|
67
|
+
fill = " " * wide
|
68
|
+
line = "=" * name.size
|
69
|
+
|
70
|
+
puts "\n#{fill} #{name}\n#{fill} #{line}\n"
|
71
|
+
data.each {|cnt, val| puts "%*d %s" % [wide, cnt, val || "NULL"] }
|
72
|
+
puts "#{fill} -----\n"
|
73
|
+
puts "%*d shown (top %d)" % [wide, rows, rows] if show
|
74
|
+
puts "%*d total (all %d)" % [wide, tots, uniq]
|
75
|
+
end
|
76
|
+
|
77
|
+
# ==[ Let 'er rip! ]==
|
78
|
+
|
79
|
+
conn = Extralite::Database.new(dbas)
|
80
|
+
resu = conn.load_extension(regx) rescue abort("unable to load regexp extension '#{regx}'")
|
81
|
+
cols = conn.columns("select * from `#{tabl}` limit 0").map(&:to_s)
|
82
|
+
want = want.empty? ? cols : want & cols
|
83
|
+
|
84
|
+
if opts[:columns]
|
85
|
+
puts cols
|
86
|
+
exit
|
87
|
+
end
|
88
|
+
|
89
|
+
if want.empty?
|
90
|
+
abort "no columns are selected"
|
91
|
+
end
|
92
|
+
|
93
|
+
want.each do |name|
|
94
|
+
sort = abcd ? "" : "cnt desc,"
|
95
|
+
stmt = show ? "limit #{show}" : ""
|
96
|
+
data = conn.sql(<<~"" + stmt).to_a
|
97
|
+
select
|
98
|
+
count(*) as cnt,
|
99
|
+
`#{name}` as val
|
100
|
+
from
|
101
|
+
`#{tabl}`
|
102
|
+
#{filt}
|
103
|
+
group by
|
104
|
+
val
|
105
|
+
order by #{sort}
|
106
|
+
-iif(regexp_like(`#{name}`, '^[-+]?((0|([1-9]\\d*)(\\.\\d*)?)|((0|([1-9]\\d*))\\.\\d+))$'), `#{name}` + 0, null) desc,
|
107
|
+
-iif(regexp_like(`#{name}`, '^0\\d+$'), length(`#{name}`), null) desc,
|
108
|
+
-iif(regexp_like(`#{name}`, '^\\d'), length(regexp_substr(`#{name}`, '^\\d+')), null) desc,
|
109
|
+
`#{name}` is null, `#{name}`
|
110
|
+
collate nocase
|
111
|
+
|
112
|
+
uniq = conn.sql(<<~"").to_a[0][0]
|
113
|
+
select
|
114
|
+
count(distinct(ifnull(`#{name}`,0)))
|
115
|
+
from
|
116
|
+
`#{tabl}`
|
117
|
+
#{filt}
|
118
|
+
|
119
|
+
tots = conn.sql(<<~"").to_a[0][0]
|
120
|
+
select
|
121
|
+
count(ifnull(`#{name}`,0))
|
122
|
+
from
|
123
|
+
`#{tabl}`
|
124
|
+
#{filt}
|
125
|
+
|
126
|
+
display(name, data, show, uniq, tots)
|
127
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slyce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Shreeve
|
@@ -28,6 +28,7 @@ description: Ruby utility to show data statistics for MySQL databases
|
|
28
28
|
email: steve.shreeve@gmail.com
|
29
29
|
executables:
|
30
30
|
- slyce
|
31
|
+
- slyce3
|
31
32
|
extensions: []
|
32
33
|
extra_rdoc_files: []
|
33
34
|
files:
|
@@ -35,6 +36,7 @@ files:
|
|
35
36
|
- LICENSE
|
36
37
|
- README.md
|
37
38
|
- bin/slyce
|
39
|
+
- bin/slyce3
|
38
40
|
- slyce.gemspec
|
39
41
|
homepage: https://github.com/shreeve/slyce
|
40
42
|
licenses:
|