U
    e4^                  
   @   s4  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 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 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( ddl)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/m0Z0 W n4 e1k
rD Z2 zede2 e2W 5 dZ2[2X Y nX zddl3m4Z4 W n e1k
rp   dZ5Y nX dZ5ddl6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z? ddl@mAZA ddlBmCZC ejDjEZEejDjFZFejDjGZGejDjHZHejDjIZIee0dd d!ZJG d"d# d#ZKG d$d% d%eZLG d&d' d'e"ZMd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)	AnyDict	GeneratorIteratorListOptionalSetTupleUnion)settings)ImproperlyConfigured)IntegrityError)BaseDatabaseWrapper)	dateparsetimezone)cached_property)MySQLConnection)CMySQLConnection)MySQLConverter)MySQLCursor)CMySQLCursor)
HexLiteral)PooledMySQLConnection)ParamsDictTypeParamsSequenceOrDictTypeParamsSequenceTypeRowType
StrOrBytesz&Error loading mysql.connector module: )datetime_to_mysqlFT   )DatabaseClient)DatabaseCreation)DatabaseFeatures)DatabaseIntrospection)DatabaseOperations)DatabaseSchemaEditor)DatabaseValidation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 r5   \/var/www/html/assets/scripts/venv/lib/python3.8/site-packages/mysql/connector/django/base.py$adapt_datetime_with_timezone_supportb   s    

r7   c                   @   s   e Zd ZdZdZeeef ddddZe	e
e
ddd	Ze	ee ee dd
dZdeee eeeeef ddf  dddZeeeedf ee f eeeeef ddf  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  N)cursorr+   c                 C   s
   || _ d S N)r9   selfr9   r5   r5   r6   __init__   s    zCursorWrapper.__init__)argsr+   c                 C   s<   | s| S t | }|  D ]\}}t|trt|||< q|S r:   )dictitems
isinstancer   r7   )r>   new_argskeyr*   r5   r5   r6   _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 r:   )list	enumeraterA   r   r7   tuple)r>   rB   iargr5   r5   r6   _adapt_execute_args   s    
z!CursorWrapper._adapt_execute_args)queryr>   r+   c              
   C   s   d}t |tr| |}n
| |}z| j||W S  tjjk
r| } z&|j	d | j
krjtt|j	 d W 5 d}~X Y nX 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   )rA   r?   rD   rJ   r9   executemysql	connectorOperationalErrorr>   codes_for_integrityerrorr   rG   )r<   rK   r>   rB   excr5   r5   r6   rL      s    

zCursorWrapper.execute.c              
   C   s^   z| j ||W S  tjjk
rX } z&|jd | jkrFtt|j d W 5 d}~X Y nX 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)	r9   executemanyrM   rN   rO   r>   rP   r   rG   )r<   rK   r>   rQ   r5   r5   r6   rR      s    zCursorWrapper.executemanyattrr+   c                 C   s   t | j|S )z%Return an attribute of wrapped cursor)getattrr9   r<   rT   r5   r5   r6   __getattr__   s    zCursorWrapper.__getattr__r+   c                 C   s
   t | jS )z&Return an iterator over wrapped cursor)iterr9   r<   r5   r5   r6   __iter__   s    zCursorWrapper.__iter__)N)__name__
