o
    Ph!_                     @   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m	Z	m
Z
mZ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 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e(de(fddZ)G dd dZ*dS )    N)OrderedDict)datetime)AnyDictIteratorListOptionalUnion)settings)DEFAULT_TIMEOUT	BaseCacheget_key_func)ImproperlyConfigured)import_string)Redis)ConnectionErrorResponseErrorTimeoutError   )pool)CompressorErrorConnectionInterrupted)CacheKeyz([*?[])sreturnc                 C   s   t d| S )Nz[\1])
special_resub)r    r   g/var/www/html/Testing_prj/Navya-Bakers/venv/lib/python3.10/site-packages/django_redis/client/default.pyglob_escape   s   r   c                   @   sn  e Zd Zdeeef deddfddZdedefdd	Z		dgdede
ee  defddZ	
		dhdede
ee  defddZdidedefddZdjddZeddddfdedede
e de
e de
e dededefdd Z	!		dkded"ede
e de
e def
d#d$Zeddfdededede
e de
e defd%d&Z			dldede
e de
e defd'd(Z	dmdede
e de
e defd)d*Z		dmdede
e de
e defd+d,Zdmdefd-d.Z		dmded/eeef de
e de
e def
d0d1Z		dmded/eeef de
e de
e def
d2d3Z			4			
dnde
e de
e fd5d6Z			dldede
e d7e
e de
e def
d8d9Z 				dod:ede
e d7e
e de
e d;e
e defd<d=Z!	dmde
e de
e fd>d?Z"dpde
e ddfd@dAZ#dee$ef defdBdCZ%dedee$ef fdDdEZ&	dmde
e de
e de'fdFdGZ(eddfdHeeef de
e de
e de
e ddf
dIdJZ)	!			dqded"ede
e de
e dKedefdLdMZ*	!			dqded"ede
e de
e dKedefdNdOZ+	!		dkded"ede
e de
e def
dPdQZ,	dmdede
e de
e de
e fdRdSZ-dmdTdUZ.	dmdede
e de
e defdVdWZ/			dldXed;e
e de
e de
e de0e f
dYdZZ1	dmdXede
e de
e dee fd[d\Z2	dmdede
e d7e
e de3fd]d^Z4	dmd:ede
e d7e
e de3fd_d`Z5dadb Z6dcdd Z7eddfdede
e de
e de
e def
dedfZ8dS )rDefaultClientparamsbackendr   Nc                 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REPLICA_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_replica_read_onlyr   _serializer_compressorr   get_connection_factoryconnection_factory)selfserverr!   r"   serializer_pathserializer_clscompressor_pathcompressor_clsr   r   r   __init__   s2   
zDefaultClient.__init__keyc                 C   s
   |  |S N)has_key)r<   rC   r   r   r   __contains__@   s   
zDefaultClient.__contains__Twritetriedc                    sx    du rt    r&t t| jk r& fddtdt| jD }t|S |s/t| jdkr1d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 a replication setup.

        Overwrite this function if you want a specific
        behavior.
        Nc                    s   g | ]}| vr|qS r   r   ).0irH   r   r   
<listcomp>Q   s    z7DefaultClient.get_next_client_index.<locals>.<listcomp>r      )r0   r4   r+   rangerandomchoicerandint)r<   rG   rH   	not_triedr   rK   r   get_next_client_indexC   s   

z#DefaultClient.get_next_client_indexF
show_indexc                 C   sH   | j ||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   rH   N)rS   r5   connect)r<   rG   rH   rT   indexr   r   r   
get_clientY   s   
zDefaultClient.get_clientr   rV   c                 C   s   | j | j| S )z
        Given a connection index, returns a new raw redis client/connection
        instance. Index is used for replication setups and indicates that
        connection string should be used. In normal setups, index is 0.
        )r;   rU   r+   )r<   rV   r   r   r   rU   p   s   zDefaultClient.connectc                 C   s"   |s| j | }|r| j|S dS )z9delegates the connection factory to disconnect the clientN)r5   r;   
disconnect)r<   rV   clientr   r   r   rX   x   s   
zDefaultClient.disconnectvaluetimeoutversionrY   nxxxc              
   C   s  | j ||d}| |}	|tu r| jj}|}
g }	 z@|du r(| jd|dd\}}|durMt|d }|dkrM|rB| j|||d W S t| j	|||dW S t|j
||	|||d	W S  ty } z!|
s|| js|t|t| jk r||| 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.
        r\   TN)rG   rH   rT     r   r\   rY   )rY   r\   )r]   pxr^   
connection)make_keyencoder   r*   default_timeoutrW   intrE   booldeleter2   _main_exceptionsr7   r4   r+   appendr   )r<   rC   rZ   r[   r\   rY   r]   r^   nkeynvalueoriginal_clientrH   rV   er   r   r   r2   ~   sB   


zDefaultClient.setrM   deltac           
   
   C   s   |du r
| j dd}|du r| jj}| ||}| j|||d}z
| j|||d}W n ty< } zt|d|d}~ww |du rGtd| t	|t
rX| 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   ra   rc   Key '%s' not foundr_   )r[   rY   )rY   )rW   r*   r\   re   r-   ttlrk   r   
ValueErrorr/   r   original_keyr2   rj   )
r<   rC   rq   r\   rY   old_keyrZ   rt   rp   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)r\   rY   r]   )r2   )r<   rC   rZ   r[   r\   rY   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.
        NFrr   r_   rc   )rW   re   r-   rk   r   decode)r<   rC   defaultr\   rY   rZ   rp   r   r   r   r-      s   
zDefaultClient.getc                 C   s,   |d u r
| j dd}| j||d}||S NTrr   r_   )rW   re   persist)r<   rC   r\   rY   r   r   r   r~     s   
zDefaultClient.persistc                 C   s.   |d u r
| j dd}| j||d}|||S r}   )rW   re   expirer<   rC   r[   r\   rY   r   r   r   r     s   zDefaultClient.expirec                 C   s2   |d u r
| j dd}| j||d}t|||S r}   )rW   re   ri   pexpirer   r   r   r   r   #  s   zDefaultClient.pexpirewhenc                 C   s2   |du r
| j dd}| j||d}t|||S z
        Set an expire flag on a ``key`` to ``when``, which can be represented
        as an integer indicating unix time or a Python datetime object.
        NTrr   r_   )rW   re   ri   	pexpireatr<   rC   r   r\   rY   r   r   r   
pexpire_at-  s   zDefaultClient.pexpire_atc                 C   s.   |du r
| j dd}| j||d}|||S r   )rW   re   expireatr   r   r   r   	expire_at?  s   zDefaultClient.expire_at皙?c                 C   s6   |d u r
| j dd}| j||d}|j|||||dS )NTrr   r_   )r[   sleepblocking_timeoutthread_local)rW   re   lock)r<   rC   r\   r[   r   r   rY   r   r   r   r   r   Q  s   
zDefaultClient.lockprefixc              
   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.
        NTrr   r\   r   rc   )rW   rj   re   rk   r   )r<   rC   r\   r   rY   rp   r   r   r   rj   g  s   
zDefaultClient.deletepatternitersizec           
   
   C   s   |du r
| j dd}| j|||d}z d}| }|j||dD ]}|| |d7 }q |  |W S  tyD }	 zt|d|	d}	~	ww )	z3
        Remove all keys matching pattern.
        NTrr   r   r   matchcountrM   rc   )rW   make_patternpipeline	scan_iterrj   executerk   r   )
r<   r   r\   r   rY   r   r   r   rC   rp   r   r   r   delete_patterny  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.
        NTrr   c                    s   g | ]	} j |d qS )r_   re   rI   kr<   r\   r   r   rL         z-DefaultClient.delete_many.<locals>.<listcomp>rc   )rW   rj   rk   r   )r<   keysr\   rY   rp   r   r   r   delete_many  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.
        NTrr   rc   )rW   flushdbrk   r   )r<   rY   rp   r   r   r   clear  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.
        )rh   ru   	TypeErrorr9   
decompressr   r8   loadsr<   rZ   r   r   r   r{     s   
zDefaultClient.decodec                 C   s4   t |ts
t |ts| j|}| j|}|S |S )z)
        Encode the given value.
        )r/   ri   rh   r8   dumpsr9   compressr   r   r   r   rf     s
   zDefaultClient.encodec           
   
      s   |du r
 j dd}|st S t }t fdd|D }z|j| }W n ty7 } zt|d|d}~ww t||D ]\}}	|	du rFq= |	||| < q=|S )z%
        Retrieve many keys.
        NFrr   c                 3   s"    | ]} j |d |fV  qdS )r_   Nr   r   r   r   r   	<genexpr>  s     z)DefaultClient.get_many.<locals>.<genexpr>rc   )rW   r   mgetrk   r   zipr{   )
r<   r   r\   rY   recovered_datamap_keysresultsrp   rC   rZ   r   r   r   get_many  s"   zDefaultClient.get_manydatac           	   
   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.
        NTrr   ra   rc   )rW   r   itemsr2   r   rk   r   )	r<   r   r[   r\   rY   r   rC   rZ   rp   r   r   r   set_many  s   zDefaultClient.set_manyignore_key_checkc           
   
   C   s   |d u r
| j dd}| j||d}zOz|sd}nd}||d||}|d u r,td| W W |S  ty`   | j|||d}|d	krHtd| | j|||d| }| j|||||d
 Y W |S w  tyr }	 zt	|d|	d }	~	ww )NTrr   r_   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])
                    rM   rs   ra   )r\   r[   rY   rc   )
