
    VzPg&                        d Z ddlmZ dZ	 ddlmZ n# e$ r	 ddlmZ Y nw xY wddlZddl	Z	ddl
Z
	 ddlmZ n# e$ r ddlZY nw xY w	 ddlZn# e$ r ddlZY nw xY wd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 G d d	ej                  Z G d
 d          Zd Zedk    r e             dS dS )a   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.

    )print_functionz0.7.5)PathN   c                 V    dt          t          |           dz            z  dd          S )Nz%02x   )abshash)keys    +lib/python3.11/site-packages/pickleshare.pygethashfiler   @   s(    ScS)))233//    c                   |    e Zd ZdZd Zd Zd Zd Zedf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dS )PickleShareDBz7 The main 'connection' object for PickleShare database c                    t          |t                    st          |          }t          j                            t          j                            |                    }t          |          | _        | j        	                                sJ	 | j        
                    d           n-# t          $ r }|j        t          j        k    r Y d}~nd}~ww xY wi | _        dS )z: Return a db object that will manage the specied directoryTparentsN)
isinstancestring_typesstrospathabspath
expanduserr   rootis_dirmkdirOSErrorerrnoEEXISTcache)selfr   es      r   __init__zPickleShareDB.__init__G   s    $-- 	t99Dwrw11$7788JJ	y!! 		----   7el** +**** 


