ruby-mysql 2.9.11 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  # coding: ascii-8bit
2
- # Copyright (C) 2003-2008 TOMITA Masahiro
2
+ # Copyright (C) 2003 TOMITA Masahiro
3
3
  # mailto:tommy@tmtm.org
4
4
 
5
5
  class Mysql
@@ -33,50 +33,88 @@ class Mysql
33
33
  COM_STMT_RESET = 26
34
34
  COM_SET_OPTION = 27
35
35
  COM_STMT_FETCH = 28
36
+ COM_DAEMON = 29
37
+ COM_BINLOG_DUMP_GTID = 30
38
+ COM_RESET_CONNECTION = 31
39
+ COM_CLONE = 32
36
40
 
37
41
  # Client flag
38
- CLIENT_LONG_PASSWORD = 1 # new more secure passwords
39
- CLIENT_FOUND_ROWS = 1 << 1 # Found instead of affected rows
40
- CLIENT_LONG_FLAG = 1 << 2 # Get all column flags
41
- CLIENT_CONNECT_WITH_DB = 1 << 3 # One can specify db on connect
42
- CLIENT_NO_SCHEMA = 1 << 4 # Don't allow database.table.column
43
- CLIENT_COMPRESS = 1 << 5 # Can use compression protocol
44
- CLIENT_ODBC = 1 << 6 # Odbc client
45
- CLIENT_LOCAL_FILES = 1 << 7 # Can use LOAD DATA LOCAL
46
- CLIENT_IGNORE_SPACE = 1 << 8 # Ignore spaces before '('
47
- CLIENT_PROTOCOL_41 = 1 << 9 # New 4.1 protocol
48
- CLIENT_INTERACTIVE = 1 << 10 # This is an interactive client
49
- CLIENT_SSL = 1 << 11 # Switch to SSL after handshake
50
- CLIENT_IGNORE_SIGPIPE = 1 << 12 # IGNORE sigpipes
51
- CLIENT_TRANSACTIONS = 1 << 13 # Client knows about transactions
52
- CLIENT_RESERVED = 1 << 14 # Old flag for 4.1 protocol
53
- CLIENT_SECURE_CONNECTION = 1 << 15 # New 4.1 authentication
54
- CLIENT_MULTI_STATEMENTS = 1 << 16 # Enable/disable multi-stmt support
55
- CLIENT_MULTI_RESULTS = 1 << 17 # Enable/disable multi-results
42
+ CLIENT_LONG_PASSWORD = 1 # new more secure passwords
43
+ CLIENT_FOUND_ROWS = 1 << 1 # Found instead of affected rows
44
+ CLIENT_LONG_FLAG = 1 << 2 # Get all column flags
45
+ CLIENT_CONNECT_WITH_DB = 1 << 3 # One can specify db on connect
46
+ CLIENT_NO_SCHEMA = 1 << 4 # Don't allow database.table.column
47
+ CLIENT_COMPRESS = 1 << 5 # Can use compression protocol
48
+ CLIENT_ODBC = 1 << 6 # Odbc client
49
+ CLIENT_LOCAL_FILES = 1 << 7 # Can use LOAD DATA LOCAL
50
+ CLIENT_IGNORE_SPACE = 1 << 8 # Ignore spaces before '('
51
+ CLIENT_PROTOCOL_41 = 1 << 9 # New 4.1 protocol
52
+ CLIENT_INTERACTIVE = 1 << 10 # This is an interactive client
53
+ CLIENT_SSL = 1 << 11 # Switch to SSL after handshake
54
+ CLIENT_IGNORE_SIGPIPE = 1 << 12 # IGNORE sigpipes
55
+ CLIENT_TRANSACTIONS = 1 << 13 # Client knows about transactions
56
+ CLIENT_RESERVED = 1 << 14 # Old flag for 4.1 protocol
57
+ CLIENT_SECURE_CONNECTION = 1 << 15 # New 4.1 authentication
58
+ CLIENT_MULTI_STATEMENTS = 1 << 16 # Enable/disable multi-stmt support
59
+ CLIENT_MULTI_RESULTS = 1 << 17 # Enable/disable multi-results
60
+ CLIENT_PS_MULTI_RESULTS = 1 << 18 # Multi-results in PS-protocol
61
+ CLIENT_PLUGIN_AUTH = 1 << 19 # Client supports plugin authentication
62
+ CLIENT_CONNECT_ATTRS = 1 << 20 # Client supports connection attribute
63
+ CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = 1 << 21 # Enable authentication response packet to be larger than 255 bytes.
64
+ CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS = 1 << 22 # Don't close the connection for a connection with expired password.
65
+ CLIENT_SESSION_TRACK = 1 << 23 # Capable of handling server state change information. Its a hint to the server to include the state change information in Ok packet.
66
+ CLIENT_DEPRECATE_EOF = 1 << 24 # Client no longer needs EOF packet
67
+ CLIENT_OPTIONAL_RESULTSET_METADATA = 1 << 25 # The client can handle optional metadata information in the resultset.
68
+ CLIENT_ZSTD_COMPRESSION_ALGORITHM = 1 << 26 # Compression protocol extended to support zstd compression method
69
+ CLIENT_CAPABILITY_EXTENSION = 1 << 29 # This flag will be reserved to extend the 32bit capabilities structure to 64bits.
70
+ CLIENT_SSL_VERIFY_SERVER_CERT = 1 << 30 # Verify server certificate.
71
+ CLIENT_REMEMBER_OPTIONS = 1 << 31 # Don't reset the options after an unsuccessful connect
56
72
 
