a
    ’éiž_  ã                
   @   s&  d Z ddlZddlmZmZ ddlmZmZmZmZm	Z	m
Z
mZmZmZ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mZ dd
lmZ ddlmZ zDddlZ ddl!m"Z" ddl#m$Z$ ddl%m&Z& ddlm'Z'm(Z(m)Z) W n6 e*�y" Z+ zede+› �ƒe+‚W Y dZ+[+n
dZ+[+0 0 zddl,m-Z- W n e*�yL   dZ.Y n0 dZ.ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z: ddl;m<Z< e j=j>Z>e j=j?Z?e j=j@Z@e j=jAZAe j=jBZBe�räddlCmDZDmEZE ee)dœdd„ZFG d d!„ d!ƒZGG d"d#„ d#eƒZHG d$d%„ d%e"ƒZIdS )&a¥  Django database Backend using MySQL Connector/Python.

This Django database backend is heavily based on the MySQL backend from Django.

Changes include:
* Support for microseconds (MySQL 5.6.3 and later)
* Using INFORMATION_SCHEMA where possible
* Using new defaults for, for example SQL_AUTO_IS_NULL

Requires and comes with MySQL Connector/Python v8.0.22 and later:
    http://dev.mysql.com/downloads/connector/python/
é    N)ÚdatetimeÚtime)ÚTYPE_CHECKINGÚAnyÚDictÚ	GeneratorÚIteratorÚListÚOptionalÚSequenceÚSetÚTupleÚUnion)Úsettings)ÚImproperlyConfigured)ÚIntegrityError)ÚBaseDatabaseWrapper)Ú	dateparseÚtimezone)Úcached_property)ÚMySQLConvertibleType)ÚMySQLConverter)Ú
HexLiteral)ÚPooledMySQLConnection)ÚParamsSequenceOrDictTypeÚRowTypeÚ
StrOrBytesz&Error loading mysql.connector module: )Údatetime_to_mysqlFTé   )ÚDatabaseClient)ÚDatabaseCreation)ÚDatabaseFeatures)ÚDatabaseIntrospection)ÚDatabaseOperations)ÚDatabaseSchemaEditor)ÚDatabaseValidation)ÚMySQLConnectionAbstractÚMySQLCursorAbstract©ÚvalueÚreturnc                 C   sf   t jrLt | ¡r8t d| › d�t¡ t ¡ }t | |¡} |  	tj
¡jdd�} tr\t| ƒ}|S |  d¡S )zDEquivalent to DateTimeField.get_db_prep_value. Used only by raw SQL.z!MySQL received a naive datetime (z$) while time zone support is active.N)Útzinfoz%Y-%m-%d %H:%M:%S.%f)r   ZUSE_TZr   Zis_naiveÚwarningsÚwarnÚRuntimeWarningZget_default_timezoneZ
make_awareÚ
astimezoneÚutcÚreplaceÚ	HAVE_CEXTr   Ústrftime)r)   Zdefault_timezoneZmysql_datetime© r4   úK/home/Claro/venv/lib/python3.9/site-packages/mysql/connector/django/base.pyÚ$adapt_datetime_with_timezone_supporti   s    

ýÿr6   c                   @   sô   e Zd ZdZdZdddœdd„Zeeee	f eee	f dœd	d
„ƒZ
eeee	  eee	  dœdd„ƒZdeeeee	 eee	f f  eed  dœdd„Zeeeee	 eee	f f  eed  dœdd„Zeedœdd„Zee dœdd„ZdS )ÚCursorWrapperzãWrapper around MySQL Connector/Python's cursor class.

    The cursor class is defined by the options passed to MySQL
    Connector/Python. If buffered option is True in those options,
    MySQLCursorBuffered will be used.
    )i  iš  ië  i¹  r'   N)Úcursorr*   c                 C   s
   || _ d S ©N)r8   ©Úselfr8   r4   r4   r5   Ú__init__�   s    zCursorWrapper.__init__)Úargsr*   c                 C   s<   | s| S t | ƒ}|  ¡ D ]\}}t|tƒrt|ƒ||< q|S r9   )ÚdictÚitemsÚ
