ó
ˆ>m^c           @  s  d  Z  d d l m Z d Z y d d l m Z Wn! e k
 rS d d l m Z n Xd d l Z d d l	 Z	 d d l
 Z
 y d d l j Z Wn e k
 rª d d l Z n Xy d d l Z Wn e k
 rÚ d d l Z n Xd d l Z d d l Z e j d d k re f Z n e e f Z d „  Z e ƒ  Z d	 e j f d
 „  ƒ  YZ d d d „  ƒ  YZ d „  Z e d k r{e ƒ  n  d S(   s   PickleShare - a small 'shelve' like datastore with concurrency support

Like shelve, a PickleShareDB object acts like a normal dictionary. Unlike
shelve, many processes can access the database simultaneously. Changing a
value in database is immediately visible to other processes accessing the
same database.

Concurrency is possible because the values are stored in separate files. Hence
the "database" is a directory where *all* files are governed by PickleShare.

Example usage::

    from pickleshare import *
    db = PickleShareDB('~/testpickleshare')
    db.clear()
    print "Should be empty:",db.items()
    db['hello'] = 15
    db['aku ankka'] = [1,2,313]
    db['paths/are/ok/key'] = [1,(5,46)]
    print db.keys()
    del db['aku ankka']

This module is certainly not ZODB, but can be used for low-load
(non-mission-critical) situations where tiny code size trumps the
advanced features of a "real" object database.

Installation guide: pip install pickleshare

Author: Ville Vainio <vivainio@gmail.com>
License: MIT open source license.

iÿÿÿÿ(   t   print_functions   0.7.5(   t   PathNi    i   c         C  s   d t  t |  ƒ d ƒ d S(   Ns   %02xi   iþÿÿÿ(   t   abst   hash(   t   key(    (    s*   lib/python2.7/site-packages/pickleshare.pyt   gethashfile@   s    t   PickleShareDBc           B  sª   e  Z d  Z d „  Z d „  Z d „  Z d „  Z e e d „ Z	 d „  Z
 d „  Z d „  Z d	 „  Z d d
 „ Z d „  Z d „  Z d „  Z d d „ Z d „  Z d „  Z RS(   s7    The main 'connection' object for PickleShare database c         C  s¯   t  | t ƒ s t | ƒ } n  t j j t j j | ƒ ƒ } t | ƒ |  _ |  j j	 ƒ  s¢ y |  j j
 d t ƒ Wq¢ t k
 rž } | j t j k rŸ ‚  qŸ q¢ Xn  i  |  _ d S(   s:    Return a db object that will manage the specied directoryt   parentsN(   t
   isinstancet   string_typest   strt   ost   patht   abspatht
   expanduserR   t   roott   is_dirt   mkdirt   Truet   OSErrort   errnot   EEXISTt   cache(   t   selfR   t   e(    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __init__G   s    c         C  s×   |  j  | } y | j ƒ  t j } Wn t k
 rC t | ƒ ‚ n X| |  j k ry | |  j | d k ry |  j | d Sy1 | j d ƒ  } t j | j	 ƒ  ƒ } Wd QXWn t | ƒ ‚ n X| | f |  j | <| S(   s    db['key'] reading i   i    t   rbN(
   R   t   statt   ST_MTIMER   t   KeyErrorR   t   opent   picklet   loadst   read(   R   R   t   filt   mtimet   ft   obj(    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __getitem__Y   s    &c      	   C  s¼   |  j  | } | j } | r< | j ƒ  r< | j d t ƒ n  | j d ƒ  } t j | | d d ƒWd QXy  | | j ƒ  j	 f |  j
 | <Wn+ t k
 r· } | j t j k r¸ ‚  q¸ n Xd S(   s    db['key'] = 5 R   t   wbt   protocoli   N(   R   t   parentR   R   R   R   R   t   dumpR   t   st_mtimeR   R   R   t   ENOENT(   R   R   t   valueR"   R)   R$   R   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __setitem__m   s    	 c         C  sj   |  j  | } | j ƒ  s& | j ƒ  n  | t | ƒ } |  j | i  ƒ } | j i | | 6ƒ | |  | <d S(   s    hashed set N(   R   R   R   R   t   gett   update(   R   t   hashrootR   R-   t   hroott   hfilet   d(    (    s*   lib/python2.7/site-packages/pickleshare.pyt   hset}   s    c         C  s‚   |  j  | } | t | ƒ } |  j | t ƒ } | t k rr | r` | t k r\ t | ƒ ‚ n  | S|  j | ƒ } n  | j | | ƒ S(   s    hashed get (   R   R   R/   t	   _sentinelR   t   hdict(   R   R1   R   t   defaultt	   fast_onlyR2   R3   R4   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   hget‰   s    c         C  sÄ   |  j  | d ƒ } | j ƒ  t | ƒ r3 | d p6 d } | j d ƒ r\ | g | d  } n  i  } x[ | D]S } y | j |  | ƒ Wn( t k
 r® t d | d ƒ |  | =n X|  j | ƒ qi W| S(   s>    Get all data contained in hashed category 'hashroot' as dict s   /*iÿÿÿÿt    t   xxt   Corrupts!   deleted - hset is not threadsafe!(   t   keyst   sortt   lent   endswithR0   R   t   printt   uncache(   R   R1   t   hfilest   lastt   allR$   (    (    s*   lib/python2.7/site-packages/pickleshare.pyR7   œ   s    
c         C  s—   |  j  | d ƒ } i  } x, | D]$ } | j |  | ƒ |  j | ƒ q  W| |  | d <x: | D]2 } |  j | } | j d k r… q] n  | j ƒ  q] Wd S(   s«    Compress category 'hashroot', so hset is fast again

        hget will fail if fast_only is True for compressed items (that were
        hset before hcompress).

        s   /*s   /xxR<   N(   R>   R0   RC   R   t   namet   unlink(   R   R1   RD   RF   R$   t   p(    (    s*   lib/python2.7/site-packages/pickleshare.pyt	   hcompress³   s    c         C  sF   |  j  | } |  j j | d ƒ y | j ƒ  Wn t k
 rA n Xd S(   s    del db["key"] N(   R   R   t   popt   NoneRH   R   (   R   R   R"   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __delitem__Ê   s    c         C  s"   t  | j |  j ƒ ƒ j d d ƒ S(   s%    Make a key suitable for user's eyes s   \t   /(   R
   t   relative_toR   t   replace(   R   RI   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   _normalizedÕ   s    c         C  s_   | d k r! |  j j d ƒ } n |  j j | ƒ } g  | D]! } | j ƒ  r: |  j | ƒ ^ q: S(   s,    All keys in DB, or all keys matching a globt   *N(   RL   R   t   rglobt   globt   is_fileRQ   (   R   t   globpatt   filesRI   (    (    s*   lib/python2.7/site-packages/pickleshare.pyR>   Ù   s    c         C  s   t  |  j ƒ  ƒ S(   N(   t   iterR>   (   R   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __iter__â   s    c         C  s   t  |  j ƒ  ƒ S(   N(   R@   R>   (   R   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __len__å   s    c         G  s:   | s i  |  _  n  x! | D] } |  j  j | d ƒ q Wd S(   sË    Removes all, or specified items from cache

        Use this after reading a large amount of large objects
        to free up memory, when you won't be needing the objects
        for a while.

        N(   R   RK   RL   (   R   t   itemst   it(    (    s*   lib/python2.7/site-packages/pickleshare.pyRC   è   s    i<   c         C  s¹   d g d d g d d g } d } d } x‡ y |  | } | SWn t  k
 rS n X| | k ro t  | ƒ ‚ n  t j | | ƒ | | | 7} | t | ƒ d k  r. | d 7} q. q. Wd S(   s   Wait (poll) for a key to get a value

        Will wait for `maxwaittime` seconds before raising a KeyError.
        The call exits normally if the `key` field in db gets a value
        within the timeout period.

        Use this for synchronizing different processes or for ensuring
        that an unfortunately timed "db['key'] = newvalue" operation
        in another process (which causes all 'get' operation to cause a
        KeyError for the duration of pickling) won't screw up your program
        logic.
        gš™™™™™É?i   g      à?i   i   i    N(   R   t   timet   sleepR@   (   R   R   t   maxwaittimet   wtimest   triest   waitedt   val(    (    s*   lib/python2.7/site-packages/pickleshare.pyt   waitgetõ   s    
c         C  s   t  |  | ƒ S(   s,    Get a convenient link for accessing items  (   t   PickleShareLink(   R   t   folder(    (    s*   lib/python2.7/site-packages/pickleshare.pyt   getlink  s    c         C  s   d |  j  S(   Ns   PickleShareDB('%s')(   R   (   R   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __repr__  s    N(   t   __name__t
   __module__t   __doc__R   R&   R.   R5   R6   R   R:   R7   RJ   RM   RQ   RL   R>   RY   RZ   RC   Rd   Rg   Rh   (    (    (    s*   lib/python2.7/site-packages/pickleshare.pyR   E   s"   												 	Re   c           B  s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   sÜ    A shortdand for accessing nested PickleShare data conveniently.

    Created through PickleShareDB.getlink(), example::

        lnk = db.getlink('myobjects/test')
        lnk.foo = 2
        lnk.bar = lnk.foo + 5

    c         C  s   |  j  j t ƒ  ƒ d  S(   N(   t   __dict__R0   t   locals(   R   t   dbt   keydir(    (    s*   lib/python2.7/site-packages/pickleshare.pyR   (  s    c         C  s   |  j  d |  j  d d | S(   NRn   Ro   RN   (   Rl   (   R   R   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __getattr__+  s    c         C  s   | |  j  |  j d | <d  S(   NRN   (   Rn   Ro   (   R   R   Rc   (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   __setattr__-  s    c         C  sd   |  j  d } | j |  j  d d ƒ } d |  j  d d j g  | D] } t | ƒ j ƒ  ^ qA ƒ f S(   NRn   Ro   s   /*s   <PickleShareLink '%s': %s>t   ;(   Rl   R>   t   joinR   t   basename(   R   Rn   R>   t   k(    (    s*   lib/python2.7/site-packages/pickleshare.pyRh   /  s
    
(   Ri   Rj   Rk   R   Rp   Rq   Rh   (    (    (    s*   lib/python2.7/site-packages/pickleshare.pyRe     s
   				c          C  s‚  d d  l  }  |  j d ƒ } t } d d  l } t | j ƒ d k  rP t | ƒ d  S| j d } | j d } | d k rº | sˆ d g } n  | | d ƒ } d d  l } | j | j ƒ  ƒ nÄ | d k r%| j	 j
 ƒ  } | | d ƒ } t | ƒ }	 | j ƒ  x€ | j ƒ  D] \ }
 } | | |
 <qWnY | d	 k ra| | d ƒ } | j ƒ  t | j d
 ƒ ƒ n | d k r~t ƒ  t ƒ  n  d  S(   NiÿÿÿÿsÅ       pickleshare - manage PickleShare databases

    Usage:

        pickleshare dump /path/to/db > dump.txt
        pickleshare load /path/to/db < dump.txt
        pickleshare test /path/to/db
    i   i   R*   t   .i    t   loadt   testwaitt   250t   test(   t   textwrapt   dedentR   t   sysR@   t   argvRB   t   pprintR[   t   stdinR!   t   evalt   clearRd   Rz   t   stress(   R{   t   usaget   DBR}   t   cmdt   argsRn   R   t   contt   dataRu   t   v(    (    s*   lib/python2.7/site-packages/pickleshare.pyt   main6  s<    	
 

t   __main__(    (   Rk   t
   __future__R    t   __version__t   pathlibR   t   ImportErrort   pathlib2R   R   R]   t   collections.abct   abct   collections_abct   collectionst   cPickleR   R   R}   t   version_infoR
   R	   t   unicodeR   t   objectR6   t   MutableMappingR   Re   R‹   Ri   (    (    (    s*   lib/python2.7/site-packages/pickleshare.pyt   <module>"   s6   $		Ù	'