
v^a8                 @   s  d  Z  d d l Z d d l m Z d d l m Z d d l m Z d d l m	 Z	 d d l
 m Z d d l m Z y d d l Z Wn4 e k
 r Z z e d  e  WYd d Z [ Xn Xd d	 l m Z m Z d d
 l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m  Z  d d l! m" Z" d d l# m$ Z$ e j% Z& e& d k  rwe d e j'   e e j( e j) i  Z* e j+ d  Z, Gd d   d  Z- Gd d   d e	  Z. d S)za
MySQL database backend for Django.

Requires mysqlclient: https://pypi.org/project/mysqlclient/
    N)ImproperlyConfigured)utils)BaseDatabaseWrapper)async_unsafe)cached_propertyz:Error loading MySQLdb module.
Did you install mysqlclient?)CLIENT
FIELD_TYPE)conversions   )DatabaseClient)DatabaseCreation)DatabaseFeatures)DatabaseIntrospection)DatabaseOperations)DatabaseSchemaEditor)DatabaseValidation      z5mysqlclient 1.3.13 or newer is required; you have %s.z(\d{1,2})\.(\d{1,2})\.(\d{1,2})c               @   s[   e  Z d  Z d Z d Z d d   Z d d	 d
  Z d d   Z d d   Z d d   Z	 d S)CursorWrappera6  
    A thin wrapper around MySQLdb's normal cursor class that catches particular
    exception instances and reraises them with the correct types.

    Implemented as a wrapper, rather than a subclass, so that it isn't stuck
    to the particular underlying representation returned by Connection.cursor().
            c             C   s   | |  _  d  S)N)cursor)selfr    r   ?/tmp/pip-build-8lau8j11/django/django/db/backends/mysql/base.py__init__D   s    zCursorWrapper.__init__Nc             C   sw   y |  j  j | |  SWnY t j k
 rr } z6 | j d |  j k r] t j t | j       WYd  d  } ~ Xn Xd  S)Nr   )	r   executeDatabaseOperationalErrorargscodes_for_integrityerrorr   IntegrityErrortuple)r   queryr!   er   r   r   r   G   s    zCursorWrapper.executec             C   sw   y |  j  j | |  SWnY t j k
 rr } z6 | j d |  j k r] t j t | j       WYd  d  } ~ Xn Xd  S)Nr   )	r   executemanyr   r    r!   r"   r   r#   r$   )r   r%   r!   r&   r   r   r   r'   R   s    zCursorWrapper.executemanyc             C   s   t  |  j |  S)N)getattrr   )r   attrr   r   r   __getattr__\   s    zCursorWrapper.__getattr__c             C   s   t  |  j  S)N)iterr   )r   r   r   r   __iter___   s    zCursorWrapper.__iter__)r   r   r   r   )
