jrubysql 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/README.md +79 -0
- data/Rakefile +8 -0
- data/bin/jrubysql +9 -0
- data/jrubysql.gemspec +31 -0
- data/lib/jrubysql/config.rb +35 -0
- data/lib/jrubysql/constants.rb +15 -0
- data/lib/jrubysql/controller.rb +141 -0
- data/lib/jrubysql/doc/help.txt.erb +10 -0
- data/lib/jrubysql/input/console.rb +84 -0
- data/lib/jrubysql/input/file.rb +19 -0
- data/lib/jrubysql/input/input.rb +17 -0
- data/lib/jrubysql/messages.rb +23 -0
- data/lib/jrubysql/messages.yml +43 -0
- data/lib/jrubysql/option_parser.rb +124 -0
- data/lib/jrubysql/output/csv.rb +49 -0
- data/lib/jrubysql/output/cterm.rb +95 -0
- data/lib/jrubysql/output/term.rb +122 -0
- data/lib/jrubysql/rdbms.rb +82 -0
- data/lib/jrubysql/version.rb +3 -0
- data/lib/jrubysql.rb +36 -0
- data/test/test_cterm.rb +0 -0
- data/test/test_jrubysql.rb +9 -0
- data/test/test_option_parser.rb +0 -0
- data/test/test_term_output.rb +0 -0
- metadata +206 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Junegunn Choi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
jrubysql
|
2
|
+
========
|
3
|
+
An SQL client for any JDBC-compliant database. Written in JRuby.
|
4
|
+
|
5
|
+
Installation
|
6
|
+
------------
|
7
|
+
|
8
|
+
```
|
9
|
+
gem install jrubysql
|
10
|
+
```
|
11
|
+
|
12
|
+
Usage
|
13
|
+
-----
|
14
|
+
|
15
|
+
```
|
16
|
+
usage: jrubysql [options]
|
17
|
+
jrubysql -t DBMS_TYPE -h HOSTNAME [-u USERNAME -p [PASSWORD] [-d DATABASE]] [-f FILENAME]
|
18
|
+
jrubysql -c CLASSNAME -j JDBC_URL [-u USERNAME -p [PASSWORD] [-d DATABASE]] [-f FILENAME]
|
19
|
+
|
20
|
+
-t, --type DBMS_TYPE Database type: mysql/oracle/postgres/sqlserver
|
21
|
+
-h, --host HOST DBMS host address
|
22
|
+
|
23
|
+
-c, --class-name CLASSNAME Class name of the JDBC driver
|
24
|
+
-j, --jdbc-url JDBC_URL JDBC URL for the connection
|
25
|
+
|
26
|
+
-u, --user USERNAME Username
|
27
|
+
-p, --password [PASSWORD] Password
|
28
|
+
-d, --database DATABASE Name of the database (optional)
|
29
|
+
|
30
|
+
-f, --filename FILENAME SQL script file
|
31
|
+
-o, --output OUTPUT_TYPE Output type: cterm|term|csv (default: cterm)
|
32
|
+
|
33
|
+
--help Show this message
|
34
|
+
--version Show version
|
35
|
+
```
|
36
|
+
|
37
|
+
Connecting to the database
|
38
|
+
--------------------------
|
39
|
+
|
40
|
+
### Setting up CLASSPATH
|
41
|
+
Add the appropriate JDBC drivers to the CLASSPATH.
|
42
|
+
|
43
|
+
```
|
44
|
+
export CLASSPATH=$CLASSPATH:~/lib/mysql-connector-java-5.1.17-bin.jar:~/lib/ojdbc6.jar
|
45
|
+
```
|
46
|
+
|
47
|
+
### With type (-t) and hostname (-h)
|
48
|
+
|
49
|
+
```
|
50
|
+
# Supports MySQL/Oracle/PostgreSQL/MSSQL
|
51
|
+
|
52
|
+
jrubysql -t mysql -h localhost -d test -u user -p
|
53
|
+
jrubysql -t oracle -h localhost:1521/orcl -u user -p password
|
54
|
+
jrubysql -t postgres -h localhost -u root
|
55
|
+
jrubysql -t sqlserver -h 192.168.62.26 -u user -p password
|
56
|
+
```
|
57
|
+
|
58
|
+
### Connect with class name of JDBC driver (-c) and JDBC URL (-j)
|
59
|
+
|
60
|
+
```
|
61
|
+
# You can connect to any database with its JDBC driver
|
62
|
+
|
63
|
+
bin/jrubysql -corg.postgresql.Driver -jjdbc:postgresql://localhost/test
|
64
|
+
bin/jrubysql -ccom.mysql.jdbc.Driver -jjdbc:mysql://localhost/test -uuser -p
|
65
|
+
```
|
66
|
+
|
67
|
+
Screenshot
|
68
|
+
----------
|
69
|
+
![](https://github.com/junegunn/jrubysql/raw/master/screenshots/simpsons.png)
|
70
|
+
|
71
|
+
TODO
|
72
|
+
----
|
73
|
+
TESTS!!!
|
74
|
+
|
75
|
+
Copyright
|
76
|
+
---------
|
77
|
+
Copyright (c) 2012 Junegunn Choi. See LICENSE.txt for
|
78
|
+
further details.
|
79
|
+
|
data/Rakefile
ADDED
data/bin/jrubysql
ADDED
data/jrubysql.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "jrubysql/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "jrubysql"
|
7
|
+
s.version = JRubySQL::VERSION
|
8
|
+
s.authors = ["Junegunn Choi"]
|
9
|
+
s.email = ["junegunn.c@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/junegunn/jrubysql"
|
11
|
+
s.summary = %q{An SQL client for any JDBC-compliant database.}
|
12
|
+
s.description = %q{An SQL client for any JDBC-compliant database. Written in JRuby.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "jrubysql"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n").reject { |f| f =~ /^screenshots/ }
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "test-unit"
|
23
|
+
|
24
|
+
s.add_runtime_dependency "jdbc-helper", '~> 0.7.2'
|
25
|
+
s.add_runtime_dependency "insensitive_hash", '~> 0.2.3'
|
26
|
+
s.add_runtime_dependency "tabularize", '~> 0.1.1'
|
27
|
+
s.add_runtime_dependency "each_sql", '~> 0.3.1'
|
28
|
+
s.add_runtime_dependency "highline", '~> 1.6.11'
|
29
|
+
s.add_runtime_dependency "ansi", '~> 1.4.2'
|
30
|
+
s.add_runtime_dependency "erubis", '~> 2.7.0'
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module JRubySQL
|
5
|
+
# A simple key-value config in YAML
|
6
|
+
class Config
|
7
|
+
DEFAULT_PATH = File.join(ENV['HOME'], '.jrubysqlrc')
|
8
|
+
|
9
|
+
def initialize path = DEFAULT_PATH
|
10
|
+
@path = path
|
11
|
+
if @path && File.exists?(@path)
|
12
|
+
@yaml = YAML.load(File.read(@path))
|
13
|
+
end
|
14
|
+
@yaml = @yaml || {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def [] key
|
18
|
+
@yaml[key]
|
19
|
+
end
|
20
|
+
|
21
|
+
def []= key, value
|
22
|
+
(@yaml[key] = value).tap { dump }
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def dump
|
27
|
+
# Try to write atomically
|
28
|
+
File.open(@path + '.tmp', 'w') do |f|
|
29
|
+
f << YAML.dump(@yaml)
|
30
|
+
end
|
31
|
+
FileUtils.mv(@path + '.tmp', @path)
|
32
|
+
end
|
33
|
+
end#Config
|
34
|
+
end#JRubySQL
|
35
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module JRubySQL
|
2
|
+
module Constants
|
3
|
+
SUPPORTED_DBMS_TYPES = [ :mysql, :oracle, :postgres, :sqlserver ]
|
4
|
+
|
5
|
+
# .jrubysqlrc
|
6
|
+
MAX_COMMAND_HISTORY = 100
|
7
|
+
MAX_CONNECTION_HISTORY = 10
|
8
|
+
|
9
|
+
# Terminal (TBD)
|
10
|
+
MAX_COLUMN_WIDTH = 80
|
11
|
+
MIN_SCREEN_ROWS = 10
|
12
|
+
MAX_SCREEN_ROWS = 50
|
13
|
+
|
14
|
+
end#Constants
|
15
|
+
end#JRubySQL
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'quote_unquote'
|
2
|
+
|
3
|
+
module JRubySQL
|
4
|
+
class Controller
|
5
|
+
include JRubySQL::Messages
|
6
|
+
|
7
|
+
attr_reader :db_type
|
8
|
+
|
9
|
+
def initialize options, argv_str
|
10
|
+
@config = JRubySQL::Config.new
|
11
|
+
histories = @config['connections']
|
12
|
+
|
13
|
+
if options.nil?
|
14
|
+
if histories.nil? || histories.empty?
|
15
|
+
JRubySQL::OptionParser.parse []
|
16
|
+
else
|
17
|
+
# FIXME: Output
|
18
|
+
puts m(:choose_parameter)
|
19
|
+
histories.each_with_index do |history, idx|
|
20
|
+
puts "[#{idx + 1}] #{history.first}"
|
21
|
+
end
|
22
|
+
print '> '
|
23
|
+
select = $stdin.gets
|
24
|
+
select = select && select.chomp
|
25
|
+
if (1..(histories.length)).include?(select.to_i)
|
26
|
+
history = histories[select.to_i - 1]
|
27
|
+
@options = history.last
|
28
|
+
@argv_str = history.first
|
29
|
+
else
|
30
|
+
puts
|
31
|
+
JRubySQL::OptionParser.parse []
|
32
|
+
end
|
33
|
+
end
|
34
|
+
else
|
35
|
+
@options = options
|
36
|
+
@argv_str = argv_str
|
37
|
+
end
|
38
|
+
|
39
|
+
@db_type = JRubySQL::RDBMS.get_type(@options[:type] || @options[:driver])
|
40
|
+
|
41
|
+
# Setting up input: file or console (and more?)
|
42
|
+
if @options[:filename]
|
43
|
+
@input = JRubySQL::Input::File.new(self, @options[:filename])
|
44
|
+
else
|
45
|
+
@input = JRubySQL::Input::Console.new(self)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Setting up output: Colored terminal
|
49
|
+
case @options[:output]
|
50
|
+
when 'cterm'
|
51
|
+
@output = JRubySQL::Output::CTerm.new
|
52
|
+
when 'term'
|
53
|
+
@output = JRubySQL::Output::Term.new
|
54
|
+
when 'csv'
|
55
|
+
@output = JRubySQL::Output::CSV.new
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def start
|
60
|
+
@output.welcome!
|
61
|
+
@output.info m(:connecting)
|
62
|
+
begin
|
63
|
+
@rdbms = JRubySQL::RDBMS.new @options
|
64
|
+
rescue Exception => e
|
65
|
+
@output.error e.to_s
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
@output.info m(:connected)
|
69
|
+
|
70
|
+
history = @config['connections'] || []
|
71
|
+
history.unshift [@argv_str, @options]
|
72
|
+
history.uniq!
|
73
|
+
if history.length > JRubySQL::Constants::MAX_CONNECTION_HISTORY
|
74
|
+
history = history[0, JRubySQL::Constants::MAX_CONNECTION_HISTORY]
|
75
|
+
end
|
76
|
+
@config['connections'] = history
|
77
|
+
|
78
|
+
loop do
|
79
|
+
ret = @input.get
|
80
|
+
|
81
|
+
ret[:sqls].each do |sql|
|
82
|
+
begin
|
83
|
+
output @rdbms.execute(sql)
|
84
|
+
rescue Exception => e
|
85
|
+
@output.error e.to_s
|
86
|
+
end
|
87
|
+
end if ret.has_key?(:sqls)
|
88
|
+
|
89
|
+
ret[:commands].each do |command|
|
90
|
+
process_command command.keys.first, command.values.first
|
91
|
+
end if ret.has_key?(:commands)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def cursor empty = true
|
96
|
+
@output.cursor empty
|
97
|
+
end
|
98
|
+
|
99
|
+
def print_cursor empty = true
|
100
|
+
@output.print_cursor empty
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
def output result
|
105
|
+
@output.print_result result
|
106
|
+
end
|
107
|
+
|
108
|
+
def process_command cmd, params
|
109
|
+
case cmd
|
110
|
+
when :help
|
111
|
+
@output.print_help
|
112
|
+
when :quit
|
113
|
+
@output.info m(:goodbye)
|
114
|
+
quit!
|
115
|
+
when :delimiter
|
116
|
+
@output.info m(:set_delimiter, params)
|
117
|
+
@input.delimiter = params
|
118
|
+
when :now
|
119
|
+
@output.info Time.now.strftime('%Y/%m/%d %H:%M:%S.%L')
|
120
|
+
when :autocommit
|
121
|
+
if params.nil?
|
122
|
+
@output.info m(:current_autocommit, @rdbms.autocommit ? 'on' : 'off')
|
123
|
+
elsif %[on off].include?(params.downcase)
|
124
|
+
@rdbms.autocommit = params.downcase == 'on'
|
125
|
+
@output.info m(:turn_autocommit, params.downcase)
|
126
|
+
else
|
127
|
+
@output.error m(:invalid_autocommit, params)
|
128
|
+
end
|
129
|
+
else
|
130
|
+
# TODO
|
131
|
+
@output.error m(:unknown_command)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def quit!
|
136
|
+
@rdbms.close rescue nil
|
137
|
+
exit 0
|
138
|
+
end
|
139
|
+
|
140
|
+
end#Controller
|
141
|
+
end#JRubySQL
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% title = JRubySQL.name %>
|
2
|
+
<%= title %>
|
3
|
+
<%= '=' * title.length %>
|
4
|
+
|
5
|
+
help Display this message.
|
6
|
+
<SQL> Execute the SQL.
|
7
|
+
autocommit [<on|off>] Show/enable/disable autocommit. (default: on)
|
8
|
+
delimiter <DELIMITER> Change SQL delimiter.
|
9
|
+
now Display current timestamp.
|
10
|
+
exit Exit JRubySQL.
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'readline'
|
2
|
+
|
3
|
+
module JRubySQL
|
4
|
+
module Input
|
5
|
+
class Console
|
6
|
+
def initialize controller
|
7
|
+
@controller = controller
|
8
|
+
@esql = JRubySQL::Input.get_parser @controller.db_type
|
9
|
+
end
|
10
|
+
|
11
|
+
def get
|
12
|
+
empty_response = { :sqls => [], :commands => [] }
|
13
|
+
line = Readline::readline(@controller.cursor(@esql.empty?), false)
|
14
|
+
|
15
|
+
return(
|
16
|
+
# CTRL-D
|
17
|
+
if line.nil?
|
18
|
+
puts
|
19
|
+
@esql.clear
|
20
|
+
empty_response
|
21
|
+
# Empty input (not inside a block)
|
22
|
+
elsif @esql.empty? && line.gsub(/\s/m, '').empty?
|
23
|
+
empty_response
|
24
|
+
# Console commands
|
25
|
+
elsif @esql.empty? && cmd = process_command(line)
|
26
|
+
{ :commands => [cmd].compact }
|
27
|
+
# Line with delimiters
|
28
|
+
elsif line.include?(@esql.delimiter)
|
29
|
+
@esql << line + ' '
|
30
|
+
result = @esql.shift
|
31
|
+
result[:sqls].each do |sql|
|
32
|
+
Readline::HISTORY << sql + @esql.delimiter
|
33
|
+
end
|
34
|
+
{ :sqls => result[:sqls] }
|
35
|
+
# SQL without delimiter
|
36
|
+
else
|
37
|
+
@esql << line + ' '
|
38
|
+
empty_response
|
39
|
+
end
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def delimiter
|
44
|
+
@esql.delimiter
|
45
|
+
end
|
46
|
+
|
47
|
+
def delimiter= delim
|
48
|
+
@esql.delimiter = delim
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def process
|
54
|
+
result = @esql.shift
|
55
|
+
result[:sqls].each do |sql|
|
56
|
+
Readline::HISTORY << sql + ';'
|
57
|
+
@controller.execute sql
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def process_command line
|
62
|
+
Readline::HISTORY << line
|
63
|
+
case line.chomp.downcase.strip
|
64
|
+
when /^help(#{Regexp.escape delimiter})?$/
|
65
|
+
{ :help => nil }
|
66
|
+
when /^delimiter (\S+$)/
|
67
|
+
{ :delimiter => $1 }
|
68
|
+
when 'autocommit'
|
69
|
+
{ :autocommit => nil }
|
70
|
+
when /^autocommit (\S+?)(#{Regexp.escape delimiter})?$/
|
71
|
+
{ :autocommit => $1 }
|
72
|
+
when 'now'
|
73
|
+
{ :now => nil }
|
74
|
+
when /^(exit|quit)(#{Regexp.escape delimiter})?$/
|
75
|
+
{ :quit => nil }
|
76
|
+
else
|
77
|
+
Readline::HISTORY.pop
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end#Console
|
82
|
+
end#Input
|
83
|
+
end#JRubySQL
|
84
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'each_sql'
|
2
|
+
|
3
|
+
module JRubySQL
|
4
|
+
module Input
|
5
|
+
class File
|
6
|
+
def initialize controller, file_path
|
7
|
+
@controller = controller
|
8
|
+
script = ::File.read(file_path)
|
9
|
+
sqls = EachSQL(script, JRubySQL::Input.get_each_sql_type(@controller.db_type))
|
10
|
+
@ret = { :sqls => sqls }
|
11
|
+
end
|
12
|
+
|
13
|
+
def get
|
14
|
+
@ret.tap { @ret = { :commands => [{ :quit => nil }] } }
|
15
|
+
end
|
16
|
+
end#Console
|
17
|
+
end#Input
|
18
|
+
end#JRubySQL
|
19
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'each_sql'
|
2
|
+
|
3
|
+
module JRubySQL
|
4
|
+
module Input
|
5
|
+
def self.get_each_sql_type db_type
|
6
|
+
{
|
7
|
+
:mysql => :mysql,
|
8
|
+
:oracle => :oracle,
|
9
|
+
:postgres => :postgres
|
10
|
+
}[db_type] || :default
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.get_parser db_type, delimiter = ';'
|
14
|
+
EachSQL.new(get_each_sql_type(db_type), delimiter)
|
15
|
+
end
|
16
|
+
end#Input
|
17
|
+
end#JRubySQL
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'insensitive_hash/minimal'
|
3
|
+
|
4
|
+
module JRubySQL
|
5
|
+
module Messages
|
6
|
+
def m *args
|
7
|
+
args = args.dup
|
8
|
+
type = args.shift
|
9
|
+
msg = MESSAGES[type]
|
10
|
+
args.each do |arg|
|
11
|
+
msg = msg.sub('$$', arg.to_s)
|
12
|
+
end
|
13
|
+
msg
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
MESSAGES =
|
18
|
+
InsensitiveHash[
|
19
|
+
YAML.load(File.read File.join( File.dirname(__FILE__), 'messages.yml' ))
|
20
|
+
].tap { |ih| ih.underscore = true }
|
21
|
+
end#Messages
|
22
|
+
end#JRubySQL
|
23
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
---
|
2
|
+
choose parameter:
|
3
|
+
"Parameter not given. Choose one:"
|
4
|
+
ask password:
|
5
|
+
"Password: "
|
6
|
+
|
7
|
+
invalid connection:
|
8
|
+
Invalid connection specification
|
9
|
+
unsupported database:
|
10
|
+
$$ is not supported yet. Try with -c and -j options instead.
|
11
|
+
oracle service name required:
|
12
|
+
Oracle service name must be included in the hostname: e.g. localhost:1521/orcl
|
13
|
+
invalid output:
|
14
|
+
Invalid output type.
|
15
|
+
file not found:
|
16
|
+
"File not found: $$"
|
17
|
+
|
18
|
+
connecting:
|
19
|
+
Connecting to the database ...
|
20
|
+
connected:
|
21
|
+
Connected.
|
22
|
+
|
23
|
+
set delimiter:
|
24
|
+
Setting delimiter to $$
|
25
|
+
current autocommit:
|
26
|
+
"Current autocommit: $$"
|
27
|
+
turn autocommit:
|
28
|
+
"Turning autocommit $$"
|
29
|
+
invalid autocommit:
|
30
|
+
"Invalid option: '$$'. Required: [on|off]"
|
31
|
+
unknown command:
|
32
|
+
Unknown command. Possibly a bug.
|
33
|
+
goodbye:
|
34
|
+
Goodbye!
|
35
|
+
|
36
|
+
interrupted:
|
37
|
+
Interrupted.
|
38
|
+
|
39
|
+
rows returned:
|
40
|
+
$$ row$$. $$
|
41
|
+
rows affected:
|
42
|
+
$$ row$$ affected. $$
|
43
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'highline'
|
3
|
+
|
4
|
+
module JRubySQL
|
5
|
+
module OptionParser
|
6
|
+
class << self
|
7
|
+
include JRubySQL::Messages
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.parse argv
|
11
|
+
{:output => 'cterm'}.tap do |options|
|
12
|
+
opts = ::OptionParser.new { |opts|
|
13
|
+
opts.banner =
|
14
|
+
[
|
15
|
+
"usage: jrubysql [options]",
|
16
|
+
" jrubysql -t DBMS_TYPE -h HOSTNAME [-u USERNAME -p [PASSWORD] [-d DATABASE]] [-f FILENAME]",
|
17
|
+
" jrubysql -c CLASSNAME -j JDBC_URL [-u USERNAME -p [PASSWORD] [-d DATABASE]] [-f FILENAME]"
|
18
|
+
].join($/)
|
19
|
+
opts.separator ''
|
20
|
+
|
21
|
+
opts.on('-t', '--type DBMS_TYPE', 'Database type: mysql/oracle/postgres/sqlserver') do |v|
|
22
|
+
options[:type] = v.downcase.to_sym
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('-h', '--host HOST', 'DBMS host address') do |v|
|
26
|
+
options[:host] = v
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.separator ""
|
30
|
+
|
31
|
+
opts.on('-c', '--class-name CLASSNAME', 'Class name of the JDBC driver') do |v|
|
32
|
+
options[:driver] = v
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on('-j', '--jdbc-url JDBC_URL', 'JDBC URL for the connection') do |v|
|
36
|
+
options[:url] = v
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.separator ""
|
40
|
+
|
41
|
+
opts.on('-u', '--user USERNAME', 'Username') do |v|
|
42
|
+
options[:user] = v
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('-p', '--password [PASSWORD]', 'Password') do |v|
|
46
|
+
options[:password] = v
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on('-d', '--database DATABASE', 'Name of the database (optional)') do |v|
|
50
|
+
options[:database] = v
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.separator ""
|
54
|
+
|
55
|
+
opts.on('-f', '--filename FILENAME', 'SQL script file') do |v|
|
56
|
+
options[:filename] = v
|
57
|
+
end
|
58
|
+
|
59
|
+
opts.on('-o', '--output OUTPUT_TYPE', 'Output type: cterm|term|csv (default: cterm)') do |v|
|
60
|
+
options[:output] = v
|
61
|
+
end
|
62
|
+
|
63
|
+
opts.separator ""
|
64
|
+
|
65
|
+
opts.on_tail('--help', "Show this message") do
|
66
|
+
puts opts
|
67
|
+
exit
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on_tail('--version', "Show version") do
|
71
|
+
puts JRubySQL.name
|
72
|
+
exit
|
73
|
+
end
|
74
|
+
}
|
75
|
+
begin
|
76
|
+
opts.parse! argv
|
77
|
+
if options.has_key?(:password) && options[:password].nil?
|
78
|
+
options[:password] = ask_password
|
79
|
+
end
|
80
|
+
|
81
|
+
validate options
|
82
|
+
rescue SystemExit
|
83
|
+
exit 0
|
84
|
+
rescue Exception => e
|
85
|
+
puts e.to_s
|
86
|
+
puts '=' * e.to_s.length
|
87
|
+
puts opts
|
88
|
+
exit 1
|
89
|
+
end
|
90
|
+
end#tap
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def self.validate opts
|
95
|
+
unless %w[cterm term csv].include?(opts[:output])
|
96
|
+
raise ArgumentError.new m(:invalid_output)
|
97
|
+
end
|
98
|
+
|
99
|
+
if (!opts[:type] && !opts[:driver]) || (opts[:type] && opts[:driver])
|
100
|
+
raise ArgumentError.new m(:invalid_connection)
|
101
|
+
end
|
102
|
+
|
103
|
+
unless (opts[:type] && opts[:host]) || (opts[:driver] && opts[:url])
|
104
|
+
raise ArgumentError.new m(:invalid_connection)
|
105
|
+
end
|
106
|
+
|
107
|
+
if opts[:type] && !JRubySQL::Constants::SUPPORTED_DBMS_TYPES.include?(opts[:type])
|
108
|
+
raise ArgumentError.new m(:unsupported_database, opts[:type])
|
109
|
+
end
|
110
|
+
|
111
|
+
if opts[:filename] && !File.exists?(opts[:filename])
|
112
|
+
raise ArgumentError.new m(:file_not_found, opts[:filename])
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.ask_password
|
118
|
+
HighLine.new.ask(m(:ask_password)) { |q| q.echo = "*" }
|
119
|
+
end
|
120
|
+
|
121
|
+
end#OptionParser
|
122
|
+
end#JRubySQL
|
123
|
+
|
124
|
+
# p JRubySQL::OptionParser.parse %w[-h aa gg -t asdfa -p]
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module JRubySQL
|
4
|
+
module Output
|
5
|
+
class CSV
|
6
|
+
def welcome!; end
|
7
|
+
def info msg
|
8
|
+
$stderr.puts "[I] #{msg}"
|
9
|
+
end
|
10
|
+
def result msg
|
11
|
+
$stderr.puts "[R] #{msg}"
|
12
|
+
end
|
13
|
+
def warn msg
|
14
|
+
$stderr.puts "[W] #{msg}"
|
15
|
+
end
|
16
|
+
def error msg
|
17
|
+
$stderr.puts "[E] #{msg}"
|
18
|
+
end
|
19
|
+
def print_help; end
|
20
|
+
|
21
|
+
def cursor empty
|
22
|
+
''
|
23
|
+
end
|
24
|
+
|
25
|
+
def print_cursor empty; end
|
26
|
+
|
27
|
+
def print_result ret
|
28
|
+
# Footer
|
29
|
+
elapsed = "(#{'%.2f' % ret[:elapsed]} sec)"
|
30
|
+
|
31
|
+
if ret[:set?]
|
32
|
+
ret[:result].each_with_index do |row, idx|
|
33
|
+
puts ::CSV.generate_line(row.labels) if idx == 0
|
34
|
+
puts ::CSV.generate_line row.map { |col|
|
35
|
+
case col
|
36
|
+
when BigDecimal
|
37
|
+
col.to_s('F')
|
38
|
+
else
|
39
|
+
col
|
40
|
+
end
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end#CSV
|
47
|
+
end#Output
|
48
|
+
end#JRubySQL
|
49
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'ansi'
|
2
|
+
require 'erubis'
|
3
|
+
require 'bigdecimal'
|
4
|
+
|
5
|
+
module JRubySQL
|
6
|
+
module Output
|
7
|
+
class CTerm < Term
|
8
|
+
include ANSI::Code
|
9
|
+
HELP = Erubis::Eruby.new(File.read File.join(File.dirname(__FILE__), '../doc/help.txt.erb')).result(binding)
|
10
|
+
|
11
|
+
def welcome!
|
12
|
+
puts bold + JRubySQL.name + reset
|
13
|
+
end
|
14
|
+
|
15
|
+
def cursor empty
|
16
|
+
if empty
|
17
|
+
wrap('jrubysql', bold) +
|
18
|
+
wrap('> ', bold + green)
|
19
|
+
else
|
20
|
+
wrap(' -', bold + yellow) +
|
21
|
+
wrap('> ', bold + red)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def print_cursor empty
|
26
|
+
print cursor(empty)
|
27
|
+
end
|
28
|
+
|
29
|
+
def print_help
|
30
|
+
puts
|
31
|
+
puts wrap(HELP, blue + bold)
|
32
|
+
puts
|
33
|
+
end
|
34
|
+
|
35
|
+
def info message
|
36
|
+
col = blue + bold
|
37
|
+
puts wrap(message, col)
|
38
|
+
end
|
39
|
+
|
40
|
+
def result message
|
41
|
+
col = green
|
42
|
+
puts wrap(message, green)
|
43
|
+
end
|
44
|
+
|
45
|
+
def warn message
|
46
|
+
col = yellow + bold
|
47
|
+
puts wrap(message, col)
|
48
|
+
end
|
49
|
+
|
50
|
+
def error message
|
51
|
+
col = red + bold
|
52
|
+
puts wrap(message, col)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def separator_for row
|
57
|
+
# 13-bytes for ANSI codes
|
58
|
+
# - bold/reset: 4
|
59
|
+
# - colors: 5
|
60
|
+
'+-' + row.map { |e| '-' * (e.length - 13) }.join('-+-') + '-+'
|
61
|
+
end
|
62
|
+
|
63
|
+
def decorate_label label
|
64
|
+
white + bold + label + reset
|
65
|
+
end
|
66
|
+
|
67
|
+
# This looks stupid though.
|
68
|
+
def decorate value
|
69
|
+
case value
|
70
|
+
when BigDecimal
|
71
|
+
cyan + value.to_s('F') + reset + reset
|
72
|
+
when Numeric
|
73
|
+
cyan + value.to_s + reset + reset
|
74
|
+
when String
|
75
|
+
yellow + value + reset + reset
|
76
|
+
when Time, Java::JavaSql::Timestamp
|
77
|
+
magenta + value.to_s + reset + reset
|
78
|
+
when NilClass
|
79
|
+
bold + red + '(null)' + reset
|
80
|
+
else
|
81
|
+
white + reset + value.to_s + reset
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def cnow
|
86
|
+
green + now + reset
|
87
|
+
end
|
88
|
+
|
89
|
+
def wrap text, color
|
90
|
+
color + text + reset
|
91
|
+
end
|
92
|
+
|
93
|
+
end#CTerm
|
94
|
+
end#Output
|
95
|
+
end#JRubySQL
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
require 'tabularize'
|
3
|
+
require 'java'
|
4
|
+
|
5
|
+
module JRubySQL
|
6
|
+
module Output
|
7
|
+
class Term
|
8
|
+
include JRubySQL::Messages
|
9
|
+
|
10
|
+
HELP = Erubis::Eruby.new(File.read File.join(File.dirname(__FILE__), '../doc/help.txt.erb')).result(binding)
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
# Make use of JLine included in JRuby
|
14
|
+
java_import 'jline.Terminal'
|
15
|
+
@terminal = Terminal.getTerminal
|
16
|
+
trap 'INT' do
|
17
|
+
Thread.main.raise Interrupt
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def welcome!
|
22
|
+
puts JRubySQL.name
|
23
|
+
end
|
24
|
+
|
25
|
+
def cursor empty
|
26
|
+
if empty
|
27
|
+
'jrubysql> '
|
28
|
+
else
|
29
|
+
' -> '
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def print_cursor empty
|
34
|
+
print cursor(empty)
|
35
|
+
end
|
36
|
+
|
37
|
+
def print_help
|
38
|
+
puts
|
39
|
+
puts HELP
|
40
|
+
puts
|
41
|
+
end
|
42
|
+
|
43
|
+
def info message
|
44
|
+
puts "[I] #{message}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def result message
|
48
|
+
puts "[R] #{message}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def warn message
|
52
|
+
puts "[W] #{message}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def error message
|
56
|
+
puts "[E] #{message}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def print_result ret
|
60
|
+
# Footer
|
61
|
+
elapsed = "(#{'%.2f' % ret[:elapsed]} sec)"
|
62
|
+
|
63
|
+
if ret[:set?]
|
64
|
+
begin
|
65
|
+
cnt = print_table ret[:result]
|
66
|
+
result m(:rows_returned, cnt, cnt > 1 ? 's' : '', elapsed)
|
67
|
+
rescue Interrupt
|
68
|
+
warn m(:interrupted)
|
69
|
+
end
|
70
|
+
elsif ret[:result]
|
71
|
+
cnt = [0, ret[:result]].max
|
72
|
+
result m(:rows_affected, cnt, cnt > 1 ? 's' : '', elapsed)
|
73
|
+
else
|
74
|
+
result elapsed
|
75
|
+
end
|
76
|
+
puts
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def print_table ret
|
81
|
+
cnt = 0
|
82
|
+
lines = [(@terminal.getTerminalHeight rescue JRubySQL::Constants::MAX_SCREEN_ROWS) - 5,
|
83
|
+
JRubySQL::Constants::MIN_SCREEN_ROWS].max
|
84
|
+
ret.each_slice(lines) do |slice|
|
85
|
+
cnt += slice.length
|
86
|
+
|
87
|
+
table = [slice.first.labels.map { |l| decorate_label l }] +
|
88
|
+
slice.map { |row| row.to_a.map { |v| decorate v } }
|
89
|
+
|
90
|
+
output = Tabularize.it(table, :unicode_display => true)
|
91
|
+
separator = separator_for(output.first)
|
92
|
+
output_strs = output.map { |r| '| ' + r.join(' | ') + ' |' }
|
93
|
+
[0, 2, -1].each { |l| output_strs.insert l, separator }
|
94
|
+
puts output_strs
|
95
|
+
end
|
96
|
+
cnt
|
97
|
+
end
|
98
|
+
|
99
|
+
def separator_for row
|
100
|
+
'+-' + row.map { |e| '-' * e.length }.join('-+-') + '-+'
|
101
|
+
end
|
102
|
+
|
103
|
+
def decorate_label label
|
104
|
+
label
|
105
|
+
end
|
106
|
+
|
107
|
+
def decorate value
|
108
|
+
case value
|
109
|
+
when BigDecimal
|
110
|
+
value.to_s('F')
|
111
|
+
else
|
112
|
+
value.to_s
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def now
|
117
|
+
Time.now.strftime('%Y/%m/%d %H:%M:%S')
|
118
|
+
end
|
119
|
+
end#Term
|
120
|
+
end#Output
|
121
|
+
end#JRubySQL
|
122
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'jdbc-helper'
|
2
|
+
|
3
|
+
module JRubySQL
|
4
|
+
class RDBMS
|
5
|
+
include JRubySQL::Messages
|
6
|
+
|
7
|
+
def self.get_type driver_or_type
|
8
|
+
case driver_or_type.to_s.downcase
|
9
|
+
when /oracle/
|
10
|
+
:oracle
|
11
|
+
when /mysql/
|
12
|
+
:mysql
|
13
|
+
when /postgres/
|
14
|
+
:postgres
|
15
|
+
when /sqlserver/
|
16
|
+
:sqlserver
|
17
|
+
else
|
18
|
+
:unknown
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize options
|
23
|
+
@conn =
|
24
|
+
if options[:type]
|
25
|
+
case options[:type]
|
26
|
+
when :mysql
|
27
|
+
JDBCHelper::MySQLConnector.connect(
|
28
|
+
options[:host], options[:user], options[:password], options[:database])
|
29
|
+
when :oracle
|
30
|
+
host, svc = options[:host].split('/')
|
31
|
+
if svc.nil?
|
32
|
+
# FIXME
|
33
|
+
raise ArgumentError.new m(:oracle_service_name_required)
|
34
|
+
end
|
35
|
+
JDBCHelper::OracleConnector.connect(
|
36
|
+
host, options[:user], options[:password], svc)
|
37
|
+
when :postgres
|
38
|
+
JDBCHelper::PostgresConnector.connect(
|
39
|
+
options[:host], options[:user], options[:password], options[:database])
|
40
|
+
when :sqlserver
|
41
|
+
JDBCHelper::SqlServerConnector.connect(
|
42
|
+
options[:host], options[:user], options[:password], options[:database])
|
43
|
+
end
|
44
|
+
elsif options[:driver]
|
45
|
+
JDBCHelper::Connection.new(
|
46
|
+
{
|
47
|
+
:driver => options[:driver],
|
48
|
+
:url => options[:url],
|
49
|
+
:user => options[:user],
|
50
|
+
:password => options[:password]
|
51
|
+
}.reject { |k, v| v.nil? }
|
52
|
+
)
|
53
|
+
else
|
54
|
+
raise ArgumentError.new m(:invalid_connection)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def autocommit
|
59
|
+
@conn.java_obj.get_auto_commit
|
60
|
+
end
|
61
|
+
|
62
|
+
def autocommit= ac
|
63
|
+
@conn.java_obj.set_auto_commit ac
|
64
|
+
end
|
65
|
+
|
66
|
+
def close
|
67
|
+
@conn.close
|
68
|
+
end
|
69
|
+
|
70
|
+
def execute sql
|
71
|
+
st = Time.now
|
72
|
+
result = @conn.execute sql
|
73
|
+
elapsed = Time.now - st
|
74
|
+
|
75
|
+
{
|
76
|
+
:set? => result.respond_to?(:each),
|
77
|
+
:result => result,
|
78
|
+
:elapsed => elapsed
|
79
|
+
}
|
80
|
+
end
|
81
|
+
end#RDBMS
|
82
|
+
end#JRubySQL
|
data/lib/jrubysql.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "jrubysql/version"
|
2
|
+
|
3
|
+
if RUBY_PLATFORM.match(/java/).nil?
|
4
|
+
puts 'Sorry. jrubysql only runs on JRuby.'
|
5
|
+
exit 1
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'jrubysql/messages'
|
9
|
+
require 'jrubysql/config'
|
10
|
+
require 'jrubysql/constants'
|
11
|
+
require 'jrubysql/rdbms'
|
12
|
+
require 'jrubysql/option_parser'
|
13
|
+
require 'jrubysql/input/input'
|
14
|
+
require 'jrubysql/input/console'
|
15
|
+
require 'jrubysql/input/file'
|
16
|
+
require 'jrubysql/output/csv'
|
17
|
+
require 'jrubysql/output/term'
|
18
|
+
require 'jrubysql/output/cterm'
|
19
|
+
require 'jrubysql/controller'
|
20
|
+
|
21
|
+
module JRubySQL
|
22
|
+
def self.name
|
23
|
+
"JRubySQL #{JRubySQL::VERSION}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.launch argv
|
27
|
+
if argv.empty?
|
28
|
+
JRubySQL::Controller.new(nil, nil).start
|
29
|
+
else
|
30
|
+
argv_str = argv.join(' ')
|
31
|
+
options = JRubySQL::OptionParser.parse argv
|
32
|
+
JRubySQL::Controller.new(options, argv_str).start
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
data/test/test_cterm.rb
ADDED
File without changes
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
ENV['BUNDLE_GEMFILE'] = File.join(File.dirname(__FILE__), '..', 'Gemfile')
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
require 'test/unit'
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
|
8
|
+
class TestJRubySQL < Test::Unit::TestCase
|
9
|
+
end
|
File without changes
|
File without changes
|
metadata
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jrubysql
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Junegunn Choi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-15 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: test-unit
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ! '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
none: false
|
22
|
+
requirement: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
none: false
|
28
|
+
prerelease: false
|
29
|
+
type: :development
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: jdbc-helper
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ~>
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.7.2
|
37
|
+
none: false
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.7.2
|
43
|
+
none: false
|
44
|
+
prerelease: false
|
45
|
+
type: :runtime
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: insensitive_hash
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.2.3
|
53
|
+
none: false
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 0.2.3
|
59
|
+
none: false
|
60
|
+
prerelease: false
|
61
|
+
type: :runtime
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: tabularize
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.1.1
|
69
|
+
none: false
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.1.1
|
75
|
+
none: false
|
76
|
+
prerelease: false
|
77
|
+
type: :runtime
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: each_sql
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ~>
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 0.3.1
|
85
|
+
none: false
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.3.1
|
91
|
+
none: false
|
92
|
+
prerelease: false
|
93
|
+
type: :runtime
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: highline
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.6.11
|
101
|
+
none: false
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ~>
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 1.6.11
|
107
|
+
none: false
|
108
|
+
prerelease: false
|
109
|
+
type: :runtime
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: ansi
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ~>
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 1.4.2
|
117
|
+
none: false
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ~>
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 1.4.2
|
123
|
+
none: false
|
124
|
+
prerelease: false
|
125
|
+
type: :runtime
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: erubis
|
128
|
+
version_requirements: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ~>
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 2.7.0
|
133
|
+
none: false
|
134
|
+
requirement: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ~>
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.7.0
|
139
|
+
none: false
|
140
|
+
prerelease: false
|
141
|
+
type: :runtime
|
142
|
+
description: An SQL client for any JDBC-compliant database. Written in JRuby.
|
143
|
+
email:
|
144
|
+
- junegunn.c@gmail.com
|
145
|
+
executables:
|
146
|
+
- jrubysql
|
147
|
+
extensions: []
|
148
|
+
extra_rdoc_files: []
|
149
|
+
files:
|
150
|
+
- .gitignore
|
151
|
+
- Gemfile
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.md
|
154
|
+
- Rakefile
|
155
|
+
- bin/jrubysql
|
156
|
+
- jrubysql.gemspec
|
157
|
+
- lib/jrubysql.rb
|
158
|
+
- lib/jrubysql/config.rb
|
159
|
+
- lib/jrubysql/constants.rb
|
160
|
+
- lib/jrubysql/controller.rb
|
161
|
+
- lib/jrubysql/doc/help.txt.erb
|
162
|
+
- lib/jrubysql/input/console.rb
|
163
|
+
- lib/jrubysql/input/file.rb
|
164
|
+
- lib/jrubysql/input/input.rb
|
165
|
+
- lib/jrubysql/messages.rb
|
166
|
+
- lib/jrubysql/messages.yml
|
167
|
+
- lib/jrubysql/option_parser.rb
|
168
|
+
- lib/jrubysql/output/csv.rb
|
169
|
+
- lib/jrubysql/output/cterm.rb
|
170
|
+
- lib/jrubysql/output/term.rb
|
171
|
+
- lib/jrubysql/rdbms.rb
|
172
|
+
- lib/jrubysql/version.rb
|
173
|
+
- test/test_cterm.rb
|
174
|
+
- test/test_jrubysql.rb
|
175
|
+
- test/test_option_parser.rb
|
176
|
+
- test/test_term_output.rb
|
177
|
+
homepage: https://github.com/junegunn/jrubysql
|
178
|
+
licenses: []
|
179
|
+
post_install_message:
|
180
|
+
rdoc_options: []
|
181
|
+
require_paths:
|
182
|
+
- lib
|
183
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ! '>='
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
none: false
|
189
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - ! '>='
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
none: false
|
195
|
+
requirements: []
|
196
|
+
rubyforge_project: jrubysql
|
197
|
+
rubygems_version: 1.8.18
|
198
|
+
signing_key:
|
199
|
+
specification_version: 3
|
200
|
+
summary: An SQL client for any JDBC-compliant database.
|
201
|
+
test_files:
|
202
|
+
- test/test_cterm.rb
|
203
|
+
- test/test_jrubysql.rb
|
204
|
+
- test/test_option_parser.rb
|
205
|
+
- test/test_term_output.rb
|
206
|
+
...
|