o
    wvXjMK  ã                   @   sÆ   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m	Z	 d dl
mZ d dlmZ d dlmZmZmZ dd	lmZ dd
lmZmZ ddlmZ eeeejfZe d¡Zdd„ ZG dd„ dƒZdS )é    N)ÚOrderedDict)Úsettings)ÚDEFAULT_TIMEOUTÚget_key_func)ÚImproperlyConfigured)Úimport_string)ÚConnectionErrorÚResponseErrorÚTimeoutErroré   )Úpool)ÚCompressorErrorÚConnectionInterrupted)ÚCacheKeyz([*?[])c                 C   s   t  d| ¡S )Nz[\1])Ú
special_reÚsub)Ús© r   úX/var/www/html/myproject/venv/lib/python3.10/site-packages/django_redis/client/default.pyÚglob_escape   s   r   c                   @   sb  e Zd Zdd„ Zdd„ ZdFdd„ZdGd
d„ZdHdd„Zeddd	d	fdd„Z	dIdd„Z
eddfdd„ZdJdd„ZdKdd„ZdKdd„Z						dLdd„ZdJd d!„Z	dMd"d#„ZdKd$d%„ZdNd&d'„Zd(d)„ Zd*d+„ ZdKd,d-„Zeddfd.d/„ZdOd0d1„ZdOd2d3„ZdId4d5„ZdKd6d7„ZdKd8d9„ZdJd:d;„ZdKd<d=„ZdKd>d?„ZdKd@dA„Z dBdC„ Z!eddfdDdE„Z"dS )PÚDefaultClientc                 C   sà   || _ || _|| _t| d¡pdƒ| _| jstdƒ‚t| jtt	t
fƒs*| j d¡| _d gt| jƒ | _| di ¡| _| j dd¡| _| j dd	¡}t|ƒ}| j d
d¡}t|ƒ}|| jd�| _|| jd�| _tj| jd�| _d S )NÚREVERSE_KEY_FUNCTIONz%django_redis.util.default_reverse_keyzMissing connections stringú,ÚOPTIONSÚSLAVE_READ_ONLYTÚ
SERIALIZERz0django_redis.serializers.pickle.PickleSerializerÚ
COMPRESSORz4django_redis.compressors.identity.IdentityCompressor)Úoptions)Ú_backendÚ_serverÚ_paramsr   ÚgetÚreverse_keyr   Ú
isinstanceÚlistÚtupleÚsetÚsplitÚlenÚ_clientsÚ_optionsÚ_slave_read_onlyr   Ú_serializerÚ_compressorr   Úget_connection_factoryÚconnection_factory)ÚselfÚserverÚparamsÚbackendÚserializer_pathÚserializer_clsÚcompressor_pathÚcompressor_clsr   r   r   Ú__init__   s2   
þÿÿzDefaultClient.__init__c                 C   s
   |   |¡S ©N)Úhas_key)r0   Úkeyr   r   r   Ú__contains__>   s   
zDefaultClient.__contains__Tr   c                    sj   ˆ rt ˆ ƒt | jƒk r‡ fdd„tdt | jƒƒD ƒ}t |¡S |s(t | jƒdkr*dS t dt | jƒd ¡S )zï
        Return a next index for read client.
        This function implements a default behavior for
        get a next read client for master-slave setup.

        Overwrite this function if you want a specific
        behavior.
        c                    s   g | ]}|ˆ vr|‘qS r   r   )Ú.0Úi©Útriedr   r   Ú
<listcomp>K   s    z7DefaultClient.get_next_client_index.<locals>.<listcomp>r   é   )r(   r   ÚrangeÚrandomÚchoiceÚrandint)r0   Úwriter@   Ú	not_triedr   r?   r   Úget_next_client_indexA   s   	
z#DefaultClient.get_next_client_indexFc                 C   sL   | j ||pg d�}| j| du r|  |¡| j|< |r!| j| |fS | j| S )zÈ
        Method used for obtain a raw redis client.

        This function is used by almost all cache backend
        operations for obtain a native redis client/connection
        instance.
        )rG   r@   N)rI   r)   Úconnect)r0   rG   r@   Ú
show_indexÚindexr   r   r   Ú
get_clientS   s   
zDefaultClient.get_clientr   c                 C   s   | j  | j| ¡S )zè
        Given a connection index, returns a new raw redis client/connection
        instance. Index is used for master/slave setups and indicates that
        connection string should be used. In normal setups, index is 0.
        )r/   rJ   r   )r0   rL   r   r   r   rJ   e   s   zDefaultClient.connectNc              
   C   s
  | j ||d�}|  |¡}	|tu r| jj}|}
