a
    LcòfG  ã                   @   s¦  d Z ddl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 ddlmZ ddlmZ ddlmZ z,zddlZW n eyÈ   ddlZY n0 W n eyæ   e	dƒ‚Y n0 dd„ Zeƒ dk �re	dej › �ƒ‚deƒ   k�r&dk �r:n ne	dej › �ƒ‚ddl!m"Z"m#Z# e#�rŠddlm$Z$m%Z% ddl&m'Z' ddl!m(Z(m)Z) e$j*d j+Z,nRddl-Zddl.Zej/ 0eej/j1¡ ej2 3¡  dZ4ej/ 5e4fdej/j6¡Z7ej/ 8e7¡ ddl9m:Z: ddl;m<Z< dd l=m>Z> dd!l?m@Z@ dd"lAmBZB dd#lCmDZD d$d%„ ZEG d&d'„ d'eƒZFe#�rŠG d(d)„ d)ƒZGG d*d+„ d+eGejHƒZIG d,d-„ d-eGejJƒZHG d.d/„ d/eƒZnej/jKZHG d0d/„ d/eƒZdS )1zY
PostgreSQL database backend for Django.

Requires psycopg2 >= 2.8.4 or psycopg >= 3.1.8
é    N)Úcontextmanager)Úsettings)ÚImproperlyConfigured)ÚDatabaseError)Úconnections)ÚBaseDatabaseWrapper©ÚCursorDebugWrapper)Úasync_unsafe)Úcached_property)Ú
SafeString)Úget_version_tuplez(Error loading psycopg2 or psycopg modulec                  C   s   t j dd¡d } t| ƒS )Nú é   r   )ÚDatabaseÚ__version__Úsplitr   )Úversion© r   ú_/home/httpd/docs/test/DocsMgr/lib/python3.9/site-packages/django/db/backends/postgresql/base.pyÚpsycopg_version    s    r   )é   é   é   z6psycopg2 version 2.8.4 or newer is required; you have )é   )r   r   r   z5psycopg version 3.1.8 or newer is required; you have r   )ÚIsolationLevelÚis_psycopg3)ÚadaptersÚsql)ÚFormat)Úget_adapters_templateÚregister_tzloaderZtimestamptzi  Ú	INETARRAY)ÚDatabaseClient)ÚDatabaseCreation)ÚDatabaseFeatures)ÚDatabaseIntrospection)ÚDatabaseOperations)ÚDatabaseSchemaEditorc                 C   s   | d d u rdS d|  S )NÚ
max_lengthZvarcharúvarchar(%(max_length)s)r   )Údatar   r   r   Ú_get_varchar_columnS   s    r,   c                       s\  e Zd ZdZdZdddde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dddœZddd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eZeZeZeZeZeZeZd+Zd,d-„ Zd.d/„ Zed0d1„ ƒZd2d3„ Zd4d5„ Z‡ fd6d7„Z edKd9d:„ƒZ!d;d<„ Z"ed=d>„ ƒZ#d?d@„ Z$dLdAdB„Z%dCdD„ Z&e'‡ fdEdF„ƒZ(e)dGdH„ ƒZ*dIdJ„ Z+‡  Z,S )MÚDatabaseWrapperÚ
postgresqlZ
PostgreSQLÚintegerZbigintZbyteaÚbooleanÚdateztimestamp with time zonez+numeric(%(max_digits)s, %(decimal_places)s)Úintervalr*   zdouble precisionZinetZjsonbZsmallintÚtextÚtimeÚuuid)Ú	AutoFieldÚBigAutoFieldZBinaryFieldZBooleanFieldZ	CharFieldZ	DateFieldZDateTimeFieldZDecimalFieldZDurationFieldZ	FileFieldZFilePathFieldZ
FloatFieldZIntegerFieldZBigIntegerFieldZIPAddressFieldZGenericIPAddressFieldZ	JSONFieldZOneToOneFieldÚPositiveBigIntegerFieldÚPositiveIntegerFieldÚPositiveSmallIntegerFieldZ	SlugFieldÚSmallAutoFieldZSmallIntegerFieldZ	TextFieldZ	TimeFieldZ	UUIDFieldz"%(column)s" >= 0)r8   r9   r:   z GENERATED BY DEFAULT AS IDENTITY)r6   r7   r;   z= %sz= UPPER(%s)zLIKE %szLIKE UPPER(%s)z~ %sz~* %sz> %sz>= %sz< %sz<= %s)ÚexactZiexactÚcontainsÚ	icontainsÚregexZiregexÚgtZgteÚltZlteÚ
startswithÚendswithÚistartswithÚ	iendswithzKREPLACE(REPLACE(REPLACE({}, E'\\', E'\\\\'), E'%%', E'\\%%'), E'_', E'\\_')zLIKE '%%' || {} || '%%'zLIKE '%%' || UPPER({}) || '%%'zLIKE {} || '%%'zLIKE UPPER({}) || '%%'zLIKE '%%' || {}zLIKE '%%' || UPPER({}))r=   r>   rB   rD   rC   rE   r   c                 C   s   t | jdƒS )zo
        Return a tuple of the database's version.
        E.g. for pg_version 120004, return (12, 4).
        i'  )ÚdivmodÚ
