U
    cc*                     @   s   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mZ G dd deZdS )    N)OrderedDict)datetime)Union)ConnectionError   )ConnectionInterrupted)HashRing)CacheKey   )DEFAULT_TIMEOUTDefaultClientc                       s  e Zd ZedejZ fddZdd ZdEddZ	d	d
 Z
dd Zeddf fdd	ZdF fdd	ZdGddZedddf fdd	ZedfddZdHddZdI fdd	ZdJ fdd	ZdK fdd 	ZdL fd!d"	ZdM fd#d$	ZdN fd%d&	ZdOeeef d' fd(d)ZdPeeef d' fd*d+ZdQ fd.d/	ZdRd0d1ZdSd3d4Z dT fd5d6	Z!dU fd7d8	Z"dVd9d:Z#dWd;d<Z$dXd=d>Z%d?d@ Z&eddf fdAdB	Z'dYdCdDZ(  Z)S )ZShardClientz.*\{(.*)\}.*c                    sB   t  j|| t| jttfs(| jg| _t| j| _|  | _	d S N)
super__init__
isinstance_serverlisttupler   _ringconnect_serverdictselfargskwargs	__class__ U/var/www/html/project/venv/lib/python3.8/site-packages/django_redis/client/sharded.pyr      s
    
zShardClient.__init__c                 O   s   t d S r   NotImplementedErrorr   r   r   r   
get_client   s    zShardClient.get_clientr   c                 C   s$   i }| j D ]}| j|||< q
|S r   )r   connection_factoryr   )r   indexZconnection_dictnamer   r   r   r      s    
zShardClient.connectc                 C   sH   t |}| j|}|d k	r8t| dkr8| d }| j|}|S )Nr   )str	_findhashmatchlengroupsr   Zget_node)r   _keykeygr%   r   r   r   get_server_name#   s    zShardClient.get_server_namec                 C   s   |  |}| j| S r   )r.   r   )r   r,   r%   r   r   r   
get_server+   s    
zShardClient.get_serverNc                    s6   |d kr | j ||d}| |}t j|||||dS )Nversion)r,   valuer1   clienttimeout)make_keyr/   r   add)r   r,   r2   r4   r1   r3   r   r   r   r6   /   s    
    zShardClient.addc                    s4   |d kr | j ||d}| |}t j||||dS )Nr0   )r,   defaultr1   r3   )r5   r/   r   get)r   r,   r7   r1   r3   r   r   r   r8   8   s    
zShardClient.getc           	         sn   |si S t  } fdd|D }tt||}|D ]4} |} j||d}|d kr\q4|||| < q4|S )Nc                    s   g | ]} j |d qS r0   r5   .0r,   r   r1   r   r   
<listcomp>E   s     z(ShardClient.get_many.<locals>.<listcomp>r,   r1   r3   )r   dictzipr/   r8   )	r   keysr1   Zrecovered_dataZnew_keysZmap_keysr,   r3   r2   r   r=   r   get_many?   s    
zShardClient.get_manyFc                    s8   |dkr | j ||d}| |}t j||||||dS )zT
        Persist a value to the cache, and set an optional expiration time.
        Nr0   )r,   r2   r4   r1   r3   nx)r5   r/   r   set)r   r,   r2   r4   r1   r3   rD   r   r   r   rE   R   s    
     zShardClient.setc                 C   s(   |  D ]\}}| j||||d qdS )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.
        r0   N)itemsrE   )r   datar4   r1   r,   r2   r   r   r   set_many`   s    zShardClient.set_manyc              
   C   sr   |dkr | j ||d}| |}| j ||d}z||dkW S  tk
rl } zt|d|W 5 d}~X Y nX dS )z%
        Test if key exists.
        Nr0   r
   
connection)r5   r/   existsr   r   )r   r,   r1   r3   er   r   r   has_keyk   s    
zShardClient.has_keyc                    s2   |d kr | j ||d}| |}t j|||dS Nr0   r?   )r5   r/   r   deleter   r,   r1   r3   r   r   r   rO   z   s    
zShardClient.deletec                    s2   |dkr | j ||d}| |}t j|||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.
        Nr0   r?   )r5   r/   r   ttlrP   r   r   r   rQ      s    
zShardClient.ttlc                    s2   |dkr | j ||d}| |}t j|||dS )z
        Executes PTTL redis command and return the "time-to-live" of specified key
        in milliseconds. If key is a non volatile key, it returns None.
        Nr0   r?   )r5   r/   r   pttlrP   r   r   r   rR      s    
zShardClient.pttlc                    s2   |d kr | j ||d}| |}t j|||dS rN   )r5   r/   r   persistrP   r   r   r   rS      s    
zShardClient.persistc                    s4   |d kr | j ||d}| |}t j||||dS Nr0   )r,   r4   r1   r3   )r5   r/   r   expirer   r,   r4   r1   r3   r   r   r   rU      s    
zShardClient.expirec                    s4   |d kr | j ||d}| |}t j||||dS rT   )r5   r/   r   pexpirerV   r   r   r   rW      s    
zShardClient.pexpire)whenc                    s4   |dkr | j ||d}| |}t j||||dS z
        Set an expire flag on a ``key`` to ``when`` on a shard client.
        ``when`` which can be represented as an integer indicating unix
        time or a Python datetime object.
        Nr0   )r,   rX   r1   r3   )r5   r/   r   
pexpire_atr   r,   rX   r1   r3   r   r   r   rZ      s    
zShardClient.pexpire_atc                    s4   |dkr | j ||d}| |}t j||||dS rY   )r5   r/   r   	expire_atr[   r   r   r   r\      s    
zShardClient.expire_at皙?Tc                    sF   |d kr | j ||d}| |}| j ||d}t j||||||dS )Nr0   )r4   sleepr3   blocking_timeoutthread_local)r5   r/   r   lock)r   r,   r1   r4   r^   r_   r3   r`   r   r   r   ra      s    
zShardClient.lockc                    s>   d} fdd|D D ] }  |}| j||d7 }q|S )z/
        Remove multiple keys at once.
        r   c                    s   g | ]} j |d qS r9   r:   r<   kr=   r   r   r>      s     z+ShardClient.delete_many.<locals>.<listcomp>r3   )r/   rO   )r   rB   r1   resr,   r3   r   r=   r   delete_many   s
    
