a
    còfKM  ã                
   @   sª  d Z ddl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 zddlZddlmZ W n2 eyÂ Z zed e¡ƒ‚W Y dZ[n
dZ[0 0 zddlmZmZ W n eyî   dZY n0 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* ej+j,Z,ej+j-Z-ej+j.Z.ej+j/Z/ej+j0Z0dd„ Z1G dd„ dƒZ2G dd„ deƒZ3G dd„ deƒZ4d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)Úsettings)ÚImproperlyConfigured)ÚIntegrityError)ÚBaseDatabaseWrapper)Úutils)Úcached_property)Ú	dateparseÚtimezone)ÚMySQLConverterz)Error loading mysql.connector module: {0})Údatetime_to_mysqlÚtime_to_mysqlFTé   )ÚDatabaseClient)ÚDatabaseCreation)ÚDatabaseIntrospection)ÚDatabaseValidation)ÚDatabaseFeatures)ÚDatabaseOperations)ÚDatabaseSchemaEditorc                 C   sb   t jrHt | ¡r4t d|  t¡ t ¡ }t | |¡} |  	tj
¡jd d�} trTt| ƒS |  d¡S d S )NzGMySQL received a naive datetime (%s) while time zone support is active.©Útzinfoz%Y-%m-%d %H:%M:%S.%f)r   ÚUSE_TZr
   Úis_naiveÚwarningsÚwarnÚRuntimeWarningZget_default_timezoneZ
make_awareÚ
astimezoneÚutcÚreplaceÚ	HAVE_CEXTr   Ústrftime)ÚvalueZdefault_timezone© r#   úX/home/httpd/docs/test/DocsMgr/lib/python3.9/site-packages/mysql/connector/django/base.pyÚ$adapt_datetime_with_timezone_supportU   s    
ÿþr%   c                   @   sN   e Zd ZdZdZdd„ Zdd„ Zdd„ Zdd
d„Zdd„ Z	dd„ Z
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¹  c                 C   s
   || _ d S ©N)Úcursor©Úselfr(   r#   r#   r$   Ú__init__s   s    zCursorWrapper.__init__c                 C   s<   |s|S t |ƒ}| ¡ D ]\}}t|tƒrt|ƒ||< q|S r'   )ÚdictÚitemsÚ
isinstancer   r%   )r*   ÚargsÚnew_argsÚkeyr"   r#   r#   r$   Ú_adapt_execute_args_dictv   s    
z&CursorWrapper._adapt_execute_args_dictc                 C   s@   |s|S t |ƒ}t|ƒD ]\}}t|tƒrt|ƒ||< qt|ƒS r'   )ÚlistÚ	enumerater.   r   r%   Útuple)r*   r/   r0   ÚiÚargr#   r#   r$   Ú_adapt_execute_args€   s    
z!CursorWrapper._adapt_execute_argsNc              
   C   s~   t |tƒr|  |¡}n
|  |¡}z| j ||¡W S  tjjyx } z,|j	d | j
v rbtt|j	ƒŽ ‚‚ 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.
        r   N)r.   r,   r2   r8   r(   ÚexecuteÚmysqlÚ	connectorÚOperationalErrorr/   Úcodes_for_integrityerrorr   r5   )r*   Úqueryr/   r0   Úer#   r#   r$   r9   Š   s    

