U
    8ÄT_Ž;  ã                
   @   sZ  d 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 zdd	lZW n, ek
r� Z zed
ƒe‚W 5 d	Z[X Y nX d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 �r edej) ƒ‚eej*ej+i–Z,edƒZ-G dd„ dƒZ.G dd„ de	ƒZ/d	S )za
MySQL database backend for Django.

Requires mysqlclient: https://pypi.org/project/mysqlclient/
é    )ÚImproperlyConfigured)ÚIntegrityError)Úutils)ÚBaseDatabaseWrapper)Úasync_unsafe)Úcached_property)Ú_lazy_re_compileNz:Error loading MySQLdb module.
Did you install mysqlclient?)ÚCLIENTÚ
FIELD_TYPE)Úconversionsé   )ÚDatabaseClient)ÚDatabaseCreation)ÚDatabaseFeatures)ÚDatabaseIntrospection)ÚDatabaseOperations)ÚDatabaseSchemaEditor)ÚDatabaseValidation)r   é   r   z4mysqlclient 1.4.0 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().
    )i  iš  ië  i¹  c                 C   s
   || _ d S ©N)Úcursor©Úselfr   © r   úA/tmp/pip-unpacked-wheel-dv63caxw/django/db/backends/mysql/base.pyÚ__init__C   s    zCursorWrapper.__init__Nc              
   C   sZ   z| j  ||¡W S  tjk
rT } z$|jd | jkrBtt|jƒŽ ‚‚ W 5 d }~X Y nX d S ©Nr   )r   ÚexecuteÚDatabaseÚOperationalErrorÚargsÚcodes_for_integrityerrorr   Útuple©r   Úqueryr!   Úer   r   r   r   F   s    zCursorWrapper.executec              
   C   sZ   z| j  ||¡W S  tjk
rT } z$|jd | jkrBtt|jƒŽ ‚‚ W 5 d }~X Y nX d S r   )r   Úexecutemanyr   r    r!   r"   r   r#   r$   r   r   r   r'   Q   s    zCursorWrapper.executemanyc                 C   s   t | j|ƒS r   )Úgetattrr   )r   Úattrr   r   r   Ú__getattr__[   s    zCursorWrapper.__getattr__c                 C   s
   t | jƒS r   )Úiterr   ©r   r   r   r   Ú__iter__^   s    zCursorWrapper.__iter__)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r"   r   r   r'   r*   r-   r   r   r   r   r   4   s   

r   c                   @   sV  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œZdZdddddddd ddddd!œZd"Zd#d$d%d&d'd(d)œZd*d+d,d-hZ	e
Z
eZeZeZeZeZeZeZd.d/„ Zed0d1„ ƒZd2d3„ ZedOd5d6„ƒZd7d8„ Zd9d:„ Zd;d<„ Z d=d>„ Z!dPd?d@„Z"dAdB„ Z#e$dCdD„ ƒZ%e$dEdF„ ƒZ&e$dGdH„ ƒZ'e$dIdJ„ ƒZ(e$dKdL„ ƒZ)e$dMdN„ ƒZ*d4S )QÚDatabaseWrapperZmysqlzinteger AUTO_INCREMENTzbigint AUTO_INCREMENTÚlongblobÚboolzvarchar(%(max_length)s)Údatezdatetime(6)z+numeric(%(max_digits)s, %(decimal_places)s)Zbigintzdouble precisionÚintegerzchar(15)zchar(39)Újsonzbigint UNSIGNEDzinteger UNSIGNEDzsmallint UNSIGNEDzsmallint AUTO_INCREMENTZsmallintÚlongtextztime(6)zchar(32))Z	AutoFieldZBigAutoFieldZBinaryFieldZBooleanFieldZ	CharFieldZ	DateFieldZDateTimeFieldZDecimalFieldZDurationFieldZ	FileFieldZFilePathFieldZ
FloatFieldZIntegerFieldZBigIntegerFieldZIPAddressFieldZGenericIPAddressFieldÚ	JSONFieldZNullBooleanFieldZOneToOneFieldÚPositiveBigIntegerFieldÚPositiveIntegerFieldÚPositiveSmallIntegerFieldZ	SlugFieldZSmallAutoFieldZSmallIntegerFieldZ	TextFieldZ	TimeFieldZ	UUIDField)	ZtinyblobZblobZ
mediumblobr3   ZtinytextÚtextZ
mediumtextr8   r7   z= %szLIKE %szLIKE BINARY %sz> %sz>= %sz< %sz<= %s)ÚexactZiexactÚcontainsÚ	icontainsÚgtZgteÚltZlteÚ
startswithÚendswithÚistartswithÚ	iendswithzCREPLACE(REPLACE(REPLACE({}, '\\', '\\\\'), '%%', '\%%'), '_', '\_')z"LIKE BINARY CONCAT('%%', {}, '%%')zLIKE CONCAT('%%', {}, '%%')zLIKE BINARY CONCAT({}, '%%')zLIKE CONCAT({}, '%%')zLIKE BINARY CONCAT('%%', {})zLIKE CONCAT('%%', {}))r?   r@   rC   rE   rD   rF   zread uncommittedúread committedzrepeatable readZserializablec                 C   s  t ddœ}| j}|d r$|d |d< |d r8|d |d< |d rL|d |d< |d	  d
¡rh|d	 |d< n|d	 r||d	 |d< |d r”t|d ƒ|d< tj|d< |d  ¡ }| dd¡}|rò| ¡ }|| j	kròt
d|d dd„ t| j	ƒD ƒ¡f ƒ‚|| _| |¡ |S )NÚutf8)ÚconvÚcharsetÚUSERÚuserÚNAMEÚdbZPASSWORDÚpasswdZHOSTú/Zunix_socketÚhostZPORTÚportZclient_flagÚOPTIONSÚisolation_levelrG   zKInvalid 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_dictrC   Úintr	   Z
FOUND_ROWSÚcopyÚpopÚlowerÚisolation_levelsr   ÚjoinÚsortedrT   Úupdate)r   ÚkwargsrY   ÚoptionsrT   r   r   r   Úget_connection_paramsÃ   s@    þ

