rsql 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +25 -11
- data/bin/rsql +69 -48
- data/example.rsqlrc +1 -1
- data/lib/rsql.rb +1 -2
- data/lib/rsql/eval_context.rb +23 -8
- data/lib/rsql/mysql_results.rb +6 -1
- data/test/test_commands.rb +0 -1
- data/test/test_eval_context.rb +0 -1
- data/test/test_mysql_results.rb +0 -1
- metadata +33 -21
- data/lib/rsql/mysql.rb +0 -1127
- data/test/dummy_mysql.rb +0 -11
data/README.rdoc
CHANGED
@@ -44,11 +44,11 @@ RSQL is invoked from the comamnd line using:
|
|
44
44
|
separate fields with a tab character).
|
45
45
|
|
46
46
|
-ssh _ssh_host_::
|
47
|
-
Establish
|
47
|
+
Establish a SSH connection before connecting to the MySQL host.
|
48
48
|
|
49
49
|
-sshconfig _ssh_config_::
|
50
|
-
Use a specific SSH configuration file instead of the
|
51
|
-
|
50
|
+
Use a specific SSH configuration file instead of the default files
|
51
|
+
loaded at runtime by Net::SSH.
|
52
52
|
|
53
53
|
-e [_query_]::
|
54
54
|
Run a query from the command line (i.e. not interactive). If a
|
@@ -58,21 +58,33 @@ RSQL is invoked from the comamnd line using:
|
|
58
58
|
*must* be the last option specified.
|
59
59
|
|
60
60
|
The _ssh_host_ and _mysql_host_ arguments may optionally include
|
61
|
-
_user_
|
61
|
+
_user_, _password_, or _port_ values using the following syntax:
|
62
62
|
|
63
|
-
[<user>[:<password>]@]<host>
|
64
|
-
|
65
|
-
An empty password can be provided by simply listing nothing between
|
66
|
-
demarcation points:
|
67
|
-
|
68
|
-
root:@127.0.0.1
|
63
|
+
[<user>[:<password>]@]<host>[:<port>]
|
69
64
|
|
70
65
|
Once at the +rsql+ prompt, normal MySQL queries can be entered as
|
71
66
|
expected, ending each with a semicolon (;) for columnar output or \G
|
72
67
|
for line-by-line output formatting.
|
73
68
|
|
74
69
|
Ruby commands will be evaluated for any content entered at the RSQL
|
75
|
-
prompt beginning with a period
|
70
|
+
prompt beginning with a period.
|
71
|
+
|
72
|
+
==== Command Line Examples
|
73
|
+
|
74
|
+
Connect as the "root" user to a MySQL server running on the local
|
75
|
+
host, with no password (because there are no characters listed between
|
76
|
+
the colon and the at sign):
|
77
|
+
|
78
|
+
rsql root:@127.0.0.1
|
79
|
+
|
80
|
+
Connect as the "readonly" user to the "internal.database.com" host's
|
81
|
+
MySQL server after establishing a SSH tunnel to the
|
82
|
+
"external.acme.com" gateway. In this case, we are either expecting
|
83
|
+
that our SSH configuration is set up with the right user name. Because
|
84
|
+
we did not provide a password for MySQL, one will be obtained directly
|
85
|
+
from the console (without echoing the characters typed):
|
86
|
+
|
87
|
+
rsql -ssh external.acme.com readonly@database.acme.com
|
76
88
|
|
77
89
|
== GETTING STARTED
|
78
90
|
|
@@ -86,6 +98,8 @@ downloaded with the source.
|
|
86
98
|
|
87
99
|
== LICENSE
|
88
100
|
|
101
|
+
RSQL is licensed under the MIT License:
|
102
|
+
|
89
103
|
Copyright (C) 2011 by Brad Robel-Forrest <brad+rsql@gigglewax.com>
|
90
104
|
|
91
105
|
Permission is hereby granted, free of charge, to any person obtaining
|
data/bin/rsql
CHANGED
@@ -27,6 +27,7 @@ begin
|
|
27
27
|
rescue LoadError
|
28
28
|
end
|
29
29
|
|
30
|
+
require 'tmpdir'
|
30
31
|
require 'thread'
|
31
32
|
require 'timeout'
|
32
33
|
require 'readline'
|
@@ -92,10 +93,12 @@ def get_password(prompt)
|
|
92
93
|
end
|
93
94
|
|
94
95
|
# safely separate login credentials while preserving "emtpy" values--
|
95
|
-
# anything of the form [<username>[:<password]@]<host>
|
96
|
+
# anything of the form [<username>[:<password]@]<host>[:<port>]
|
96
97
|
#
|
97
98
|
def split_login(str)
|
98
99
|
login = []
|
100
|
+
# search from the right so we don't pick out ampersands in a
|
101
|
+
# password or username
|
99
102
|
if i = str.rindex(?@)
|
100
103
|
login << str[i+1..-1]
|
101
104
|
if 0 < i
|
@@ -114,6 +117,11 @@ def split_login(str)
|
|
114
117
|
else
|
115
118
|
login << str
|
116
119
|
end
|
120
|
+
if login.first.sub!(/:(\d+)$/,'')
|
121
|
+
login << $1.to_i
|
122
|
+
else
|
123
|
+
login << nil
|
124
|
+
end
|
117
125
|
end
|
118
126
|
|
119
127
|
if ARGV.delete('-version')
|
@@ -139,7 +147,7 @@ end
|
|
139
147
|
if i = ARGV.index('-ssh')
|
140
148
|
require 'net/ssh'
|
141
149
|
ARGV.delete_at(i)
|
142
|
-
(ssh_host, ssh_user, ssh_password) = split_login(ARGV.delete_at(i))
|
150
|
+
(ssh_host, ssh_user, ssh_password, ssh_port) = split_login(ARGV.delete_at(i))
|
143
151
|
end
|
144
152
|
|
145
153
|
if i = ARGV.index('-sshconfig')
|
@@ -165,8 +173,9 @@ if ARGV.size < 1
|
|
165
173
|
|
166
174
|
usage: #{bn} [-version] [-help] [-verbose]
|
167
175
|
#{prefix}[-rc <rcfile>] [-maxrows <max>] [-batch <field_separator>]
|
168
|
-
#{prefix}[-ssh [<ssh_user>[:<ssh_password>]@]<ssh_host>
|
169
|
-
#{prefix}[<
|
176
|
+
#{prefix}[-ssh [<ssh_user>[:<ssh_password>]@]<ssh_host>[:<ssh_port>]
|
177
|
+
#{prefix}[-sshconfig <ssh_config>]
|
178
|
+
#{prefix}[<mysql_user>[:<mysql_password>]@]<mysql_host>[:<mysql_port>]
|
170
179
|
#{prefix}[<database>] [-e <remaining_args_as_input>]
|
171
180
|
|
172
181
|
If -ssh is used, a SSH tunnel is established before trying to
|
@@ -180,14 +189,15 @@ USAGE
|
|
180
189
|
exit 1
|
181
190
|
end
|
182
191
|
|
183
|
-
(mysql_host, mysql_user, mysql_password) = split_login(ARGV.shift)
|
184
|
-
mysql_password ||= get_password("#{
|
192
|
+
(mysql_host, mysql_user, mysql_password, mysql_port) = split_login(ARGV.shift)
|
193
|
+
mysql_password ||= get_password("#{mysql_user}@#{mysql_host} MySQL password: ")
|
185
194
|
real_mysql_host = mysql_host
|
186
195
|
|
187
196
|
if ssh_host
|
188
197
|
# randomly pick a tcp port above 1024
|
198
|
+
remote_mysql_port = mysql_port || 3306
|
189
199
|
mysql_port = rand(0xffff-1025) + 1025
|
190
|
-
|
200
|
+
elsif mysql_port.nil?
|
191
201
|
mysql_port = 3306
|
192
202
|
end
|
193
203
|
|
@@ -227,20 +237,35 @@ end
|
|
227
237
|
|
228
238
|
MySQLResults.max_rows ||= batch_output ? 5000 : 1000
|
229
239
|
|
230
|
-
ssh_enabled = false
|
231
|
-
|
232
240
|
if ssh_host
|
233
241
|
|
234
242
|
# might need to open an idle channel here so server doesn't close on
|
235
243
|
# us...or just loop reconnection here in the thread...
|
236
244
|
|
237
|
-
port_opened = false
|
238
|
-
getting_password = false
|
239
245
|
password_retry_cnt = 0
|
240
246
|
|
241
|
-
|
247
|
+
unless batch_input
|
248
|
+
print "SSH #{ssh_user}#{ssh_user ? '@' : ''}#{ssh_host}..."
|
249
|
+
$stdout.flush
|
250
|
+
end
|
251
|
+
|
252
|
+
# we have to run mysql in a separate process due to the blocking
|
253
|
+
# nature of its calls interfering with the pure ruby ssh
|
254
|
+
# calls...so we'll run ssh in the background since its only
|
255
|
+
# purpose is to forward us in for accessing the mysql server
|
256
|
+
|
257
|
+
# we'll use a poor-man's ipc to determine when the ssh process is
|
258
|
+
# ready
|
259
|
+
ipc_fn = File.join(Dir.tmpdir, "rsql_ssh_#{$$}.pid")
|
260
|
+
|
242
261
|
ssh = nil
|
243
|
-
|
262
|
+
ssh_pid = Process.fork do
|
263
|
+
File.open(ipc_fn,'w'){|f| f.puts('start')}
|
264
|
+
ssh_enabled = false
|
265
|
+
Signal.trap('INT') do
|
266
|
+
$stderr.puts 'Shutting down...'
|
267
|
+
ssh_enabled = false
|
268
|
+
end
|
244
269
|
opts = {:timeout => 15}
|
245
270
|
opts[:config] = ssh_config if ssh_config
|
246
271
|
if verbose
|
@@ -254,14 +279,14 @@ if ssh_host
|
|
254
279
|
opts[:password] = ssh_password if ssh_password
|
255
280
|
ssh = Net::SSH.start(ssh_host, ssh_user, opts)
|
256
281
|
ssh_enabled = true
|
282
|
+
printf "connected (#{$$})..."
|
283
|
+
$stdout.flush
|
257
284
|
rescue Net::SSH::AuthenticationFailed
|
258
285
|
if 2 < password_retry_cnt
|
259
286
|
$stderr.puts 'Permission denied. Giving up.'
|
260
287
|
else
|
261
288
|
$stderr.puts 'Permission denied, please try again.' if ssh_password
|
262
|
-
getting_password = true
|
263
289
|
ssh_password = get_password("#{ssh_user}@#{ssh_host} SSH password: ")
|
264
|
-
getting_password = false
|
265
290
|
unless ssh_password.empty?
|
266
291
|
password_retry_cnt += 1
|
267
292
|
retry
|
@@ -269,39 +294,25 @@ if ssh_host
|
|
269
294
|
end
|
270
295
|
end
|
271
296
|
if ssh_enabled
|
272
|
-
ssh.forward.local(mysql_port, mysql_host,
|
273
|
-
|
297
|
+
ssh.forward.local(mysql_port, mysql_host, remote_mysql_port)
|
298
|
+
puts(verbose ? "ready (#{mysql_port} => #{remote_mysql_port})" : 'ready')
|
299
|
+
File.open(ipc_fn,'w'){|f| f.puts('ready')}
|
274
300
|
ssh.loop(1) { ssh_enabled }
|
275
301
|
end
|
302
|
+
File.open(ipc_fn,'w'){|f| f.puts('fail')}
|
276
303
|
end
|
277
304
|
|
278
|
-
|
279
|
-
|
280
|
-
while getting_password
|
281
|
-
# give them extra time
|
282
|
-
sleep(1)
|
283
|
-
end
|
305
|
+
ipc_state = ''
|
306
|
+
60.times do
|
284
307
|
sleep(1)
|
308
|
+
File.open(ipc_fn,'r'){|f| ipc_state = f.gets.strip}
|
309
|
+
break if ipc_state == 'ready' || ipc_state == 'fail'
|
285
310
|
end
|
286
311
|
|
287
|
-
|
288
|
-
$stderr.puts "failed to connect to #{ssh_host} SSH host"
|
289
|
-
begin
|
290
|
-
ssh_thread.join
|
291
|
-
rescue Exception => ex
|
292
|
-
$stderr.puts(" => #{ex.message} (#{ex.class})")
|
293
|
-
end
|
294
|
-
exit 1
|
295
|
-
end
|
312
|
+
File.unlink(ipc_fn)
|
296
313
|
|
297
|
-
unless
|
298
|
-
$stderr.puts
|
299
|
-
"ssh host in 15 seconds")
|
300
|
-
begin
|
301
|
-
ssh_thread.join
|
302
|
-
rescue Exception => ex
|
303
|
-
$stderr.puts(" => #{ex.message}: #{ex.class}")
|
304
|
-
end
|
314
|
+
unless ipc_state == 'ready'
|
315
|
+
$stderr.puts "failed to connect to #{ssh_host} SSH host"
|
305
316
|
exit 1
|
306
317
|
end
|
307
318
|
|
@@ -309,16 +320,24 @@ if ssh_host
|
|
309
320
|
mysql_host = '127.0.0.1'
|
310
321
|
end
|
311
322
|
|
312
|
-
|
323
|
+
unless batch_input
|
324
|
+
print "MySQL #{mysql_user}@#{real_mysql_host}..."
|
325
|
+
$stdout.flush
|
326
|
+
end
|
327
|
+
|
328
|
+
mysql_conn = "#{mysql_host}:#{remote_mysql_port || mysql_port}"
|
329
|
+
|
313
330
|
begin
|
314
331
|
MySQLResults.conn = Mysql.new(mysql_host, mysql_user, mysql_password,
|
315
332
|
MySQLResults.database_name, mysql_port)
|
333
|
+
puts 'connected'
|
316
334
|
rescue Mysql::Error => ex
|
317
335
|
if ex.message.include?('Client does not support authentication')
|
318
|
-
$stderr.puts "failed to connect to #{
|
336
|
+
$stderr.puts "failed to connect to #{mysql_conn} mysql server: unknown credentials?"
|
319
337
|
else
|
320
|
-
$stderr.puts "failed to connect to #{
|
338
|
+
$stderr.puts "failed to connect to #{mysql_conn} mysql server: #{ex.message}"
|
321
339
|
end
|
340
|
+
$stderr.puts ex.backtrace if verbose
|
322
341
|
exit 1
|
323
342
|
rescue NoMethodError
|
324
343
|
# this happens when mysql tries to read four bytes and assume it
|
@@ -326,10 +345,12 @@ rescue NoMethodError
|
|
326
345
|
# because the connect succeeds due to the SSH forwarded port but
|
327
346
|
# then there isn't anybody connected on the remote side of the
|
328
347
|
# proxy
|
329
|
-
$stderr.puts "failed to connect to #{
|
348
|
+
$stderr.puts "failed to connect to #{mysql_conn} mysql server"
|
349
|
+
$stderr.puts ex.backtrace if verbose
|
330
350
|
exit 1
|
331
351
|
rescue Exception => ex
|
332
|
-
$stderr.puts "failed to connect to #{
|
352
|
+
$stderr.puts "failed to connect to #{mysql_conn} mysql server: #{ex.message} (#{ex.class})"
|
353
|
+
$stderr.puts ex.backtrace if verbose
|
333
354
|
exit 1
|
334
355
|
end
|
335
356
|
|
@@ -417,7 +438,6 @@ unless MySQLResults.conn.nil?
|
|
417
438
|
end
|
418
439
|
|
419
440
|
sleep(0.3)
|
420
|
-
ssh_enabled = false
|
421
441
|
|
422
442
|
if Readline::HISTORY.any?
|
423
443
|
if 100 < Readline::HISTORY.size
|
@@ -428,6 +448,7 @@ if Readline::HISTORY.any?
|
|
428
448
|
File.open(history_fn, 'w') {|f| YAML.dump(Readline::HISTORY.to_a, f)}
|
429
449
|
end
|
430
450
|
|
431
|
-
if
|
432
|
-
|
451
|
+
if ssh_pid && 0 <= ssh_pid
|
452
|
+
Process.kill('INT', ssh_pid)
|
453
|
+
Process.waitpid(ssh_pid)
|
433
454
|
end
|
data/example.rsqlrc
CHANGED
data/lib/rsql.rb
CHANGED
data/lib/rsql/eval_context.rb
CHANGED
@@ -149,13 +149,28 @@ module RSQL
|
|
149
149
|
end
|
150
150
|
|
151
151
|
begin
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
152
|
+
# in order to print out errors in a loaded script so
|
153
|
+
# that we have file/line info, we need to rescue their
|
154
|
+
# exceptions inside the evaluation
|
155
|
+
th = Thread.new do
|
156
|
+
eval('$SAFE=2;begin;' << content << %q{
|
157
|
+
rescue Exception => ex
|
158
|
+
if @verbose
|
159
|
+
$stderr.puts("#{ex.class}: #{ex.message}", ex.backtrace)
|
160
|
+
else
|
161
|
+
bt = []
|
162
|
+
ex.backtrace.each do |t|
|
163
|
+
break if t.include?('bin/rsql')
|
164
|
+
bt << t unless t.include?('lib/rsql/') || t.include?('(eval)')
|
165
|
+
end
|
166
|
+
$stderr.puts(ex.message.gsub(/\(eval\):\d+:/,''),bt)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
})
|
158
170
|
end
|
171
|
+
value = th.value
|
172
|
+
rescue Exception => ex
|
173
|
+
$stderr.puts(ex.message.gsub(/\(eval\):\d+:/,''))
|
159
174
|
ensure
|
160
175
|
$stdout = orig_stdout if stdout
|
161
176
|
end
|
@@ -409,7 +424,7 @@ module RSQL
|
|
409
424
|
|
410
425
|
if block.nil?
|
411
426
|
source = args.pop
|
412
|
-
sql =
|
427
|
+
sql = squeeze!(source.dup)
|
413
428
|
|
414
429
|
argstr = args.join(',')
|
415
430
|
usage << "(#{argstr})" unless argstr.empty?
|
@@ -534,7 +549,7 @@ module RSQL
|
|
534
549
|
|
535
550
|
# Squeeze out any spaces.
|
536
551
|
#
|
537
|
-
def
|
552
|
+
def squeeze!(sql) # :doc:
|
538
553
|
sql.gsub!(/\s+/,' ')
|
539
554
|
sql.strip!
|
540
555
|
sql << ';' unless sql[-1] == ?;
|
data/lib/rsql/mysql_results.rb
CHANGED
@@ -21,12 +21,17 @@
|
|
21
21
|
|
22
22
|
module RSQL
|
23
23
|
|
24
|
+
require 'mysql'
|
25
|
+
|
24
26
|
########################################
|
25
27
|
# A wrapper to make it easier to work with MySQL results (and prettier).
|
26
28
|
#
|
27
29
|
class MySQLResults
|
28
30
|
|
29
|
-
HEX_RANGE =
|
31
|
+
HEX_RANGE = [
|
32
|
+
Mysql::Field::TYPE_BLOB,
|
33
|
+
Mysql::Field::TYPE_STRING,
|
34
|
+
]
|
30
35
|
|
31
36
|
@@conn = nil
|
32
37
|
@@field_separator = ' '
|
data/test/test_commands.rb
CHANGED
data/test/test_eval_context.rb
CHANGED
data/test/test_mysql_results.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brad Robel-Forrest
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-09-18 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: net-ssh
|
@@ -34,9 +34,25 @@ dependencies:
|
|
34
34
|
type: :runtime
|
35
35
|
version_requirements: *id001
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
37
|
+
name: mysql
|
38
38
|
prerelease: false
|
39
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 47
|
45
|
+
segments:
|
46
|
+
- 2
|
47
|
+
- 8
|
48
|
+
- 0
|
49
|
+
version: 2.8.0
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: mocha
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
40
56
|
none: false
|
41
57
|
requirements:
|
42
58
|
- - ">="
|
@@ -48,11 +64,11 @@ dependencies:
|
|
48
64
|
- 12
|
49
65
|
version: 0.9.12
|
50
66
|
type: :development
|
51
|
-
version_requirements: *
|
67
|
+
version_requirements: *id003
|
52
68
|
- !ruby/object:Gem::Dependency
|
53
69
|
name: rake
|
54
70
|
prerelease: false
|
55
|
-
requirement: &
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
56
72
|
none: false
|
57
73
|
requirements:
|
58
74
|
- - ">="
|
@@ -62,11 +78,11 @@ dependencies:
|
|
62
78
|
- 0
|
63
79
|
version: "0"
|
64
80
|
type: :development
|
65
|
-
version_requirements: *
|
81
|
+
version_requirements: *id004
|
66
82
|
- !ruby/object:Gem::Dependency
|
67
83
|
name: rdoc
|
68
84
|
prerelease: false
|
69
|
-
requirement: &
|
85
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
70
86
|
none: false
|
71
87
|
requirements:
|
72
88
|
- - ">="
|
@@ -76,11 +92,11 @@ dependencies:
|
|
76
92
|
- 0
|
77
93
|
version: "0"
|
78
94
|
type: :development
|
79
|
-
version_requirements: *
|
95
|
+
version_requirements: *id005
|
80
96
|
- !ruby/object:Gem::Dependency
|
81
97
|
name: rcov
|
82
98
|
prerelease: false
|
83
|
-
requirement: &
|
99
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
84
100
|
none: false
|
85
101
|
requirements:
|
86
102
|
- - ">="
|
@@ -90,7 +106,7 @@ dependencies:
|
|
90
106
|
- 0
|
91
107
|
version: "0"
|
92
108
|
type: :development
|
93
|
-
version_requirements: *
|
109
|
+
version_requirements: *id006
|
94
110
|
description: |
|
95
111
|
RSQL makes working with a MySQL command line more convenient through
|
96
112
|
the use of recipes and embedding the common operation of using a SSH
|
@@ -112,11 +128,9 @@ files:
|
|
112
128
|
- lib/rsql/commands.rb
|
113
129
|
- lib/rsql/eval_context.rb
|
114
130
|
- lib/rsql/mysql_results.rb
|
115
|
-
- test/dummy_mysql.rb
|
116
131
|
- test/test_commands.rb
|
117
132
|
- test/test_eval_context.rb
|
118
133
|
- test/test_mysql_results.rb
|
119
|
-
- lib/rsql/mysql.rb
|
120
134
|
homepage: https://rubygems.org/gems/rsql
|
121
135
|
licenses: []
|
122
136
|
|
@@ -126,8 +140,6 @@ rdoc_options:
|
|
126
140
|
- RSQL Documentation
|
127
141
|
- --main
|
128
142
|
- README.rdoc
|
129
|
-
- --exclude
|
130
|
-
- mysql.rb
|
131
143
|
require_paths:
|
132
144
|
- lib
|
133
145
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -135,12 +147,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
147
|
requirements:
|
136
148
|
- - ">="
|
137
149
|
- !ruby/object:Gem::Version
|
138
|
-
hash:
|
150
|
+
hash: 55
|
139
151
|
segments:
|
140
152
|
- 1
|
141
153
|
- 8
|
142
|
-
-
|
143
|
-
version: 1.8.
|
154
|
+
- 0
|
155
|
+
version: 1.8.0
|
144
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
157
|
none: false
|
146
158
|
requirements:
|
@@ -153,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
165
|
requirements: []
|
154
166
|
|
155
167
|
rubyforge_project:
|
156
|
-
rubygems_version: 1.8.
|
168
|
+
rubygems_version: 1.8.10
|
157
169
|
signing_key:
|
158
170
|
specification_version: 3
|
159
171
|
summary: Ruby based MySQL command line with recipes.
|