pg_version©Úselfr   r   r   Úget_database_version·   s    z$DatabaseWrapper.get_database_versionc                 C   s–  | j }|d dkr,| di ¡ d¡s,tdƒ‚t|d p8dƒ| j ¡ krjtd|d t|d ƒ| j ¡ f ƒ‚|d rˆd|d i|d ¥}n>|d d u rº| di ¡ dd ¡ ddi|d ¥}ni |d ¥}d	|d
< | dd ¡ | dd ¡ | dd ¡}| dt�r|du �rt	nt
¡ |d �r(|d |d< |d �r>|d |d< |d �rT|d |d< |d �rj|d |d< t�r’ttj| jƒ|d< | dd ¡|d< |S )NÚNAMEÚ ÚOPTIONSZservicez`settings.DATABASES is improperly configured. Please supply the NAME or OPTIONS['service'] value.z‡The database name '%s' (%d characters) is longer than PostgreSQL's limit of %d characters. Supply a shorter NAME in settings.DATABASES.ZdbnameÚpostgresÚUTF8Zclient_encodingÚassume_roleÚisolation_levelÚserver_side_bindingZcursor_factoryTÚUSERÚuserZPASSWORDÚpasswordZHOSTÚhostZPORTÚportÚcontextZprepare_threshold)Úsettings_dictÚgetr   ÚlenÚopsZmax_name_lengthÚpopÚ
setdefaultr   ÚServerBindingCursorÚCursorr    r   ÚUSE_TZÚtimezone)rI   rY   Úconn_paramsrR   r   r   r   Úget_connection_params¾   sj    ÿÿ
ýýÿ
ÿþÿÿü



ÿÿz%DatabaseWrapper.get_connection_paramsc                 C   s¦   | j d }d}z|d }W n ty4   tj| _Y n80 zt|ƒ| _d}W n" tyj   td|› d�ƒ‚Y n0 | jjf i |¤Ž}|rŠ| j|_t	s¢t
jj|dd„ d	� |S )
NrM   FrQ   Tz$Invalid transaction isolation level z9 specified. Use one of the psycopg.IsolationLevel values.c                 S   s   | S ©Nr   )Úxr   r   r   Ú<lambda>  ó    z4DatabaseWrapper.get_new_connection.<locals>.<lambda>)Zconn_or_cursÚloads)rY   ÚKeyErrorr   ZREAD_COMMITTEDrQ   Ú
ValueErrorr   r   Úconnectr   Úpsycopg2ÚextrasZregister_default_jsonb)rI   rc   ÚoptionsZset_isolation_levelZisolation_level_valueÚ
connectionr   r   r   Úget_new_connectionü   s*    


ÿ
ÿz"DatabaseWrapper.get_new_connectionc                 C   st   | j d u rdS | j j d¡}| j}|rp||krp| j  ¡ �$}| | j ¡ |g¡ W d   ƒ n1 sb0    Y  dS dS )NFZTimeZoneT)rp   ÚinfoZparameter_statusÚtimezone_nameÚcursorÚexecuter\   Zset_time_zone_sql)rI   Zconn_timezone_namers   rt   r   r   r   Úensure_timezone  s    
2zDatabaseWrapper.ensure_timezonec                 C   sr   | j d u rdS | j di ¡ d¡ }rn| j  ¡ �*}| j d|g¡}| |¡ W d   ƒ n1 s`0    Y  dS dS )NFrM   rP   zSET ROLE %sT)rp   rY   rZ   rt   r\   Zcompose_sqlru   )rI   Znew_rolert   r   r   r   r   Úensure_role*  s    
(zDatabaseWrapper.ensure_rolec                    s8   t ƒ  ¡  |  ¡ }|  ¡ }|s"|r4|  ¡ s4| j ¡  d S re   )ÚsuperÚinit_connection_staterv   rw   Zget_autocommitrp   Úcommit)rI   Z	commit_tzZcommit_role©Ú	__class__r   r   ry   4  s
    
