csvql 0.2.3 → 0.2.4
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/lib/csvql/csvql.rb +1 -0
- data/lib/csvql/version.rb +1 -1
- data/lib/csvql.rb +49 -48
- data/spec/csvql_spec.rb +7 -7
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dde4233623d84d9417709ae86a5cc854ed8a6e5
|
4
|
+
data.tar.gz: 36e69e39b2f9c5a5dce0699942afff427f4ab753
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2673f91dd259536d838e20d4e1d12e9493d972ce2a0151be669cbb20be983f1481a4d111ade364d5a72aab92719eec00d051b6943f91373ed1667dbac54b4bd6
|
7
|
+
data.tar.gz: 072b5d5f0aae880362953600b288f3c412d771f0313eb213137e21209a269160dd7f3b8f2e7b2ec01eaecc08842b5c9c5f33bb3079f796f0c24064945a6db7f6
|
data/lib/csvql/csvql.rb
CHANGED
data/lib/csvql/version.rb
CHANGED
data/lib/csvql.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'csv'
|
4
4
|
require 'nkf'
|
5
5
|
require 'optparse'
|
6
|
+
require 'ostruct'
|
6
7
|
|
7
8
|
require "csvql/csvql"
|
8
9
|
require "csvql/version"
|
@@ -10,62 +11,62 @@ require "csvql/version"
|
|
10
11
|
module Csvql
|
11
12
|
class << self
|
12
13
|
def option_parse(argv)
|
13
|
-
|
14
|
-
|
14
|
+
opt_parser = OptionParser.new("Usage: csvql [csvfile] [options]")
|
15
|
+
opt = OpenStruct.new
|
15
16
|
|
16
17
|
# default
|
17
18
|
# option[:header] = true
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
20
|
+
opt_parser.on("--console", "After all commands are run, open sqlite3 console with this data") {|v| opt.console = v }
|
21
|
+
opt_parser.on("--[no-]header", "Treat file as having the first row as a header row") {|v| opt.header = v }
|
22
|
+
opt_parser.on('--output-dlm="|"', "Output delimiter (|)") {|v| opt.output_dlm = v }
|
23
|
+
opt_parser.on("--save-to=FILE", "If set, sqlite3 db is left on disk at this path") {|v| opt.save_to = v }
|
24
|
+
opt_parser.on("--append", "Append mode (not dropping any tables)") {|v| opt.append = v }
|
25
|
+
opt_parser.on("--skip-comment", "Skip comment lines start with '#'") {|v| opt.skip_comment = v }
|
26
|
+
opt_parser.on("--source=FILE", "Source file to load, or defaults to stdin") {|v| opt.source = v }
|
27
|
+
opt_parser.on("--sql=SQL", "SQL Command(s) to run on the data") {|v| opt.sql = v }
|
28
|
+
opt_parser.on("--select=COLUMN", "Select column (*)") {|v| opt.select = v }
|
29
|
+
opt_parser.on("--schema=FILE or STRING", "Specify a table schema") {|v| opt.schema = v }
|
30
|
+
opt_parser.on("--strip", "Strip spaces around columns") {|v| opt.strip = v }
|
31
|
+
opt_parser.on("--where=COND", "Where clause") {|v| opt.where = v }
|
32
|
+
opt_parser.on("--table-name=NAME", "Override the default table name (tbl)") {|v| opt.table_name = v }
|
33
|
+
opt_parser.on("--verbose", "Enable verbose logging") {|v| opt.verbose = v }
|
34
|
+
opt_parser.parse!(argv)
|
34
35
|
|
35
|
-
|
36
|
-
#
|
37
|
-
|
38
|
-
File.basename(
|
36
|
+
opt.source ||= argv[0]
|
37
|
+
# opt.where] ||= argv[1]
|
38
|
+
opt.table_name ||= if opt.save_to && opt.source != nil
|
39
|
+
File.basename(opt.source.downcase, ".csv").gsub(/\./, "_")
|
39
40
|
else
|
40
41
|
"tbl"
|
41
42
|
end
|
42
|
-
if
|
43
|
-
|
43
|
+
if opt.output_dlm == 'tab'
|
44
|
+
opt.output_dlm = "\t"
|
44
45
|
end
|
45
|
-
|
46
|
+
opt.output_dlm ||= "|"
|
46
47
|
|
47
|
-
if
|
48
|
+
if opt.completion
|
48
49
|
puts opt.compsys('csvql')
|
49
50
|
exit 0
|
50
51
|
end
|
51
|
-
|
52
|
+
opt
|
52
53
|
end
|
53
54
|
|
54
55
|
def run(argv)
|
55
|
-
|
56
|
-
if
|
56
|
+
opt = option_parse(argv)
|
57
|
+
if opt.console && opt.source == nil
|
57
58
|
puts "Can not open console with pipe input, read a file instead"
|
58
59
|
exit 1
|
59
60
|
end
|
60
|
-
if
|
61
|
+
if opt.sql && (opt.select || opt.where)
|
61
62
|
puts "Can not use --sql option and --select|--where option at the same time."
|
62
63
|
exit 1
|
63
64
|
end
|
64
65
|
|
65
|
-
csvfile =
|
66
|
+
csvfile = opt.source ? File.open(opt.source) : $stdin
|
66
67
|
first_line = csvfile.readline
|
67
68
|
|
68
|
-
schema =
|
69
|
+
schema = opt.schema
|
69
70
|
if schema
|
70
71
|
file = File.expand_path(schema)
|
71
72
|
if File.exist?(file)
|
@@ -73,43 +74,43 @@ module Csvql
|
|
73
74
|
end
|
74
75
|
else
|
75
76
|
cols = first_line.parse_csv
|
76
|
-
col_name = if
|
77
|
+
col_name = if opt.header
|
77
78
|
cols
|
78
79
|
else
|
79
80
|
cols.size.times.map {|i| "c#{i}" }
|
80
81
|
end
|
81
82
|
schema = col_name.map {|c| "#{c} NONE" }.join(",")
|
82
83
|
end
|
83
|
-
csvfile.rewind unless
|
84
|
+
csvfile.rewind unless opt.header
|
84
85
|
|
85
|
-
tbl = TableHandler.new(
|
86
|
-
tbl.drop_table(
|
87
|
-
tbl.create_table(schema,
|
88
|
-
tbl.create_alias(
|
86
|
+
tbl = TableHandler.new(opt.save_to, opt.console)
|
87
|
+
tbl.drop_table(opt.table_name) unless opt.append
|
88
|
+
tbl.create_table(schema, opt.table_name)
|
89
|
+
tbl.create_alias(opt.table_name) if opt.save_to
|
89
90
|
tbl.exec("PRAGMA synchronous=OFF")
|
90
91
|
tbl.exec("BEGIN TRANSACTION")
|
91
92
|
csvfile.each.with_index(1) do |line,i|
|
92
93
|
line = NKF.nkf('-w', line).strip
|
93
94
|
next if line.size == 0
|
94
|
-
next if
|
95
|
+
next if opt.skip_comment && line.start_with?("#")
|
95
96
|
row = line.parse_csv
|
96
|
-
row.map!(&:strip) if
|
97
|
+
row.map!(&:strip) if opt.strip
|
97
98
|
tbl.insert(row, i)
|
98
99
|
end
|
99
100
|
tbl.exec("COMMIT TRANSACTION")
|
100
101
|
|
101
|
-
if
|
102
|
-
sql =
|
103
|
-
elsif
|
104
|
-
|
105
|
-
sql = "select #{
|
106
|
-
if
|
107
|
-
sql += " where (#{
|
102
|
+
if opt.sql
|
103
|
+
sql = opt.sql
|
104
|
+
elsif opt.select || opt.where
|
105
|
+
opt.select ||= "*"
|
106
|
+
sql = "select #{opt.select} from #{opt.table_name}"
|
107
|
+
if opt.where
|
108
|
+
sql += " where (#{opt.where})"
|
108
109
|
end
|
109
110
|
end
|
110
111
|
|
111
|
-
tbl.exec(sql).each {|row| puts row.join(
|
112
|
-
tbl.open_console if
|
112
|
+
tbl.exec(sql).each {|row| puts row.join(opt.output_dlm) } if sql
|
113
|
+
tbl.open_console if opt.console
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
data/spec/csvql_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe Csvql do
|
|
9
9
|
|
10
10
|
it 'select name' do
|
11
11
|
expect(capture {
|
12
|
-
Csvql.run([csvfile, "--select", "name"])
|
12
|
+
Csvql.run([csvfile, "--header", "--select", "name"])
|
13
13
|
}).to eq(<<EOL)
|
14
14
|
Anne
|
15
15
|
Bob
|
@@ -21,7 +21,7 @@ EOL
|
|
21
21
|
|
22
22
|
it 'where age > 40' do
|
23
23
|
expect(capture {
|
24
|
-
Csvql.run([csvfile, "--where", "age > 40"])
|
24
|
+
Csvql.run([csvfile, "--header", "--where", "age > 40"])
|
25
25
|
}).to eq(<<EOL)
|
26
26
|
3|Charry|48
|
27
27
|
5|Edward|52
|
@@ -30,7 +30,7 @@ EOL
|
|
30
30
|
|
31
31
|
it 'sql option' do
|
32
32
|
expect(capture {
|
33
|
-
Csvql.run([csvfile, "--sql", "select name,age from tbl where age between 20 and 40"])
|
33
|
+
Csvql.run([csvfile, "--header", "--sql", "select name,age from tbl where age between 20 and 40"])
|
34
34
|
}).to eq(<<EOL)
|
35
35
|
Anne|33
|
36
36
|
Bob|25
|
@@ -39,7 +39,7 @@ EOL
|
|
39
39
|
|
40
40
|
it 'change output delimiter' do
|
41
41
|
expect(capture {
|
42
|
-
Csvql.run([csvfile, "--where", "id = 3", "--output-dlm", ","])
|
42
|
+
Csvql.run([csvfile, "--header", "--where", "id = 3", "--output-dlm", ","])
|
43
43
|
}).to eq(<<EOL)
|
44
44
|
3,Charry,48
|
45
45
|
EOL
|
@@ -47,7 +47,7 @@ EOL
|
|
47
47
|
|
48
48
|
it 'change table name' do
|
49
49
|
expect(capture {
|
50
|
-
Csvql.run([csvfile, "--sql", "select id,name from users where id >= 4", "--table-name", "users"])
|
50
|
+
Csvql.run([csvfile, "--header", "--sql", "select id,name from users where id >= 4", "--table-name", "users"])
|
51
51
|
}).to eq(<<EOL)
|
52
52
|
4|Daniel
|
53
53
|
5|Edward
|
@@ -56,7 +56,7 @@ EOL
|
|
56
56
|
|
57
57
|
it 'save-to db file' do
|
58
58
|
dbfile = "csvql_test.db"
|
59
|
-
Csvql.run([csvfile, "--save-to", dbfile])
|
59
|
+
Csvql.run([csvfile, "--header", "--save-to", dbfile])
|
60
60
|
expect(`sqlite3 #{dbfile} "select * from tbl"`).to eq(<<EOL)
|
61
61
|
1|Anne|33
|
62
62
|
2|Bob|25
|
@@ -77,7 +77,7 @@ EOL
|
|
77
77
|
|
78
78
|
it 'source option' do
|
79
79
|
expect(capture {
|
80
|
-
Csvql.run(["--source", csvfile, "--select", "count(*)"])
|
80
|
+
Csvql.run(["--source", csvfile, "--header", "--select", "count(*)"])
|
81
81
|
}).to eq(<<EOL)
|
82
82
|
5
|
83
83
|
EOL
|