g }	 z>|du r(| jd|dd�\}}|durKt|d ƒ}|dkrK|rB| j|||d� W S | j|||d�W S t	|j
||	|||d	�ƒW S  ty„ } z!|
sz| jszt|ƒt| jƒk rz| |¡ d}W Y d}~qt|d
�|‚d}~ww )zÀ
        Persist a value to the cache, and set an optional expiration time.

        Also supports optional nx parameter. If set to True - will use redis
        setnx instead of set.
        ©ÚversionTN)rG   r@   rK   éè  r   ©rO   Úclient)rR   rO   )ÚnxÚpxÚxx©Ú
connection)Úmake_keyÚencoder   r   Údefault_timeoutrM   Úintr:   ÚdeleteÚboolr&   Ú_main_exceptionsr+   r(   r   Úappendr   )r0   r;   ÚvalueÚtimeoutrO   rR   rS   rU   ÚnkeyÚnvalueÚoriginal_clientr@   rL   Úer   r   r   r&   m   s>   

ÿÿþ
€÷zDefaultClient.setrB   c           
   
   C   sä   |du r
| j dd�}|du r| jj}|  ||¡}| j|||d�}z| |¡}W n ty9 } zt|d�|‚d}~ww |du rDtd| ƒ‚t	|t
ƒrU| j| ¡ || d�}	n	| j||| d�}	| j|	|||d� | j||d	� || S )
zh
        Adds delta to the cache version for the supplied key. Returns the
        new version.
        NT©rG   rQ   rV   úKey '%s' not foundrN   )ra   rR   )rR   )rM   r   rO   rX   r!   Úttlr^   r   Ú
ValueErrorr#   r   Úoriginal_keyr&   r\   )
r0   r;   ÚdeltarO   rR   Úold_keyr`   rh   re   Únew_keyr   r   r   Úincr_version¨   s(   €ÿ
zDefaultClient.incr_versionc                 C   s   | j |||||dd�S )z“
        Add a value to the cache, failing if the key already exists.

        Returns ``True`` if the object was added, ``False`` if not.
        T)rO   rR   rS   )r&   )r0   r;   r`   ra   rO   rR   r   r   r   ÚaddÈ   s   zDefaultClient.addc              
   C   sl   |du r
| j dd�}| j||d�}z| |¡}W n ty* } zt|d�|‚d}~ww |du r1|S |  |¡S )zv
        Retrieve a value from the cache.

        Returns decoded value if key is found, the default if not.
        NFrf   rN   rV   )rM   rX   r!   r^   r   Údecode)r0   r;   ÚdefaultrO   rR   r`   re   r   r   r   r!   Ð   s   €ÿ
zDefaultClient.getc                 C   s>   |d u r
| j dd�}| j||d�}| |¡r| |¡ d S d S ©NTrf   rN   )rM   rX   ÚexistsÚpersist)r0   r;   rO   rR   r   r   r   rt   å   s   
ÿzDefaultClient.persistc                 C   s@   |d u r
| j dd�}| j||d�}| |¡r| ||¡ d S d S rr   )rM   rX   rs   Úexpire©r0   r;   ra   rO   rR   r   r   r   ru   î   s   
ÿzDefaultClient.expireçš™™™™™¹?c                 C   s6   |d u r
| j dd�}| j||d�}|j|||||d�S )NTrf   rN   )ra   ÚsleepÚblocking_timeoutÚthread_local)rM   rX   Úlock)r0   r;   rO   ra   rx   ry   rR   rz   r   r   r   r{   ÷   s   
ûzDefaultClient.lockc              
   C   sR   |du r
| j dd�}z| | j|||d�¡W S  ty( } zt|d�|‚d}~ww )z.
        Remove a key from the cache.
        NTrf   ©rO   ÚprefixrV   )rM   r\   rX   r^   r   )r0   r;   rO   r}   rR   re   r   r   r   r\     s   €ÿzDefaultClient.deletec           
   
   C   s�   |du r
| j dd�}| j|||d�}d|i}|r||d< zd}|jd
i |¤ŽD ]}| |¡ |d7 }q'|W S  tyG }	 zt|d	�|	‚d}	~	ww )z3
        Remove all keys matching pattern.
        NTrf   r|   ÚmatchÚcountr   rB   rV   r   )rM   Úmake_patternÚ	scan_iterr\   r^   r   )
r0   ÚpatternrO   r}   rR   ÚitersizeÚkwargsr   r;   re   r   r   r   Údelete_pattern  s    

€ÿzDefaultClient.delete_patternc              
      sb   |du r
ˆ j dd�}‡ ‡fdd„|D ƒ}|sdS z|j|Ž W S  ty0 } zt|d�|‚d}~ww )z/
        Remove multiple keys at once.
        NTrf   c                    s   g | ]	}ˆ j |ˆd �‘qS )rN   ©rX   ©r=   Úk©r0   rO   r   r   rA   :  ó    z-DefaultClient.delete_many.<locals>.<listcomp>rV   )rM   r\   r^   r   )r0   ÚkeysrO   rR   re   r   r‰   r   Údelete_many2  s   €ÿzDefaultClient.delete_manyc              
   C   sH   |du r
| j dd�}z| ¡  W dS  ty# } zt|d�|‚d}~ww )z'
        Flush all cache keys.
        NTrf   rV   )rM   Úflushdbr^   r   )r0   rR   re   r   r   r   ÚclearD  s   €ÿzDefaultClient.clearc                 C   sX   zt |ƒ}W |S  ttfy+   z| j |¡}W n	 ty!   Y nw | j |¡}Y |S w )z)
        Decode the given value.
        )r[   ri   Ú	TypeErrorr-   Ú
decompressr   r,   Úloads©r0   r`   r   r   r   rp   Q  s   
ùþùzDefaultClient.decodec                 C   s4   t |tƒs
t |tƒs| j |¡}| j |¡}|S |S )z)
        Encode the given value.
        )r#   r]   r[   r,   Údumpsr-   Úcompressr’   r   r   r   rY   `  s
   zDefaultClient.encodec           
   
      s¢   |du r