zCursorWrapper.executec              
   C   s^   z| j  ||¡W S  tjjyX } z,|jd | jv rBtt|jƒŽ ‚‚ 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)	r(   Úexecutemanyr:   r;   r<   r/   r=   r   r5   )r*   r>   r/   r?   r#   r#   r$   r@   ›   s    zCursorWrapper.executemanyc                 C   s   t | j|ƒS )z"Return attribute of wrapped cursor)Úgetattrr(   ©r*   Úattrr#   r#   r$   Ú__getattr__¨   s    zCursorWrapper.__getattr__c                 C   s
   t | jƒS )z$Returns iterator over wrapped cursor)Úiterr(   ©r*   r#   r#   r$   Ú__iter__¬   s    zCursorWrapper.__iter__)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r=   r+   r2   r8   r9   r@   rD   rG   r#   r#   r#   r$   r&   e   s   


r&   c                       st  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dd#œZd$Zd%d&d'd(d)d*d+œZh d,£Z	e
jZeZeZeZeZeZeZeZ‡ fd-d.„Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ ZdTd8d9„Z d:d;„ Z!d<d=„ Z"d>d?„ Z#d@dA„ Z$dUdBdC„Z%dDdE„ Z&e'dFdG„ ƒZ(e'dHdI„ ƒZ)e'dJdK„ ƒZ*e'dLdM„ ƒZ+e'dNdO„ ƒZ,e'dPdQ„ ƒZ-e.dRdS„ ƒZ/‡  Z0S )VÚDatabaseWrapperr:   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
mediumblobrM   ZtinytextÚtextZ
mediumtextrR   rQ   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('%%', {}))rX   rY   r]   r_   r^   r`   >   zread committedzrepeatable readzread uncommittedZserializablec                    sR   t t| ƒj|i |¤Ž z| jd d | _W n tyD   t | _Y n0 tƒ | _d S )NÚOPTIONSÚuse_pure)	ÚsuperrL   r+   Úsettings_dictÚ	_use_pureÚKeyErrorr    ÚDjangoMySQLConverterÚ	converter)r*   r/   Úkwargs©Ú	__class__r#   r$   r+     s    zDatabaseWrapper.__init__c                 C   s   |  d¡rdS t‚d S )NZmysql_isF)r]   ÚAttributeErrorrB   r#   r#   r$   rD     s    
zDatabaseWrapper.__getattr__c                 C   sÞ   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 r˜t|d ƒ|d< tj|d< tjjjj	g|d< z| 
|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ÚportZraise_on_warningsZclient_flagsra   )rd   r]   Úintr   ÚDEBUGr:   r;   Ú	constantsZ
ClientFlagZ
FOUND_ROWSÚupdaterf   )r*   ri   rd   r#   r#   r$   Úget_connection_params#  s4    ü

þz%DatabaseWrapper.get_connection_paramsc                 C   s&   d|vrt |d< tjjf i |¤Ž}|S )NZconverter_class)rg   r:   r;   Úconnect)r*   Zconn_paramsZcnxr#   r#   r$   Úget_new_connectionI  s    z"DatabaseWrapper.get_new_connectionc                 C   s˜   g }| j jr| d¡ |rR|  ¡ � }| d |¡¡ W d   ƒ n1 sH0    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; Z
AUTOCOMMIT)
ÚfeaturesZis_sql_auto_is_null_enabledÚappendr(   r9   Újoinrd   Zset_autocommitrl   Ú_set_autocommit)r*   Zassignmentsr(   r#   r#   r$   Úinit_connection_stateP  s    

.
z%DatabaseWrapper.init_connection_stateNc                 C   s   | j  ¡ }t|ƒS r'   )Ú
connectionr(   r&   )r*   Únamer(   r#   r#   r$   Úcreate_cursorc  s    
zDatabaseWrapper.create_cursorc                 C   s&   zt  | ¡ W n ty    Y n0 d S r'   )r   Ú	_rollbackÚNotSupportedErrorrF   r#   r#   r$   r†   g  s    zDatabaseWrapper._rollbackc                 C   s2   | j � || j_W d   ƒ n1 s$0    Y  d S r'   )Zwrap_database_errorsrƒ   Ú
autocommit)r*   rˆ   r#   r#   r$   r�   m  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)r(   r9   r)   r#   r#   r$   Údisable_constraint_checkingq  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_rollbackr(   r9   )r*   rŠ   r(   r#   r#   r$   Úenable_constraint_checking{  s
    
*z*DatabaseWrapper.enable_constraint_checkingc           
      C   sÊ   |   ¡ �®}|du r| j |¡}|D ]„}| j ||¡}|s:q"| j ||¡}|D ]X\}}}| d||||||||f ¡ | ¡ D ]&}	td||	d |||	d ||f ƒ‚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.
        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_columnsr9   Zfetchallr   )
r*   r�   r(   Z
table_nameZprimary_key_column_nameZkey_columnsZcolumn_nameZreferenced_table_nameZreferenced_column_nameZbad_rowr#   r#   r$   Úcheck_constraintsˆ  s2    
ýûÿ
þýÿz!DatabaseWrapper.check_constraintsc                 C   s,   z| j  ¡  W n ty"   Y dS 0 dS d S )NFT)rƒ   ZpingÚErrorrF   r#   r#   r$   Ú	is_usable°  s
    zDatabaseWrapper.is_usablec                 C   s   dS )NÚMySQLr#   rF   r#   r#   r$   Údisplay_name¸  s    zDatabaseWrapper.display_namec                 C   s   | j jrddddœ}|S i S )Nz`%(column)s` >= 0)rS   rT   rU   )r~   Z!supports_column_check_constraints)r*   rŽ   r#   r#   r$   Ú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 )	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   é   é   é   é   )ÚversionÚsql_modeZdefault_storage_engineZsql_auto_is_nullZlower_case_table_namesZhas_zoneinfo_database)Útemporary_connectionr9   ÚfetchonerN   )r*   r(   Úrowr#   r#   r$   Úmysql_server_dataÇ  s    

&


úz!DatabaseWrapper.mysql_server_datac                 C   sB   |   ¡ �&}| d¡ | ¡ d W  d   ƒ S 1 s40    Y  d S )NzSELECT VERSION()r   )rš   r9   r›   r)   r#   r#   r$   Úmysql_server_infoß  s    

z!DatabaseWrapper.mysql_server_infoc                 C   sF   |   ¡ }tjjf i |¤Ž�}| ¡ }W d   ƒ n1 s80    Y  |S r'   )r{   r:   r;   r|   Zget_server_version)r*   ÚconfigÚconnZserver_versionr#   r#   r$   Úmysql_versionå  s    &zDatabaseWrapper.mysql_versionc                 C   sT   |   ¡ �"}| d¡ | ¡ }W d   ƒ n1 s00    Y  t|rN|d  d¡ndƒS )NzSELECT @@sql_moder   ú,r#   )r(   r9   r›   ÚsetÚsplit)r*   r(   r™   r#   r#   r$   r™   ì  s    

&zDatabaseWrapper.sql_modec                 C   s   | j S r'   )re   rF   r#   r#   r$   rb   ó  s    zDatabaseWrapper.use_pure)N)N)1rH   rI   rJ   ÚvendorÚ
data_typesZ_limited_data_typesÚ	operatorsZpattern_escZpattern_opsZisolation_levelsr:   r;   ZDatabaser   ZSchemaEditorClassr   Zclient_classr   Zcreation_classr   Zfeatures_classr   Zintrospection_classr   Z	ops_classr   Zvalidation_classr+   rD   r{   r}   r‚   r…   r†   r�   r‰   r‹   rŽ   r�   r   r’   r“   r�   rž   r¡   r™   Úpropertyrb   Ú__classcell__r#   r#   rj   r$   rL   ±   s²   ä$òú	
&


(






rL   c                   @   s<   e Zd ZdZddd„Zddd„Zdd„ Zd	d
„ Zdd„ ZdS )rg   zCustom converter for Django.Nc                 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"   Údscr#   r#   r$   Ú_TIME_to_pythonú  s    z$DjangoMySQLConverter._TIME_to_pythonc                 C   sB   |sdS t  | |¡}|du r dS tjr>t |¡r>|jtjd�}|S )a  Connector/Python always returns naive datetime.datetime

        Connector/Python always returns naive timestamps since MySQL has
        no time zone support. Since Django needs non-naive, we need to add
        the UTC time zone.

        Returns datetime.datetime()
        Nr   )r   Z_DATETIME_to_pythonr   r   r
   r   r   r   )r*   r"   r«   Údtr#   r#   r$   Z__DATETIME_to_python  s    	z)DjangoMySQLConverter.__DATETIME_to_pythonc                 C   s
   |   |¡S r'   ©Z_str_to_mysql©r*   r"   r#   r#   r$   Ú_safestring_to_mysql  s    z)DjangoMySQLConverter._safestring_to_mysqlc                 C   s
   |   |¡S r'   r®   r¯   r#   r#   r$   Ú_safetext_to_mysql  s    z'DjangoMySQLConverter._safetext_to_mysqlc                 C   s
   |   |¡S r'   )Z_bytes_to_mysqlr¯   r#   r#   r$   Ú_safebytes_to_mysql  s    z(DjangoMySQLConverter._safebytes_to_mysql)N)N)	rH   rI   rJ   rK   r¬   Z)_DjangoMySQLConverter__DATETIME_to_pythonr°   r±   r²   r#   r#   r#   r$   rg   ø  s   

rg   )5rK   r   Úsysr   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backends.base.baser   r   Zdjango.utils.functionalr   Zdjango.utilsr	   r
   Zmysql.connectorr:   Zmysql.connector.conversionr   ÚImportErrorÚerrÚformatZ_mysql_connectorr   r   r    Úclientr   Zcreationr   rŒ   r   Z
validationr   r~   r   Ú
operationsr   Zschemar   r;   r�   ZDatabaseErrorr‡   r<   ZProgrammingErrorr%   r&   rL   rg   r#   r#   r#   r$   Ú<module>   sP   ÿ
L  I