Menu

[947b1a]: / MySQLdb / MySQLdb / connections.py  Maximize  Restore  History

Download this file

490 lines (387 with data), 16.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
"""
MySQLdb Connections
-------------------
This module implements connections for MySQLdb. Presently there is
only one class: Connection. Others are unlikely. However, you might
want to make your own subclasses. In most cases, you will probably
override Connection.default_cursor with a non-standard Cursor class.
"""
<<<<<<< HEAD
__revision__ = "$Revision$"[11:-2]
__author__ = "$Author$"[9:-2]
=======
from MySQLdb import cursors
from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
DatabaseError, OperationalError, IntegrityError, InternalError, \
NotSupportedError, ProgrammingError
import types, _mysql
import re
>>>>>>> MySQLdb-1.2
def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
"""
If cursor is not None, (errorclass, errorvalue) is appended to
cursor.messages; otherwise it is appended to connection.messages. Then
errorclass is raised with errorvalue as the value.
You can override this with your own error handler by assigning it to the
instance.
"""
error = errorclass, errorvalue
if cursor:
cursor.messages.append(error)
else:
connection.messages.append(error)
del cursor
del connection
<<<<<<< HEAD
raise errorclass, errorvalue
=======
raise errorclass(errorvalue)
re_numeric_part = re.compile(r"^(\d+)")
def numeric_part(s):
"""Returns the leading numeric part of a string.
>>> numeric_part("20-alpha")
20
>>> numeric_part("foo")
>>> numeric_part("16b")
16
"""
m = re_numeric_part.match(s)
if m:
return int(m.group(1))
return None
>>>>>>> MySQLdb-1.2
class Connection(object):
"""MySQL Database Connection Object"""
errorhandler = defaulterrorhandler
from MySQLdb.exceptions import Warning, Error, InterfaceError, DataError, \
DatabaseError, OperationalError, IntegrityError, InternalError, \
NotSupportedError, ProgrammingError
def __init__(self, *args, **kwargs):
"""
Create a connection to the database. It is strongly recommended that
you only use keyword parameters. Consult the MySQL C API documentation
for more information.
host
string, host to connect
user
string, user to connect as
passwd
string, password to use
db
string, database to use
port
integer, TCP/IP port to connect to
unix_socket
string, location of unix_socket to use
<<<<<<< HEAD
decoders
list, SQL decoder stack
encoders
list, SQL encoder stack
=======
conv
conversion dictionary, see MySQLdb.converters
>>>>>>> MySQLdb-1.2
connect_timeout
number of seconds to wait before the connection attempt
fails.
compress
if set, compression is enabled
named_pipe
if set, a named pipe is used to connect (Windows only)
init_command
command which is run once the connection is created
read_default_file
file from which default client values are read
read_default_group
configuration group to use from the default file
use_unicode
If True, text-like columns are returned as unicode objects
using the connection's character set. Otherwise, text-like
columns are returned as strings. columns are returned as
normal strings. Unicode objects will always be encoded to
the connection's character set regardless of this setting.
charset
If supplied, the connection character set will be changed
to this character set (MySQL-4.1 and newer). This implies
use_unicode=True.
sql_mode
If supplied, the session SQL mode will be changed to this
setting (MySQL-4.1 and newer). For more details and legal
values, see the MySQL documentation.
client_flag
integer, flags to use or 0
(see MySQL docs or constants/CLIENTS.py)
ssl
dictionary or mapping, contains SSL connection parameters;
see the MySQL documentation for more details
(mysql_ssl_set()). If this is set, and the client does not
support SSL, NotSupportedError will be raised.
local_infile
integer, non-zero enables LOAD LOCAL INFILE; zero disables
There are a number of undocumented, non-standard methods. See the
documentation for the MySQL C API for some hints on what they do.
"""
from MySQLdb.constants import CLIENT, FIELD_TYPE
<<<<<<< HEAD
from MySQLdb.converters import default_decoders, default_encoders, default_row_formatter
from MySQLdb.cursors import Cursor
import _mysql
kwargs2 = kwargs.copy()
self.cursorclass = Cursor
charset = kwargs2.pop('charset', '')
self.encoders = kwargs2.pop('encoders', default_encoders)
self.decoders = kwargs2.pop('decoders', default_decoders)
self.row_formatter = kwargs2.pop('row_formatter', default_row_formatter)
client_flag = kwargs.get('client_flag', 0)
client_version = tuple(
[ int(n) for n in _mysql.get_client_info().split('.')[:2] ])
=======
from MySQLdb.converters import conversions
from weakref import proxy, WeakValueDictionary
import types
kwargs2 = kwargs.copy()
if 'conv' in kwargs:
conv = kwargs['conv']
else:
conv = conversions
conv2 = {}
for k, v in conv.items():
if isinstance(k, int) and isinstance(v, list):
conv2[k] = v[:]
else:
conv2[k] = v
kwargs2['conv'] = conv2
cursorclass = kwargs2.pop('cursorclass', self.default_cursor)
charset = kwargs2.pop('charset', '')
if charset:
use_unicode = True
else:
use_unicode = False
use_unicode = kwargs2.pop('use_unicode', use_unicode)
sql_mode = kwargs2.pop('sql_mode', '')
client_flag = kwargs.get('client_flag', 0)
client_version = tuple([ numeric_part(n) for n in _mysql.get_client_info().split('.')[:2] ])
>>>>>>> MySQLdb-1.2
if client_version >= (4, 1):
client_flag |= CLIENT.MULTI_STATEMENTS
if client_version >= (5, 0):
client_flag |= CLIENT.MULTI_RESULTS
<<<<<<< HEAD
kwargs2['client_flag'] = client_flag
sql_mode = kwargs2.pop('sql_mode', None)
self._db = _mysql.connection(*args, **kwargs2)
self._server_version = tuple(
[ int(n) for n in self._db.get_server_info().split('.')[:2] ])
if charset:
self._db.set_character_set(charset)
=======
kwargs2['client_flag'] = client_flag
super(Connection, self).__init__(*args, **kwargs2)
self.cursorclass = cursorclass
self.encoders = dict([ (k, v) for k, v in conv.items()
if type(k) is not int ])
self._server_version = tuple([ numeric_part(n) for n in self.get_server_info().split('.')[:2] ])
db = proxy(self)
def _get_string_literal():
def string_literal(obj, dummy=None):
return db.string_literal(obj)
return string_literal
def _get_unicode_literal():
def unicode_literal(u, dummy=None):
return db.literal(u.encode(unicode_literal.charset))
return unicode_literal
def _get_string_decoder():
def string_decoder(s):
return s.decode(string_decoder.charset)
return string_decoder
string_literal = _get_string_literal()
self.unicode_literal = unicode_literal = _get_unicode_literal()
self.string_decoder = string_decoder = _get_string_decoder()
if not charset:
charset = self.character_set_name()
self.set_character_set(charset)
>>>>>>> MySQLdb-1.2
if sql_mode:
self.set_sql_mode(sql_mode)
<<<<<<< HEAD
self._transactional = bool(self._db.server_capabilities & CLIENT.TRANSACTIONS)
=======
if use_unicode:
self.converter[FIELD_TYPE.STRING].append((None, string_decoder))
self.converter[FIELD_TYPE.VAR_STRING].append((None, string_decoder))
self.converter[FIELD_TYPE.VARCHAR].append((None, string_decoder))
self.converter[FIELD_TYPE.BLOB].append((None, string_decoder))
self.encoders[types.StringType] = string_literal
self.encoders[types.UnicodeType] = unicode_literal
self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
>>>>>>> MySQLdb-1.2
if self._transactional:
# PEP-249 requires autocommit to be initially off
self.autocommit(False)
self.messages = []
self._active_cursor = None
def autocommit(self, do_autocommit):
self._autocommit = do_autocommit
return self._db.autocommit(do_autocommit)
def ping(self, reconnect=False):
if reconnect and not self._autocommit:
raise ProgrammingError("autocommit must be enabled before enabling auto-reconnect; consider the consequences")
return self._db.ping(reconnect)
def commit(self):
return self._db.commit()
def rollback(self):
return self._db.rollback()
def close(self):
return self._db.close()
def escape_string(self, s):
return self._db.escape_string(s)
def string_literal(self, s):
return self._db.string_literal(s)
def cursor(self, encoders=None, decoders=None, row_formatter=None):
"""
<<<<<<< HEAD
Create a cursor on which queries may be performed. The optional
cursorclass parameter is used to create the Cursor. By default,
self.cursorclass=cursors.Cursor is used.
=======
return (cursorclass or self.cursorclass)(self)
def __enter__(self): return self.cursor()
def __exit__(self, exc, value, tb):
if exc:
self.rollback()
else:
self.commit()
def literal(self, o):
>>>>>>> MySQLdb-1.2
"""
if self._active_cursor:
self._active_cursor._flush()
if not encoders:
encoders = self.encoders[:]
if not decoders:
decoders = self.decoders[:]
if not row_formatter:
row_formatter = self.row_formatter
self._active_cursor = self.cursorclass(self, encoders, decoders, row_formatter)
return self._active_cursor
def __enter__(self):
return self.cursor()
def __exit__(self, exc, value, traceback):
if exc:
self.rollback()
else:
self.commit()
def literal(self, obj):
"""
<<<<<<< HEAD
Given an object obj, returns an SQL literal as a string.
Non-standard.
"""
for encoder in self.encoders:
f = encoder(obj)
if f:
return f(self, obj)
raise self.NotSupportedError("could not encode as SQL", obj)
=======
return self.escape(o, self.encoders)
def begin(self):
"""Explicitly begin a connection. Non-standard.
DEPRECATED: Will be removed in 1.3.
Use an SQL BEGIN statement instead."""
from warnings import warn
warn("begin() is non-standard and will be removed in 1.3",
DeprecationWarning, 2)
self.query("BEGIN")
if not hasattr(_mysql.connection, 'warning_count'):
>>>>>>> MySQLdb-1.2
def character_set_name(self):
return self._db.character_set_name()
def set_character_set(self, charset):
"""Set the connection character set to charset. The character set can
only be changed in MySQL-4.1 and newer. If you try to change the
character set from the current value in an older version,
NotSupportedError will be raised.
Non-standard. It is better to set the character set when creating the
connection using the charset parameter."""
if self.character_set_name() != charset:
try:
self._db.set_character_set(charset)
except AttributeError:
if self._server_version < (4, 1):
raise self.NotSupportedError("server is too old to set charset")
self._db.query('SET NAMES %s' % charset)
self._db.get_result()
def set_sql_mode(self, sql_mode):
"""Set the connection sql_mode. See MySQL documentation for legal
values.
Non-standard. It is better to set this when creating the connection
using the sql_mode parameter."""
if self._server_version < (4, 1):
raise self.NotSupportedError("server is too old to set sql_mode")
self._db.query("SET SESSION sql_mode='%s'" % sql_mode)
self._db.get_result()
def _warning_count(self):
"""Return the number of warnings generated from the last query."""
if hasattr(self._db, "warning_count"):
return self._db.warning_count()
else:
info = self._db.info()
if info:
return int(info.split()[-1])
else:
return 0
<<<<<<< HEAD
=======
def set_character_set(self, charset):
"""Set the connection character set to charset. The character
set can only be changed in MySQL-4.1 and newer. If you try
to change the character set from the current value in an
older version, NotSupportedError will be raised."""
if self.character_set_name() != charset:
try:
super(Connection, self).set_character_set(charset)
except AttributeError:
if self._server_version < (4, 1):
raise NotSupportedError("server is too old to set charset")
self.query('SET NAMES %s' % charset)
self.store_result()
self.string_decoder.charset = charset
self.unicode_literal.charset = charset
def set_sql_mode(self, sql_mode):
"""Set the connection sql_mode. See MySQL documentation for
legal values."""
if self._server_version < (4, 1):
raise NotSupportedError("server is too old to set sql_mode")
self.query("SET SESSION sql_mode='%s'" % sql_mode)
self.store_result()
def show_warnings(self):
"""Return detailed information about warnings as a
sequence of tuples of (Level, Code, Message). This
is only supported in MySQL-4.1 and up. If your server
is an earlier version, an empty sequence is returned."""
if self._server_version < (4,1): return ()
self.query("SHOW WARNINGS")
r = self.store_result()
warnings = r.fetch_row(0)
return warnings
Warning = Warning
Error = Error
InterfaceError = InterfaceError
DatabaseError = DatabaseError
DataError = DataError
OperationalError = OperationalError
IntegrityError = IntegrityError
InternalError = InternalError
ProgrammingError = ProgrammingError
NotSupportedError = NotSupportedError
>>>>>>> MySQLdb-1.2
def _show_warnings(self):
"""Return detailed information about warnings as a sequence of tuples
of (Level, Code, Message). This is only supported in MySQL-4.1 and up.
If your server is an earlier version, an empty sequence is returned.
Non-standard. This is invoked automatically after executing a query,
so you should not usually call it yourself."""
if self._server_version < (4, 1): return ()
self._db.query("SHOW WARNINGS")
return tuple(self._db.get_result())