o
    ÕèFh<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yd   ddlZY nw W n eyq   e	dƒ‚w 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,n)d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dS 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   ú[/var/www/html/loop/nvenv/lib/python3.10/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_tzloaderÚtimestamptzi  Ú	INETARRAY)ÚDatabaseClient)ÚDatabaseCreation)ÚDatabaseFeatures)ÚDatabaseIntrospection)ÚDatabaseOperations)ÚDatabaseSchemaEditorc                 C   s   | d d u rdS d|  S )NÚ
max_lengthÚvarcharúvarchar(%(max_length)s)r   )Údatar   r   r   Ú_get_varchar_columnS   s   r.   c                       s¤  e Zd ZdZdZi dd“dd“d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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/d0d1d2d+d+d,d,d3œZ	d4Z
d5d6d7d8d9d: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dAdB„ ƒZdCdD„ ZdEdF„ Z‡ fdGdH„Z ed\dJdK„ƒZ!dLdM„ Z"edNdO„ ƒZ#dPdQ„ Z$d\dRdS„Z%dTdU„ Z&e'‡ fdVdW„ƒZ(e)dXdY„ ƒZ*dZd[„ Z+‡  Z,S )]ÚDatabaseWrapperÚ
postgresqlÚ
PostgreSQLÚ	AutoFieldÚintegerÚBigAutoFieldÚbigintÚBinaryFieldÚbyteaÚBooleanFieldÚbooleanÚ	CharFieldÚ	DateFieldÚdateÚDateTimeFieldztimestamp with time zoneÚDecimalFieldz+numeric(%(max_digits)s, %(decimal_places)s)ÚDurationFieldÚintervalÚ	FileFieldr,   ÚFilePathFieldÚ
FloatFieldzdouble precisionÚIntegerFieldÚBigIntegerFieldÚIPAddressFieldÚinetÚGenericIPAddressFieldÚ	JSONFieldÚjsonbÚsmallintÚtextÚtimeÚuuid)
ÚOneToOneFieldÚPositiveBigIntegerFieldÚPositiveIntegerFieldÚPositiveSmallIntegerFieldÚ	SlugFieldÚSmallAutoFieldÚSmallIntegerFieldÚ	TextFieldÚ	TimeFieldÚ	UUIDFieldz"%(column)s" >= 0)rP   rQ   rR   z GENERATED BY DEFAULT AS IDENTITY)r2   r4   rT   z= %sz= UPPER(%s)zLIKE %szLIKE UPPER(%s)z~ %sz~* %sz> %sz>= %sz< %sz<= %s)ÚexactÚiexactÚcontainsÚ	icontainsÚregexÚiregexÚgtÚgteÚltÚ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\   rc   re   rd   rf   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 pdƒ| j ¡ kr5td|d t|d ƒ| j ¡ f ƒ‚|d rDd|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 r¥|d |d< |d r¯|d |d< trÂttj| jƒ|d< | dd ¡|d< |S )NÚNAMEÚ ÚOPTIONSÚ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.ÚdbnameÚpostgresÚUTF8Úclient_encodingÚassume_roleÚisolation_levelÚserver_side_bindingÚcursor_factoryTÚUSERÚuserÚPASSWORDÚpasswordÚHOSTÚhostÚPORTÚportÚcontextÚprepare_threshold)Úsettings_dictÚgetr   ÚlenÚopsÚmax_name_lengthÚpopÚ
setdefaultr   ÚServerBindingCursorÚCursorr    r   ÚUSE_TZÚtimezone)rj   r‚   Úconn_paramsrv   r   r   r   Úget_connection_params¾   sj   ÿÿ
ýýÿ
ÿþÿÿûÿÿz%DatabaseWrapper.get_connection_paramsc                 C   s¢   | j d }d}z|d }W n ty   tj| _Y nw z	t|ƒ| _d}W n ty3   td|› d�ƒ‚w | jjd
i |¤Ž}|rC| j|_t	sOt
jj|dd„ d	� |S )Nrn   Fru   Tz$Invalid transaction isolation level z9 specified. Use one of the psycopg.IsolationLevel values.c                 S   s   | S ©Nr   )Úxr   r   r   Ú<lambda>  s    z4DatabaseWrapper.get_new_connection.<locals>.<lambda>)Úconn_or_cursÚloadsr   )r‚   ÚKeyErrorr   ÚREAD_COMMITTEDru   Ú
ValueErrorr   r   Úconnectr   Úpsycopg2ÚextrasÚregister_default_jsonb)rj   r�   ÚoptionsÚset_isolation_levelÚisolation_level_valueÚ
connectionr   r   r   Úget_new_connectionþ   s.   
ÿ

