aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/vendor/mysql.rb
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2005-11-09 06:43:40 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2005-11-09 06:43:40 +0000
commit44591ffb710701993ffdec0b61185f8067e4e78f (patch)
tree8d4937ae9e9eb4077435b1eafe4a2d11b0aac281 /activerecord/lib/active_record/vendor/mysql.rb
parentbb4c32e2b5858b25524191ee4868e616fa5bd9be (diff)
downloadrails-44591ffb710701993ffdec0b61185f8067e4e78f.tar.gz
rails-44591ffb710701993ffdec0b61185f8067e4e78f.tar.bz2
rails-44591ffb710701993ffdec0b61185f8067e4e78f.zip
r3886@sedna: jeremy | 2005-11-07 03:09:59 -0800
r3944@sedna: jeremy | 2005-11-09 01:29:56 -0800 Upgrade bundled ruby-mysql 0.2.4 with mysql411 shim (see #440) to ruby-mysql0.2.6 with a patchset for 4.1 protocol support. Local change [301] is now apart of the main driver; reapplied local change [2182]. Removed GC.start fromResult.free. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2947 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/vendor/mysql.rb')
-rw-r--r--activerecord/lib/active_record/vendor/mysql.rb101
1 files changed, 89 insertions, 12 deletions
diff --git a/activerecord/lib/active_record/vendor/mysql.rb b/activerecord/lib/active_record/vendor/mysql.rb
index 39ceb607b0..bcf667f575 100644
--- a/activerecord/lib/active_record/vendor/mysql.rb
+++ b/activerecord/lib/active_record/vendor/mysql.rb
@@ -1,14 +1,15 @@
-# $Id: mysql.rb,v 1.1 2004/02/24 15:42:29 webster132 Exp $
+# $Id: mysql.rb,v 1.24 2005/02/12 11:37:15 tommy Exp $
#
-# Copyright (C) 2003 TOMITA Masahiro
+# Copyright (C) 2003-2005 TOMITA Masahiro
# tommy@tmtm.org
#
class Mysql
- VERSION = "4.0-ruby-0.2.4"
+ VERSION = "4.0-ruby-0.2.5"
require "socket"
+ require "digest/sha1"
MAX_PACKET_LENGTH = 256*256*256-1
MAX_ALLOWED_PACKET = 1024*1024*1024
@@ -51,11 +52,15 @@ class Mysql
CLIENT_ODBC = 1 << 6
CLIENT_LOCAL_FILES = 1 << 7
CLIENT_IGNORE_SPACE = 1 << 8
+ CLIENT_PROTOCOL_41 = 1 << 9
CLIENT_INTERACTIVE = 1 << 10
CLIENT_SSL = 1 << 11
CLIENT_IGNORE_SIGPIPE = 1 << 12
CLIENT_TRANSACTIONS = 1 << 13
+ CLIENT_RESERVED = 1 << 14
+ CLIENT_SECURE_CONNECTION = 1 << 15
CLIENT_CAPABILITIES = CLIENT_LONG_PASSWORD|CLIENT_LONG_FLAG|CLIENT_TRANSACTIONS
+ PROTO_AUTH41 = CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION
# Connection Option
OPT_CONNECT_TIMEOUT = 0
@@ -115,19 +120,37 @@ class Mysql
@server_capabilities, = a.slice!(0,2).unpack("v")
end
if a.size >= 16 then
- @server_language, @server_status = a.unpack("cv")
+ @server_language, @server_status = a.slice!(0,3).unpack("cv")
end
flag = 0 if flag == nil
flag |= @client_flag | CLIENT_CAPABILITIES
flag |= CLIENT_CONNECT_WITH_DB if db
- data = Net::int2str(flag)+Net::int3str(@max_allowed_packet)+(user||"")+"\0"+scramble(passwd, @scramble_buff, @protocol_version==9)
+
+ if !@server_capabilities & PROTO_AUTH41
+ data = Net::int2str(flag)+Net::int3str(@max_allowed_packet)+
+ (user||"")+"\0"+
+ scramble(passwd, @scramble_buff, @protocol_version==9)
+ else
+ dummy, @salt2 = a.unpack("a13a12")
+ @scramble_buff += @salt2
+ flag |= PROTO_AUTH41
+ data = Net::int4str(flag) + Net::int4str(@max_allowed_packet) +
+ ([8] + Array.new(23, 0)).pack("c24") + (user||"")+"\0"+
+ scramble41(passwd, @scramble_buff)
+ end
+
if db and @server_capabilities & CLIENT_CONNECT_WITH_DB != 0 then
- data << "\0"+db
+ if PROTO_AUTH41
+ data << db+"\0"
+ else
+ data << "\0"+db
+ end
@db = db.dup
end
write data
read
+ ObjectSpace.define_finalizer(self, Mysql.finalizer(@net))
self
end
alias :connect :real_connect
@@ -182,7 +205,11 @@ class Mysql
end
def change_user(user="", passwd="", db="")
+ if !@server_capabilities & PROTO_AUTH41
data = user+"\0"+scramble(passwd, @scramble_buff, @protocol_version==9)+"\0"+db
+ else
+ data = user+"\0"+ scramble41(passwd, @scramble_buff)
+ end
command COM_CHANGE_USER, data
@user = user
@passwd = passwd
@@ -243,7 +270,11 @@ class Mysql
def list_fields(table, field=nil)
command COM_FIELD_LIST, "#{table}\0#{field}", true
+ if !@server_capabilities & PROTO_AUTH41
f = read_rows 6
+ else
+ f = read_rows 7
+ end
fields = unpack_fields(f, @server_capabilities & CLIENT_LONG_FLAG != 0)
res = Result::new self, fields, f.length
res.eof = true
@@ -253,7 +284,11 @@ class Mysql
def list_processes()
data = command COM_PROCESS_INFO
@field_count = get_length data
+ if !@server_capabilities & PROTO_AUTH41
fields = read_rows 5
+ else
+ fields = read_rows 7
+ end
@fields = unpack_fields(fields, @server_capabilities & CLIENT_LONG_FLAG != 0)
@status = :STATUS_GET_RESULT
store_result
@@ -311,7 +346,11 @@ class Mysql
def read_one_row(field_count)
data = read
- return if data[0] == 254 and data.length == 1
+ if data[0] == 254 and data.length == 1 ## EOF
+ return
+ elsif data[0] == 254 and data.length == 5
+ return
+ end
rec = []
field_count.times do
len = get_length data
@@ -363,7 +402,11 @@ class Mysql
end
else
@extra_info = get_length(data, true)
+ if !@server_capabilities & PROTO_AUTH41
fields = read_rows 5
+ else
+ fields = read_rows(7)
+ end
@fields = unpack_fields(fields, @server_capabilities & CLIENT_LONG_FLAG != 0)
@status = :STATUS_GET_RESULT
end
@@ -373,6 +416,7 @@ class Mysql
def unpack_fields(data, long_flag_protocol)
ret = []
data.each do |f|
+ if !@server_capabilities & PROTO_AUTH41
table = org_table = f[0]
name = f[1]
length = f[2][0]+f[2][1]*256+f[2][2]*256*256
@@ -386,8 +430,22 @@ class Mysql
end
def_value = f[5]
max_length = 0
+ else
+ catalog = f[0]
+ db = f[1]
+ table = f[2]
+ org_table = f[3]
+ name = f[4]
+ org_name = f[5]
+ length = f[6][2]+f[6][3]*256+f[6][4]*256*256
+ type = f[6][6]
+ flags = f[6][7]+f[6][8]*256
+ decimals = f[6][9]
+ def_value = ""
+ max_length = 0
ret << Field::new(table, org_table, name, length, type, flags, decimals, def_value, max_length)
end
+ end
ret
end
@@ -489,6 +547,19 @@ class Mysql
to.join
end
+ def scramble41(password, message)
+ if password.length != 0
+ buf = [0x14]
+ s1 = Digest::SHA1.new(password).digest
+ s2 = Digest::SHA1.new(s1).digest
+ x = Digest::SHA1.new(message + s2).digest
+ (0..s1.length - 1).each {|i| buf.push(s1[i] ^ x[i])}
+ buf.pack("C*")
+ else
+ 0x00.chr
+ end
+ end
+
def error(errno)
@errno = errno
@error = Error::err errno
@@ -574,7 +645,6 @@ class Mysql
def free()
@handle.skip_result
@handle = @fields = @data = nil
- GC::start
end
def num_fields()
@@ -1023,8 +1093,8 @@ class Mysql
@sock.sync = true
buf.join
rescue
- errno = Error::CR_SERVER_LOST
- raise Error::new(errno, Error::err(errno))
+ errno = Error::CR_SERVER_LOST
+ raise Error::new(errno, Error::err(errno))
end
def write(data)
@@ -1043,8 +1113,8 @@ class Mysql
@sock.sync = true
@sock.flush
rescue
- errno = Error::CR_SERVER_LOST
- raise Error::new(errno, Error::err(errno))
+ errno = Error::CR_SERVER_LOST
+ raise Error::new(errno, Error::err(errno))
end
def close()
@@ -1091,6 +1161,13 @@ class << Mysql
end
alias :connect :real_connect
+ def finalizer(net)
+ proc {
+ net.clear
+ net.write Mysql::COM_QUIT.chr
+ }
+ end
+
def escape_string(str)
str.gsub(/([\0\n\r\032\'\"\\])/) do
case $1