__module____qualname____doc__rP   r   r   r   r=   staticmethodr   rD   r	   r   rJ   strr   r   rL   r   r   rR   r   rW   r   r   r[   r5   r5   r5   r6   r8   t   s2   
  
r8   c                       sP  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.< d/d0d1d2hZejZeZeZeZeZeZeZeZe e d-d3 fd4d5Z!ee"d6d7d8Z#e$ee f d9d:d;Z%e$ee f e&e'e(e)f d<d=d>Z*d-d9d?d@Z+dae e,dAdBdCZ-d-d9dDdEZ.e"d-dFdGdHZ/e"d9dIdJZ0d-d9dKdLZ1dbee2e  d-dMdNdOZ3e"d9dPdQZ4e5e6ed9dRdSZ7e5e$eef d9dTdUZ8e5e$ee f d9dVdWZ9e5e d9dXdYZ:e5e;e<dZf d9d[d\Z=e5e>e d9d]d^Z?e@e"d9d_d`ZA  ZBS )cDatabaseWrapperz Represent a database connection.rM   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
mediumblobrc   ZtinytexttextZ
mediumtextrh   rg   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('%%', {}))rn   ro   rs   ru   rt   rv   Nisolation_levelzread uncommittedzread committedzrepeatable readZserializable)r>   kwargsr+   c                    sj   t  j|| | jd}|rV|dt | _|dt}t|tsLt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getr3   	_use_pureDjangoMySQLConverter
issubclassProgrammingError	converter)r<   r>   rx   optionsr{   	__class__r5   r6   r=   <  s    

zDatabaseWrapper.__init__rS   c                 C   s   | drdS td S )NZmysql_isF)rs   AttributeErrorrV   r5   r5   r6   rW   P  s    
zDatabaseWrapper.__getattr__rX   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< zt|d  }|d}|r8| }|| jkr8ddd t| jD }td| d| d|| _|| W n tk
r`   Y nX |S )Nutf8TF)charsetZuse_unicodebufferedZconsume_resultsUSERuserNAMEZdatabaseZPASSWORDpasswdZHOST/Zunix_sockethostZPORTportry   Zinit_commandZraise_on_warningsZclient_flagsrw   z, c                 s   s   | ]}d | d V  qdS )'Nr5   ).0levelr5   r5   r6   	<genexpr>|  s    z8DatabaseWrapper.get_connection_params.<locals>.<genexpr>z%Invalid transaction isolation level 'z' specified.
Use one of z
, or None.)r}   rs   intr~   r   DEBUGrM   rN   	constantsZ
ClientFlagZ
FOUND_ROWScopypoplowerisolation_levelsjoinsortedr   rw   updateKeyError)r<   rx   r}   r   rw   Zvalid_levelsr5   r5   r6   get_connection_paramsU  sP    



z%DatabaseWrapper.get_connection_params)conn_paramsr+   c                 C   s"   d|krt |d< tjjf |}|S )Nr{   )r   rM   rN   connect)r<   r   Zcnxr5   r5   r6   get_new_connection  s    z"DatabaseWrapper.get_new_connectionc              	   C   s   g }| j jr|d | jr2|d| j   |rZ|  }|d| W 5 Q R X d| jkrz| 	| jd  W n$ t
k
r   | | jd  Y nX d S )NzSET SQL_AUTO_IS_NULL = 0z(SET SESSION TRANSACTION ISOLATION LEVEL z; Z
AUTOCOMMIT)featuresZis_sql_auto_is_null_enabledappendrw   upperr9   rL   r   r}   Zset_autocommitr   _set_autocommit)r<   Zassignmentsr9   r5   r5   r6   init_connection_state  s    


z%DatabaseWrapper.init_connection_state)namer+   c                 C   s   | j  }t|S r:   )
connectionr9   r8   )r<   r   r9   r5   r5   r6   create_cursor  s    
zDatabaseWrapper.create_cursorc                 C   s(   zt |  W n tk
r"   Y nX d S r:   )r   	_rollbackNotSupportedErrorrZ   r5   r5   r6   r     s    zDatabaseWrapper._rollback)
autocommitr+   c              	   C   s   | j  || j_W 5 Q R X d S r:   )Zwrap_database_errorsr   r   )r<   r   r5   r5   r6   r     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)r9   rL   r;   r5   r5   r6   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_rollbackr9   rL   )r<   r   r9   r5   r5   r6   enable_constraint_checking  s
    
z*DatabaseWrapper.enable_constraint_checking)table_namesr+   c           
      C   s   |   }|dk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 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.
        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 )r9   introspectionr   Zget_primary_key_columnZget_key_columnsrL   Zfetchallr   )
r<   r   r9   Z
table_nameZprimary_key_column_nameZkey_columnsZcolumn_nameZreferenced_table_nameZreferenced_column_nameZbad_rowr5   r5   r6   check_constraints  sN    
 6z!DatabaseWrapper.check_constraintsc                 C   s.   z| j   W n tk
r$   Y dS X dS d S )NFT)r   ZpingErrorrZ   r5   r5   r6   	is_usable  s
    zDatabaseWrapper.is_usablec                   C   s   dS )zDisplay name.MySQLr5   r5   r5   r5   r6   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)ri   rj   rk   )r   Z!supports_column_check_constraints)r<   r   r5   r5   r6   data_type_check_constraints  s    z+DatabaseWrapper.data_type_check_constraintsc              	   C   s\   |   }|d | }W 5 Q R X |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
            r   r!               )versionsql_modeZdefault_storage_engineZsql_auto_is_nullZlower_case_table_namesZhas_zoneinfo_database)temporary_connectionrL   fetchonerd   )r<   r9   rowr5   r5   r6   mysql_server_data  s    




z!DatabaseWrapper.mysql_server_datac              
   C   s6   |   $}|d | d W  5 Q R  S Q R X dS )Return MySQL version.zSELECT VERSION()r   N)r   rL   r   r;   r5   r5   r6   mysql_server_info6  s    

z!DatabaseWrapper.mysql_server_info.c              	   C   s.   |   }tjjf |}| }W 5 Q R X |S )r   )r   rM   rN   r   Zget_server_version)r<   configconnZserver_versionr5   r5   r6   mysql_version=  s    zDatabaseWrapper.mysql_versionc              	   C   s@   |   }|d | }W 5 Q R X t|r:|d dndS )zReturn SQL mode.zSELECT @@sql_moder   ,r5   )r9   rL   r   setsplit)r<   r9   r   r5   r5   r6   r   E  s    

zDatabaseWrapper.sql_modec                 C   s
   | j }|S )z1Return True if pure Python version is being used.)r   )r<   Zansr5   r5   r6   rz   M  s    zDatabaseWrapper.use_pure)N)N)Cr\   r]   r^   r_   vendor
data_typesZ_limited_data_types	operatorsZpattern_escZpattern_opsrw   r	   ra   __annotations__r   rM   rN   ZDatabaser'   ZSchemaEditorClassr"   Zclient_classr#   Zcreation_classr$   Zfeatures_classr%   Zintrospection_classr&   Z	ops_classr(   Zvalidation_classr   r=   rd   rW   r   r   r   r   r   r   r   r   r8   r   r   r   r   r   r   r   r   r   r`   r   r   r   r   r   r   r   r
   r   propertyrz   __classcell__r5   r5   r   r6   rb      s   
