B
    CVvgP?  ã            
   @   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 ydd	lZW n, ek
r� Z zed
ƒe‚W d	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-install-o3oxmrkh/Django/django/db/backends/mysql/base.pyÚ__init__C   s    zCursorWrapper.__init__Nc          
   C   sX   y| j  ||¡S  tjk
rR } z$|jd | jkr@tt|jƒŽ ‚‚ W d 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   sX   y| j  ||¡S  tjk
rR } z$|jd | jkr@tt|jƒŽ ‚‚ W d d }~X Y nX d S )Nr   )r   Úexecutemanyr   r   r   r   r   r    )r   r!   r   r"   r   r   r   r#   Q   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__)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r#   r&   r(   r   r   r   r   r   4   s   

r   c               @   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œ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dQd5d6„ƒZd7d8„ Zd9d:„ Zd;d<„ Z d=d>„ Z!dRd?d@„Z"dAdB„ Z#e$dCdD„ ƒZ%e$dEdF„ ƒZ&e$dGdH„ ƒZ'e$dIdJ„ ƒZ(e$dKdL„ ƒZ)e$dMdN„ ƒZ*e$dOdP„ ƒZ+d4S )SÚ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
mediumblobr.   ZtinytextÚtextZ
mediumtextr3   r2   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;   r>   r@   r?   rA   zread uncommittedz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ÚNAMEZdatabaseZPASSWORDÚpasswordZ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_dictr>   Úintr	   Z
FOUND_ROWSÚcopyÚpopÚlowerÚisolation_levelsr   ÚjoinÚsortedrM   Úupdate)r   ÚkwargsrR   ÚoptionsrM   r   r   r   Úget_connection_paramsÃ   s8    

 
z%DatabaseWrapper.get_connection_paramsc             C   s,   t jf |Ž}|j t¡tkr(|j t¡ |S )N)r   ÚconnectÚencodersÚgetÚbytesrU   )r   Zconn_paramsÚ
connectionr   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 d 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ÚappendrM   Úupperr   r   rX   )r   Zassignmentsr   r   r   r   Úinit_connection_stateó   s    

z%DatabaseWrapper.init_connection_stateNc             C   s   | j  ¡ }t|ƒS )N)rb   r   r   )r   Únamer   r   r   r   Úcreate_cursor  s    
zDatabaseWrapper.create_cursorc             C   s*   yt  | ¡ W n tjk
r$   Y nX d S )N)r   Ú	_rollbackr   ZNotSupportedError)r   r   r   r   rj     s    zDatabaseWrapper._rollbackc          	   C   s"   | j � | j |¡ W d Q R X d S )N)Zwrap_database_errorsrb   Ú
autocommit)r   rk   r   r   r   Ú_set_autocommit  s    zDatabaseWrapper._set_autocommitc          	   C   s"   |   ¡ �}| d¡ W d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=0NT)r   r   )r   r   r   r   r   Údisable_constraint_checking  s    
z+DatabaseWrapper.disable_constraint_checkingc          	   C   s>   d| j  | _ }z"|  ¡ �}| d¡ W dQ R X W d|| _ X dS )zM
        Re-enable foreign key checks after they have been disabled.
        FzSET foreign_key_checks=1N)Úneeds_rollbackr   r   )r   rn   r   r   r   r   Úenable_constraint_checking  s
    
z*DatabaseWrapper.enable_constraint_checkingc       
      C   sÂ   |   ¡ �°}|dkr| j |¡}x”|D ]Œ}| j ||¡}|s<q$| j ||¡}xd|D ]\\}}}| d||||||||f ¡ x2| ¡ D ]&}	td||	d |||	d ||f ƒ‚q‚W qPW q$W W d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   rq   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   s.   y| j  ¡  W n tjk
r$   dS X dS d S )NFT)rb   Zpingr   ÚError)r   r   r   r   Ú	is_usableQ  s
    zDatabaseWrapper.is_usablec             C   s   | j r
dS dS )NZMariaDBZMySQL)Úmysql_is_mariadb)r   r   r   r   Údisplay_nameY  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)r5   r6   r7   )é
   r   é   zJSON_VALID(`%(column)s`)r4   )rd   Z!supports_column_check_constraintsru   Úmysql_version)r   rr   r   r   r   Údata_type_check_constraints]  s    z+DatabaseWrapper.data_type_check_constraintsc          	   C   s\   |   ¡ �}| d¡ | ¡ }W d Q R X |d |d |d t|d ƒt|d ƒt|d ƒdœS )	Na2  
                SELECT VERSION(),
                       @@sql_mode,
                       @@default_storage_engine,
                       @@sql_auto_is_null,
                       @@lower_case_table_names,
                       CONVERT_TZ('2001-01-01 01:00:00', 'UTC', 'UTC') IS NOT NULL
            r   r   é   rx   r   é   )ÚversionÚsql_modeZdefault_storage_engineZsql_auto_is_nullZlower_case_table_namesZhas_zoneinfo_database)Ztemporary_connectionr   Zfetchoner/   )r   r   Úrowr   r   r   Úmysql_server_datal  s    


z!DatabaseWrapper.mysql_server_datac             C   s
   | j d S )Nr}   )r€   )r   r   r   r   Úmysql_server_info„  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 )N)rS   )rN   Úxr   r   r   rP   �  s    z0DatabaseWrapper.mysql_version.<locals>.<genexpr>)Úserver_version_reÚmatchr�   Ú	Exceptionr    Úgroups)r   r„   r   r   r   ry   ˆ  s    zDatabaseWrapper.mysql_versionc             C   s   d| j  ¡ kS )NZmariadb)r�   rV   )r   r   r   r   ru   �  s    z DatabaseWrapper.mysql_is_mariadbc             C   s    | j d }t|r| d¡ndƒS )Nr~   ú,r   )r€   ÚsetÚsplit)r   r~   r   r   r   r~   “  s    
zDatabaseWrapper.sql_mode)N)N),r)   r*   r+   ÚvendorZ
data_typesZ_limited_data_typesÚ	operatorsZpattern_escZpattern_opsrW   r   r   ZSchemaEditorClassr   Zclient_classr   Zcreation_classr   Zfeatures_classr   Zintrospection_classr   Z	ops_classr   Zvalidation_classr]   r   rc   rg   ri   rj   rl   rm   ro   rr   rt   r   rv   rz   r€   r�   ry   ru   r~   r   r   r   r   r-   b   sž   	%

(r-   )0r,   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   rd   r   rp   r   Ú
operationsr   Zschemar   Z
validationr   Úversion_infor}   Ú__version__ZTIMEZtypecast_timerQ   rƒ   r   r-   r   r   r   r   Ú<module>   s<   
.