57
73
  # Connection Option
58
- OPT_CONNECT_TIMEOUT = 0
59
- OPT_COMPRESS = 1
60
- OPT_NAMED_PIPE = 2
61
- INIT_COMMAND = 3
62
- READ_DEFAULT_FILE = 4
63
- READ_DEFAULT_GROUP = 5
64
- SET_CHARSET_DIR = 6
65
- SET_CHARSET_NAME = 7
66
- OPT_LOCAL_INFILE = 8
67
- OPT_PROTOCOL = 9
68
- SHARED_MEMORY_BASE_NAME = 10
69
- OPT_READ_TIMEOUT = 11
70
- OPT_WRITE_TIMEOUT = 12
71
- OPT_USE_RESULT = 13
72
- OPT_USE_REMOTE_CONNECTION = 14
73
- OPT_USE_EMBEDDED_CONNECTION = 15
74
- OPT_GUESS_CONNECTION = 16
75
- SET_CLIENT_IP = 17
76
- SECURE_AUTH = 18
77
- REPORT_DATA_TRUNCATION = 19
78
- OPT_RECONNECT = 20
79
- OPT_SSL_VERIFY_SERVER_CERT = 21
74
+ OPT_CONNECT_TIMEOUT = 0
75
+ OPT_COMPRESS = 1
76
+ OPT_NAMED_PIPE = 2
77
+ INIT_COMMAND = 3
78
+ READ_DEFAULT_FILE = 4
79
+ READ_DEFAULT_GROUP = 5
80
+ SET_CHARSET_DIR = 6
81
+ SET_CHARSET_NAME = 7
82
+ OPT_LOCAL_INFILE = 8
83
+ OPT_PROTOCOL = 9
84
+ SHARED_MEMORY_BASE_NAME = 10
85
+ OPT_READ_TIMEOUT = 11
86
+ OPT_WRITE_TIMEOUT = 12
87
+ OPT_USE_RESULT = 13
88
+ REPORT_DATA_TRUNCATION = 14
89
+ OPT_RECONNECT = 15
90
+ PLUGIN_DIR = 16
91
+ DEFAULT_AUTH = 17
92
+ OPT_BIND = 18
93
+ OPT_SSL_KEY = 19
94
+ OPT_SSL_CERT = 20
95
+ OPT_SSL_CA = 21
96
+ OPT_SSL_CAPATH = 22
97
+ OPT_SSL_CIPHER = 23
98
+ OPT_SSL_CRL = 24
99
+ OPT_SSL_CRLPATH = 25
100
+ OPT_CONNECT_ATTR_RESET = 26
101
+ OPT_CONNECT_ATTR_ADD = 27
102
+ OPT_CONNECT_ATTR_DELETE = 28
103
+ SERVER_PUBLIC_KEY = 29
104
+ ENABLE_CLEARTEXT_PLUGIN = 30
105
+ OPT_CAN_HANDLE_EXPIRED_PASSWORDS = 31
106
+ OPT_MAX_ALLOWED_PACKET = 32
107
+ OPT_NET_BUFFER_LENGTH = 33
108
+ OPT_TLS_VERSION = 34
109
+ OPT_SSL_MODE = 35
110
+ OPT_GET_SERVER_PUBLIC_KEY = 36
111
+ OPT_RETRY_COUNT = 37
112
+ OPT_OPTIONAL_RESULTSET_METADATA = 38
113
+ OPT_SSL_FIPS_MODE = 39
114
+ OPT_TLS_CIPHERSUITES = 40
115
+ OPT_COMPRESSION_ALGORITHMS = 41
116
+ OPT_ZSTD_COMPRESSION_LEVEL = 42
117
+ OPT_LOAD_DATA_LOCAL_DIR = 43
80
118
 