ˆ j dd�}|si S tƒ }t‡ ‡fdd„|D ƒƒ}z|j|Ž }W n ty6 } zt|d�|‚d}~ww t||ƒD ]\}}	|	du rEq<ˆ  |	¡||| < q<|S )z%
        Retrieve many keys.
        NFrf   c                 3   s"   � | ]}ˆ j |ˆd �|fV  qdS )rN   Nr†   r‡   r‰   r   r   Ú	<genexpr>y  s   €  z)DefaultClient.get_many.<locals>.<genexpr>rV   )rM   r   Úmgetr^   r   Úziprp   )
r0   r‹   rO   rR   Úrecovered_dataÚmap_keysÚresultsre   r;   r`   r   r‰   r   Úget_manyl  s"   €ÿzDefaultClient.get_manyc           	   
   C   sv   |du r
| j dd�}z| ¡ }| ¡ D ]\}}| j|||||d� q| ¡  W dS  ty: } zt|d�|‚d}~ww )a"  
        Set a bunch of values in the cache at once from a dict of key/value
        pairs. This is much more efficient than calling set() multiple times.

        If timeout is given, that timeout will be used for the key; otherwise
        the default cache timeout will be used.
        NTrf   rQ   rV   )rM   ÚpipelineÚitemsr&   Úexecuter^   r   )	r0   Údatara   rO   rR   rœ   r;   r`   re   r   r   r   Úset_many†  s   €ÿzDefaultClient.set_manyc           
   
   C   sà   |d u r
| j dd�}| j||d�}zLz|sd}nd}| |d||¡}|d u r,td| ƒ‚W W |S  ty]   | |¡}|dkrEtd| ƒ‚| j|||d	�| }| j|||||d
� Y W |S w  tyo }	 zt	|d�|	‚d }	~	ww )NTrf   rN   zð
                    local exists = redis.call('EXISTS', KEYS[1])
                    if (exists == 1) then
                        return redis.call('INCRBY', KEYS[1], ARGV[1])
                    else return false end
                    zW
                    return redis.call('INCRBY', KEYS[1], ARGV[1])
                    rB   rg   éþÿÿÿrQ   )rO   ra   rR   rV   )
