o
    ˷e7                  
   @   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ddlZddlZddlZW n eyp Z  ze	de  dZ [ ww dd Z!e! Z"e"dk re	dej# 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j01eej0j2 ej34  dZ5ej06e5fdej0j7Z8ej09e8 G dd deZ:G dd deZdS ) zW
PostgreSQL database backend for Django.

Requires psycopg 2: https://www.psycopg.org/
    N)contextmanager)settings)ImproperlyConfigured)DatabaseError)connections)BaseDatabaseWrapperCursorDebugWrapper)async_unsafe)cached_property)
SafeString)get_version_tuplez!Error loading psycopg2 module: %sc                  C   s   t jddd } t| S )N    r   )psycopg2__version__splitr   )version r   Y/var/www/ideatree/venv/lib/python3.10/site-packages/django/db/backends/postgresql/base.pypsycopg2_version   s   r   )         z8psycopg2 version 2.8.4 or newer is required; you have %sr   )DatabaseClient)DatabaseCreation)DatabaseFeatures)DatabaseIntrospection)DatabaseOperations)DatabaseSchemaEditori  	INETARRAYc                       s  e Zd ZdZdZi 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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 fdEdFZedZdHdIZdJdK Z edLdM Z!dNdO Z"dZdPdQZ#dRdS Z$e% fdTdUZ&e'dVdW Z(dXdY Z)  Z*S )[DatabaseWrapper
postgresql
PostgreSQL	AutoFieldintegerBigAutoFieldbigintBinaryFieldbyteaBooleanFieldboolean	CharFieldzvarchar(%(max_length)s)	DateFielddateDateTimeFieldztimestamp with time zoneDecimalFieldz+numeric(%(max_digits)s, %(decimal_places)s)DurationFieldinterval	FileField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)rB   rC   rD   z GENERATED BY DEFAULT AS IDENTITY)r$   r&   rF   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({}))rM   rN   rU   rW   rV   rX   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 i }|d rFd|d i|d }n|d d u r_|di dd  ddi|d }ni |d }|d	d  |d
 ru|d
 |d< |d r|d |d< |d r|d |d< |d r|d |d< |S )NNAME OPTIONSservicez`settings.DATABASES is improperly configured. Please supply the NAME or OPTIONS['service'] value.zThe database name '%s' (%d characters) is longer than PostgreSQL's limit of %d characters. Supply a shorter NAME in settings.DATABASES.databasepostgresisolation_levelUSERuserPASSWORDpasswordHOSThostPORTport)settings_dictgetr   lenopsmax_name_lengthpop)r\   rm   conn_paramsr   r   r   get_connection_params   sH   

z%DatabaseWrapper.get_connection_paramsc                 C   sv   t jdi |}| jd }z|d | _W n ty!   |j| _Y nw | j|jkr/|j| jd tjj|dd d |S )Nr`   rd   )rd   c                 S   s   | S Nr   )xr   r   r   <lambda>   s    z4DatabaseWrapper.get_new_connection.<locals>.<lambda>)conn_or_cursloadsr   )	Databaseconnectrm   rd   KeyErrorset_sessionr   extrasregister_default_jsonb)r\   rs   
connectionoptionsr   r   r   get_new_connection   s   
z"DatabaseWrapper.get_new_connectionc                 C   st   | j d u rdS | j d}| j}|r8||kr8| j  }|| j |g W d    dS 1 s1w   Y  dS dS )NFTimeZoneT)r   get_parameter_statustimezone_namecursorexecuterp   set_time_zone_sql)r\   conn_timezone_namer   r   r   r   r   ensure_timezone   s   

zDatabaseWrapper.ensure_timezonec                    s@   t    | jd |  }|r|  s| j  d S d S d S )NUTF8)superinit_connection_stater   set_client_encodingr   get_autocommitcommit)r\   timezone_changed	__class__r   r   r      s   
z%DatabaseWrapper.init_connection_stateNc                 C   sB   |r| j j|d| j jd}n| j  }tjr| j|_|S d |_|S )NF)
scrollablewithhold)r   r   
autocommitr   USE_TZtzinfo_factory)r\   namer   r   r   r   create_cursor  s   

zDatabaseWrapper.create_cursorc                 C   s   | j S ru   )timezone)r\   offsetr   r   r   r     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)r\   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 ru   )wrap_database_errorsr   r   )r\   r   r   r   r   _set_autocommit0  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   )r\   table_namesr   r   r   r   check_constraints4  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   rz   Errorr\   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.r"   r^   rc   )alias)r   _nodb_cursorrz   r   WrappedDatabaseErrorwarningswarnRuntimeWarningr   allvendorrm   r   r   r   close)r\   r   r   connr   r   r   r   G  sD   &


zDatabaseWrapper._nodb_cursorc                 C   s4   |    | jjW  d    S 1 sw   Y  d S ru   )temporary_connectionr   server_versionr[   r   r   r   rZ   m  s   
$zDatabaseWrapper.pg_versionc                 C   s
   t || S ru   r   r   r   r   r   make_debug_cursorr  s   
z!DatabaseWrapper.make_debug_cursorru   )+__name__
__module____qualname__r   display_name
data_typesdata_type_check_constraintsdata_types_suffix	operatorspattern_escpattern_opsrz   r   SchemaEditorClassr   client_classr   creation_classr   features_classr   introspection_classr   	ops_classr   r]   rt   r
   r   r   r   r   r   r   r   r   r   r   r   r   rZ   r   __classcell__r   r   r   r   r!   C   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 ru   )	debug_sqlr   copy_expert)r\   sqlfileargsr   r   r   r   w  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)r\   r   tabler   kwargsr   r   r   r   {  s   $zCursorDebugWrapper.copy_toN)r   r   r   r   r   r   r   r   r   r	   v  s    r	   );__doc__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   r   rz   psycopg2.extensionspsycopg2.extrasImportErrorer   PSYCOPG2_VERSIONr   clientr   creationr   featuresr   introspectionr   
operationsr   schemar   
extensionsregister_adapterQuotedStringr~   register_uuidINETARRAY_OIDnew_array_typeUNICODEr    register_typer!   r   r   r   r   <module>   sd    
  5