81
119
  # Server Option
82
120
  OPTION_MULTI_STATEMENTS_ON = 0
@@ -92,18 +130,36 @@ class Mysql
92
130
  SERVER_STATUS_LAST_ROW_SENT = 1 << 7
93
131
  SERVER_STATUS_DB_DROPPED = 1 << 8
94
132
  SERVER_STATUS_NO_BACKSLASH_ESCAPES = 1 << 9
133
+ SERVER_STATUS_METADATA_CHANGED = 1 << 10
134
+ SERVER_QUERY_WAS_SLOW = 1 << 11
135
+ SERVER_PS_OUT_PARAMS = 1 << 12
136
+ SERVER_STATUS_IN_TRANS_READONLY = 1 << 13
137
+ SERVER_SESSION_STATE_CHANGED = 1 << 14
95
138
 
96
139
  # Refresh parameter
97
- REFRESH_GRANT = 1
98
- REFRESH_LOG = 1 << 1
99
- REFRESH_TABLES = 1 << 2
100
- REFRESH_HOSTS = 1 << 3
101
- REFRESH_STATUS = 1 << 4
102
- REFRESH_THREADS = 1 << 5
103
- REFRESH_SLAVE = 1 << 6
104
- REFRESH_MASTER = 1 << 7
105
- REFRESH_READ_LOCK = 1 << 14
106
- REFRESH_FAST = 1 << 15
140
+ REFRESH_GRANT = 1
141
+ REFRESH_LOG = 1 << 1
142
+ REFRESH_TABLES = 1 << 2
143
+ REFRESH_HOSTS = 1 << 3
144
+ REFRESH_STATUS = 1 << 4
145
+ REFRESH_THREADS = 1 << 5
146
+ REFRESH_SLAVE = 1 << 6
147
+ REFRESH_MASTER = 1 << 7
148
+ REFRESH_ERROR_LOG = 1 << 8
149
+ REFRESH_ENGINE_LOG = 1 << 9
150
+ REFRESH_BINARY_LOG = 1 << 10
151
+ REFRESH_RELAY_LOG = 1 << 11
152
+ REFRESH_GENERAL_LOG = 1 << 12
153
+ REFRESH_SLOW_LOG = 1 << 13
154
+ REFRESH_READ_LOCK = 1 << 14
155
+ REFRESH_FAST = 1 << 15
156
+ REFRESH_QUERY_CACHE = 1 << 16
157
+ REFRESH_QUERY_CACHE_FREE = 1 << 17
158
+ REFRESH_DES_KEY_FILE = 1 << 18
159
+ REFRESH_USER_RESOURCES = 1 << 19
160
+ REFRESH_FOR_EXPORT = 1 << 20
161
+ REFRESH_OPTIMIZER_COSTS = 1 << 21
162
+ REFRESH_PERSIST = 1 << 22
107
163
 