z%DatabaseWrapper.init_connection_stateNc                 C   sl   |r| j j|d| j jd�}n
| j  ¡ }trV| j j ttj¡}| j	|j	krht
| j	|ƒ ntjrb| jnd |_|S )NF)Z
scrollableZwithhold)rp   rt   Ú
autocommitr   r   Ú
get_loaderÚTIMESTAMPTZ_OIDr   ZTEXTrb   r!   r   ra   Útzinfo_factory)rI   Únamert   Ztzloaderr   r   r   Úcreate_cursorA  s    
ÿ
zDatabaseWrapper.create_cursorc                 C   s   | j S re   )rb   )rI   Úoffsetr   r   r   r€   V  s    zDatabaseWrapper.tzinfo_factoryc                 C   sf   |  j d7  _ zt ¡ }W n ty0   d }Y n0 |rDtt|ƒƒ}nd}| jdt ¡ j	|| j f d�S )Nr   Úsyncz_django_curs_%d_%s_%d)r�   )
Ú_named_cursor_idxÚasyncioÚcurrent_taskÚRuntimeErrorÚstrÚidZ_cursorÚ	threadingÚcurrent_threadÚident)rI   r‡   Z
task_identr   r   r   Úchunked_cursorY  s     
üÿÿzDatabaseWrapper.chunked_cursorc                 C   s2   | j � || j_W d   ƒ n1 s$0    Y  d S re   )Zwrap_database_errorsrp   r}   )rI   r}   r   r   r   Ú_set_autocommitu  s    zDatabaseWrapper._set_autocommitc                 C   s@   |   ¡ �$}| d¡ | d¡ W d  ƒ n1 s20    Y  dS )zl
        Check constraints by setting them to immediate. Return them to deferred
        afterward.
        zSET CONSTRAINTS ALL IMMEDIATEzSET CONSTRAINTS ALL DEFERREDN)rt   ru   )rI   Ztable_namesrt   r   r   r   Úcheck_constraintsy  s    

z!DatabaseWrapper.check_constraintsc                 C   sX   z8| j  ¡ �}| d¡ W d   ƒ n1 s,0    Y  W n tjyN   Y dS 0 dS d S )NzSELECT 1FT)rp   rt   ru   r   ÚError©rI   rt   r   r   r   Ú	is_usable‚  s    ,zDatabaseWrapper.is_usablec                 #   s  d }z4t ƒ  ¡ �}|V  W d   ƒ n1 s,0    Y  W nÄ tjtfyü   |d urV‚ t dt¡ t 	¡ D ]Š}|j
dkrj|jd dkrj| ji | j¥d|jd i¥| jd�}z:| ¡ �}|V  W d   ƒ n1 sÐ0    Y  W | ¡  n
| ¡  0  qøqj‚ Y n0 d S )Na8  Normally Django will use a connection to the 'postgres' database to avoid running initialization queries against the production database when it's not needed (for example, when running tests). Django was unable to create a connection to the 'postgres' database and will use the first PostgreSQL database instead.r.   rK   rN   )Úalias)rx   Ú_nodb_cursorr   r   ÚWrappedDatabaseErrorÚwarningsÚwarnÚRuntimeWarningr   ÚallÚvendorrY   r|   r”   rt   Úclose)rI   rt   rp   Úconnr{   r   r   r•   Œ  s<    (úÿþÿ
þû
&zDatabaseWrapper._nodb_cursorc                 C   s6   |   ¡ � | jjjW  d   ƒ S 1 s(0    Y  d S re   )Ztemporary_connectionrp   rr   Zserver_versionrH   r   r   r   rG   ²  s    
zDatabaseWrapper.pg_versionc                 C   s
   t || ƒS re   r   r’   r   r   r   Úmake_debug_cursor·  s    z!DatabaseWrapper.make_debug_cursor)N)N)-Ú__name__Ú