rM   rX   Úevalri   r	   rh   r!   r&   r^   r   )
r0   r;   rk   rO   rR   Úignore_key_checkÚluar`   ra   re   r   r   r   Ú_incr™  s2   ÿî
î€ÿzDefaultClient._incrc                 C   s   | j |||||d�S )zØ
        Add delta to value in the cache. If the key does not exist, raise a
        ValueError exception. if ignore_key_check=True then the key will be
        created and set to the delta value by default.
        )r;   rk   rO   rR   r£   ©r¥   )r0   r;   rk   rO   rR   r£   r   r   r   ÚincrÆ  s   ûzDefaultClient.incrc                 C   s   | j || ||d�S )zx
        Decreace delta to value in the cache. If the key does not exist, raise a
        ValueError exception.
        )r;   rk   rO   rR   r¦   )r0   r;   rk   rO   rR   r   r   r   ÚdecrÔ  s   zDefaultClient.decrc                 C   sb   |du r
| j dd�}| j||d�}| |¡sdS | |¡}|dkr#|S |dkr)dS |dkr/dS dS )z“
        Executes TTL redis command and return the "time-to-live" of specified key.
        If key is a non volatile key, it returns None.
        NFrf   rN   r   éÿÿÿÿr¡   )rM   rX   rs   rh   )r0   r;   rO   rR   Útr   r   r   rh   Û  s   

zDefaultClient.ttlc              
   C   sX   |du r
| j dd�}| j||d�}z| |¡dkW S  ty+ } zt|d�|‚d}~ww )z%
        Test if key exists.
        NFrf   rN   rB   rV   )rM   rX   rs   r^   r   )r0   r;   rO   rR   re   r   r   r   r:   ó  s   €ÿzDefaultClient.has_keyc                 c   sL   � |du r| j dd�}| j||d�}|j||d�D ]
}|  | ¡ ¡V  qdS )zo
        Same as keys, but uses redis >= 2.8 cursors
        for make memory efficient keys iteration.
        NFrf   rN   )r~   r   )rM   r€   r�   r"   rp   )r0   Úsearchrƒ   rR   rO   r‚   Úitemr   r   r   Ú	iter_keys  s   €ÿzDefaultClient.iter_keysc              
      sb   |du r
ˆ j dd�}ˆ j||d�}z‡ fdd„| |¡D ƒW S  ty0 } zt|d�|‚d}~ww )zÇ
        Execute KEYS command and return matched results.
        Warning: this can return huge number of results, in
        this case, it strongly recommended use iter_keys
        for it.
        NFrf   rN   c                    s   g | ]	}ˆ   | ¡ ¡‘qS r   )r"   rp   r‡   ©r0   r   r   rA     rŠ   z&DefaultClient.keys.<locals>.<listcomp>rV   )rM   r€   r‹   r^   r   )r0   r«   rO   rR   r‚   re   r   r®   r   r‹     s   €ÿzDefaultClient.keysc                 C   sB   t |tƒr|S |d u r| jj}|d u r| jj}t| j |||¡ƒS r9   )r#   r   r   Ú
key_prefixrO   Úkey_func)r0   r;   rO   r}   r   r   r   rX     s   
zDefaultClient.make_keyc                 C   sV   t |tƒr|S |d u r| jj}t|ƒ}|d u r| jj}tt|ƒƒ}t| j |||¡ƒS r9   )r#   r   r   r¯   r   rO   Ústrr°   )r0   r‚   rO   r}   r   r   r   r€   +  s   
zDefaultClient.make_patternc                 K   sN   t tddƒr#tt| jƒƒD ]}| j| jjD ]}| ¡  qd | j|< qd S d S )NÚDJANGO_REDIS_CLOSE_CONNECTIONF)Úgetattrr   rC   r(   r)   Úconnection_poolÚ_available_connectionsÚ
disconnect)r0   r„   r>   Úcr   r   r   Úclose9  s   
üzDefaultClient.closec                 C   sd   |t u r| jj}|du r| jdd�}| j||d�}|du r$t| |¡ƒS t|d ƒ}t| ||¡ƒS )z2
        Sets a new expiration for a key.
        NTrf   rN   rP   )	r   r   rZ   rM   rX   r]   rt   r[   Úpexpirerv   r   r   r   Útouch@  s   zDefaultClient.touch)Tr   )Tr   F)r   )rB   NN)NNN)NN)NNrw   NNT)NNNNr9   )rB   NNF)#Ú__name__Ú
__module__Ú__qualname__r8   r<   rI   rM   rJ   r   r&   rn   ro   r!   rt   ru   r{   r\   r…   rŒ   rŽ   rp   rY   r›   r    r¥   r§   r¨   rh   r:   r­   r‹   rX   r€   r¸   rº   r   r   r   r   r      sX    #



ø
; 


	
ø

ÿ




-






r   )rD   ÚreÚsocketÚcollectionsr   Údjango.confr   Údjango.core.cache.backends.baser   r   Údjango.core.exceptionsr   Údjango.utils.module_loadingr   Úredis.exceptionsr   r	   r
   Ú r   Ú
exceptionsr   r   Úutilr   ra   r^   Úcompiler   r   r   r   r   r   r   Ú<module>   s     