108
164
  class Field
109
165
  # Field type
@@ -124,6 +180,13 @@ class Mysql
124
180
  TYPE_NEWDATE = 14
125
181
  TYPE_VARCHAR = 15
126
182
  TYPE_BIT = 16
183
+ TYPE_TIMESTAMP2 = 17
184
+ TYPE_DATETIME2 = 18
185
+ TYPE_TIME2 = 19
186
+ TYPE_TYPED_ARRAY = 20
187
+ TYPE_INVALID = 243
188
+ TYPE_BOOL = 244
189
+ TYPE_JSON = 245
127
190
  TYPE_NEWDECIMAL = 246
128
191
  TYPE_ENUM = 247
129
192
  TYPE_SET = 248
@@ -138,28 +201,42 @@ class Mysql
138
201
  TYPE_INTERVAL = TYPE_ENUM
139
202
 
140
203
  # Flag
141
- NOT_NULL_FLAG = 1
142
- PRI_KEY_FLAG = 2
143
- UNIQUE_KEY_FLAG = 4
144
- MULTIPLE_KEY_FLAG = 8
145
- BLOB_FLAG = 16
146
- UNSIGNED_FLAG = 32
147
- ZEROFILL_FLAG = 64
148
- BINARY_FLAG = 128
149
- ENUM_FLAG = 256
150
- AUTO_INCREMENT_FLAG = 512
151
- TIMESTAMP_FLAG = 1024
152
- SET_FLAG = 2048
153
- NUM_FLAG = 32768
154
- PART_KEY_FLAG = 16384
155
- GROUP_FLAG = 32768
156
- UNIQUE_FLAG = 65536
157
- BINCMP_FLAG = 131072
204
+ NOT_NULL_FLAG = 1
205
+ PRI_KEY_FLAG = 2
206
+ UNIQUE_KEY_FLAG = 4
207
+ MULTIPLE_KEY_FLAG = 8
208
+ BLOB_FLAG = 16
209
+ UNSIGNED_FLAG = 32
210
+ ZEROFILL_FLAG = 64
211
+ BINARY_FLAG = 128
212
+ ENUM_FLAG = 256
213
+ AUTO_INCREMENT_FLAG = 512
214
+ TIMESTAMP_FLAG = 1024
215
+ SET_FLAG = 2048
216
+ NO_DEFAULT_VALUE_FLAG = 4096
217
+ ON_UPDATE_NOW_FLAG = 8192
218
+ NUM_FLAG = 32768
219
+ PART_KEY_FLAG = 16384
220
+ GROUP_FLAG = 32768
221
+ UNIQUE_FLAG = 65536
222
+ BINCMP_FLAG = 131072
223
+ GET_FIXED_FIELDS_FLAG = 1 << 18
224
+ FIELD_IN_PART_FUNC_FLAG = 1 << 19
225
+ FIELD_IN_ADD_INDEX = 1 << 20
226
+ FIELD_IS_RENAMED = 1 << 21
227
+ FIELD_FLAGS_STORAGE_MEDIA_MASK = 3 << 22
228
+ FIELD_FLAGS_COLUMN_FORMAT_MASK = 3 << 24
229
+ FIELD_IS_DROPPED = 1 << 26
230
+ EXPLICIT_NULL_FLAG = 1 << 27
231
+ FIELD_IS_MARKED = 1 << 28
232
+ NOT_SECONDARY_FLAG = 1 << 29
158
233
  end
159
234
 
160
235
  class Stmt
161
236
  # Cursor type