zShardClient.delete_manyr
   c           
   
   C   s  |d kr | j ||d}| |}|d kr0| jj}|  ||}| j|||d}z| j|||d}W n. tk
r } zt|d|W 5 d }~X Y nX |d krtd| t	|t
r| j | || d}	n| j ||| d}	| j|	||| |	d | j||d || S )Nr0   )r1   r3   rI   zKey '%s' not found)r4   r3   rd   )r5   r/   Z_backendr1   r8   rQ   r   r   
ValueErrorr   r	   Zoriginal_keyrE   rO   )
r   r,   deltar1   r3   old_keyr2   rQ   rL   Znew_keyr   r   r   incr_version   s&    

zShardClient.incr_versionc                    s4   |d kr | j ||d}| |}t j||||dS Nr0   )r,   rh   r1   r3   )r5   r/   r   incrr   r,   rh   r1   r3   r   r   r   rl     s    
zShardClient.incrc                    s4   |d kr | j ||d}| |}t j||||dS rk   )r5   r/   r   decrrm   r   r   r   rn     s    
zShardClient.decrc                 C   s   t dd S )Nz)iter_keys not supported on sharded clientr    )r   r,   r1   r   r   r   	iter_keys  s    zShardClient.iter_keysc           	   
      s    j ||d}g }z( j D ]\}}||| qW n8 tk
rr } z |}t|d|W 5 d }~X Y nX  fdd|D S )Nr0   rI   c                    s   g | ]}  | qS r   )Zreverse_keydecoderb   r   r   r   r>   !  s     z$ShardClient.keys.<locals>.<listcomp>)make_patternr   rF   extendrB   r   r/   r   )	r   searchr1   patternrB   serverrJ   rL   r3   r   rq   r   rB     s    
zShardClient.keysc                 C   s   | j |||d}d|i}|r$||d< g }| j D ]$\}}	|dd |	jf |D  q2d}
|r| j D ]\}}	|
|	j| 7 }
qj|
S )z3
        Remove all keys matching pattern.
        )r1   prefixr(   countc                 s   s   | ]
}|V  qd S r   r   r;   r   r   r   	<genexpr>0  s     z-ShardClient.delete_pattern.<locals>.<genexpr>r   )rr   r   rF   rs   Z	scan_iterrO   )r   ru   r1   r3   Zitersizerw   r   rB   rv   rJ   re   r   r   r   delete_pattern#  s    zShardClient.delete_patternc                 C   s    | j  D ]}| j|d q
d S )Nrd   )r   valuesZ
disconnect)r   r3   r   r   r   do_close_clients8  s    zShardClient.do_close_clientsc                    s4   |d kr | j ||d}| |}t j||||dS rT   )r5   r/   r   touchrV   r   r   r   r}   <  s    
zShardClient.touchc                 C   s   | j  D ]}|  q
d S r   )r   r{   Zflushdb)r   r3   rJ   r   r   r   clearC  s    zShardClient.clear)r   )NNN)N)NN)NN)NN)NN)NN)NN)NN)NN)NN)NNr]   NNT)N)r
   NN)r
   NN)r
   NN)N)N)NNNN)N)*__name__
__module____qualname__recompileIr'   r   r"   r   r.   r/   r   r6   r8   rC   rE   rH   rM   rO   rQ   rR   rS   rU   rW   r   r   intrZ   r\   ra   rf   rj   rl   rn   ro   rB   rz   r|   r}   r~   __classcell__r   r   r   r   r      sZ   	
	
   
      




       
r   )r   collectionsr   r   typingr   Zredis.exceptionsr   
exceptionsr   Z	hash_ringr   utilr	   r7   r   r   r   r   r   r   r   <module>   s   