rW   re   evalru   r   rt   r-   r2   rk   r   )
r<   rC   rq   r\   rY   r   luarZ   r[   rp   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.
        )rC   rq   r\   rY   r   r   )r<   rC   rq   r\   rY   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.
        )rC   rq   r\   rY   r   )r<   rC   rq   r\   rY   r   r   r   decrQ  s   zDefaultClient.decrc                 C   b   |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.
        NFrr   r_   r   r   )rW   re   existsrt   r<   rC   r\   rY   tr   r   r   rt   ^  s   

zDefaultClient.ttlc                 C   r   )z
        Executes PTTL redis command and return the "time-to-live" of specified key.
        If key is a non volatile key, it returns None.
        NFrr   r_   r   r   r   )rW   re   r   pttlr   r   r   r   r   x  s   

zDefaultClient.pttlc              
   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.
        NFrr   r_   rM   rc   )rW   re   r   rk   r   )r<   rC   r\   rY   rp   r   r   r   rE     s   zDefaultClient.has_keysearchc                 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.
        NFrr   r_   r   )rW   r   r   r.   r{   )r<   r   r   rY   r\   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.
        NFrr   r_   c                    s   g | ]	}  | qS r   )r.   r{   r   r<   r   r   rL     r   z&DefaultClient.keys.<locals>.<listcomp>rc   )rW   r   r   rk   r   )r<   r   r\   rY   r   rp   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 rD   )r/   r   r*   