isinstancer   r6   )r=   Únew_argsÚkeyr)   r4   r4   r5   Ú_adapt_execute_args_dict�   s    
z&CursorWrapper._adapt_execute_args_dictc                 C   s@   | s| S t | ƒ}t| ƒD ]\}}t|tƒrt|ƒ||< qt|ƒS r9   )ÚlistÚ	enumerater@   r   r6   Útuple)r=   rA   ÚiÚargr4   r4   r5   Ú_adapt_execute_args�   s    
z!CursorWrapper._adapt_execute_args)r'   NN)Úqueryr=   r*   c              
   C   s„   d}t |tƒr|  |¡}n
|  |¡}z| j ||¡W S  tjjy~ } z.|j	d | j
v rhtt|j	ƒŽ d‚‚ W Y d}~n
d}~0 0 dS )z­Executes the given operation

        This wrapper method around the execute()-method of the cursor is
        mainly needed to re-raise using different exceptions.
        Nr   )r@   r>   rC   rI   r8   ÚexecuteÚmysqlÚ	connectorÚOperationalErrorr=   Úcodes_for_integrityerrorr   rF   )r;   rJ   r=   rA   Úexcr4   r4   r5   rK   ª   s    

zCursorWrapper.executec              
   C   s`   z| j  ||¡W S  tjjyZ } z.|jd | jv rDtt|jƒŽ d‚‚ W Y d}~n
d}~0 0 dS )z±Executes the given operation

        This wrapper method around the executemany()-method of the cursor is
        mainly needed to re-raise using different exceptions.
        r   N)	r8   ÚexecutemanyrL   rM   rN   r=   rO   r   rF   )r;   rJ   r=   rP   r4   r4   r5   rQ   Â   s    zCursorWrapper.executemany©Úattrr*   c                 C   s   t | j|ƒS )z%Return an attribute of wrapped cursor)Úgetattrr8   ©r;   rS   r4   r4   r5   Ú__getattr__Õ   s    zCursorWrapper.__getattr__©r*   c                 C   s
   t | jƒS )z&Return an iterator over wrapped cursor)Úiterr8   ©r;   r4   r4   r5   Ú__iter__Ù   s    zCursorWrapper.__iter__)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rO   r<   Ústaticmethodr   Ústrr   rC   r
   r   rI   r   r   rK   rQ   r   rV   r   r   rZ   r4   r4   r4   r5   r7   ~   s6   

þ

þ ûÿ
úÿ
úr7   c                       sF  e Zd ZU 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+Z
ee ed,< h d-£ZejZeZeZeZeZeZeZeZe e d+d.œ‡ fd/d0„Z!ee"d1œd2d3„Z#e$ee f d4œd5d6„Z%e$ee f e&e'd7f d8œd9d:„Z(d+d4œd;d<„Z)d]e e*d=œd>d?„Z+d+d4œd@dA„Z,e"d+dBœdCdD„Z-e"d4œdEdF„Z.d+d4œdGdH„Z/d^ee0e  d+dIœdJdK„Z1e"d4œdLdM„Z2e3e4ed4œdNdO„ƒƒZ5e3e$eef d4œdPdQ„ƒZ6e3e$ee f d4œdRdS„ƒZ7e3e d4œdTdU„ƒZ8e3e9e:dVf d4œdWdX„ƒZ;e3e<e d4œdYdZ„ƒZ=e>e"d4œd[d\„ƒZ?‡  Z@S )_ÚDatabaseWrapperz Represent a database connection.rL   z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GenericIPAddressFieldZ	JSONFieldZNullBooleanFieldZOneToOneFieldÚPositiveBigIntegerFieldÚPositiveIntegerFieldÚPositiveSmallIntegerFieldZ	SlugFieldZSmallAutoFieldZSmallIntegerFieldZ	TextFieldZ	TimeFieldZ	UUIDField)	ZtinyblobZblobZ
mediumblobrb   ZtinytextÚtextZ
mediumtextrg   rf   z= %szLIKE %szLIKE CAST(%s AS BINARY)z> %sz>= %sz< %sz<= %s)ÚexactZiexactÚcontainsÚ	icontainsÚgtZgteÚltZlteÚ
startswithÚendswithÚistartswithÚ	iendswithzCREPLACE(REPLACE(REPLACE({}, '\\', '\\\\'), '%%', '\%%'), '_', '\_')z+LIKE CAST(CONCAT('%%', {}, '%%') AS BINARY)zLIKE CONCAT('%%', {}, '%%')z%LIKE CAST(CONCAT({}, '%%') AS BINARY)zLIKE CONCAT({}, '%%')z%LIKE CAST(CONCAT('%%', {}) AS BINARY)zLIKE CONCAT('%%', {}))rm   rn   rq   rs   rr   rt   NÚisolation_level>   zread uncommittedzread committedZserializablezrepeatable read)r=   Úkwargsr*   c                    sn   t ƒ j|i |¤Ž | j d¡}|rZ| dt ¡| _| dt¡}t|tƒsPtdƒ‚|ƒ | _	ntƒ | _	t | _d S )NÚOPTIONSÚuse_pureÚconverter_classzXConverter class should be a subclass of mysql.connector.django.base.DjangoMySQLConverter)
Úsuperr<   Úsettings_dictÚgetr2   Ú	_use_pureÚDjangoMySQLConverterÚ
issubclassÚProgrammingErrorÚ	converter)r;   r=   rv   Úoptionsry   ©Ú	__class__r4   r5   r<   I  s    þ
ÿ
zDatabaseWrapper.__init__rR   c                 C   s   |  d¡rdS t‚d S )NZmysql_isF)rq   ÚAttributeErrorrU   r4   r4   r5   rV   ]  s    
zDatabaseWrapper.__getattr__rW   c                 C   s`  ddi}| j }|d r"|d |d< |d r6|d |d< |d rJ|d |d< |d	  d
¡rf|d	 |d< n|d	 rz|d	 |d< |d r’t|d ƒ|d< | di ¡ d¡r´|d d |d< tj|d< tjjj	j
g|d< zv|d  ¡ }| dd ¡}|�r4| ¡ }|| jv�r4d dd„ t| jƒD ƒ¡}td|› d|› d�ƒ‚|| _| |¡ W n t�yZ   Y n0 |S )NZconsume_resultsTÚUSERÚuserÚNAMEZdatabaseZPASSWORDÚpasswdZHOSTú/Zunix_socketÚhostZPORTÚportrw   Zinit_commandZraise_on_warningsZclient_flagsru   z, c                 s   s   | ]}d |› d �V  qdS )ú'Nr4   )Ú.0Úlevelr4   r4   r5   Ú	<genexpr>†  s   z8DatabaseWrapper.get_connection_params.<locals>.<genexpr>z%Invalid transaction isolation level 'z' specified.
Use one of z
, or None.)r{   rq   Úintr|   r   ÚDEBUGrL   rM   Ú	constantsZ
ClientFlagZ
FOUND_ROWSÚcopyÚpopÚlowerÚisolation_levelsÚjoinÚsortedr   ru   ÚupdateÚKeyError)r;   rv   r{   r‚   ru   Zvalid_levelsr4   r4   r5   Úget_connection_paramsb  sN    ÿ

þ
ÿÿÿz%DatabaseWrapper.get_connection_paramsr&   )Úconn_paramsr*   c                 C   s&   d|vrt |d< tjjf i |¤Ž}|S )Nry   )r~   rL   rM   Úconnect)r;   r�   Zcnxr4   r4   r5   Úget_new_connection”  s    z"DatabaseWrapper.get_new_connectionc                 C   s´   g }| j jr| d¡ | jr2| d| j ¡ › �¡ |rn|  ¡ � }| d |¡¡ W d   ƒ n1 sd0    Y  d| jv r°z|  	| jd ¡ W n" t
y®   |  | jd ¡ Y n0 d S )NzSET SQL_AUTO_IS_NULL = 0z(SET SESSION TRANSACTION ISOLATION LEVEL z; Z
AUTOCOMMIT)ÚfeaturesZis_sql_auto_is_null_enabledÚappendru   Úupperr8   rK   r˜   r{   Zset_autocommitr…   Ú_set_autocommit)r;   Zassignmentsr8   r4   r4   r5   Úinit_connection_state�  s"    
ÿÿ
.
z%DatabaseWrapper.init_connection_state)Únamer*   c                 C   s   | j  ¡ }t|ƒS r9   )Ú
connectionr8   r7   )r;   r¥   r8   r4   r4   r5   Úcreate_cursor¶  s    
zDatabaseWrapper.create_cursorc                 C   s&   zt  | ¡ W n ty    Y n0 d S r9   )r   Ú	_rollbackÚNotSupportedErrorrY   r4   r4   r5   r¨   º  s    zDatabaseWrapper._rollback)Ú
autocommitr*   c                 C   s2   | j � || j_W d   ƒ n1 s$0    Y  d S r9   )Zwrap_database_errorsr¦   rª   )r;   rª   r4   r4   r5   r£   À  s    zDatabaseWrapper._set_autocommitc                 C   s6   |   ¡ �}| d¡ W d  ƒ n1 s(0    Y  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)r8   rK   r:   r4   r4   r5   Údisable_constraint_checkingÄ  s    
(z+DatabaseWrapper.disable_constraint_checkingc                 C   sX   d| j  | _ }z<|  ¡ �}| d¡ W d  ƒ n1 s80    Y  W || _ n|| _ 0 dS )zM
        Re-enable foreign key checks after they have been disabled.
        FzSET foreign_key_checks=1N)Úneeds_rollbackr8   rK   )r;   r¬   r8   r4   r4   r5   Úenable_constraint_checkingÎ  s
    