__module__Ú__qualname__r›   Zdisplay_namer,   Ú
data_typesZdata_type_check_constraintsZdata_types_suffixÚ	operatorsZpattern_escZpattern_opsr   r(   ZSchemaEditorClassr#   Zclient_classr$   Zcreation_classr%   Zfeatures_classr&   Zintrospection_classr'   Z	ops_classr…   rJ   rd   r
   rq   rv   rw   ry   r‚   r€   rŽ   r�   r�   r“   r   r•   r   rG   rž   Ú__classcell__r   r   r{   r   r-   Y   s´   åýýòÿú	>
"


	
%
r-   c                   @   s   e Zd ZdZddd„ZdS )ÚCursorMixinzE
        A subclass of psycopg cursor implementing callproc.
        Nc                 C   sˆ   t |tjƒst |¡}t d¡|t d¡g}|r`|D ]$}| t |¡¡ | t d¡¡ q4|d= | t d¡¡ t |¡}|  |¡ |S )NzSELECT * FROM ú(ú,éÿÿÿÿú))Ú
isinstancer   Z
IdentifierÚSQLÚappendÚLiteralZComposedru   )rI   r�   ÚargsZqpartsÚitemÚstmtr   r   r   ÚcallprocÂ  s    


zCursorMixin.callproc)N)rŸ   r    r¡   Ú__doc__r±   r   r   r   r   r¥   ½  s   r¥   c                   @   s   e Zd ZdS )r_   N©rŸ   r    r¡   r   r   r   r   r_   Ò  s   r_   c                   @   s   e Zd ZdS )r`   Nr³   r   r   r   r   r`   Õ  s   r`   c                   @   s   e Zd Zdd„ ZdS )r	   c                 C   s:   |   |¡� | j |¡W  d   ƒ S 1 s,0    Y  d S re   )Ú	debug_sqlrt   Úcopy)rI   Z	statementr   r   r   rµ   Ù  s    zCursorDebugWrapper.copyN)rŸ   r    r¡   rµ   r   r   r   r   r	   Ø  s   r	   c                   @   s   e Zd Zdd„ Zdd„ ZdS )r	   c                 G   sD   |   |¡�& | jj||g|¢R Ž W  d   ƒ S 1 s60    Y  d S re   )r´   rt   Úcopy_expert)rI   r   Úfiler®   r   r   r   r¶   á  s    zCursorDebugWrapper.copy_expertc                 O   sP   | j d| d��, | jj||g|¢R i |¤ŽW  d   ƒ S 1 sB0    Y  d S )NzCOPY %s TO STDOUT)r   )r´   rt   Úcopy_to)rI   r·   Útabler®   Úkwargsr   r   r   r¸   å  s    zCursorDebugWrapper.copy_toN)rŸ   r    r¡   r¶   r¸   r   r   r   r   r	   à  s   )Lr²   r†   r‹   r—   Ú
contextlibr   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   r–   r   Zdjango.db.backends.base.baser   Zdjango.db.backends.utilsr	   ZBaseCursorDebugWrapperZdjango.utils.asyncior
   Zdjango.utils.functionalr   Zdjango.utils.safestringr   Zdjango.utils.versionr   Zpsycopgr   ÚImportErrorrm   r   r   Zpsycopg_anyr   r   r   r   Z
psycopg.pqr   r    r!   ÚtypesÚoidr   Zpsycopg2.extensionsZpsycopg2.extrasÚ
extensionsZregister_adapterÚQuotedStringrn   Zregister_uuidZINETARRAY_OIDZnew_array_typeÚUNICODEr"   Zregister_typeÚclientr#   Zcreationr$   Úfeaturesr%   Zintrospectionr&   Ú
operationsr'   Zschemar(   r,   r-   r¥   r`   r_   ZClientCursorrt   r   r   r   r   Ú<module>   s€   
ÿ
ÿ
ý  d