django-moxy/moxy/base.py

132 lines
5.0 KiB
Python

#!/usr/bin/env python
'''
MySQL database backend for Django using MySQLdb and Eventlet
'''
import eventlet.db_pool
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseOperations, util
try:
import MySQLdb
except ImportError, e:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
import re
from django.db.backends import *
from django.db.backends.mysql import base as mysqldb_base
from django.db.backends.mysql.client import DatabaseClient
from django.db.backends.mysql.creation import DatabaseCreation
from django.db.backends.mysql.introspection import DatabaseIntrospection
from django.db.backends.mysql.validation import DatabaseValidation
from django.db.backends.signals import connection_created
from django.utils.safestring import SafeString, SafeUnicode
# Raise exceptions for database warnings if DEBUG is on
from django.conf import settings
DatabaseError = MySQLdb.DatabaseError
IntegrityError = MySQLdb.IntegrityError
# This should match the numerical portion of the version numbers (we can treat
# versions like 5.0.24 and 5.0.24a as the same). Based on the list of version
# at http://dev.mysql.com/doc/refman/4.1/en/news.html and
# http://dev.mysql.com/doc/refman/5.0/en/news.html .
server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
# MySQLdb-1.2.1 and newer automatically makes use of SHOW WARNINGS on
# MySQL-4.1 and newer, so the MysqlDebugWrapper is unnecessary. Since the
# point is to raise Warnings as exceptions, this can be done with the Python
# warning module, and this is setup when the connection is created, and the
# standard util.CursorDebugWrapper can be used. Also, using sql_mode
# TRADITIONAL will automatically cause most warnings to be treated as errors.
class DatabaseFeatures(mysqldb_base.DatabaseFeatures):
pass
class DatabaseWrapper(BaseDatabaseWrapper):
operators = {
'exact': '= %s',
'iexact': 'LIKE %s',
'contains': 'LIKE BINARY %s',
'icontains': 'LIKE %s',
'regex': 'REGEXP BINARY %s',
'iregex': 'REGEXP %s',
'gt': '> %s',
'gte': '>= %s',
'lt': '< %s',
'lte': '<= %s',
'startswith': 'LIKE BINARY %s',
'endswith': 'LIKE BINARY %s',
'istartswith': 'LIKE %s',
'iendswith': 'LIKE %s',
}
def __init__(self, *args, **kwargs):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
self.server_version = None
self.features = DatabaseFeatures()
self.ops = mysqldb_base.DatabaseOperations()
self.client = DatabaseClient(self)
self.creation = DatabaseCreation(self)
self.introspection = DatabaseIntrospection(self)
self.validation = DatabaseValidation()
def _valid_connection(self):
if self.connection is not None:
try:
self.connection.ping()
return True
except DatabaseError:
self.connection.close()
self.connection = None
return False
def _cursor(self):
if not self._valid_connection():
kwargs = {
#'conv': django_conversions,
'charset': 'utf8',
'use_unicode': True,
}
settings_dict = self.settings_dict
if settings_dict['DATABASE_USER']:
kwargs['user'] = settings_dict['DATABASE_USER']
if settings_dict['DATABASE_NAME']:
kwargs['db'] = settings_dict['DATABASE_NAME']
if settings_dict['DATABASE_PASSWORD']:
kwargs['passwd'] = settings_dict['DATABASE_PASSWORD']
if settings_dict['DATABASE_HOST'].startswith('/'):
kwargs['unix_socket'] = settings_dict['DATABASE_HOST']
elif settings_dict['DATABASE_HOST']:
kwargs['host'] = settings_dict['DATABASE_HOST']
if settings_dict['DATABASE_PORT']:
kwargs['port'] = int(settings_dict['DATABASE_PORT'])
kwargs.update(settings_dict['DATABASE_OPTIONS'])
self.connection = eventlet.db_pool.ConnectionPool.connect(MySQLdb, 15, **kwargs)
connection_created.send(sender=self.__class__)
cursor = mysqldb_base.CursorWrapper(self.connection.cursor())
return cursor
def _rollback(self):
try:
BaseDatabaseWrapper._rollback(self)
except Database.NotSupportedError:
pass
def get_server_version(self):
if not self.server_version:
if not self._valid_connection():
self.cursor()
self.server_version = self.connection._obj.get_server_info()
#m = server_version_re.match(self.connection.get_server_version())
#if not m:
# raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_version())
#self.server_version = tuple([int(x) for x in m.groups()])
return self.server_version