slyce 1.5.2 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/bin/slyce +15 -11
  4. data/bin/slyce3 +1 -1
  5. data/bin/slyced +59 -29
  6. data/slyce.gemspec +18 -16
  7. metadata +22 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44084fdce3c1789a721168848cf683134ba5fd6e4cfc507407e00c3c0513ac99
4
- data.tar.gz: 9ed23516f4f28c3a36f9107d6edffe1c93fc1d19abf83573ba15bac339eff873
3
+ metadata.gz: 9494f3b07aa6625fdb858913588120801e41f7abde508c7b46c6dcd7f40a35c9
4
+ data.tar.gz: c27456ca335865f82c2b0f3fa3aeb9d64c8c0c4ea44c065f481da61f780a7a27
5
5
  SHA512:
6
- metadata.gz: a9d9bebd0f769095ffb62deb70aafe40f03d4bf2b0744cc8940709ffe8d11f8d19cccf4d6206dc5ff20c947feac3c747d2f0510a5370acb5e9b2d0049c50630a
7
- data.tar.gz: f58765772f90d5af7c395db8ff3624556a7bba867155c3c2bdc0114406e6976d5c69846e131ea6e051bc091086e7af3eaa4f033e419e43161a1ea38128f66c04
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
- -r, --rows <count> Rows of data to select
21
- -s, --suppress Suppress header when exporting delimited files
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.5.2"
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
- dbas ||= ARGV.shift or abort "no database given"
77
- tabl ||= ARGV.shift or opts[:tables] or !want.empty? or abort "no table given"
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
@@ -49,7 +49,7 @@ end
49
49
  # ==[ Options ]==
50
50
 
51
51
  OptionParser.new.instance_eval do
52
- @version = "1.5.2"
52
+ @version = "1.7.0"
53
53
  @banner = "usage: #{program_name} [options] <database> <table>"
54
54
 
55
55
  on "--csv" , "Output comma separated values"
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.5.2"
40
+ @version = "1.7.0"
42
41
  @banner = "usage: #{program_name} [options] <database> <table>"
43
42
 
44
- on "--csv" , "Output comma separated values"
45
- on "--psv" , "Output pipe separated values"
46
- on "--tsv" , "Output tab separated values"
47
- on "-a", "--ascii" , "Convert data to ASCII using AnyAscii"
48
- on "-c", "--columns" , "Display column names and quit"
49
- on "-h", "--help" , "Show help and command usage" do Kernel.abort to_s; end
50
- on "-H", "--headerless" , "Do not show headers when exporting delimited files"
51
- on "-n", "--natural" , "Sort naturally, not numerically"
52
- on "-s", "--show <count>" , "Show this many values", Integer
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 to extract"
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
- dbas ||= ARGV.shift or abort "no database given"
76
- tabl ||= ARGV.shift or abort "no table given"
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) nulls last,
131
- if(regexp_matches("#{name}", '^\\d+\\D'),length(regexp_extract("#{name}",'^(\\d+)',1)),null) nulls last,
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}",0))),
149
- count(ifnull("#{name}",0))
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 |s|
4
- s.name = "slyce"
5
- s.version = `grep -m 1 '^\s*@version' bin/slyce | cut -f 2 -d '"'`
6
- s.author = "Steve Shreeve"
7
- s.email = "steve.shreeve@gmail.com"
8
- s.summary =
9
- s.description = "Ruby utility to show data statistics for MySQL databases"
10
- s.homepage = "https://github.com/shreeve/slyce"
11
- s.license = "MIT"
12
- s.files = `git ls-files`.split("\n") - %w[.gitignore]
13
- s.executables = `cd bin && git ls-files .`.split("\n")
14
- s.add_runtime_dependency "any_ascii", "~> 0.3.2"
15
- s.add_runtime_dependency "censive", "~> 1.1.0"
16
- s.add_runtime_dependency "duckdb", "~> 0.9"
17
- s.add_runtime_dependency "extralite-bundle", "~> 2.1"
18
- s.add_runtime_dependency "mysql2", "~> 0.5"
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.5.2
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: 2023-10-18 00:00:00.000000000 Z
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: '0.9'
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: '0.9'
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 data statistics for MySQL databases
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.4.20
119
- signing_key:
130
+ rubygems_version: 3.6.3
120
131
  specification_version: 4
121
- summary: Ruby utility to show data statistics for MySQL databases
132
+ summary: A Ruby utility to show statistics for databases or csv files
122
133
  test_files: []