o
    ^"<f3                  
   @   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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yl Z  ze	de  dZ [ ww dd Z!e! Z"e"dk re	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/html/kck/venv/lib/python3.10/site-packages/django/db/backends/postgresql/base.pypsycopg2_version    s   r   )         z8psycopg2_version 2.5.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&d'Zd(d(d(d)Zd*d+d,d-d.d/d0d1d2d3d,d,d-d-d4Zd5Zd6d7d8d9d:d;d<Z	e
Z
eZeZeZeZeZeZd=Zd>d? Zed@dA ZdBdC ZdDdE ZedYdGdHZdIdJ ZedKdL ZdMdN Z dYdOdPZ!dQdR Z"e# fdSdTZ$e%dUdV Z&dWdX Z'  Z(S )ZDatabaseWrapper
postgresql
PostgreSQL	AutoFieldserialBigAutoField	bigserial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integerBigIntegerFieldbigintIPAddressFieldinetGenericIPAddressField	JSONFieldjsonbsmallintsmallserialtexttimeuuid)NullBooleanFieldOneToOneFieldPositiveBigIntegerFieldPositiveIntegerFieldPositiveSmallIntegerField	SlugFieldSmallAutoFieldSmallIntegerField	TextField	TimeField	UUIDFieldz"%(column)s" >= 0)rF   rG   rH   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({}))rQ   rR   rY   r[   rZ   r\   r   c                 C   s   | j }|d dkrtdt|d pd| j kr,td|d t|d | j f d|d p2di|d }|dd  |d	 rH|d	 |d
< |d rR|d |d< |d r\|d |d< |d rf|d |d< |S )NNAME zJsettings.DATABASES is improperly configured. Please supply the NAME 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OPTIONSisolation_levelUSERuserPASSWORDpasswordHOSThostPORTport)settings_dictr   lenopsmax_name_lengthpop)selfrk   conn_paramsr   r   r   get_connection_params   s8   

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 )Nra   rb   )rb   c                 S   s   | S Nr   )xr   r   r   <lambda>   s    z4DatabaseWrapper.get_new_connection.<locals>.<lambda>)conn_or_cursloadsr   )	Databaseconnectrk   rb   KeyErrorset_sessionr   extrasregister_default_jsonb)rp   rq   
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executerm   set_time_zone_sql)rp   conn_timezone_namer   r   r   r   r   ensure_timezone   s   

zDatabaseWrapper.ensure_timezonec                 C   s6   | j d |  }|r|  s| j   d S d S d S )NUTF8)r~   set_client_encodingr   get_autocommitcommit)rp   timezone_changedr   r   r   init_connection_state   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)rp   namer   r   r   r   create_cursor   s   
zDatabaseWrapper.create_cursorc                 C   s   | j S rs   )timezone)rp   offsetr   r   r   r      s   zDatabaseWrapper.tzinfo_factoryc                 C   s|   |  j d7  _ zttdrt }ntj }W n ty#   d }Y nw |r-tt|}nd}| jdt	
 j|| j f dS )Nr   current_tasksyncz_django_curs_%d_%s_%d)r   )_named_cursor_idxhasattrasyncior   TaskRuntimeErrorstrid_cursor	threadingcurrent_threadident)rp   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 rs   )wrap_database_errorsr~   r   )rp   r   r   r   r   _set_autocommit  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   )rp   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   rx   Errorrp   r   r   r   r   	is_usable   s   zDatabaseWrapper.is_usablec                 #   s    zt   }|V  W d    W d S 1 sw   Y  W d S  tjtfy{   tdt t	 D ]G}|j
dkry|jd dkry| ji | jd|jd i| jd}z| }|V  W d    n1 sew   Y  W |  n|  w  Y d S q2 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]   r`   )alias)super_nodb_cursorrx   r   WrappedDatabaseErrorwarningswarnRuntimeWarningr   allvendorrk   	__class__r   r   close)rp   r   r~   connr   r   r   r   *  s4   &
zDatabaseWrapper._nodb_cursorc                 C   s4   |    | jjW  d    S 1 sw   Y  d S rs   )temporary_connectionr~   server_version)rp   r   r   r   
pg_versionG  s   
$zDatabaseWrapper.pg_versionc                 C   s
   t || S rs   r   r   r   r   r   make_debug_cursorL  s   
z!DatabaseWrapper.make_debug_cursorrs   ))__name__
__module____qualname__r   display_name
data_typesdata_type_check_constraints	operatorspattern_escpattern_opsrx   r   SchemaEditorClassr   client_classr   creation_classr   features_classr   introspection_classr   	ops_classr   rr   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r!   A   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 rs   )	debug_sqlr   copy_expert)rp   sqlfileargsr   r   r   r   Q  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)rp   r   tabler   kwargsr   r   r   r   U  s   $zCursorDebugWrapper.copy_toN)r   r   r   r   r   r   r   r   r   r	   P  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   rx   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>   sZ    
  