1
1
# Python implementation of the MySQL client-server protocol
2
2
# http://dev.mysql.com/doc/internals/en/client-server-protocol.html
3
+ # Error codes:
4
+ # http://dev.mysql.com/doc/refman/5.5/en/error-messages-client.html
3
5
4
6
from __future__ import print_function
5
7
from ._compat import PY2 , range_type , text_type , str_type , JYTHON , IRONPYTHON
8
+ DEBUG = False
6
9
7
10
import errno
8
11
from functools import partial
9
- import os
10
12
import hashlib
13
+ import io
14
+ import os
11
15
import socket
16
+ import struct
17
+ import sys
12
18
13
19
try :
14
20
import ssl
15
21
SSL_ENABLED = True
16
22
except ImportError :
23
+ ssl = None
17
24
SSL_ENABLED = False
18
25
19
- import struct
20
- import sys
21
26
if PY2 :
22
27
import ConfigParser as configparser
23
28
else :
24
29
import configparser
25
30
26
- import io
27
-
28
31
try :
29
32
import getpass
30
33
DEFAULT_USER = getpass .getuser ()
34
+ del getpass
31
35
except ImportError :
32
36
DEFAULT_USER = None
33
37
34
38
35
39
from .charset import MBLENGTH , charset_by_name , charset_by_id
36
40
from .cursors import Cursor
37
- from .constants import FIELD_TYPE
38
- from .constants import SERVER_STATUS
39
- from .constants .CLIENT import *
40
- from .constants .COMMAND import *
41
+ from .constants import CLIENT , COMMAND , FIELD_TYPE , SERVER_STATUS
41
42
from .util import byte2int , int2byte
42
43
from .converters import escape_item , encoders , decoders , escape_string
43
44
from .err import (
@@ -96,8 +97,6 @@ def _makefile(sock, mode):
96
97
97
98
sha_new = partial (hashlib .new , 'sha1' )
98
99
99
- DEBUG = False
100
-
101
100
NULL_COLUMN = 251
102
101
UNSIGNED_CHAR_COLUMN = 251
103
102
UNSIGNED_SHORT_COLUMN = 252
@@ -114,9 +113,8 @@ def _makefile(sock, mode):
114
113
115
114
116
115
def dump_packet (data ):
117
-
118
116
def is_ascii (data ):
119
- if 65 <= byte2int (data ) <= 122 : #data.isalnum():
117
+ if 65 <= byte2int (data ) <= 122 :
120
118
if isinstance (data , int ):
121
119
return chr (data )
122
120
return data
@@ -134,9 +132,9 @@ def is_ascii(data):
134
132
pass
135
133
dump_data = [data [i :i + 16 ] for i in range_type (0 , min (len (data ), 256 ), 16 )]
136
134
for d in dump_data :
137
- print (' ' .join (map (lambda x :"{:02X}" .format (byte2int (x )), d )) +
135
+ print (' ' .join (map (lambda x : "{:02X}" .format (byte2int (x )), d )) +
138
136
' ' * (16 - len (d )) + ' ' * 2 +
139
- ' ' .join (map (lambda x :"{}" .format (is_ascii (x )), d )))
137
+ ' ' .join (map (lambda x : "{}" .format (is_ascii (x )), d )))
140
138
print ("-" * 88 )
141
139
print ()
142
140
@@ -487,14 +485,21 @@ def __init__(self, host="localhost", user=None, password="",
487
485
unix_socket: Optionally, you can use a unix socket rather than TCP/IP.
488
486
charset: Charset you want to use.
489
487
sql_mode: Default SQL_MODE to use.
490
- read_default_file: Specifies my.cnf file to read these parameters from under the [client] section.
491
- conv: Decoders dictionary to use instead of the default one. This is used to provide custom marshalling of types. See converters.
492
- use_unicode: Whether or not to default to unicode strings. This option defaults to true for Py3k.
488
+ read_default_file:
489
+ Specifies my.cnf file to read these parameters from under the [client] section.
490
+ conv:
491
+ Decoders dictionary to use instead of the default one.
492
+ This is used to provide custom marshalling of types. See converters.
493
+ use_unicode:
494
+ Whether or not to default to unicode strings.
495
+ This option defaults to true for Py3k.
493
496
client_flag: Custom flags to send to MySQL. Find potential values in constants.CLIENT.
494
497
cursorclass: Custom cursor class to use.
495
498
init_command: Initial SQL statement to run when connection is established.
496
499
connect_timeout: Timeout before throwing an exception when connecting.
497
- ssl: A dict of arguments similar to mysql_ssl_set()'s parameters. For now the capath and cipher arguments are not supported.
500
+ ssl:
501
+ A dict of arguments similar to mysql_ssl_set()'s parameters.
502
+ For now the capath and cipher arguments are not supported.
498
503
read_default_group: Group to read from in the configuration file.
499
504
compress; Not supported
500
505
named_pipe: Not supported
@@ -524,7 +529,7 @@ def __init__(self, host="localhost", user=None, password="",
524
529
if not SSL_ENABLED :
525
530
raise NotImplementedError ("ssl module not found" )
526
531
self .ssl = True
527
- client_flag |= SSL
532
+ client_flag |= CLIENT . SSL
528
533
for k in ('key' , 'cert' , 'ca' ):
529
534
v = None
530
535
if k in ssl :
@@ -577,10 +582,9 @@ def _config(key, default):
577
582
578
583
self .encoding = charset_by_name (self .charset ).encoding
579
584
580
- client_flag |= CAPABILITIES
581
- client_flag |= MULTI_STATEMENTS
585
+ client_flag |= CLIENT .CAPABILITIES | CLIENT .MULTI_STATEMENTS
582
586
if self .db :
583
- client_flag |= CONNECT_WITH_DB
587
+ client_flag |= CLIENT . CONNECT_WITH_DB
584
588
self .client_flag = client_flag
585
589
586
590
self .cursorclass = cursorclass
@@ -603,7 +607,7 @@ def close(self):
603
607
''' Send the quit message and close the socket '''
604
608
if self .socket is None :
605
609
raise Error ("Already closed" )
606
- send_data = struct .pack ('<i' , 1 ) + int2byte (COM_QUIT )
610
+ send_data = struct .pack ('<i' , 1 ) + int2byte (COMMAND . COM_QUIT )
607
611
try :
608
612
self ._write_bytes (send_data )
609
613
except Exception :
@@ -647,28 +651,28 @@ def _read_ok_packet(self):
647
651
648
652
def _send_autocommit_mode (self ):
649
653
''' Set whether or not to commit after every execute() '''
650
- self ._execute_command (COM_QUERY , "SET AUTOCOMMIT = %s" %
654
+ self ._execute_command (COMMAND . COM_QUERY , "SET AUTOCOMMIT = %s" %
651
655
self .escape (self .autocommit_mode ))
652
656
self ._read_ok_packet ()
653
657
654
658
def begin (self ):
655
659
"""Begin transaction."""
656
- self ._execute_command (COM_QUERY , "BEGIN" )
660
+ self ._execute_command (COMMAND . COM_QUERY , "BEGIN" )
657
661
self ._read_ok_packet ()
658
662
659
663
def commit (self ):
660
664
''' Commit changes to stable storage '''
661
- self ._execute_command (COM_QUERY , "COMMIT" )
665
+ self ._execute_command (COMMAND . COM_QUERY , "COMMIT" )
662
666
self ._read_ok_packet ()
663
667
664
668
def rollback (self ):
665
669
''' Roll back the current transaction '''
666
- self ._execute_command (COM_QUERY , "ROLLBACK" )
670
+ self ._execute_command (COMMAND . COM_QUERY , "ROLLBACK" )
667
671
self ._read_ok_packet ()
668
672
669
673
def select_db (self , db ):
670
674
'''Set current db'''
671
- self ._execute_command (COM_INIT_DB , db )
675
+ self ._execute_command (COMMAND . COM_INIT_DB , db )
672
676
self ._read_ok_packet ()
673
677
674
678
def escape (self , obj ):
@@ -710,7 +714,7 @@ def query(self, sql, unbuffered=False):
710
714
# print("DEBUG: sending query:", sql)
711
715
if isinstance (sql , text_type ) and not (JYTHON or IRONPYTHON ):
712
716
sql = sql .encode (self .encoding )
713
- self ._execute_command (COM_QUERY , sql )
717
+ self ._execute_command (COMMAND . COM_QUERY , sql )
714
718
self ._affected_rows = self ._read_query_result (unbuffered = unbuffered )
715
719
return self ._affected_rows
716
720
@@ -723,7 +727,7 @@ def affected_rows(self):
723
727
724
728
def kill (self , thread_id ):
725
729
arg = struct .pack ('<I' , thread_id )
726
- self ._execute_command (COM_PROCESS_KILL , arg )
730
+ self ._execute_command (COMMAND . COM_PROCESS_KILL , arg )
727
731
return self ._read_ok_packet ()
728
732
729
733
def ping (self , reconnect = True ):
@@ -735,7 +739,7 @@ def ping(self, reconnect=True):
735
739
else :
736
740
raise Error ("Already closed" )
737
741
try :
738
- self ._execute_command (COM_PING , "" )
742
+ self ._execute_command (COMMAND . COM_PING , "" )
739
743
return self ._read_ok_packet ()
740
744
except Exception :
741
745
if reconnect :
@@ -748,7 +752,7 @@ def set_charset(self, charset):
748
752
# Make sure charset is supported.
749
753
encoding = charset_by_name (charset ).encoding
750
754
751
- self ._execute_command (COM_QUERY , "SET NAMES %s" % self .escape (charset ))
755
+ self ._execute_command (COMMAND . COM_QUERY , "SET NAMES %s" % self .escape (charset ))
752
756
self ._read_packet ()
753
757
self .charset = charset
754
758
self .encoding = encoding
@@ -766,7 +770,7 @@ def _connect(self):
766
770
while True :
767
771
try :
768
772
sock = socket .create_connection (
769
- (self .host , self .port ), self .connect_timeout )
773
+ (self .host , self .port ), self .connect_timeout )
770
774
break
771
775
except (OSError , IOError ) as e :
772
776
if e .errno == errno .EINTR :
@@ -804,7 +808,6 @@ def _connect(self):
804
808
raise OperationalError (
805
809
2003 , "Can't connect to MySQL server on %r (%s)" % (self .host , e ))
806
810
807
-
808
811
def _read_packet (self , packet_type = MysqlPacket ):
809
812
"""Read an entire "mysql packet" in its entirety from the network
810
813
and return a MysqlPacket type that represents the results.
@@ -839,10 +842,11 @@ def _read_bytes(self, num_bytes):
839
842
if e .errno == errno .EINTR :
840
843
continue
841
844
raise OperationalError (
842
- 2013 , "Lost connection to MySQL server during query (%r)" % (e ,))
845
+ 2013 ,
846
+ "Lost connection to MySQL server during query (%s)" % (e ,))
843
847
if len (data ) < num_bytes :
844
- raise OperationalError (2013 ,
845
- "Lost connection to MySQL server during query" )
848
+ raise OperationalError (
849
+ 2013 , "Lost connection to MySQL server during query" )
846
850
return data
847
851
848
852
def _write_bytes (self , data ):
@@ -909,9 +913,9 @@ def _execute_command(self, command, sql):
909
913
seq_id += 1
910
914
911
915
def _request_authentication (self ):
912
- self .client_flag |= CAPABILITIES
916
+ self .client_flag |= CLIENT . CAPABILITIES
913
917
if self .server_version .startswith ('5' ):
914
- self .client_flag |= MULTI_RESULTS
918
+ self .client_flag |= CLIENT . MULTI_RESULTS
915
919
916
920
if self .user is None :
917
921
raise ValueError ("Did not specify a username" )
@@ -920,8 +924,8 @@ def _request_authentication(self):
920
924
if isinstance (self .user , text_type ):
921
925
self .user = self .user .encode (self .encoding )
922
926
923
- data_init = struct .pack ('<i' , self .client_flag ) + struct .pack ("<I" , 1 ) + \
924
- int2byte (charset_id ) + int2byte (0 )* 23
927
+ data_init = ( struct .pack ('<i' , self .client_flag ) + struct .pack ("<I" , 1 ) +
928
+ int2byte (charset_id ) + int2byte (0 )* 23 )
925
929
926
930
next_packet = 1
927
931
@@ -1018,8 +1022,9 @@ def _get_server_information(self):
1018
1022
i += 10
1019
1023
1020
1024
if len (data ) >= i + salt_len :
1021
- self .salt += data [i :i + salt_len ] # salt_len includes auth_plugin_data_part_1 and filler
1022
- #TODO: AUTH PLUGIN NAME may appeare here.
1025
+ # salt_len includes auth_plugin_data_part_1 and filler
1026
+ self .salt += data [i :i + salt_len ]
1027
+ # TODO: AUTH PLUGIN NAME may appeare here.
1023
1028
1024
1029
def get_server_info (self ):
1025
1030
return self .server_version
@@ -1185,3 +1190,5 @@ def _get_descriptions(self):
1185
1190
eof_packet = self .connection ._read_packet ()
1186
1191
assert eof_packet .is_eof_packet (), 'Protocol error, expecting EOF'
1187
1192
self .description = tuple (description )
1193
+
1194
+ # g:khuno_ignore='E226,E301,E701'
0 commit comments