þÿÿ
z%DatabaseWrapper.get_connection_paramsc                 C   s   t jf |ŽS r   )r   Úconnect)r   Zconn_paramsr   r   r   Úget_new_connectionè   s    z"DatabaseWrapper.get_new_connectionc              	   C   s\   g }| j jr| d¡ | jr0| d| j ¡  ¡ |rX|  ¡ �}| d |¡¡ W 5 Q R X d 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  ¡ }t|ƒS r   )Ú
connectionr   r   )r   Únamer   r   r   r   Úcreate_cursorü   s    
zDatabaseWrapper.create_cursorc                 C   s*   zt  | ¡ W n tjk
r$   Y nX d S r   )r   Ú	_rollbackr   ZNotSupportedErrorr,   r   r   r   rn     s    zDatabaseWrapper._rollbackc              	   C   s"   | j � | j |¡ W 5 Q R X d S r   )Zwrap_database_errorsrk   Ú
autocommit)r   ro   r   r   r   Ú_set_autocommit  s    zDatabaseWrapper._set_autocommitc              	   C   s"   |   ¡ �}| d¡ W 5 Q R X 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"|  ¡ �}| d¡ W 5 Q R X W 5 || _ X d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   r   Úenable_constraint_checking  s
    
z*DatabaseWrapper.enable_constraint_checkingc           
      C   s¶   |   ¡ �¤}|dkr| j |¡}|D ]„}| j ||¡}|s:q"| j ||¡}|D ]X\}}}| d||||||||f ¡ | ¡ D ]&}	td||	d |||	d ||f ƒ‚q|qLq"W 5 Q R X d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
                        z–The 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   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"  sF    
     ýûÿ     þýÿz!DatabaseWrapper.check_constraintsc                 C   s0   z| j  ¡  W n tjk
r&   Y dS X dS d S )NFT)rk   Zpingr   ÚErrorr,   r   r   r   Ú	is_usableJ  s
    zDatabaseWrapper.is_usablec                 C   s   | j r
dS dS )NZMariaDBZMySQL)Úmysql_is_mariadbr,   r   r   r   Údisplay_nameR  s    zDatabaseWrapper.display_namec                 C   s4   | j jr0ddddœ}| jr,| jdk r,d|d< |S i S )Nz`%(column)s` >= 0)r:   r;   r<   )é
   r   é   zJSON_VALID(`%(column)s`)r9   )rg   Z!supports_column_check_constraintsry   Úmysql_version)r   rv   r   r   r   Údata_type_check_constraintsV  s    ýz+DatabaseWrapper.data_type_check_constraintsc              
   C   s6   |   ¡ �$}| d¡ | ¡ d W  5 Q R £ S Q R X d S )NzSELECT VERSION()r   )Ztemporary_connectionr   Úfetchoner   r   r   r   Úmysql_server_infoe  s    

z!DatabaseWrapper.mysql_server_infoc                 C   s4   t  | j¡}|std| j ƒ‚tdd„ | ¡ D ƒƒS )Nz8Unable to determine MySQL version from version string %rc                 s   s   | ]}t |ƒV  qd S r   )rZ   )rU   Úxr   r   r   rW   p  s     z0DatabaseWrapper.mysql_version.<locals>.<genexpr>)Úserver_version_reÚmatchr€   Ú	Exceptionr#   Úgroups)r   rƒ   r   r   r   r}   k  s    zDatabaseWrapper.mysql_versionc                 C   s   d| j  ¡ kS )NZmariadb)r€   r]   r,   r   r   r   ry   r  s    z DatabaseWrapper.mysql_is_mariadbc              	   C   s@   |   ¡ �}| d¡ | ¡ }W 5 Q R X t|r:|d  d¡ndƒS )NzSELECT @@sql_moder   ú,r   )r   r   r   ÚsetÚsplit)r   r   Úsql_moder   r   r   r‰   v  s    

zDatabaseWrapper.sql_mode)N)N)+r.   r/   r0   Ú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   r   r2   b   s²   ä$ôú
ü%


(




r2   )0r1   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backendsr   Zbackend_utilsZdjango.db.backends.base.baser   Zdjango.utils.asyncior   Zdjango.utils.functionalr   Zdjango.utils.regex_helperr   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   r‚   r   r2   r   r   r   r   Ú<module>   sB   ÿý

þ.