*z*DatabaseWrapper.enable_constraint_checking)Útable_namesr*   c           
      C   s  |   ¡ �æ}|du r| j |¡}|D ]¼}| j ||¡}|s:q"| j ||¡}|D ]�\}}}| d|› d|› d|› d|› d|› d|› d|› d	|› d
�¡ | ¡ D ]@}	td|› d|	d › d|› d|› d|	d › d|› d|› d�ƒ‚qšqLq"W d  ƒ n1 sô0    Y  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.
        Nz+
                        SELECT REFERRING.`z&`,
                        REFERRING.`z `
                        FROM `z2` as REFERRING
                        LEFT JOIN `zR` as REFERRED
                        ON (
                            REFERRING.`z*` =
                            REFERRED.`zE`
                        )
                        WHERE REFERRING.`z4` IS NOT NULL
                        AND REFERRED.`z"` IS NULL
                        zThe row in table 'z' with primary key 'r   z' has an invalid foreign key: Ú.z contains a value 'r   z.' that does not have a corresponding value in )r8   Úintrospectionr®   Zget_primary_key_columnZget_key_columnsrK   Zfetchallr   )
r;   r®   r8   Z
table_nameZprimary_key_column_nameZkey_columnsZcolumn_nameZreferenced_table_nameZreferenced_column_nameZbad_rowr4   r4   r5   Úcheck_constraintsÛ  sh    
ÿÿüÿþýüþùþùÿÿþþýûúÿz!DatabaseWrapper.check_constraintsc                 C   s(   z| j  ¡  W n ty"   Y dS 0 dS )NFT)r¦   ZpingÚErrorrY   r4   r4   r5   Ú	is_usable  s
    zDatabaseWrapper.is_usablec                   C   s   dS )zDisplay name.ZMySQLr4   r4   r4   r4   r5   Údisplay_name  s    zDatabaseWrapper.display_namec                 C   s   | j jrddddœ}|S i S )z<Mapping of Field objects to their SQL for CHECK constraints.z`%(column)s` >= 0)rh   ri   rj   )r    Z!supports_column_check_constraints)r;   r±   r4   r4   r5   Údata_type_check_constraints  s    ýz+DatabaseWrapper.data_type_check_constraintsc                 C   sp   |   ¡ �"}| d¡ | ¡ }W d  ƒ n1 s00    Y  |d |d |d t|d ƒt|d ƒt|d ƒd	œS )