$	6
	
0rb   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   r5   r5   r6   _time_to_pythonY  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   r5   r5   r6   r   a  s    z(DjangoMySQLConverter._datetime_to_pythonr)   c                 C   s
   |  |S r:   Z_str_to_mysqlr<   r*   r5   r5   r6   _safestring_to_mysqlv  s    z)DjangoMySQLConverter._safestring_to_mysqlc                 C   s
   |  |S r:   r   r   r5   r5   r6   _safetext_to_mysqly  s    z'DjangoMySQLConverter._safetext_to_mysqlc                 C   s
   |  |S r:   )Z_bytes_to_mysqlr   r5   r5   r6   _safebytes_to_mysql|  s    z(DjangoMySQLConverter._safebytes_to_mysql)N)N)r\   r]   r^   r_   r`   bytesr   r	   r   r   r   r   ra   r   r   r   r   r   r5   r5   r5   r6   r   T  s   r   )Nr_   r-   r   r   typingr   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.connectorrM   Zmysql.connector.connectionr   Zmysql.connector.connection_cextr   Zmysql.connector.conversionr   Zmysql.connector.cursorr   Zmysql.connector.cursor_cextr   Zmysql.connector.custom_typesr   Zmysql.connector.poolingr   Zmysql.connector.typesr   r   r   r   r   ImportErrorerrZ_mysql_connectorr    r3   clientr"   Zcreationr#   r   r$   r   r%   
operationsr&   Zschemar'   Z
validationr(   rN   r   ZDatabaseErrorr   rO   r   r7   r8   rb   r   r5   r5   r5   r6   <module>   sZ   , "
[   