162
- CURSOR_TYPE_NO_CURSOR = 0
163
- CURSOR_TYPE_READ_ONLY = 1
237
+ CURSOR_TYPE_NO_CURSOR = 0
238
+ CURSOR_TYPE_READ_ONLY = 1
239
+ CURSOR_TYPE_FOR_UPDATE = 2
240
+ CURSOR_TYPE_SCROLLABLE = 4
164
241
  end
165
242
  end
data/lib/mysql/error.rb CHANGED
@@ -977,7 +977,16 @@ class Mysql
977
977
  CR_AUTH_PLUGIN_CANNOT_LOAD = 2059
978
978
  CR_DUPLICATE_CONNECTION_ATTR = 2060
979
979
  CR_AUTH_PLUGIN_ERR = 2061
980
- CR_ERROR_LAST = 2061
980
+ CR_INSECURE_API_ERR = 2062
981
+ CR_FILE_NAME_TOO_LONG = 2063
982
+ CR_SSL_FIPS_MODE_ERR = 2064
983
+ CR_DEPRECATED_COMPRESSION_NOT_SUPPORTED = 2065
984
+ CR_COMPRESSION_WRONGLY_CONFIGURED = 2066
985
+ CR_KERBEROS_USER_NOT_FOUND = 2067
986
+ CR_LOAD_DATA_LOCAL_INFILE_REJECTED = 2068
987
+ CR_LOAD_DATA_LOCAL_INFILE_REALPATH_FAIL = 2069
988
+ CR_DNS_SRV_LOOKUP_FAILED = 2070
989
+ CR_ERROR_LAST = 2070
981
990
  end
982
991
 
983
992
  ClientError.define_error_class(/\ACR_/)
@@ -1,5 +1,5 @@
1
1
  # coding: ascii-8bit
2
- # Copyright (C) 2008-2012 TOMITA Masahiro
2
+ # Copyright (C) 2008 TOMITA Masahiro
3
3
  # mailto:tommy@tmtm.org
4
4
 
5
5
  require "socket"
@@ -23,7 +23,7 @@ class Mysql
23
23
  # Object :: converted value.
24
24
  def self.net2value(pkt, type, unsigned)
25
25
  case type
26
- when Field::TYPE_STRING, Field::TYPE_VAR_STRING, Field::TYPE_NEWDECIMAL, Field::TYPE_BLOB
26
+ when Field::TYPE_STRING, Field::TYPE_VAR_STRING, Field::TYPE_NEWDECIMAL, Field::TYPE_BLOB, Field::TYPE_JSON
27
27
  return pkt.lcs
28
28
  when Field::TYPE_TINY
29
29
  v = pkt.utiny
@@ -33,11 +33,11 @@ class Mysql
33
33
  return unsigned ? v : v < 32768 ? v : v-65536
34
34
  when Field::TYPE_INT24, Field::TYPE_LONG
35
35
  v = pkt.ulong
36
- return unsigned ? v : v < 2**32/2 ? v : v-2**32
36
+ return unsigned ? v : v < 0x8000_0000 ? v : v-0x10000_0000
37
37
  when Field::TYPE_LONGLONG
38
38
  n1, n2 = pkt.ulong, pkt.ulong
39
39
  v = (n2 << 32) | n1
40
- return unsigned ? v : v < 2**64/2 ? v : v-2**64
40
+ return unsigned ? v : v < 0x8000_0000_0000_0000 ? v : v-0x10000_0000_0000_0000
41
41
  when Field::TYPE_FLOAT
42
42
  return pkt.read(4).unpack('e').first
43
43
  when Field::TYPE_DOUBLE
@@ -79,38 +79,17 @@ class Mysql
79
79
  type = Field::TYPE_NULL
80
80
  val = ""
81
81
  when Integer
