rspider 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,111 @@
1
+ R_links_regexps=[/href\s*=\s*[\'\"]?([+:%\/\?~=&;\\\(\),._a-zA-Z0-9-]*)(#[.a-zA-Z0-9-]*)?[\'\" ]?(\s*rel\s*=\s*[\'\"]?(nofollow)[\'\"]?)?/i,
2
+ /(frame[^>]*src[[:blank:]]*)=[[:blank:]]*[\'\"]?(([[a-z]{3,5}:\/\/(([.a-zA-Z0-9-])+(:[0-9]+)*))*([+:%\/?=&;\\\(\),._ a-zA-Z0-9-]*))(#[.a-zA-Z0-9-]*)?[\'\" ]?/i,
3
+ /(window[.]location)[[:blank:]]*=[[:blank:]]*[\'\"]?(([[a-z]{3,5}:\/\/(([.a-zA-Z0-9-])+(:[0-9]+)*))*([+:%\/?=&;\\\(\),._ a-zA-Z0-9-]*))(#[.a-zA-Z0-9-]*)?[\'\" ]?/i,
4
+ /(http-equiv=['\"]refresh['\"] *content=['\"][0-9]+;url)[[:blank:]]*=[[:blank:]]*[\'\"]?(([[a-z]{3,5}:\/\/(([.a-zA-Z0-9-])+(:[0-9]+)*))*([+:%\/?=&;\\\(\),._ a-zA-Z0-9-]*))(#[.a-zA-Z0-9-]*)?[\'\" ]?/i,
5
+ /(window[.]open[[:blank:]]*[(])[[:blank:]]*[\'\"]+(([[a-z]{3,5}:\/\/(([.a-zA-Z0-9-])+(:[0-9]+)*))*([+:%\/?=&;\\\(\),._ a-zA-Z0-9-]*))(#[.a-zA-Z0-9-]*)?[\'\" ]?/i ]
6
+
7
+ def scan_html_relative_links(html,base_url)
8
+ links=[]
9
+ R_links_regexps.each{ |r|
10
+ matches=html.scan(r)
11
+ matches.each{ |m|
12
+ links.push m[0] if m[3].nil? and m[0] != ""
13
+ }
14
+ }
15
+ links
16
+ end
17
+ def scan_html_simple_links(html,base_url)
18
+ r=Regexp.compile('href=[\'\"]([^\'^\"^\s]*)[\'\"]')
19
+ links=[]
20
+ matches=html.scan(r)
21
+ matches.each{ |m|
22
+ links.push m[0]
23
+ }
24
+ links
25
+ end
26
+ def get_head_data(html)
27
+ r=Regexp.compile('<head[^>]*>(.*?)<\/head>',Regexp::IGNORECASE|Regexp::MULTILINE)
28
+ m=html.scan(r)
29
+ return nil if m.nil?
30
+ return nil if m[0].nil?
31
+ head={}
32
+ head[:title]=""
33
+ head[:keywords]=""
34
+ head[:robots]=""
35
+ head[:description]=""
36
+ head[:nofollow]=false
37
+ head[:noindex]=false
38
+ head[:base]=""
39
+
40
+
41
+ h=m[0][0]
42
+ begin
43
+ r_robots=/<meta +name *=[\"']?robots[\"']? *content=[\"']?([^<>'\"]+)[\"']?/im
44
+ robots=h.scan(r_robots)[0][0]
45
+ head[:robots]=robots
46
+ rescue
47
+ end
48
+ begin
49
+ r_desc=/<meta +name *=[\"']?description[\"']? *content=[\"']?([^<>'\"]+)[\"']?/im
50
+ head[:description]=h.scan(r_desc)[0][0]
51
+ rescue
52
+ end
53
+ begin
54
+ r_keys=/<meta +name *=[\"']?keywords[\"']? *content=[\"']?([^<>'\"]+)[\"']?/im
55
+ head[:keywords]=h.scan(r_keys)[0][0]
56
+ rescue
57
+ end
58
+
59
+ #<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
60
+ begin
61
+ r_charset=/<meta +http\-equiv*=[\"']?Content-Type[\"']? *content=[\"']?([^<>'\"]+)[\"']?/im
62
+ head[:charset]=h.scan(r_charset)[0][0].split("=").pop
63
+ rescue
64
+ end
65
+
66
+ begin
67
+ r_base=/<base +href *= *[\"']?([^<>'\"]+)[\"']?/im
68
+ head[:base]=h.scan(r_base)[0][0]
69
+ rescue
70
+ end
71
+ begin
72
+ r_title=/<title *>(.*?)<\/title*>/im
73
+ head[:title]=h.scan(r_title)[0][0].gsub("\n","")
74
+ rescue
75
+ end
76
+
77
+ begin
78
+ archives=[]
79
+ r_archives=/<link +rel*=[\"']?archives[\"']? *[^\>]+href=[\"']?([^<>'\"]+)[\"']?/im
80
+ h.scan(r_archives).each{ |l|
81
+ archives.push l[0]
82
+ }
83
+ head[:archives]=archives
84
+ rescue
85
+ end
86
+ begin
87
+ links=[]
88
+ r_alternates=/<link +rel*=[\"']?alternate[\"']? *[^\>]+href=[\"']?([^<>'\"]+)[\"']?/im
89
+ h.scan(r_alternates).each{ |l|
90
+ links.push l[0]
91
+ }
92
+ head[:rss_links]=links
93
+ rescue
94
+ end
95
+ robots.downcase.split(",").each{ |j|
96
+ head[:noindex]=true if j=="noindex"
97
+ head[:nofollow]=true if j=="nofollow"
98
+ } unless robots.nil?
99
+ head
100
+ end
101
+ html=open("3.html").read
102
+ lnks=scan_html_relative_links(html,"http://localhost/search_doc/")
103
+ lnks2=scan_html_simple_links(html,"http://localhost/search_doc/")
104
+ puts lnks2-lnks
105
+ get_head_data(html).each{|k,v|
106
+ if v.class==Array
107
+ puts "#{k}:Array:#{v.length},#{v.join("\narch:")}"
108
+ else
109
+ puts "#{k}:#{v}"
110
+ end
111
+ }
@@ -0,0 +1,1131 @@
1
+ # $Id: mysql.rb,v 1.24 2005/02/12 11:37:15 tommy Exp $
2
+ #
3
+ # Copyright (C) 2003-2005 TOMITA Masahiro
4
+ # tommy@tmtm.org
5
+ #
6
+
7
+ class Mysql
8
+
9
+ VERSION = "4.0-ruby-0.2.5"
10
+
11
+ require "socket"
12
+
13
+ MAX_PACKET_LENGTH = 256*256*256-1
14
+ MAX_ALLOWED_PACKET = 1024*1024*1024
15
+
16
+ MYSQL_UNIX_ADDR = "/var/lib/mysql/mysql.sock"
17
+ #MYSQL_UNIX_ADDR = "/tmp/mysql.sock"
18
+ MYSQL_PORT = 3306
19
+ PROTOCOL_VERSION = 10
20
+
21
+ # Command
22
+ COM_SLEEP = 0
23
+ COM_QUIT = 1
24
+ COM_INIT_DB = 2
25
+ COM_QUERY = 3
26
+ COM_FIELD_LIST = 4
27
+ COM_CREATE_DB = 5
28
+ COM_DROP_DB = 6
29
+ COM_REFRESH = 7
30
+ COM_SHUTDOWN = 8
31
+ COM_STATISTICS = 9
32
+ COM_PROCESS_INFO = 10
33
+ COM_CONNECT = 11
34
+ COM_PROCESS_KILL = 12
35
+ COM_DEBUG = 13
36
+ COM_PING = 14
37
+ COM_TIME = 15
38
+ COM_DELAYED_INSERT = 16
39
+ COM_CHANGE_USER = 17
40
+ COM_BINLOG_DUMP = 18
41
+ COM_TABLE_DUMP = 19
42
+ COM_CONNECT_OUT = 20
43
+ COM_REGISTER_SLAVE = 21
44
+
45
+ # Client flag
46
+ CLIENT_LONG_PASSWORD = 1
47
+ CLIENT_FOUND_ROWS = 1 << 1
48
+ CLIENT_LONG_FLAG = 1 << 2
49
+ CLIENT_CONNECT_WITH_DB= 1 << 3
50
+ CLIENT_NO_SCHEMA = 1 << 4
51
+ CLIENT_COMPRESS = 1 << 5
52
+ CLIENT_ODBC = 1 << 6
53
+ CLIENT_LOCAL_FILES = 1 << 7
54
+ CLIENT_IGNORE_SPACE = 1 << 8
55
+ CLIENT_INTERACTIVE = 1 << 10
56
+ CLIENT_SSL = 1 << 11
57
+ CLIENT_IGNORE_SIGPIPE = 1 << 12
58
+ CLIENT_TRANSACTIONS = 1 << 13
59
+ CLIENT_CAPABILITIES = CLIENT_LONG_PASSWORD|CLIENT_LONG_FLAG|CLIENT_TRANSACTIONS
60
+
61
+ # Connection Option
62
+ OPT_CONNECT_TIMEOUT = 0
63
+ OPT_COMPRESS = 1
64
+ OPT_NAMED_PIPE = 2
65
+ INIT_COMMAND = 3
66
+ READ_DEFAULT_FILE = 4
67
+ READ_DEFAULT_GROUP = 5
68
+ SET_CHARSET_DIR = 6
69
+ SET_CHARSET_NAME = 7
70
+ OPT_LOCAL_INFILE = 8
71
+
72
+ # Server Status
73
+ SERVER_STATUS_IN_TRANS = 1
74
+ SERVER_STATUS_AUTOCOMMIT = 2
75
+
76
+ # Refresh parameter
77
+ REFRESH_GRANT = 1
78
+ REFRESH_LOG = 2
79
+ REFRESH_TABLES = 4
80
+ REFRESH_HOSTS = 8
81
+ REFRESH_STATUS = 16
82
+ REFRESH_THREADS = 32
83
+ REFRESH_SLAVE = 64
84
+ REFRESH_MASTER = 128
85
+
86
+ def initialize(*args)
87
+ @client_flag = 0
88
+ @max_allowed_packet = MAX_ALLOWED_PACKET
89
+ @query_with_result = true
90
+ @status = :STATUS_READY
91
+ if args[0] != :INIT then
92
+ real_connect(*args)
93
+ end
94
+ end
95
+
96
+ def real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=nil)
97
+ @server_status = SERVER_STATUS_AUTOCOMMIT
98
+ if (host == nil or host == "localhost") and defined? UNIXSocket then
99
+ unix_socket = socket || ENV["MYSQL_UNIX_PORT"] || MYSQL_UNIX_ADDR
100
+ sock = UNIXSocket::new(unix_socket)
101
+ @host_info = Error::err(Error::CR_LOCALHOST_CONNECTION)
102
+ @unix_socket = unix_socket
103
+ else
104
+ sock = TCPSocket::new(host, port||ENV["MYSQL_TCP_PORT"]||(Socket::getservbyname("mysql","tcp") rescue MYSQL_PORT))
105
+ @host_info = sprintf Error::err(Error::CR_TCP_CONNECTION), host
106
+ end
107
+ @host = host ? host.dup : nil
108
+ sock.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true
109
+ @net = Net::new sock
110
+
111
+ a = read
112
+ @protocol_version = a.slice!(0)
113
+ @server_version, a = a.split(/\0/,2)
114
+ @thread_id, @scramble_buff = a.slice!(0,13).unpack("La8")
115
+ if a.size >= 2 then
116
+ @server_capabilities, = a.slice!(0,2).unpack("v")
117
+ end
118
+ if a.size >= 16 then
119
+ @server_language, @server_status = a.unpack("cv")
120
+ end
121
+
122
+ flag = 0 if flag == nil
123
+ flag |= @client_flag | CLIENT_CAPABILITIES
124
+ flag |= CLIENT_CONNECT_WITH_DB if db
125
+ data = Net::int2str(flag)+Net::int3str(@max_allowed_packet)+(user||"")+"\0"+scramble(passwd, @scramble_buff, @protocol_version==9)
126
+ if db and @server_capabilities & CLIENT_CONNECT_WITH_DB != 0 then
127
+ data << "\0"+db
128
+ @db = db.dup
129
+ end
130
+ write data
131
+ read
132
+ ObjectSpace.define_finalizer(self, Mysql.finalizer(@net))
133
+ self
134
+ end
135
+ alias :connect :real_connect
136
+
137
+ def escape_string(str)
138
+ Mysql::escape_string str
139
+ end
140
+ alias :quote :escape_string
141
+
142
+ def get_client_info()
143
+ VERSION
144
+ end
145
+ alias :client_info :get_client_info
146
+
147
+ def options(option, arg=nil)
148
+ if option == OPT_LOCAL_INFILE then
149
+ if arg == false or arg == 0 then
150
+ @client_flag &= ~CLIENT_LOCAL_FILES
151
+ else
152
+ @client_flag |= CLIENT_LOCAL_FILES
153
+ end
154
+ else
155
+ raise "not implemented"
156
+ end
157
+ end
158
+
159
+ def real_query(query)
160
+ command COM_QUERY, query, true
161
+ read_query_result
162
+ self
163
+ end
164
+
165
+ def use_result()
166
+ if @status != :STATUS_GET_RESULT then
167
+ error Error::CR_COMMANDS_OUT_OF_SYNC
168
+ end
169
+ res = Result::new self, @fields, @field_count
170
+ @status = :STATUS_USE_RESULT
171
+ res
172
+ end
173
+
174
+ def store_result()
175
+ if @status != :STATUS_GET_RESULT then
176
+ error Error::CR_COMMANDS_OUT_OF_SYNC
177
+ end
178
+ @status = :STATUS_READY
179
+ data = read_rows @field_count
180
+ res = Result::new self, @fields, @field_count, data
181
+ @fields = nil
182
+ @affected_rows = data.length
183
+ res
184
+ end
185
+
186
+ def change_user(user="", passwd="", db="")
187
+ data = user+"\0"+scramble(passwd, @scramble_buff, @protocol_version==9)+"\0"+db
188
+ command COM_CHANGE_USER, data
189
+ @user = user
190
+ @passwd = passwd
191
+ @db = db
192
+ end
193
+
194
+ def character_set_name()
195
+ raise "not implemented"
196
+ end
197
+
198
+ def close()
199
+ @status = :STATUS_READY
200
+ command COM_QUIT, nil, true
201
+ @net.close
202
+ self
203
+ end
204
+
205
+ def create_db(db)
206
+ command COM_CREATE_DB, db
207
+ self
208
+ end
209
+
210
+ def drop_db(db)
211
+ command COM_DROP_DB, db
212
+ self
213
+ end
214
+
215
+ def dump_debug_info()
216
+ command COM_DEBUG
217
+ self
218
+ end
219
+
220
+ def get_host_info()
221
+ @host_info
222
+ end
223
+ alias :host_info :get_host_info
224
+
225
+ def get_proto_info()
226
+ @protocol_version
227
+ end
228
+ alias :proto_info :get_proto_info
229
+
230
+ def get_server_info()
231
+ @server_version
232
+ end
233
+ alias :server_info :get_server_info
234
+
235
+ def kill(id)
236
+ command COM_PROCESS_KILL, Net::int4str(id)
237
+ self
238
+ end
239
+
240
+ def list_dbs(db=nil)
241
+ real_query "show databases #{db}"
242
+ @status = :STATUS_READY
243
+ read_rows(1).flatten
244
+ end
245
+
246
+ def list_fields(table, field=nil)
247
+ command COM_FIELD_LIST, "#{table}\0#{field}", true
248
+ f = read_rows 6
249
+ fields = unpack_fields(f, @server_capabilities & CLIENT_LONG_FLAG != 0)
250
+ res = Result::new self, fields, f.length
251
+ res.eof = true
252
+ res
253
+ end
254
+
255
+ def list_processes()
256
+ data = command COM_PROCESS_INFO
257
+ @field_count = get_length data
258
+ fields = read_rows 5
259
+ @fields = unpack_fields(fields, @server_capabilities & CLIENT_LONG_FLAG != 0)
260
+ @status = :STATUS_GET_RESULT
261
+ store_result
262
+ end
263
+
264
+ def list_tables(table=nil)
265
+ real_query "show tables #{table}"
266
+ @status = :STATUS_READY
267
+ read_rows(1).flatten
268
+ end
269
+
270
+ def ping()
271
+ command COM_PING
272
+ self
273
+ end
274
+
275
+ def query(query)
276
+ real_query query
277
+ if not @query_with_result then
278
+ return self
279
+ end
280
+ if @field_count == 0 then
281
+ return nil
282
+ end
283
+ store_result
284
+ end
285
+
286
+ def refresh(r)
287
+ command COM_REFRESH, r.chr
288
+ self
289
+ end
290
+
291
+ def reload()
292
+ refresh REFRESH_GRANT
293
+ self
294
+ end
295
+
296
+ def select_db(db)
297
+ command COM_INIT_DB, db
298
+ @db = db
299
+ self
300
+ end
301
+
302
+ def shutdown()
303
+ command COM_SHUTDOWN
304
+ self
305
+ end
306
+
307
+ def stat()
308
+ command COM_STATISTICS
309
+ end
310
+
311
+ attr_reader :info, :insert_id, :affected_rows, :field_count, :thread_id
312
+ attr_accessor :query_with_result, :status
313
+
314
+ def read_one_row(field_count)
315
+ data = read
316
+ return if data[0] == 254 and data.length == 1
317
+ rec = []
318
+ field_count.times do
319
+ len = get_length data
320
+ if len == nil then
321
+ rec << len
322
+ else
323
+ rec << data.slice!(0,len)
324
+ end
325
+ end
326
+ rec
327
+ end
328
+
329
+ def skip_result()
330
+ if @status == :STATUS_USE_RESULT then
331
+ loop do
332
+ data = read
333
+ break if data[0] == 254 and data.length == 1
334
+ end
335
+ @status = :STATUS_READY
336
+ end
337
+ end
338
+
339
+ def inspect()
340
+ "#<#{self.class}>"
341
+ end
342
+
343
+ private
344
+
345
+ def read_query_result()
346
+ data = read
347
+ @field_count = get_length(data)
348
+ if @field_count == nil then # LOAD DATA LOCAL INFILE
349
+ File::open(data) do |f|
350
+ write f.read
351
+ end
352
+ write "" # mark EOF
353
+ data = read
354
+ @field_count = get_length(data)
355
+ end
356
+ if @field_count == 0 then
357
+ @affected_rows = get_length(data, true)
358
+ @insert_id = get_length(data, true)
359
+ if @server_capabilities & CLIENT_TRANSACTIONS != 0 then
360
+ a = data.slice!(0,2)
361
+ @server_status = a[0]+a[1]*256
362
+ end
363
+ if data.size > 0 and get_length(data) then
364
+ @info = data
365
+ end
366
+ else
367
+ @extra_info = get_length(data, true)
368
+ fields = read_rows 5
369
+ @fields = unpack_fields(fields, @server_capabilities & CLIENT_LONG_FLAG != 0)
370
+ @status = :STATUS_GET_RESULT
371
+ end
372
+ self
373
+ end
374
+
375
+ def unpack_fields(data, long_flag_protocol)
376
+ ret = []
377
+ data.each do |f|
378
+ table = org_table = f[0]
379
+ name = f[1]
380
+ length = f[2][0]+f[2][1]*256+f[2][2]*256*256
381
+ type = f[3][0]
382
+ if long_flag_protocol then
383
+ flags = f[4][0]+f[4][1]*256
384
+ decimals = f[4][2]
385
+ else
386
+ flags = f[4][0]
387
+ decimals = f[4][1]
388
+ end
389
+ def_value = f[5]
390
+ max_length = 0
391
+ ret << Field::new(table, org_table, name, length, type, flags, decimals, def_value, max_length)
392
+ end
393
+ ret
394
+ end
395
+
396
+ def read_rows(field_count)
397
+ ret = []
398
+ while rec = read_one_row(field_count) do
399
+ ret << rec
400
+ end
401
+ ret
402
+ end
403
+
404
+ def get_length(data, longlong=nil)
405
+ return if data.length == 0
406
+ c = data.slice!(0)
407
+ case c
408
+ when 251
409
+ return nil
410
+ when 252
411
+ a = data.slice!(0,2)
412
+ return a[0]+a[1]*256
413
+ when 253
414
+ a = data.slice!(0,3)
415
+ return a[0]+a[1]*256+a[2]*256**2
416
+ when 254
417
+ a = data.slice!(0,8)
418
+ if longlong then
419
+ return a[0]+a[1]*256+a[2]*256**2+a[3]*256**3+
420
+ a[4]*256**4+a[5]*256**5+a[6]*256**6+a[7]*256**7
421
+ else
422
+ return a[0]+a[1]*256+a[2]*256**2+a[3]*256**3
423
+ end
424
+ else
425
+ c
426
+ end
427
+ end
428
+
429
+ def command(cmd, arg=nil, skip_check=nil)
430
+ unless @net then
431
+ error Error::CR_SERVER_GONE_ERROR
432
+ end
433
+ if @status != :STATUS_READY then
434
+ error Error::CR_COMMANDS_OUT_OF_SYNC
435
+ end
436
+ @net.clear
437
+ write cmd.chr+(arg||"")
438
+ read unless skip_check
439
+ end
440
+
441
+ def read()
442
+ unless @net then
443
+ error Error::CR_SERVER_GONE_ERROR
444
+ end
445
+ a = @net.read
446
+ if a[0] == 255 then
447
+ if a.length > 3 then
448
+ @errno = a[1]+a[2]*256
449
+ @error = a[3 .. -1]
450
+ else
451
+ @errno = Error::CR_UNKNOWN_ERROR
452
+ @error = Error::err @errno
453
+ end
454
+ raise Mysql::Error::new(@errno, @error)
455
+ #raise "#{@errno}:#{@error}"
456
+ #raise @error
457
+ #hack by renlu
458
+ end
459
+ a
460
+ end
461
+
462
+ def write(arg)
463
+ unless @net then
464
+ error Error::CR_SERVER_GONE_ERROR
465
+ end
466
+ @net.write arg
467
+ end
468
+
469
+ def hash_password(password)
470
+ nr = 1345345333
471
+ add = 7
472
+ nr2 = 0x12345671
473
+ password.each_byte do |i|
474
+ next if i == 0x20 or i == 9
475
+ nr ^= (((nr & 63) + add) * i) + (nr << 8)
476
+ nr2 += (nr2 << 8) ^ nr
477
+ add += i
478
+ end
479
+ [nr & ((1 << 31) - 1), nr2 & ((1 << 31) - 1)]
480
+ end
481
+
482
+ def scramble(password, message, old_ver)
483
+ return "" if password == nil or password == ""
484
+ raise "old version password is not implemented" if old_ver
485
+ hash_pass = hash_password password
486
+ hash_message = hash_password message
487
+ rnd = Random::new hash_pass[0] ^ hash_message[0], hash_pass[1] ^ hash_message[1]
488
+ to = []
489
+ 1.upto(message.length) do
490
+ to << ((rnd.rnd*31)+64).floor
491
+ end
492
+ extra = (rnd.rnd*31).floor
493
+ to.map! do |t| (t ^ extra).chr end
494
+ to.join
495
+ end
496
+
497
+ def error(errno)
498
+ @errno = errno
499
+ @error = Error::err errno
500
+ raise Error::new(@errno, @error)
501
+ end
502
+
503
+ class Result
504
+ def initialize(mysql, fields, field_count, data=nil)
505
+ @handle = mysql
506
+ @fields = fields
507
+ @field_count = field_count
508
+ @data = data
509
+ @current_field = 0
510
+ @current_row = 0
511
+ @eof = false
512
+ @row_count = 0
513
+ end
514
+ attr_accessor :eof
515
+
516
+ def data_seek(n)
517
+ @current_row = n
518
+ end
519
+
520
+ def fetch_field()
521
+ return if @current_field >= @field_count
522
+ f = @fields[@current_field]
523
+ @current_field += 1
524
+ f
525
+ end
526
+
527
+ def fetch_fields()
528
+ @fields
529
+ end
530
+
531
+ def fetch_field_direct(n)
532
+ @fields[n]
533
+ end
534
+
535
+ def fetch_lengths()
536
+ @data ? @data[@current_row].map{|i| i ? i.length : 0} : @lengths
537
+ end
538
+
539
+ def fetch_row()
540
+ if @data then
541
+ if @current_row >= @data.length then
542
+ @handle.status = :STATUS_READY
543
+ return
544
+ end
545
+ ret = @data[@current_row]
546
+ @current_row += 1
547
+ else
548
+ return if @eof
549
+ ret = @handle.read_one_row @field_count
550
+ if ret == nil then
551
+ @eof = true
552
+ return
553
+ end
554
+ @lengths = ret.map{|i| i ? i.length : 0}
555
+ @row_count += 1
556
+ end
557
+ ret
558
+ end
559
+
560
+ def fetch_hash(with_table=nil)
561
+ row = fetch_row
562
+ return if row == nil
563
+ hash = {}
564
+ @fields.each_index do |i|
565
+ f = with_table ? @fields[i].table+"."+@fields[i].name : @fields[i].name
566
+ hash[f] = row[i]
567
+ end
568
+ hash
569
+ end
570
+
571
+ def field_seek(n)
572
+ @current_field = n
573
+ end
574
+
575
+ def field_tell()
576
+ @current_field
577
+ end
578
+
579
+ def free()
580
+ @handle.skip_result
581
+ @handle = @fields = @data = nil
582
+ GC::start
583
+ end
584
+
585
+ def num_fields()
586
+ @field_count
587
+ end
588
+
589
+ def num_rows()
590
+ @data ? @data.length : @row_count
591
+ end
592
+
593
+ def row_seek(n)
594
+ @current_row = n
595
+ end
596
+
597
+ def row_tell()
598
+ @current_row
599
+ end
600
+
601
+ def each()
602
+ while row = fetch_row do
603
+ yield row
604
+ end
605
+ end
606
+
607
+ def each_hash(with_table=nil)
608
+ while hash = fetch_hash(with_table) do
609
+ yield hash
610
+ end
611
+ end
612
+
613
+ def inspect()
614
+ "#<#{self.class}>"
615
+ end
616
+
617
+ end
618
+
619
+ class Field
620
+ # Field type
621
+ TYPE_DECIMAL = 0
622
+ TYPE_TINY = 1
623
+ TYPE_SHORT = 2
624
+ TYPE_LONG = 3
625
+ TYPE_FLOAT = 4
626
+ TYPE_DOUBLE = 5
627
+ TYPE_NULL = 6
628
+ TYPE_TIMESTAMP = 7
629
+ TYPE_LONGLONG = 8
630
+ TYPE_INT24 = 9
631
+ TYPE_DATE = 10
632
+ TYPE_TIME = 11
633
+ TYPE_DATETIME = 12
634
+ TYPE_YEAR = 13
635
+ TYPE_NEWDATE = 14
636
+ TYPE_ENUM = 247
637
+ TYPE_SET = 248
638
+ TYPE_TINY_BLOB = 249
639
+ TYPE_MEDIUM_BLOB = 250
640
+ TYPE_LONG_BLOB = 251
641
+ TYPE_BLOB = 252
642
+ TYPE_VAR_STRING = 253
643
+ TYPE_STRING = 254
644
+ TYPE_GEOMETRY = 255
645
+ TYPE_CHAR = TYPE_TINY
646
+ TYPE_INTERVAL = TYPE_ENUM
647
+
648
+ # Flag
649
+ NOT_NULL_FLAG = 1
650
+ PRI_KEY_FLAG = 2
651
+ UNIQUE_KEY_FLAG = 4
652
+ MULTIPLE_KEY_FLAG = 8
653
+ BLOB_FLAG = 16
654
+ UNSIGNED_FLAG = 32
655
+ ZEROFILL_FLAG = 64
656
+ BINARY_FLAG = 128
657
+ ENUM_FLAG = 256
658
+ AUTO_INCREMENT_FLAG = 512
659
+ TIMESTAMP_FLAG = 1024
660
+ SET_FLAG = 2048
661
+ NUM_FLAG = 32768
662
+ PART_KEY_FLAG = 16384
663
+ GROUP_FLAG = 32768
664
+ UNIQUE_FLAG = 65536
665
+
666
+ def initialize(table, org_table, name, length, type, flags, decimals, def_value, max_length)
667
+ @table = table
668
+ @org_table = org_table
669
+ @name = name
670
+ @length = length
671
+ @type = type
672
+ @flags = flags
673
+ @decimals = decimals
674
+ @def = def_value
675
+ @max_length = max_length
676
+ if (type <= TYPE_INT24 and (type != TYPE_TIMESTAMP or length == 14 or length == 8)) or type == TYPE_YEAR then
677
+ @flags |= NUM_FLAG
678
+ end
679
+ end
680
+ attr_reader :table, :org_table, :name, :length, :type, :flags, :decimals, :def, :max_length
681
+
682
+ def inspect()
683
+ "#<#{self.class}:#{@name}>"
684
+ end
685
+ end
686
+
687
+ #class Error < StandardError
688
+ #Hack by renlu
689
+ class Error < StandardError
690
+ # Server Error
691
+ ER_HASHCHK = 1000
692
+ ER_NISAMCHK = 1001
693
+ ER_NO = 1002
694
+ ER_YES = 1003
695
+ ER_CANT_CREATE_FILE = 1004
696
+ ER_CANT_CREATE_TABLE = 1005
697
+ ER_CANT_CREATE_DB = 1006
698
+ ER_DB_CREATE_EXISTS = 1007
699
+ ER_DB_DROP_EXISTS = 1008
700
+ ER_DB_DROP_DELETE = 1009
701
+ ER_DB_DROP_RMDIR = 1010
702
+ ER_CANT_DELETE_FILE = 1011
703
+ ER_CANT_FIND_SYSTEM_REC = 1012
704
+ ER_CANT_GET_STAT = 1013
705
+ ER_CANT_GET_WD = 1014
706
+ ER_CANT_LOCK = 1015
707
+ ER_CANT_OPEN_FILE = 1016
708
+ ER_FILE_NOT_FOUND = 1017
709
+ ER_CANT_READ_DIR = 1018
710
+ ER_CANT_SET_WD = 1019
711
+ ER_CHECKREAD = 1020
712
+ ER_DISK_FULL = 1021
713
+ ER_DUP_KEY = 1022
714
+ ER_ERROR_ON_CLOSE = 1023
715
+ ER_ERROR_ON_READ = 1024
716
+ ER_ERROR_ON_RENAME = 1025
717
+ ER_ERROR_ON_WRITE = 1026
718
+ ER_FILE_USED = 1027
719
+ ER_FILSORT_ABORT = 1028
720
+ ER_FORM_NOT_FOUND = 1029
721
+ ER_GET_ERRNO = 1030
722
+ ER_ILLEGAL_HA = 1031
723
+ ER_KEY_NOT_FOUND = 1032
724
+ ER_NOT_FORM_FILE = 1033
725
+ ER_NOT_KEYFILE = 1034
726
+ ER_OLD_KEYFILE = 1035
727
+ ER_OPEN_AS_READONLY = 1036
728
+ ER_OUTOFMEMORY = 1037
729
+ ER_OUT_OF_SORTMEMORY = 1038
730
+ ER_UNEXPECTED_EOF = 1039
731
+ ER_CON_COUNT_ERROR = 1040
732
+ ER_OUT_OF_RESOURCES = 1041
733
+ ER_BAD_HOST_ERROR = 1042
734
+ ER_HANDSHAKE_ERROR = 1043
735
+ ER_DBACCESS_DENIED_ERROR = 1044
736
+ ER_ACCESS_DENIED_ERROR = 1045
737
+ ER_NO_DB_ERROR = 1046
738
+ ER_UNKNOWN_COM_ERROR = 1047
739
+ ER_BAD_NULL_ERROR = 1048
740
+ ER_BAD_DB_ERROR = 1049
741
+ ER_TABLE_EXISTS_ERROR = 1050
742
+ ER_BAD_TABLE_ERROR = 1051
743
+ ER_NON_UNIQ_ERROR = 1052
744
+ ER_SERVER_SHUTDOWN = 1053
745
+ ER_BAD_FIELD_ERROR = 1054
746
+ ER_WRONG_FIELD_WITH_GROUP = 1055
747
+ ER_WRONG_GROUP_FIELD = 1056
748
+ ER_WRONG_SUM_SELECT = 1057
749
+ ER_WRONG_VALUE_COUNT = 1058
750
+ ER_TOO_LONG_IDENT = 1059
751
+ ER_DUP_FIELDNAME = 1060
752
+ ER_DUP_KEYNAME = 1061
753
+ ER_DUP_ENTRY = 1062
754
+ ER_WRONG_FIELD_SPEC = 1063
755
+ ER_PARSE_ERROR = 1064
756
+ ER_EMPTY_QUERY = 1065
757
+ ER_NONUNIQ_TABLE = 1066
758
+ ER_INVALID_DEFAULT = 1067
759
+ ER_MULTIPLE_PRI_KEY = 1068
760
+ ER_TOO_MANY_KEYS = 1069
761
+ ER_TOO_MANY_KEY_PARTS = 1070
762
+ ER_TOO_LONG_KEY = 1071
763
+ ER_KEY_COLUMN_DOES_NOT_EXITS = 1072
764
+ ER_BLOB_USED_AS_KEY = 1073
765
+ ER_TOO_BIG_FIELDLENGTH = 1074
766
+ ER_WRONG_AUTO_KEY = 1075
767
+ ER_READY = 1076
768
+ ER_NORMAL_SHUTDOWN = 1077
769
+ ER_GOT_SIGNAL = 1078
770
+ ER_SHUTDOWN_COMPLETE = 1079
771
+ ER_FORCING_CLOSE = 1080
772
+ ER_IPSOCK_ERROR = 1081
773
+ ER_NO_SUCH_INDEX = 1082
774
+ ER_WRONG_FIELD_TERMINATORS = 1083
775
+ ER_BLOBS_AND_NO_TERMINATED = 1084
776
+ ER_TEXTFILE_NOT_READABLE = 1085
777
+ ER_FILE_EXISTS_ERROR = 1086
778
+ ER_LOAD_INFO = 1087
779
+ ER_ALTER_INFO = 1088
780
+ ER_WRONG_SUB_KEY = 1089
781
+ ER_CANT_REMOVE_ALL_FIELDS = 1090
782
+ ER_CANT_DROP_FIELD_OR_KEY = 1091
783
+ ER_INSERT_INFO = 1092
784
+ ER_INSERT_TABLE_USED = 1093
785
+ ER_NO_SUCH_THREAD = 1094
786
+ ER_KILL_DENIED_ERROR = 1095
787
+ ER_NO_TABLES_USED = 1096
788
+ ER_TOO_BIG_SET = 1097
789
+ ER_NO_UNIQUE_LOGFILE = 1098
790
+ ER_TABLE_NOT_LOCKED_FOR_WRITE = 1099
791
+ ER_TABLE_NOT_LOCKED = 1100
792
+ ER_BLOB_CANT_HAVE_DEFAULT = 1101
793
+ ER_WRONG_DB_NAME = 1102
794
+ ER_WRONG_TABLE_NAME = 1103
795
+ ER_TOO_BIG_SELECT = 1104
796
+ ER_UNKNOWN_ERROR = 1105
797
+ ER_UNKNOWN_PROCEDURE = 1106
798
+ ER_WRONG_PARAMCOUNT_TO_PROCEDURE = 1107
799
+ ER_WRONG_PARAMETERS_TO_PROCEDURE = 1108
800
+ ER_UNKNOWN_TABLE = 1109
801
+ ER_FIELD_SPECIFIED_TWICE = 1110
802
+ ER_INVALID_GROUP_FUNC_USE = 1111
803
+ ER_UNSUPPORTED_EXTENSION = 1112
804
+ ER_TABLE_MUST_HAVE_COLUMNS = 1113
805
+ ER_RECORD_FILE_FULL = 1114
806
+ ER_UNKNOWN_CHARACTER_SET = 1115
807
+ ER_TOO_MANY_TABLES = 1116
808
+ ER_TOO_MANY_FIELDS = 1117
809
+ ER_TOO_BIG_ROWSIZE = 1118
810
+ ER_STACK_OVERRUN = 1119
811
+ ER_WRONG_OUTER_JOIN = 1120
812
+ ER_NULL_COLUMN_IN_INDEX = 1121
813
+ ER_CANT_FIND_UDF = 1122
814
+ ER_CANT_INITIALIZE_UDF = 1123
815
+ ER_UDF_NO_PATHS = 1124
816
+ ER_UDF_EXISTS = 1125
817
+ ER_CANT_OPEN_LIBRARY = 1126
818
+ ER_CANT_FIND_DL_ENTRY = 1127
819
+ ER_FUNCTION_NOT_DEFINED = 1128
820
+ ER_HOST_IS_BLOCKED = 1129
821
+ ER_HOST_NOT_PRIVILEGED = 1130
822
+ ER_PASSWORD_ANONYMOUS_USER = 1131
823
+ ER_PASSWORD_NOT_ALLOWED = 1132
824
+ ER_PASSWORD_NO_MATCH = 1133
825
+ ER_UPDATE_INFO = 1134
826
+ ER_CANT_CREATE_THREAD = 1135
827
+ ER_WRONG_VALUE_COUNT_ON_ROW = 1136
828
+ ER_CANT_REOPEN_TABLE = 1137
829
+ ER_INVALID_USE_OF_NULL = 1138
830
+ ER_REGEXP_ERROR = 1139
831
+ ER_MIX_OF_GROUP_FUNC_AND_FIELDS = 1140
832
+ ER_NONEXISTING_GRANT = 1141
833
+ ER_TABLEACCESS_DENIED_ERROR = 1142
834
+ ER_COLUMNACCESS_DENIED_ERROR = 1143
835
+ ER_ILLEGAL_GRANT_FOR_TABLE = 1144
836
+ ER_GRANT_WRONG_HOST_OR_USER = 1145
837
+ ER_NO_SUCH_TABLE = 1146
838
+ ER_NONEXISTING_TABLE_GRANT = 1147
839
+ ER_NOT_ALLOWED_COMMAND = 1148
840
+ ER_SYNTAX_ERROR = 1149
841
+ ER_DELAYED_CANT_CHANGE_LOCK = 1150
842
+ ER_TOO_MANY_DELAYED_THREADS = 1151
843
+ ER_ABORTING_CONNECTION = 1152
844
+ ER_NET_PACKET_TOO_LARGE = 1153
845
+ ER_NET_READ_ERROR_FROM_PIPE = 1154
846
+ ER_NET_FCNTL_ERROR = 1155
847
+ ER_NET_PACKETS_OUT_OF_ORDER = 1156
848
+ ER_NET_UNCOMPRESS_ERROR = 1157
849
+ ER_NET_READ_ERROR = 1158
850
+ ER_NET_READ_INTERRUPTED = 1159
851
+ ER_NET_ERROR_ON_WRITE = 1160
852
+ ER_NET_WRITE_INTERRUPTED = 1161
853
+ ER_TOO_LONG_STRING = 1162
854
+ ER_TABLE_CANT_HANDLE_BLOB = 1163
855
+ ER_TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164
856
+ ER_DELAYED_INSERT_TABLE_LOCKED = 1165
857
+ ER_WRONG_COLUMN_NAME = 1166
858
+ ER_WRONG_KEY_COLUMN = 1167
859
+ ER_WRONG_MRG_TABLE = 1168
860
+ ER_DUP_UNIQUE = 1169
861
+ ER_BLOB_KEY_WITHOUT_LENGTH = 1170
862
+ ER_PRIMARY_CANT_HAVE_NULL = 1171
863
+ ER_TOO_MANY_ROWS = 1172
864
+ ER_REQUIRES_PRIMARY_KEY = 1173
865
+ ER_NO_RAID_COMPILED = 1174
866
+ ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175
867
+ ER_KEY_DOES_NOT_EXITS = 1176
868
+ ER_CHECK_NO_SUCH_TABLE = 1177
869
+ ER_CHECK_NOT_IMPLEMENTED = 1178
870
+ ER_CANT_DO_THIS_DURING_AN_TRANSACTION = 1179
871
+ ER_ERROR_DURING_COMMIT = 1180
872
+ ER_ERROR_DURING_ROLLBACK = 1181
873
+ ER_ERROR_DURING_FLUSH_LOGS = 1182
874
+ ER_ERROR_DURING_CHECKPOINT = 1183
875
+ ER_NEW_ABORTING_CONNECTION = 1184
876
+ ER_DUMP_NOT_IMPLEMENTED = 1185
877
+ ER_FLUSH_MASTER_BINLOG_CLOSED = 1186
878
+ ER_INDEX_REBUILD = 1187
879
+ ER_MASTER = 1188
880
+ ER_MASTER_NET_READ = 1189
881
+ ER_MASTER_NET_WRITE = 1190
882
+ ER_FT_MATCHING_KEY_NOT_FOUND = 1191
883
+ ER_LOCK_OR_ACTIVE_TRANSACTION = 1192
884
+ ER_UNKNOWN_SYSTEM_VARIABLE = 1193
885
+ ER_CRASHED_ON_USAGE = 1194
886
+ ER_CRASHED_ON_REPAIR = 1195
887
+ ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196
888
+ ER_TRANS_CACHE_FULL = 1197
889
+ ER_SLAVE_MUST_STOP = 1198
890
+ ER_SLAVE_NOT_RUNNING = 1199
891
+ ER_BAD_SLAVE = 1200
892
+ ER_MASTER_INFO = 1201
893
+ ER_SLAVE_THREAD = 1202
894
+ ER_TOO_MANY_USER_CONNECTIONS = 1203
895
+ ER_SET_CONSTANTS_ONLY = 1204
896
+ ER_LOCK_WAIT_TIMEOUT = 1205
897
+ ER_LOCK_TABLE_FULL = 1206
898
+ ER_READ_ONLY_TRANSACTION = 1207
899
+ ER_DROP_DB_WITH_READ_LOCK = 1208
900
+ ER_CREATE_DB_WITH_READ_LOCK = 1209
901
+ ER_WRONG_ARGUMENTS = 1210
902
+ ER_NO_PERMISSION_TO_CREATE_USER = 1211
903
+ ER_UNION_TABLES_IN_DIFFERENT_DIR = 1212
904
+ ER_LOCK_DEADLOCK = 1213
905
+ ER_TABLE_CANT_HANDLE_FULLTEXT = 1214
906
+ ER_CANNOT_ADD_FOREIGN = 1215
907
+ ER_NO_REFERENCED_ROW = 1216
908
+ ER_ROW_IS_REFERENCED = 1217
909
+ ER_CONNECT_TO_MASTER = 1218
910
+ ER_QUERY_ON_MASTER = 1219
911
+ ER_ERROR_WHEN_EXECUTING_COMMAND = 1220
912
+ ER_WRONG_USAGE = 1221
913
+ ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222
914
+ ER_CANT_UPDATE_WITH_READLOCK = 1223
915
+ ER_MIXING_NOT_ALLOWED = 1224
916
+ ER_DUP_ARGUMENT = 1225
917
+ ER_USER_LIMIT_REACHED = 1226
918
+ ER_SPECIFIC_ACCESS_DENIED_ERROR = 1227
919
+ ER_LOCAL_VARIABLE = 1228
920
+ ER_GLOBAL_VARIABLE = 1229
921
+ ER_NO_DEFAULT = 1230
922
+ ER_WRONG_VALUE_FOR_VAR = 1231
923
+ ER_WRONG_TYPE_FOR_VAR = 1232
924
+ ER_VAR_CANT_BE_READ = 1233
925
+ ER_CANT_USE_OPTION_HERE = 1234
926
+ ER_NOT_SUPPORTED_YET = 1235
927
+ ER_MASTER_FATAL_ERROR_READING_BINLOG = 1236
928
+ ER_SLAVE_IGNORED_TABLE = 1237
929
+ ER_ERROR_MESSAGES = 238
930
+
931
+ # Client Error
932
+ CR_MIN_ERROR = 2000
933
+ CR_MAX_ERROR = 2999
934
+ CR_UNKNOWN_ERROR = 2000
935
+ CR_SOCKET_CREATE_ERROR = 2001
936
+ CR_CONNECTION_ERROR = 2002
937
+ CR_CONN_HOST_ERROR = 2003
938
+ CR_IPSOCK_ERROR = 2004
939
+ CR_UNKNOWN_HOST = 2005
940
+ CR_SERVER_GONE_ERROR = 2006
941
+ CR_VERSION_ERROR = 2007
942
+ CR_OUT_OF_MEMORY = 2008
943
+ CR_WRONG_HOST_INFO = 2009
944
+ CR_LOCALHOST_CONNECTION = 2010
945
+ CR_TCP_CONNECTION = 2011
946
+ CR_SERVER_HANDSHAKE_ERR = 2012
947
+ CR_SERVER_LOST = 2013
948
+ CR_COMMANDS_OUT_OF_SYNC = 2014
949
+ CR_NAMEDPIPE_CONNECTION = 2015
950
+ CR_NAMEDPIPEWAIT_ERROR = 2016
951
+ CR_NAMEDPIPEOPEN_ERROR = 2017
952
+ CR_NAMEDPIPESETSTATE_ERROR = 2018
953
+ CR_CANT_READ_CHARSET = 2019
954
+ CR_NET_PACKET_TOO_LARGE = 2020
955
+ CR_EMBEDDED_CONNECTION = 2021
956
+ CR_PROBE_SLAVE_STATUS = 2022
957
+ CR_PROBE_SLAVE_HOSTS = 2023
958
+ CR_PROBE_SLAVE_CONNECT = 2024
959
+ CR_PROBE_MASTER_CONNECT = 2025
960
+ CR_SSL_CONNECTION_ERROR = 2026
961
+ CR_MALFORMED_PACKET = 2027
962
+
963
+ CLIENT_ERRORS = [
964
+ "Unknown MySQL error",
965
+ "Can't create UNIX socket (%d)",
966
+ "Can't connect to local MySQL server through socket '%-.64s' (%d)",
967
+ "Can't connect to MySQL server on '%-.64s' (%d)",
968
+ "Can't create TCP/IP socket (%d)",
969
+ "Unknown MySQL Server Host '%-.64s' (%d)",
970
+ "MySQL server has gone away",
971
+ "Protocol mismatch. Server Version = %d Client Version = %d",
972
+ "MySQL client run out of memory",
973
+ "Wrong host info",
974
+ "Localhost via UNIX socket",
975
+ "%-.64s via TCP/IP",
976
+ "Error in server handshake",
977
+ "Lost connection to MySQL server during query",
978
+ "Commands out of sync; You can't run this command now",
979
+ "%-.64s via named pipe",
980
+ "Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
981
+ "Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
982
+ "Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
983
+ "Can't initialize character set %-.64s (path: %-.64s)",
984
+ "Got packet bigger than 'max_allowed_packet'",
985
+ "Embedded server",
986
+ "Error on SHOW SLAVE STATUS:",
987
+ "Error on SHOW SLAVE HOSTS:",
988
+ "Error connecting to slave:",
989
+ "Error connecting to master:",
990
+ "SSL connection error",
991
+ "Malformed packet"
992
+ ]
993
+
994
+ def initialize(errno, error)
995
+ @errno = errno
996
+ @error = error
997
+ super error
998
+ end
999
+ attr_reader :errno, :error
1000
+
1001
+ def Error::err(errno)
1002
+ CLIENT_ERRORS[errno - Error::CR_MIN_ERROR]
1003
+ end
1004
+ end
1005
+
1006
+ class Net
1007
+ def initialize(sock)
1008
+ @sock = sock
1009
+ @pkt_nr = 0
1010
+ end
1011
+
1012
+ def clear()
1013
+ @pkt_nr = 0
1014
+ end
1015
+
1016
+ def read()
1017
+ buf = []
1018
+ len = nil
1019
+ @sock.sync = false
1020
+ while len == nil or len == MAX_PACKET_LENGTH do
1021
+ a = @sock.read(4)
1022
+ len = a[0]+a[1]*256+a[2]*256*256
1023
+ pkt_nr = a[3]
1024
+ if @pkt_nr != pkt_nr then
1025
+ raise "Packets out of order: #{@pkt_nr}<>#{pkt_nr}"
1026
+ end
1027
+ @pkt_nr = @pkt_nr + 1 & 0xff
1028
+ buf << @sock.read(len)
1029
+ end
1030
+ @sock.sync = true
1031
+ buf.join
1032
+ end
1033
+
1034
+ def write(data)
1035
+ if data.is_a? Array then
1036
+ data = data.join
1037
+ end
1038
+ @sock.sync = false
1039
+ ptr = 0
1040
+ while data.length >= MAX_PACKET_LENGTH do
1041
+ @sock.write Net::int3str(MAX_PACKET_LENGTH)+@pkt_nr.chr+data[ptr, MAX_PACKET_LENGTH]
1042
+ @pkt_nr = @pkt_nr + 1 & 0xff
1043
+ ptr += MAX_PACKET_LENGTH
1044
+ end
1045
+ @sock.write Net::int3str(data.length-ptr)+@pkt_nr.chr+data[ptr .. -1]
1046
+ @pkt_nr = @pkt_nr + 1 & 0xff
1047
+ @sock.sync = true
1048
+ @sock.flush
1049
+ end
1050
+
1051
+ def close()
1052
+ @sock.close
1053
+ end
1054
+
1055
+ def Net::int2str(n)
1056
+ [n].pack("v")
1057
+ end
1058
+
1059
+ def Net::int3str(n)
1060
+ [n%256, n>>8].pack("cv")
1061
+ end
1062
+
1063
+ def Net::int4str(n)
1064
+ [n].pack("V")
1065
+ end
1066
+
1067
+ end
1068
+
1069
+ class Random
1070
+ def initialize(seed1, seed2)
1071
+ @max_value = 0x3FFFFFFF
1072
+ @seed1 = seed1 % @max_value
1073
+ @seed2 = seed2 % @max_value
1074
+ end
1075
+
1076
+ def rnd()
1077
+ @seed1 = (@seed1*3+@seed2) % @max_value
1078
+ @seed2 = (@seed1+@seed2+33) % @max_value
1079
+ @seed1.to_f / @max_value
1080
+ end
1081
+ end
1082
+
1083
+ end
1084
+
1085
+ class << Mysql
1086
+ def init()
1087
+ Mysql::new :INIT
1088
+ end
1089
+
1090
+ def real_connect(*args)
1091
+ Mysql::new(*args)
1092
+ end
1093
+ alias :connect :real_connect
1094
+
1095
+ def finalizer(net)
1096
+ proc {
1097
+ net.clear
1098
+ net.write Mysql::COM_QUIT.chr
1099
+ }
1100
+ end
1101
+
1102
+ def escape_string(str)
1103
+ str.gsub(/([\0\n\r\032\'\"\\])/) do
1104
+ case $1
1105
+ when "\0" then "\\0"
1106
+ when "\n" then "\\n"
1107
+ when "\r" then "\\r"
1108
+ when "\032" then "\\Z"
1109
+ else "\\"+$1
1110
+ end
1111
+ end
1112
+ end
1113
+ alias :quote :escape_string
1114
+
1115
+ def get_client_info()
1116
+ Mysql::VERSION
1117
+ end
1118
+ alias :client_info :get_client_info
1119
+
1120
+ def debug(str)
1121
+ raise "not implemented"
1122
+ end
1123
+ end
1124
+
1125
+ #
1126
+ # for compatibility
1127
+ #
1128
+
1129
+ MysqlRes = Mysql::Result
1130
+ MysqlField = Mysql::Field
1131
+ MysqlError = Mysql::Error