B
    `?                 @   s   d dl Z d dlZd dlZd dlZd dlZyd dlZd dlZd dlZW n ek
r`   dZdZY nX 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mZ G dd de
ZG d	d
 d
eZdS )    N)NamespaceManager)SynchronizerImpl)SyncDictmachine_identifier)sha1)string_typePY2c                   s   e Zd ZdZdZe Z fddZdd Zdd Z	d	d
 Z
dd Zdd ZdddZdd Zdd Zdd Zdd Zdd Z  ZS )MongoNamespaceManagera^  Provides the :class:`.NamespaceManager` API over MongoDB.

    Provided ``url`` can be both a mongodb connection string or
    an already existing MongoClient instance.

    The data will be stored into ``beaker_cache`` collection of the
    *default database*, so make sure your connection string or
    MongoClient point to a default database.
    i   c                s\   t t| | d | _td kr&tdt|trFtj	|tj
|| _n|| _| j | _d S )Nzpymongo3 is not available)superr	   __init__Zlock_dirpymongoRuntimeError
isinstancer   clientsgetMongoClientclientget_default_databasedb)self	namespaceurlkw)	__class__ Z/home/kop/projects/devel/pgwui/test_venv/lib/python3.7/site-packages/beaker/ext/mongodb.pyr   $   s    
zMongoNamespaceManager.__init__c             C   sX   t |ts|d}t|| jt| j d krJts>|d}t|	 }d| j|f S )Nascii   zutf-8z%s:%s)
r   strdecodelenMAX_KEY_LENGTHr   r   encoder   	hexdigest)r   keyr   r   r   _format_key1   s    


z!MongoNamespaceManager._format_keyc             C   s   t | || jS )N)MongoSynchronizerr%   r   )r   r$   r   r   r   get_creation_lock:   s    z'MongoNamespaceManager.get_creation_lockc             C   s>   |    | jjd| |i}|d kr0t|t|d S )N_idvalue)_clear_expiredr   backer_cachefind_oner%   KeyErrorpickleloads)r   r$   entryr   r   r   __getitem__=   s
    z!MongoNamespaceManager.__getitem__c             C   s(   |    | jjd| |i}|d k	S )Nr(   )r*   r   r+   r,   r%   )r   r$   r0   r   r   r   __contains__D   s    z"MongoNamespaceManager.__contains__c             C   s   || kS )Nr   )r   r$   r   r   r   has_keyI   s    zMongoNamespaceManager.has_keyNc             C   s\   |    d }|d k	r t | }t|}| jjjd| |idt	||didd d S )Nr(   z$set)r)   
expirationT)upsert)
r*   timer.   dumpsr   r+   
update_oner%   bsonBinary)r   r$   r)   Z
expiretimer4   r   r   r   	set_valueL   s    

zMongoNamespaceManager.set_valuec             C   s   |  || d S )N)r;   )r   r$   r)   r   r   r   __setitem__Y   s    z!MongoNamespaceManager.__setitem__c             C   s$   |    | jjd| |i d S )Nr(   )r*   r   r+   delete_manyr%   )r   r$   r   r   r   __delitem__\   s    z!MongoNamespaceManager.__delitem__c             C   s    | j jddd| j ii d S )Nr(   z$regexz^%s)r   r+   r=   r   )r   r   r   r   	do_remove`   s    zMongoNamespaceManager.do_removec             C   s&   dd | j jddd| j iiD S )Nc             S   s    g | ]}|d   ddd qS )r$   :r   )split).0er   r   r   
<listcomp>d   s    z.MongoNamespaceManager.keys.<locals>.<listcomp>r(   z$regexz^%s)r   r+   Zfind_allr   )r   r   r   r   keysc   s    zMongoNamespaceManager.keysc             C   s0   t   }| jjdd| j id |dd d S )Nz$regexz^%s)z$nez$lte)r(   r4   )r6   r   r+   r=   r   )r   nowr   r   r   r*   h   s    z$MongoNamespaceManager._clear_expired)N)__name__
__module____qualname____doc__r!   r   r   r   r%   r'   r1   r2   r3   r;   r<   r>   r?   rF   r*   __classcell__r   r   )r   r   r	      s   		
r	   c                   sZ   e Zd ZdZdZe Z fddZdd Zdd Z	d	d
 Z
dd Zdd Zdd Z  ZS )r&   a  Provides a Writer/Reader lock based on MongoDB.

    Provided ``url`` can be both a mongodb connection string or
    an already existing MongoClient instance.

    The data will be stored into ``beaker_locks`` collection of the
    *default database*, so make sure your connection string or
    MongoClient point to a default database.

    Locks are identified by local machine, PID and threadid, so
    are suitable for use in both local and distributed environments.
    i  c                sJ   t t|   || _t|tr4tj|t	j
|| _n|| _| j | _d S )N)r
   r&   r   
identifierr   r   r	   r   r   r   r   r   r   r   )r   rM   r   )r   r   r   r      s    
zMongoSynchronizer.__init__c             C   s:   t j  }|t j| jd }| jj| jd|id |S )N)secondsz$lte)r(   	timestamp)datetimeutcnow	timedeltaLOCK_EXPIRATIONr   beaker_locksr=   rM   )r   rG   Zexpiredr   r   r   _clear_expired_locks   s    
z&MongoSynchronizer._clear_expired_locksc             C   s   d| j t t jf S )Nz%s-%s-%s)
MACHINE_IDosgetpid	threadingcurrent_threadident)r   r   r   r   _get_owner_id   s    zMongoSynchronizer._get_owner_idc             C   s,   |   }| jj| j|ddd|ii d S )N)r(   readersz$pullr]   )r\   r   rT   r8   rM   )r   owner_idr   r   r   do_release_read_lock   s    z&MongoSynchronizer.do_release_read_lockc             C   st   |   }|  }x^y.| jjj| jd dd|id|iddd dS  tjjk
rj   |s\dS t	
d Y qX qW d S )	N)r(   ownerrO   r]   )z$setz$pushT)r5   Fg?)rU   r\   r   rT   r8   rM   r   errorsDuplicateKeyErrorr6   sleep)r   waitrG   r^   r   r   r   do_acquire_read_lock   s    
z&MongoSynchronizer.do_acquire_read_lockc             C   s   | j j| j|  d d S )N)r(   r`   )r   rT   Z
delete_onerM   r\   )r   r   r   r   do_release_write_lock   s    z'MongoSynchronizer.do_release_write_lockc             C   sr   |   }|  }x\y,| jjj| jd g dd||didd dS  tjjk
rh   |sZdS t	
d Y qX qW d S )N)r(   r`   r]   z$set)r`   rO   T)r5   Fg?)rU   r\   r   rT   r8   rM   r   ra   rb   r6   rc   )r   rd   rG   r^   r   r   r   do_acquire_write_lock   s    z'MongoSynchronizer.do_acquire_write_lock)rH   rI   rJ   rK   rS   r   rV   r   rU   r\   r_   re   rf   rg   rL   r   r   )r   r   r&   n   s   	r&   )rP   rW   rY   r6   r.   r   Zpymongo.errorsr9   ImportErrorZbeaker.containerr   Zbeaker.synchronizationr   Zbeaker.utilr   r   Zbeaker.crypto.utilr   Zbeaker._compatr   r   r	   r&   r   r   r   r   <module>   s$   
X