__name__
__module____qualname____doc__r"   r   r   r'   r*   r,   r   r   r   r   r   5   s      
r   c            4   @   sb  e  Z d  Z d Z d d d d d d d d	 d
 d d d d d d d d d d d d d d d d d d d d d d d d d	 d  d d! d" d# d$ d% d d& d' d( d) d* d+ d, d- d. d/ i Z dt Z d7 d8 d9 d: d; d< d= d: d> d? d@ dA dB dC dD dE dF d< dG d< dH d: dI d: i Z dJ Z d; dK d= dL dF dM dH dN dG dO dI dP i Z dQ dR dS dT h Z	 e
 Z
 e Z e Z e Z e Z e Z e Z e Z dU dV   Z e dW dX    Z dY dZ   Z e d[ d\ d]   Z d^ d_   Z d` da   Z db dc   Z  dd de   Z! d[ df dg  Z" dh di   Z# e$ dj dk    Z% e$ dl dm    Z& e$ dn do    Z' e$ dp dq    Z( e$ dr ds    Z) d[ S)uDatabaseWrapperZmysqlZ	AutoFieldzinteger AUTO_INCREMENTZBigAutoFieldzbigint AUTO_INCREMENTZBinaryFieldlongblobZBooleanFieldboolZ	CharFieldzvarchar(%(max_length)s)Z	DateFielddateZDateTimeFieldzdatetime(6)ZDecimalFieldz+numeric(%(max_digits)s, %(decimal_places)s)ZDurationFieldZbigintZ	FileFieldZFilePathFieldZ
FloatFieldzdouble precisionZIntegerFieldintegerZBigIntegerFieldZIPAddressFieldzchar(15)ZGenericIPAddressFieldzchar(39)ZNullBooleanFieldZOneToOneFieldPositiveIntegerFieldzinteger UNSIGNEDPositiveSmallIntegerFieldzsmallint UNSIGNEDZ	SlugFieldZSmallAutoFieldzsmallint AUTO_INCREMENTZSmallIntegerFieldZsmallintZ	TextFieldlongtextZ	TimeFieldztime(6)Z	UUIDFieldzchar(32)tinyblobblob
mediumblobtinytexttext
mediumtextjsonexactz= %sZiexactzLIKE %scontainszLIKE BINARY %sZ	icontainsgtz> %sgtez>= %sltz< %sltez<= %s
startswithendswithZistartswithZ	iendswithzCREPLACE(REPLACE(REPLACE({}, '\\', '\\\\'), '%%', '\%%'), '_', '\_')z"LIKE BINARY CONCAT('%%', {}, '%%')zLIKE CONCAT('%%', {}, '%%')zLIKE BINARY CONCAT({}, '%%')zLIKE CONCAT({}, '%%')zLIKE BINARY CONCAT('%%', {})zLIKE CONCAT('%%', {})zread uncommittedzread committedzrepeatable readZserializablec             C   s\  d t  d d i } |  j } | d r3 | d | d <| d rK | d | d <| d rc | d | d	 <| d
 j d  r | d
 | d <n | d
 r | d
 | d <| d r t | d  | d <t j | d <| d j   } | j d d  } | rB| j   } | |  j	 k rBt
 d | d j d d   t |  j	  D  f   | |  _ | j |  | S)Nconvcharsetutf8USERuserNAMEdbZPASSWORDpasswdZHOST/Zunix_sockethostZPORTportZclient_flagOPTIONSisolation_levelzread committedzKInvalid transaction isolation level '%s' specified.
Use one of %s, or None.z, c             s   s   |  ] } d  | Vq d S)z'%s'Nr   ).0sr   r   r   	<genexpr>   s    z8DatabaseWrapper.get_connection_params.<locals>.<genexpr>)django_conversionssettings_dictrF   intr   Z
FOUND_ROWScopypoplowerisolation_levelsr   joinsortedrT   update)r   kwargsrY   optionsrT   r   r   r   get_connection_params   s8    	




,	z%DatabaseWrapper.get_connection_paramsc             C   s   t  j |   S)N)r   connect)r   Zconn_paramsr   r   r   get_new_connection   s    z"DatabaseWrapper.get_new_connectionc          
   C   sx   g  } |  j  j r | j d  |  j rB | j d |  j j    | rt |  j    } | j d j |   Wd  QRXd  S)NzSET SQL_AUTO_IS_NULL = 0z*SET SESSION TRANSACTION ISOLATION LEVEL %sz; )featuresZis_sql_auto_is_null_enabledappendrT   upperr   r   r_   )r   Zassignmentsr   r   r   r   init_connection_state   s    	z%DatabaseWrapper.init_connection_stateNc             C   s   |  j  j   } t |  S)N)
connectionr   r   )r   namer   r   r   r   create_cursor   s    zDatabaseWrapper.create_cursorc             C   s-   y t  j |   Wn t j k
 r( Yn Xd  S)N)r   	_rollbackr   ZNotSupportedError)r   r   r   r   rn      s    zDatabaseWrapper._rollbackc          	   C   s%   |  j   |  j j |  Wd  QRXd  S)N)Zwrap_database_errorsrk   
autocommit)r   ro   r   r   r   _set_autocommit  s    
zDatabaseWrapper._set_autocommitc             C   s   |  j    j d  d S)z
        Disable foreign key checks, primarily for use in adding rows with
        forward references. Always return True to indicate constraint checks
        need to be re-enabled.
        zSET foreign_key_checks=0T)r   r   )r   r   r   r   disable_constraint_checking
  s    z+DatabaseWrapper.disable_constraint_checkingc             C   s;   d |  j  |  _  } z |  j   j d  Wd | |  _  Xd S)zM
        Re-enable foreign key checks after they have been disabled.
        FzSET foreign_key_checks=1N)needs_rollbackr   r   )r   rr   r   r   r   enable_constraint_checking  s    z*DatabaseWrapper.enable_constraint_checkingc       
      C   s  |  j     } | d k r- |  j j |  } x | D] } |  j j | |  } | sX q4 |  j j | |  } x | D] \ } } } | j d | | | | | | | | f  xD | j   D]6 }	 t j d | |	 d | | |	 d | | f   q Wqt Wq4 WWd QRXd S)a]  
        Check each table name in `table_names` for rows with invalid foreign
        key references. This method is intended to be used in conjunction with
        `disable_constraint_checking()` and `enable_constraint_checking()`, to
        determine if rows with invalid references were entered while constraint
        checks were off.
        Na0  
                        SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
                        LEFT JOIN `%s` as REFERRED
                        ON (REFERRING.`%s` = REFERRED.`%s`)
                        WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL
                        zThe row in table '%s' with primary key '%s' has an invalid foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s.r   r
   )	r   introspectiontable_namesZget_primary_key_columnZget_key_columnsr   Zfetchallr   r#   )
r   ru   r   Z
table_nameZprimary_key_column_nameZkey_columnsZcolumn_nameZreferenced_table_nameZreferenced_column_nameZbad_rowr   r   r   check_constraints  s&    		z!DatabaseWrapper.check_constraintsc             C   s5   y |  j  j   Wn t j k
 r, d SYn Xd Sd  S)NFT)rk   Zpingr   Error)r   r   r   r   	is_usableG  s
    	zDatabaseWrapper.is_usablec             C   s   |  j  r d Sd S)NZMariaDBZMySQL)mysql_is_mariadb)r   r   r   r   display_nameO  s    zDatabaseWrapper.display_namec             C   s    |  j  j r d d d d i Si  S)Nr6   z`%(column)s` >= 0r7   )rg   Z!supports_column_check_constraints)r   r   r   r   data_type_check_constraintsS  s    
z+DatabaseWrapper.data_type_check_constraintsc          	   C   s5   |  j    " } | j d  | j   d SWd  QRXd  S)NzSELECT VERSION()r   )Ztemporary_connectionr   Zfetchone)r   r   r   r   r   mysql_server_info\  s    z!DatabaseWrapper.mysql_server_infoc             C   sH   t  j |  j  } | s+ t d |  j   t d d   | j   D  S)Nz8Unable to determine MySQL version from version string %rc             s   s   |  ] } t  |  Vq d  S)N)rZ   )rU   xr   r   r   rW   g  s    z0DatabaseWrapper.mysql_version.<locals>.<genexpr>)server_version_rematchr|   	Exceptionr$   groups)r   r   r   r   r   mysql_versionb  s    zDatabaseWrapper.mysql_versionc             C   s   d |  j  j   k S)NZmariadb)r|   r]   )r   r   r   r   ry   i  s    z DatabaseWrapper.mysql_is_mariadb)	r9   r:   r;   r2   r<   ztextr>   r8   zjson)*r-   r.   r/   vendorZ
data_typesZ_limited_data_types	operatorsZpattern_escZpattern_opsr^   r   r   ZSchemaEditorClassr   Zclient_classr   Zcreation_classr   Zfeatures_classr   Zintrospection_classr   Z	ops_classr   Zvalidation_classrd   r   rf   rj   rm   rn   rp   rq   rs   rv   rx   r   rz   r{   r|   r   ry   r   r   r   r   r1   c   s   	 	%	(	r1   )r
   r   r   )/r0   reZdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backendsZbackend_utilsZdjango.db.backends.base.baser   Zdjango.utils.asyncior   Zdjango.utils.functionalr   ZMySQLdbr   ImportErrorerrZMySQLdb.constantsr   r   ZMySQLdb.convertersr	   clientr   Zcreationr   rg   r   rt   r   
operationsr   Zschemar   Z
validationr   version_infoversion__version__ZTIMEZtypecast_timerX   compiler~   r   r1   r   r   r   r   <module>   s<   	.