a
    lJh_                  
   @   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rd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   M/var/www/shaz/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 )CursorWrapperzWrapper 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 )zExecutes 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 )zExecutes 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                       sJ  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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-d0 fd1d2Z!ee"d3d4d5Z#e$ee f d6d7d8Z%e$ee f e&e'd9f d:d;d<Z(d-d6d=d>Z)d_e e*d?d@dAZ+d-d6dBdCZ,e"d-dDdEdFZ-e"d6dGdHZ.d-d6dIdJZ/d`ee0e  d-dKdLdMZ1e"d6dNdOZ2e3e4ed6dPdQZ5e3e$eef d6dRdSZ6e3e$ee f d6dTdUZ7e3e d6dVdWZ8e3e9e:dXf d6dYdZZ;e3e<e d6d[d\Z=e>e"d6d]d^Z?  Z@S )a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 BINARY %szREGEXP BINARY %sz	REGEXP %sz> %sz>= %sz< %sz<= %s)exactZiexactcontains	icontainsregexZiregex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('%%', {}))rm   rn   rr   rt   rs   ru   Nisolation_level>   zread uncommittedzread committedzrepeatable readZserializable)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=   rw   optionsrz   	__class__r4   r5   r<   K  s    

zDatabaseWrapper.__init__rR   c                 C   s   | drdS td S )NZmysql_isF)rr   AttributeErrorrU   r4   r4   r5   rV   _  s    
zDatabaseWrapper.__getattr__rW   c                 C   sf  ddddd}| j }|d r(|d |d< |d r<|d |d< |d	 rP|d	 |d
< |d drl|d |d< n|d r|d |d< |d rt|d |d< |di dr|d d |d< tj|d< tjjj	j
g|d< zv|d  }|dd }|r:| }|| jvr:ddd t| jD }td| d| d|| _|| W n ty`   Y n0 |S )Nutf8TF)charsetZuse_unicodebufferedZconsume_resultsUSERuserNAMEZdatabaseZPASSWORDpasswdZHOST/Zunix_sockethostZPORTportrx   Zinit_commandZraise_on_warningsZclient_flagsrv   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|   rr   intr}   r   DEBUGrL   rM   	constantsZ
ClientFlagZ
FOUND_ROWScopypoplowerisolation_levelsjoinsortedr   rv   updateKeyError)r;   rw   r|   r   rv   Zvalid_levelsr4   r4   r5   get_connection_paramsd  sT    


z%DatabaseWrapper.get_connection_paramsr&   )conn_paramsr*   c                 C   s&   d|vrt |d< tjjf i |}|S )Nrz   )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 rz| 	| 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appendrv   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qqLq"W d   n1 s0    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.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   sB   |   &}|d | d W  d   S 1 s40    Y  dS )Return MySQL version.zSELECT VERSION()r   N)r   rK   r   r:   r4   r4   r5   mysql_server_infoF  s    

z!DatabaseWrapper.mysql_server_info.c                 C   sD   |   }tjjf i |}|j}W d   n1 s60    Y  |S )r   N)r   rL   rM   r   server_version)r;   configconnr   r4   r4   r5   mysql_versionM  s    $zDatabaseWrapper.mysql_versionc                 C   sT   |   "}|d | }W d   n1 s00    Y  t|rN|d dndS )zReturn SQL mode.zSELECT @@sql_modeNr   ,r4   )r8   rK   r   setsplit)r;   r8   r   r4   r4   r5   r   U  s    

&zDatabaseWrapper.sql_modec                 C   s
   | j }|S )z1Return True if pure Python version is being used.)r~   )r;   Zansr4   r4   r5   ry   ]  s    zDatabaseWrapper.use_pure)N)N)Ar[   r\   r]   r^   vendor
data_typesZ_limited_data_types	operatorsZpattern_escZpattern_opsrv   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   propertyry   __classcell__r4   r4   r   r5   ra      s   
$	6

	
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_pythoni  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   q  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   d  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&
`   	