ÿÿÿz"DatabaseWrapper.get_new_connectionc                 C   sv   | j d u rdS | j j d¡}| j}|r9||kr9| j  ¡ �}| | j ¡ |g¡ W d   ƒ dS 1 s2w   Y  dS dS )NFÚTimeZoneT)rž   ÚinfoÚparameter_statusÚtimezone_nameÚcursorÚexecuter…   Úset_time_zone_sql)rj   Úconn_timezone_namer£   r¤   r   r   r   Úensure_timezone!  s   

ÿþzDatabaseWrapper.ensure_timezonec                 C   st   | j d u rdS | j di ¡ d¡ }r8| j  ¡ �}| j d|g¡}| |¡ W d   ƒ dS 1 s1w   Y  dS dS )NFrn   rt   zSET ROLE %sT)rž   r‚   rƒ   r¤   r…   Úcompose_sqlr¥   )rj   Únew_roler¤   r   r   r   r   Úensure_role,  s   

þýzDatabaseWrapper.ensure_rolec                    s@   t ƒ  ¡  |  ¡ }|  ¡ }|s|r|  ¡ s| j ¡  d S d S d S r�   )ÚsuperÚinit_connection_stater¨   r«   Úget_autocommitrž   Úcommit)rj   Ú	commit_tzÚcommit_role©Ú	__class__r   r   r­   6  s   
ÿz%DatabaseWrapper.init_connection_stateNc                 C   sn   |r| j j|d| j jd�}n| j  ¡ }tr,| j j ttj¡}| j	|j	kr*t
| j	|ƒ |S tjr2| jnd |_|S )NF)Ú
scrollableÚwithhold)rž   r¤   Ú
autocommitr   r   Ú
get_loaderÚTIMESTAMPTZ_OIDr   ÚTEXTrŒ   r!   r   r‹   Útzinfo_factory)rj   Únamer¤   Útzloaderr   r   r   Úcreate_cursorC  s   
ÿ
ÿzDatabaseWrapper.create_cursorc                 C   s   | j S r�   )rŒ   )rj   Úoffsetr   r   r   rº   X  s   zDatabaseWrapper.tzinfo_factoryc                 C   sf   |  j d7  _ zt ¡ }W n ty   d }Y nw |r"t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ÚidÚ_cursorÚ	threadingÚcurrent_threadÚident)rj   rÂ   Ú
task_identr   r   r   Úchunked_cursor[  s"   ÿüÿÿzDatabaseWrapper.chunked_cursorc                 C   s4   | j � || j_W d   ƒ d S 1 sw   Y  d S r�   )Úwrap_database_errorsrž   r¶   )rj   r¶   r   r   r   Ú_set_autocommitw  s   
"ÿzDatabaseWrapper._set_autocommitc                 C   sB   |   ¡ �}| d¡ | d¡ W d  ƒ dS 1 sw   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)r¤   r¥   )rj   Útable_namesr¤   r   r   r   Úcheck_constraints{  s   

"þz!DatabaseWrapper.check_constraintsc                 C   sV   z| j  ¡ �}| d¡ W d   ƒ W dS 1 sw   Y  W dS  tjy*   Y dS w )NzSELECT 1FT)rž   r¤   r¥   r   ÚError©rj   r¤   r   r   r   Ú	is_usable„  s   ÿûýÿzDatabaseWrapper.is_usablec                 #   s  � d }zt ƒ  ¡ �}|V  W d   ƒ W d S 1 sw   Y  W d S  tjtfy‚   |d ur/‚ t dt¡ t 	¡ D ]G}|j
dkr€|jd dkr€| ji | j¥d|jd i¥| jd�}z| ¡ �}|V  W d   ƒ n1 slw   Y  W | ¡  n| ¡  w  Y d S q9‚ w )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.r0   rl   rq   )Úalias)r¬   Ú_nodb_cursorr   r   ÚWrappedDatabaseErrorÚwarningsÚwarnÚRuntimeWarningr   ÚallÚvendorr‚   r³   rÓ   r¤   Úclose)rj   r¤   rž   Úconnr²   r   r   rÔ   Ž  sD   €&ÿú
ÿ
þû
ÿ€€âzDatabaseWrapper._nodb_cursorc                 C   s6   |   ¡ � | jjjW  d   ƒ S 1 sw   Y  d S r�   )Útemporary_connectionrž   r¡   Úserver_versionri   r   r   r   rh   ´  s   
$ÿzDatabaseWrapper.pg_versionc                 C   s
   t || ƒS r�   r   rÑ   r   r   r   Úmake_debug_cursor¹  s   