key_prefixr\   key_func)r<   rC   r\   r   r   r   r   re     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 rD   )r/   r   r*   r   r   r\   strr   )r<   r   r\   r   version_strr   r   r   r     s   
zDefaultClient.make_patternc                 K   s*   | j dttdd}|r|   d S d S )NCLOSE_CONNECTIONDJANGO_REDIS_CLOSE_CONNECTIONF)r6   r-   getattrr
   do_close_clients)r<   kwargs
close_flagr   r   r   close  s   
zDefaultClient.closec                 C   s4   t | j}t|D ]}| j|d q	dg| | _dS )z1default implementation: Override in custom client)rV   N)r4   r5   rN   rX   )r<   num_clientsidxr   r   r   r     s   
zDefaultClient.do_close_clientsc                 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.
        NTrr   r_   r`   )	r   r*   rg   rW   re   ri   r~   rh   r   r   r   r   r   touch  s   zDefaultClient.touch)TN)TNF)r   )r   N)rM   NN)NNN)NN)NNr   NNT)NNNNrD   )rM   NNF)9__name__
__module____qualname__r   r   r   r   rB   ri   rF   r   r   rh   rS   rW   r   rU   rX   r   floatr2   ry   rz   r-   r~   r   r   r	   r   r   r   r   rj   r   r   r   bytesr{   rf   r   r   r   r   r   r   rt   r   rE   r   r   r   r   re   r   r   r   r   r   r   r   r   r       s   #





	
@
*















7









r    )+rO   resocketcollectionsr   r   typingr   r   r   r   r   r	   django.confr
   django.core.cache.backends.baser   r   r   django.core.exceptionsr   django.utils.module_loadingr   redisr   redis.exceptionsr   r   r    r   
exceptionsr   r   utilr   r[   rk   compiler   r   r   r    r   r   r   r   <module>   s&     