zReturn MySQL server data.a2  
                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
            Nr   r   é   é   é   é   )ÚversionÚsql_modeZdefault_storage_engineZsql_auto_is_nullZlower_case_table_namesZhas_zoneinfo_database)Útemporary_connectionrK   Úfetchonerc   )r;   r8   Úrowr4   r4   r5   Úmysql_server_data&  s    
ÿ
&


úz!DatabaseWrapper.mysql_server_datac                 C   sP   | j r| j jS |  ¡ �&}| d¡ | ¡ d W  d  ƒ S 1 sB0    Y  dS )úReturn MySQL version.zSELECT VERSION()r   N)r¦   Zserver_infor¼   rK   r½   r:   r4   r4   r5   Úmysql_server_infoA  s
    

z!DatabaseWrapper.mysql_server_info.c                 C   sR   | j r| j jS |  ¡ }tjjf i |¤Ž�}|j}W d  ƒ n1 sD0    Y  |S )rÀ   N)r¦   Úserver_versionrœ   rL   rM   rž   )r;   ÚconfigÚconnrÂ   r4   r4   r5   Úmysql_versionJ  s    $zDatabaseWrapper.mysql_versionc                 C   sl   | j rt| j j d¡ƒS |  ¡ �"}| d¡ | ¡ }W d  ƒ n1 sH0    Y  t|rf|d  d¡ndƒS )zReturn SQL mode.ú,zSELECT @@sql_modeNr   r4   )r¦   Úsetr»   Úsplitr8   rK   r½   )r;   r8   r»   r4   r4   r5   r»   T  s    