82
- if v >= 0
83
- if v < 256
84
- type = Field::TYPE_TINY | 0x8000
85
- val = [v].pack("C")
86
- elsif v < 256**2
87
- type = Field::TYPE_SHORT | 0x8000
88
- val = [v].pack("v")
89
- elsif v < 256**4
90
- type = Field::TYPE_LONG | 0x8000
91
- val = [v].pack("V")
92
- elsif v < 256**8
93
- type = Field::TYPE_LONGLONG | 0x8000
94
- val = [v&0xffffffff, v>>32].pack("VV")
95
- else
96
- raise ProtocolError, "value too large: #{v}"
97
- end
82
+ if -0x8000_0000 <= v && v < 0x8000_0000
83
+ type = Field::TYPE_LONG
84
+ val = [v].pack('V')
85
+ elsif -0x8000_0000_0000_0000 <= v && v < 0x8000_0000_0000_0000
86
+ type = Field::TYPE_LONGLONG
87
+ val = [v&0xffffffff, v>>32].pack("VV")
88
+ elsif 0x8000_0000_0000_0000 <= v && v <= 0xffff_ffff_ffff_ffff
89
+ type = Field::TYPE_LONGLONG | 0x8000
90
+ val = [v&0xffffffff, v>>32].pack("VV")
98
91
  else
99
- if -v <= 256/2
100
- type = Field::TYPE_TINY
101
- val = [v].pack("C")
102
- elsif -v <= 256**2/2
103
- type = Field::TYPE_SHORT
104
- val = [v].pack("v")
105
- elsif -v <= 256**4/2
106
- type = Field::TYPE_LONG
107
- val = [v].pack("V")
108
- elsif -v <= 256**8/2
109
- type = Field::TYPE_LONGLONG
110
- val = [v&0xffffffff, v>>32].pack("VV")
111
- else
112
- raise ProtocolError, "value too large: #{v}"
113
- end
92
+ raise ProtocolError, "value too large: #{v}"
114
93
  end
115
94
  when Float
116
95
  type = Field::TYPE_DOUBLE
@@ -118,9 +97,12 @@ class Mysql
118
97
  when String
119
98
  type = Field::TYPE_STRING
120
99
  val = Packet.lcs(v)
121
- when Mysql::Time, ::Time
100
+ when ::Time
101
+ type = Field::TYPE_DATETIME
102
+ val = [11, v.year, v.month, v.day, v.hour, v.min, v.sec, v.usec].pack("CvCCCCCV")
103
+ when Mysql::Time
122
104
  type = Field::TYPE_DATETIME
123
- val = [7, v.year, v.month, v.day, v.hour, v.min, v.sec].pack("CvCCCCC")
105
+ val = [11, v.year, v.month, v.day, v.hour, v.min, v.sec, v.second_part].pack("CvCCCCCV")
124
106
  else
125
107
  raise ProtocolError, "class #{v.class} is not supported"
126
108
  end
@@ -152,15 +134,17 @@ class Mysql
152
134
  # conn_timeout :: [Integer] connect timeout (sec).
153
135
  # read_timeout :: [Integer] read timeout (sec).
154
136
  # write_timeout :: [Integer] write timeout (sec).
137
+ # local_infile :: [String] local infile path
155
138
  # === Exception
156
139
  # [ClientError] :: connection timeout
157
- def initialize(host, port, socket, conn_timeout, read_timeout, write_timeout)
140
+ def initialize(host, port, socket, conn_timeout, read_timeout, write_timeout, local_infile)
158
141
  @insert_id = 0
159
142
  @warning_count = 0
160
143
  @gc_stmt_queue = [] # stmt id list which GC destroy.
161
144
  set_state :INIT
162
145
  @read_timeout = read_timeout
163
146
  @write_timeout = write_timeout
147
+ @local_infile = local_infile
164
148
  begin
165
149
  Timeout.timeout conn_timeout do
166
150
  if host.nil? or host.empty? or host == "localhost"
@@ -198,6 +182,7 @@ class Mysql
198
182
  @server_version = init_packet.server_version.split(/\D/)[0,3].inject{|a,b|a.to_i*100+b.to_i}
199
183
  @thread_id = init_packet.thread_id