s   B+ +
C5CCc                    | j         |z  }	 |                                t          j                 }n# t          $ r t	          |          w xY w|| j        v r*|| j        |         d         k    r| j        |         d         S 	 |                    d          5 }t          j        |	                                          }ddd           n# 1 swxY w Y   n#  t	          |          xY w||f| j        |<   |S )z db['key'] reading    r   rbN)
r   statST_MTIMEr   KeyErrorr!   openpickleloadsread)r"   r   filmtimefobjs         r   __getitem__zPickleShareDB.__getitem__Y   s,   i#o	 XXZZ.EE 	  	  	 3--	  $*$*S/!*<!<!<:c?1%%	 $ -1l16688,,- - - - - - - - - - - - - - -	 3--u+
3
s9   $1 AC 'C
>C 
CC CC C'c                    | j         |z  }|j        }|r*|                                s|                    d           |                    d          5 }t          j        ||d           ddd           n# 1 swxY w Y   	 ||                                j        f| j	        |<   dS # t          $ r!}|j        t          j        k    r Y d}~dS d}~ww xY w)z db['key'] = 5 Tr   wb   )protocolN)r   parentr   r   r+   r,   dumpr(   st_mtimer!   r   r   ENOENT)r"   r   valuer/   r8   r1   r#   s          r   __setitem__zPickleShareDB.__setitem__m   s#   i#o 	'&--// 	'LLL&&& XXd^^ 	.qKq1----	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.	$chhjj&9:DJsOOO 	 	 	w%,&& '&&&&&	s*   A77A;>A;#B( (
C2CCc                     | j         |z  }|                                s|                                 |t          |          z  }|                     |i           }|                    ||i           || |<   dS )z hashed set N)r   r   r   r   getupdate)r"   hashrootr   r<   hroothfileds          r   hsetzPickleShareDB.hset}   ss    	H$||~~ 	KKMMMC(((HHUB	3-   Ur   Tc                    | j         |z  }|t          |          z  }|                     |t                    }|t          u r1|r|t          u rt	          |          |S |                     |          }|                    ||          S )z hashed get )r   r   r?   	_sentinelr*   hdict)r"   rA   r   default	fast_onlyrB   rC   rD   s           r   hgetzPickleShareDB.hget   s    	H$C(((HHUI''	>> i''"3--' 

8$$AuuS'"""r   c                    |                      |dz             }|                                 t          |          r|d         pd}|                    d          r|g|dd         z   }i }|D ]X}	 |                    | |                    n$# t
          $ r t          d|d           | |= Y nw xY w|                     |           Y|S )z> Get all data contained in hashed category 'hashroot' as dict /* xxNCorruptz!deleted - hset is not threadsafe!)keyssortlenendswithr@   r*   printuncache)r"   rA   hfileslastallr1   s         r   rH   zPickleShareDB.hdict   s    8d?++6{{)vbz/R== 	*VfSbSk)F 	 	A

47####   i"EFFFGGG LLOOOO
s   0BB-,B-c                    |                      |dz             }i }|D ]2}|                    | |                    |                     |           3|| |dz   <   |D ],}| j        |z  }|j        dk    r|                                 -dS )z Compress category 'hashroot', so hset is fast again

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

        rM   z/xxrP   N)rR   r@   rW   r   nameunlink)r"   rA   rX   rZ   r1   ps         r   	hcompresszPickleShareDB.hcompress   s     8d?++ 	 	AJJtAwLLOOOO!$X 	 	A	AAv~~HHJJJJ		 	r   c                     | j         |z  }| j                            |d           	 |                                 dS # t          $ r Y dS w xY w)z del db["key"] N)r   r!   popr]   r   )r"   r   r/   s      r   __delitem__zPickleShareDB.__delitem__   s]    i#o
s4   	JJLLLLL 	 	 	 DD	s   = 
A
Ac                 x    t          |                    | j                                                dd          S )z% Make a key suitable for user's eyes \/)r   relative_tor   replace)r"   r^   s     r   _normalizedzPickleShareDB._normalized   s.    1==++,,44T#>>>r   Nc                      | j                             d          }n j                             |          } fd|D             S )z, All keys in DB, or all keys matching a globN*c                 b    g | ]+}|                                                     |          ,S  )is_filerh   ).0r^   r"   s     r   
<listcomp>z&PickleShareDB.keys.<locals>.<listcomp>   s4    BBBaiikkB  ##BBBr   )r   rglobglob)r"   globpatfiless   `  r   rR   zPickleShareDB.keys   sL     ?IOOC((EEINN7++EBBBBUBBBBr   c                 D    t          |                                           S N)iterrR   r"   s    r   __iter__zPickleShareDB.__iter__   s    DIIKK   r   c                 D    t          |                                           S ru   )rT   rR   rw   s    r   __len__zPickleShareDB.__len__   s    499;;r   c                 X    |si | _         |D ]}| j                             |d           dS )z 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!   ra   )r"   itemsits      r   rW   zPickleShareDB.uncache   sE      	DJ 	$ 	$BJNN2d####	$ 	$r   <   c                    dgdz  dgdz  z   dgz   }d}d}	 	 | |         }|S # t           $ r Y nw xY w||k    rt          |          t          j        ||                    |||         z  }|t          |          dz
  k     r|dz  }q)a   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?r   g      ?r6   r&   r   )r*   timesleeprT   )r"   r   maxwaittimewtimestrieswaitedvals          r   waitgetzPickleShareDB.waitget   s     cUQY&!,	3i
    ##smm#Jve}%%%F5M!Fs6{{A~%%q	s   	" 
//c                 "    t          | |          S )z, Get a convenient link for accessing items  )PickleShareLink)r"   folders     r   getlinkzPickleShareDB.getlink  s    tV,,,r   c                     d| j         z  S )NzPickleShareDB('%s'))r   rw   s    r   __repr__zPickleShareDB.__repr__  s    $ty00r   ru   )r~   )__name__
__module____qualname____doc__r$   r3   r=   rE   rG   rK   rH   r_   rb   rh   rR   rx   rz   rW   r   r   r   rl   r   r   r   r   E   s%       AA  $  (      -64 # # # #&  .  .	 	 	? ? ?C C C C! ! !     $ $ $   @- - -1 1 1 1 1r   r   c                   *    e Zd ZdZd Zd Zd Zd ZdS )r   z 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                 R    | j                             t                                 d S ru   )__dict__r@   locals)r"   dbkeydirs      r   r$   zPickleShareLink.__init__(  s"    VXX&&&&&r   c                 J    | j         d         | j         d         dz   |z            S )Nr   r   re   )r   )r"   r   s     r   __getattr__zPickleShareLink.__getattr__+  s%    }T"4=#:3#>#DEEr   c                 0    || j         | j        dz   |z   <   d S )Nre   )r   r   )r"   r   r   s      r   __setattr__zPickleShareLink.__setattr__-  s    ),C#%&&&r   c                     | j         d         }|                    | j         d         dz             }d| j         d         dd                    d |D                       dS )	Nr   r   rM   z<PickleShareLink 'z': ;c                 P    g | ]#}t          |                                          $S rl   )r   basename)rn   ks     r   ro   z,PickleShareLink.__repr__.<locals>.<listcomp>4  s*    777Qd1gg&&((777r   >)r   rR   join)r"   r   rR   s      r   r   zPickleShareLink.__repr__/  sk    ]4 wwh/566M(###HH77$7778888: 	:r   N)r   r   r   r   r$   r   r   r   rl   r   r   r   r     s]         ' ' 'F F F- - -: : : : :r   r   c                  8   dd l } |                     d          }t          }dd l}t	          |j                  dk     rt          |           d S |j        d         }|j        dd          }|dk    rC|sdg} ||d                   }dd l}|                    |                                           d S |dk    rn|j	        
                                } ||d                   }t          |          }	|                                 |                                D ]
\  }
}|||
<   d S |dk    rI ||d                   }|                                 t          |                    d	                     d S |d
k    rt                       t                       d S d S )Nr   z    pickleshare - manage PickleShare databases

    Usage:

        pickleshare dump /path/to/db > dump.txt
        pickleshare load /path/to/db < dump.txt
        pickleshare test /path/to/db
    r6   r&   r9   .loadtestwait250test)textwrapdedentr   sysrT   argvrV   pprintr|   stdinr.   evalclearr   r   stress)r   usageDBr   cmdargsr   r   contdatar   vs               r   mainr   6  s   OOOOO  	 	E 
BJJJ
38}}qe
(1+C8ABB<D
f}} C5TRQ[[bhhjj!!!!!	y~~RQ[[Dzz



88:: 	 	CAaBqEE	 		
		RQ[[



bjj     	 
r   __main__)r   
__future__r   __version__pathlibr   ImportErrorpathlib2r   r(   r   collections.abcabccollections_abccollectionscPickler,   r   r   version_infor   r   unicoder   objectrG   MutableMappingr   r   r   r   rl   r   r   <module>r      s   B & % % % % %                *------- * * *))))))*   MMMMM  



A!6LL>L0 0 0 FHH	U1 U1 U1 U1 U1O2 U1 U1 U1r: : : : : : : :0% % %N jDFFFFF s-    !!8 	AAA 	AA