&zDatabaseWrapper.sql_modec                 C   s
   | j }|S )z1Return True if pure Python version is being used.)r}   )r;   Zansr4   r4   r5   rx   ^  s    zDatabaseWrapper.use_pure)N)N)Ar[   r\   r]   r^   ÚvendorÚ
data_typesZ_limited_data_typesÚ	operatorsZpattern_escZpattern_opsru   r
   r`   Ú__annotations__r—   rL   rM   ZDatabaser$   ZSchemaEditorClassr   Zclient_classr    Zcreation_classr!   Zfeatures_classr"   Zintrospection_classr#   Z	ops_classr%   Zvalidation_classr   r<   rc   rV   r   rœ   r   r   rŸ   r¤   r7   r§   r¨   r£   r«   r­   r	   r±   r³   r   r_   r´   rµ   r¿   rÁ   r   r‘   rÅ   r   r»   Úpropertyrx   Ú__classcell__r4   r4   rƒ   r5   ra   Þ   s¸   
ä$ôú	3

þ	
2		ra   c                   @   sˆ   e Zd ZdZedeeee dœdd„ƒZ	edeeee
 dœdd„ƒZeeeef dœd	d
„Zeeeef dœdd„Zeedœdd„ZdS )r~   zCustom converter for Django.N)r)   Údscr*   c                 C   s   t  |  d¡¡S )zXReturn MySQL TIME data type as datetime.time()

        Returns datetime.time()
        zutf-8)r   Z
parse_timeÚdecode©r)   rÏ   r4   r4   r5   Ú_time_to_pythonj  s    z$DjangoMySQLConverter._time_to_pythonc                 C   s   | rt  | ¡S dS )ao  Connector/Python always returns naive datetime.datetime

        Connector/Python always returns naive timestamps since MySQL has
        no time zone support.

        - A naive datetime is a datetime that doesn't know its own timezone.

        Django needs a non-naive datetime, but in this method we don't need
        to make a datetime value time zone aware since Django itself at some
        point will make it aware (at least in versions 3.2.16 and 4.1.2) when
        USE_TZ=True. This may change in a future release, we need to keep an
        eye on this behaviour.

        Returns datetime.datetime()
        N)r   Ú_datetime_to_pythonrÑ   r4   r4   r5   rÓ   r  s    z(DjangoMySQLConverter._datetime_to_pythonr(   c                 C   s
   |   |¡S r9   ©Z_str_to_mysql©r;   r)   r4   r4   r5   Ú_safestring_to_mysql‡  s    z)DjangoMySQLConverter._safestring_to_mysqlc                 C   s
   |   |¡S r9   rÔ   rÕ   r4   r4   r5   Ú_safetext_to_mysqlŠ  s    z'DjangoMySQLConverter._safetext_to_mysqlc                 C   s
   |   |¡S r9   )Z_bytes_to_mysqlrÕ   r4   r4   r5   Ú_safebytes_to_mysql�  s    z(DjangoMySQLConverter._safebytes_to_mysql)N)N)r[   r\   r]   r^   r_   Úbytesr   r
   r   rÒ   r   rÓ   r`   r   r   rÖ   r×   rØ   r4   r4   r4   r5   r~   e  s   r~   )Jr^   r,   r   r   Útypingr   r   r   r   r   r	   r
   r   r   r   r   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backends.base.baser   Zdjango.utilsr   r   Zdjango.utils.functionalr   Zmysql.connector.typesr   Zmysql.connectorrL   Zmysql.connector.conversionr   Zmysql.connector.custom_typesr   Zmysql.connector.poolingr   r   r   r   ÚImportErrorÚerrZ_mysql_connectorr   r2   Úclientr   Zcreationr    r    r!   r°   r"   Ú
operationsr#   Zschemar$   Z
validationr%   rM   r²   ZDatabaseErrorr©   rN   r€   Zmysql.connector.abstractsr&   r'   r6   r7   ra   r~   r4   r4   r4   r5   Ú<module>   sX   4&
`   