200
184
  client_flags = CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION
185
+ client_flags |= CLIENT_LOCAL_FILES if @local_infile
201
186
  client_flags |= CLIENT_CONNECT_WITH_DB if db
202
187
  client_flags |= flag
203
188
  @charset = charset
@@ -248,10 +233,7 @@ class Mysql
248
233
  return res_packet.field_count
249
234
  end
250
235
  if res_packet.field_count.nil? # LOAD DATA LOCAL INFILE
251
- filename = res_packet.message
252
- File.open(filename){|f| write f}
253
- write nil # EOF mark
254
- read
236
+ send_local_file(res_packet.message)
255
237
  end
256
238
  @affected_rows, @insert_id, @server_status, @warning_count, @message =
257
239
  res_packet.affected_rows, res_packet.insert_id, res_packet.server_status, res_packet.warning_count, res_packet.message
@@ -263,6 +245,19 @@ class Mysql
263
245
  end
264
246
  end
265
247
 
248
+ # send local file to server
249
+ def send_local_file(filename)
250
+ filename = File.absolute_path(filename)
251
+ if filename.start_with? @local_infile
252
+ File.open(filename){|f| write f}
253
+ else
254
+ raise ClientError::LoadDataLocalInfileRejected, 'LOAD DATA LOCAL INFILE file request rejected due to restrictions on access.'
255
+ end
256
+ ensure
257
+ write nil # EOF mark
258
+ read
259
+ end
260
+
266
261
  # Retrieve n fields
267
262
  # === Argument
268
263
  # n :: [Integer] number of fields
@@ -488,7 +483,7 @@ class Mysql
488
483
  # === Exception
489
484
  # [ProtocolError] invalid packet sequence number
490
485
  def read
491
- ret = ""
486
+ data = ''
492
487
  len = nil
493
488
  begin
494
489
  Timeout.timeout @read_timeout do
@@ -500,6 +495,7 @@ class Mysql
500
495
  @seq = (@seq + 1) % 256
501
496
  ret = @sock.read(len)
502
497
  raise EOFError unless ret && ret.length == len
498
+ data.concat ret
503
499
  end
504
500
  rescue EOFError
505
501
  raise ClientError::ServerGoneError, 'MySQL server has gone away'
@@ -510,18 +506,19 @@ class Mysql
510
506
  @sqlstate = "00000"
511
507
 
512
508
  # Error packet
513
- if ret[0] == ?\xff
514
- f, errno, marker, @sqlstate, message = ret.unpack("Cvaa5a*")
509
+ if data[0] == ?\xff
510
+ f, errno, marker, @sqlstate, message = data.unpack("Cvaa5a*")
515
511
  unless marker == "#"
516
- f, errno, message = ret.unpack("Cva*") # Version 4.0 Error
512
+ f, errno, message = data.unpack("Cva*") # Version 4.0 Error
517
513
  @sqlstate = ""
518
514
  end
515
+ message.force_encoding(@charset.encoding)
519
516
  if Mysql::ServerError::ERROR_MAP.key? errno
520
517
  raise Mysql::ServerError::ERROR_MAP[errno].new(message, @sqlstate)
521
518
  end
522
519
  raise Mysql::ServerError.new(message, @sqlstate)
523
520
  end
524
- Packet.new(ret)
521
+ Packet.new(data)
525
522
  end
526
523
 
527
524
  # Write one packet data
@@ -600,7 +597,7 @@ class Mysql
600
597
  server_capabilities = pkt.ushort
601
598
  server_charset = pkt.utiny
602
599
  server_status = pkt.ushort
603
- f1 = pkt.read(13)
600
+ _f1 = pkt.read(13)
604
601
  rest_scramble_buff = pkt.string
605
602
  raise ProtocolError, "unsupported version: #{protocol_version}" unless protocol_version == VERSION
606
603
  raise ProtocolError, "invalid packet: f0=#{f0}" unless f0 == 0