z!DatabaseWrapper.make_debug_cursorr�   )-Ú__name__Ú
__module__Ú__qualname__rÚ   Údisplay_namer.   Ú
data_typesÚdata_type_check_constraintsÚdata_types_suffixÚ	operatorsÚpattern_escÚpattern_opsr   r)   ÚSchemaEditorClassr$   Úclient_classr%   Úcreation_classr&   Úfeatures_classr'   Úintrospection_classr(   Ú	ops_classrÀ   rk   rŽ   r
   rŸ   r¨   r«   r­   r½   rº   rË   rÍ   rÏ   rÒ   r   rÔ   r   rh   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}|r0|D ]}| t |¡¡ | t d¡¡ q|d= | t d¡¡ t |¡}|  |¡ |S )NzSELECT * FROM ú(ú,éÿÿÿÿú))Ú
isinstancer   Ú
IdentifierÚSQLÚappendÚLiteralÚComposedr¥   )rj   r»   ÚargsÚqpartsÚitemÚstmtr   r   r   ÚcallprocÄ  s   


zCursorMixin.callprocr�   )rà   rá   râ   Ú__doc__r   r   r   r   r   rñ   ¿  s    rñ   c                   @   ó   e Zd ZdS )r‰   N©rà   rá   râ   r   r   r   r   r‰   Ô  ó    r‰   c                   @   r  )rŠ   Nr  r   r   r   r   rŠ   ×  r  rŠ   c                   @   s   e Zd Zdd„ ZdS )r	   c                 C   s:   |   |¡� | j |¡W  d   ƒ S 1 sw   Y  d S r�   )Ú	debug_sqlr¤   Úcopy)rj   Ú	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 sw   Y  d S r�   )r  r¤   Úcopy_expert)rj   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 s!w   Y  d S )NzCOPY %s TO STDOUT)r   )r  r¤   Úcopy_to)rj   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   Údjango.confr   Údjango.core.exceptionsr   Ú	django.dbr   rÕ   r   Údjango.db.backends.base.baser   Údjango.db.backends.utilsr	   ÚBaseCursorDebugWrapperÚdjango.utils.asyncior
   Údjango.utils.functionalr   Údjango.utils.safestringr   Údjango.utils.versionr   Úpsycopgr   ÚImportErrorr˜   r   r   Úpsycopg_anyr   r   r   r   Ú
psycopg.pqr   r    r!   ÚtypesÚoidr¸   Úpsycopg2.extensionsÚpsycopg2.extrasÚ
extensionsÚregister_adapterÚQuotedStringr™   Úregister_uuidÚINETARRAY_OIDÚnew_array_typeÚUNICODEr#   Úregister_typeÚclientr$   Úcreationr%   Úfeaturesr&   Úintrospectionr'   Ú
operationsr(   Úschemar)   r.   r/   rñ   rŠ   r‰   ÚClientCursorr¤   r   r   r   r   Ú<module>   sˆ    ÿ€ÿ

ÿ
ÿ
ý  f