@@ -643,13 +640,13 @@ class Mysql
643
640
  # Field packet
644
641
  class FieldPacket
645
642
  def self.parse(pkt)
646
- first = pkt.lcs
643
+ _first = pkt.lcs
647
644
  db = pkt.lcs
648
645
  table = pkt.lcs
649
646
  org_table = pkt.lcs
650
647
  name = pkt.lcs
651
648
  org_name = pkt.lcs
652
- f0 = pkt.utiny
649
+ _f0 = pkt.utiny
653
650
  charsetnr = pkt.ushort
654
651
  length = pkt.ulong
655
652
  type = pkt.utiny
data/lib/mysql.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # coding: ascii-8bit
2
- # Copyright (C) 2008-2012 TOMITA Masahiro
2
+ # Copyright (C) 2008 TOMITA Masahiro
3
3
  # mailto:tommy@tmtm.org
4
4
 
5
5
  # MySQL connection class.
@@ -21,7 +21,7 @@ class Mysql
21
21
  rescue LoadError
22
22
  end
23
23
 
24
- VERSION = 20911 # Version number of this library
24
+ VERSION = 21000 # Version number of this library
25
25
  MYSQL_UNIX_PORT = "/tmp/mysql.sock" # UNIX domain socket filename
26
26
  MYSQL_TCP_PORT = 3306 # TCP socket port number
27
27
 
@@ -109,11 +109,11 @@ class Mysql
109
109
  # @return self
110
110
  def connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=0)
111
111
  if flag & CLIENT_COMPRESS != 0
112
- warn 'unsupported flag: CLIENT_COMPRESS'
112
+ warn 'unsupported flag: CLIENT_COMPRESS' if $VERBOSE
113
113
  flag &= ~CLIENT_COMPRESS
114
114
  end
115
- @protocol = Protocol.new host, port, socket, @connect_timeout, @read_timeout, @write_timeout
116
- @protocol.authenticate user, passwd, db, (@local_infile ? CLIENT_LOCAL_FILES : 0) | flag, @charset
115
+ @protocol = Protocol.new host, port, socket, @connect_timeout, @read_timeout, @write_timeout, @local_infile
116
+ @protocol.authenticate user, passwd, db, flag, @charset
117
117
  @charset ||= @protocol.charset
118
118
  @host_info = (host.nil? || host == "localhost") ? 'Localhost via UNIX socket' : "#{host} via TCP/IP"
119
119
  query @init_command if @init_command
@@ -158,6 +158,8 @@ class Mysql
158
158
  @connect_timeout = value
159
159
  # when Mysql::GUESS_CONNECTION
160
160
  when Mysql::OPT_LOCAL_INFILE
161
+ @local_infile = value ? '' : nil
162
+ when Mysql::OPT_LOAD_DATA_LOCAL_DIR
161
163
  @local_infile = value
162
164
  # when Mysql::OPT_NAMED_PIPE
163
165
  # when Mysql::OPT_PROTOCOL
@@ -179,7 +181,7 @@ class Mysql
179
181
  @charset = Charset.by_name value.to_s
180
182
  # when Mysql::SHARED_MEMORY_BASE_NAME
181
183
  else
182
- warn "option not implemented: #{opt}"
184
+ warn "option not implemented: #{opt}" if $VERBOSE
183
185
  end
184
186
  self
185
187
  end
@@ -731,8 +733,8 @@ class Mysql
731
733
  max_length = Array.new(@fields.size, 0)
732
734
  @records.each_with_index do |rec, i|
733
735
  rec = @records[i] = rec.to_a if rec.is_a? RawRecord
734
- max_length.each_index do |i|
735
- max_length[i] = rec[i].length if rec[i] && rec[i].length > max_length[i]
736
+ max_length.each_index do |j|
737
+ max_length[j] = rec[j].length if rec[j] && rec[j].length > max_length[j]
736
738
  end
737
739
  end
738
740
  max_length.each_with_index do |len, i|