o cR@sddlZddlZddlZddlZddlmZgdZeZGddde Z Gddde Z Gdd d eZ Gd d d eZ ed jZd dZddZGdddeZGdddeZGdddeZdS)N) StringType)Persist PickleBackendBPickleBackendpath_string_to_tuplepath_tuple_to_string RootedPersist PersistErrorPersistReadOnlyErrorc@ eZdZdS)r N__name__ __module__ __qualname__rr7/usr/lib/python3/dist-packages/landscape/lib/persist.pyr %r c@r )r Nr rrrrr )rr c@seZdZdZd(ddZddZddZd d ZeeeZ eeZ d d Z d dZ ddZ d)ddZeefddZd*ddZedddfddZd*ddZd+ddZd,ddZd*d d!Zeddfd"d#Zd,d$d%Zd&d'ZdS)-raPersist a hierarchical database of key=>value pairs. There are three different kinds of option maps, regarding the persistence and priority that maps are queried. - hard - Options are persistent. - soft - Options are not persistent, and have a higher priority than persistent options. - weak - Options are not persistent, and have a lower priority than persistent options. @ivar filename: The name of the file where persist data is saved or None if no filename is available. NcCsl|durt}||_||_i|_i|_d|_d|_||_||_ |dur2t j |r4| |dSdSdS)a @param backend: The backend to use. If none is specified, L{BPickleBackend} will be used. @param filename: The default filename to save to and load from. If specified, and the file exists, it will be immediately loaded. Specifying this will also allow L{save} to be called without any arguments to save the persist. NF)r_backendnew_hardmap_softmap_weakmap _readonly _modified_configfilenameospathexistsload)selfbackendrrrr__init__?s  zPersist.__init__cC|jSN)rr rrr _get_readonlyUzPersist._get_readonlycCst||_dSr$)boolr)r flagrrr _set_readonlyXzPersist._set_readonlycCr#r$rr%rrr _get_modified[r'zPersist._get_modifiedcCs d|_dS)z(Set the database status as non-modified.FNr,r%rrrreset_modifiedas zPersist.reset_modifiedcCs|jrtddS)zRAssert if the object is writable @raise: L{PersistReadOnlyError} z"Configuration is in readonly mode.N)rr r%rrrassert_writableeszPersist.assert_writablecsfdd}tjtjs|rdStdtjdkr+|dSz j_WdSt yH|rBYdStdw)zLoad a persisted database.csXd}tj|r*tj|dkr*z j|_WdSty)td|wdS)N.oldrBroken configuration file at %sTF) rrisfilegetsizerrr Exceptionr ) filepatholdfilepathr rrload_oldps  zPersist.load..load_oldNzFile not found: %srr1) rr expanduserr2r r3rrrr4)r r7r8rr6rrms      z Persist.loadcCs|dur|jdur td|j}tj|}tj|r$t||dtj|}|r7tj|s7t ||j ||j dS)zSave the persist to the given C{filepath}. If None is specified, then the filename passed during construction will be used. If the destination file already exists, it will be renamed to C{.old}. NzNeed a filename!r0) rr rrr9r2renamedirnameisdirmakedirsrsaver)r r7r;rrrr>s     z Persist.savec Cs:|tur |j|}t|}t}|}|rG|}|d}|j||}|tur@|r1|dt| }tdt |t |t |f||urEn|s||urY||urW|j |||}|S||ura|}|S t|dkrvt |dt ursg} ni} n|} |j ||| }|turtdt |t |f|s |S|}|d}qb)NrzCan't traverse %r (%r): %rTzCan't traverse %r with %r)NOTHINGrcopylistpopgetNotImplementedlenr typerstrsetint) r objrdefaultsetvaluequeuemarkernewobjelemnewvaluerrr _traversesX      zPersist._traverseFcCst|tr t|}t}|r||j||}|S|r#||j||}|S|r/||j||}|S||j||}||urO||j||}||urO||j||}|Sr$) isinstancerrr?rRrrr)r rsofthardweakrNvaluerrr _getvalues$   zPersist._getvaluec CsV|||||}t}||urdS||urdS|j||}|tur)tdt||S)NFTzCan't check %r for containment)rXr?rhasrDr rF) r rrWrTrUrVrJrNresultrrrrYsz Persist.hascCsD|||||}|turgS|j|}|tur tdt||S)NzCan't return keys for %s)rXr?rkeysrDr rF)r rrTrUrVrJrZrrrr[s z Persist.keyscCs(|||||}|tur|S|j|Sr$)rXr?rr@)r rrKrTrUrVrWrrrrCs z Persist.getcCsZ|sJt|tr t|}|r|j}n|r|j}n |d|_|j}|j|||ddSNT)rL) rSrrrrr/rrrR)r rrWrTrVmaprrrrHs z Persist.setcCs|sJt|tr t|}|r|j}n|r|j}n |d|_|j}|r7|||}t |t ur7||vr7dS|t j f}|j|||ddSr\) rSrrrrr/rrrRrFrAsysmaxsize)r rrWuniquerTrVr]currentrrradd s    z Persist.addc Cs|sJt|tr t|}|r|j}n|r|j}n |d|_|j}t}|r{||ur<| ||dd}|d}d} n | ||}|}d} d} ||urb|j ||| } | t urbt d|t|f|j |rv||uro|}n |dd}n | S|s'| S)NTFzCan't remove %r from %r)rSrrrrr/rrr?rRrremoverDr rFempty) r rrWrTrVr]rNrJrPisvaluerZrrrrdsD    zPersist.removecCs|s|s|t|trt|}t|trt|}d}t}||||p%| |}||ur?|j|||d|||||d}|S)NF)rTrVT)r/rSrrr?rXrdrH)r oldpathnewpathrTrVrZrNrWrrrmoveBs  z Persist.movecCs t||S)zv Rebase the database hierarchy. @return: A L{RootedPersist} using this L{Persist} as parent. )rr rrrrroot_atRs zPersist.root_at)NNr$FFFNFFFFF)r rr__doc__r"r&r*r-propertyreadonlymodifiedr.r/rr>r?rRrXrYr[rCrHrbrdrirkrrrrr-s,   " +   % rc@seZdZdZddZeddZeddZddZe d d d fd d Z dd d Z dddZ dddZ dddZe d d fddZdddZddZdS)raxRoot a L{Persist}'s tree at a particular branch. This class shares the same interface of L{Persist} and provides a shortcut to access the nodes of a particular branch in a L{Persist}'s tree. The chosen branch will be viewed as the root of the tree of the L{RootedPersist} and all operations will be forwarded to the parent L{Persist} as appropriate. cCs(||_t|trt||_dS||_dS)z @param parent: the parent L{Persist}. @param root: a branch of the parent L{Persist}'s tree, that will be used as root of this L{RootedPersist}. N)parentrSrrroot)r rsrtrrrr"fs  zRootedPersist.__init__cC|jjSr$)rsrqr%rrrrzRootedPersist.cCrur$)rsrrr%rrrrvsrwcCs|jdSr$)rsr/r%rrrr/ur+zRootedPersist.assert_writableFcC,t|tr t|}|j|j|||||Sr$)rSrrrsrYrt)r rrWrTrUrVrrrrYx zRootedPersist.hascC*t|tr t|}|j|j||||Sr$)rSrrrsr[rt)r rrTrUrVrrrr[} zRootedPersist.keysNcCrxr$)rSrrrsrCrt)r rrKrTrUrVrrrrCryzRootedPersist.getcCrzr$)rSrrrsrHrtr rrWrTrVrrrrHr{zRootedPersist.setcCrxr$)rSrrrsrbrt)r rrWr`rTrVrrrrbryzRootedPersist.addcCrzr$)rSrrrsrdrtr|rrrrdr{zRootedPersist.removecCsBt|tr t|}t|trt|}|j|j||j|||Sr$)rSrrrsrirt)r rgrhrTrVrrrris  zRootedPersist.movecCs$t|tr t|}|j|j|Sr$)rSrrrsrkrtrjrrrrks zRootedPersist.root_atrlrmrn)r rrror"rprqrrr/r?rYr[rCrHrbrdrirkrrrrr[s       rz(\[-?\d+\])|(?|ddkr>z |t|ddWqty=td|w||ddqt|S) aConvert a L{Persist} path string to a path tuple. Examples: >>> path_string_to_tuple("ab") ("ab",) >>> path_string_to_tuple("ab.cd") ("ab", "cd")) >>> path_string_to_tuple("ab[0][1]") ("ab", 0, 1) >>> path_string_to_tuple("ab[0].cd[1]") ("ab", 0, "cd", 1) Raises L{PersistError} if the given path string is invalid. .[rrc]zInvalid path index: %r\.) _splitpathappendrI ValueErrorr replacetuple)rrZtokenstokenrrrrs  rcCsPg}|D]}t|tur|dd|7<q|t|ddqd|S)Nrcz[%d]r}r)rFrIrrGrjoin)rrZrPrrrrs   rc@sdeZdZdZddZddZddZefdd Zd d Z d d Z ddZ ddZ ddZ ddZdS)BackendaD Base class for L{Persist} backends implementing hierarchical storage functionality. Each node of the hierarchy is an object of type C{dict}, C{list} or C{tuple}. A node can have zero or more children, each child can be another node or a leaf value compatible with the backend's serialization mechanism. Each child element is associated with a unique key, that can be used to get, set or remove the child itself from its containing node. If the node object is of type C{dict}, then the child keys will be the keys of the dictionary, otherwise if the node object is of type C{list} or C{tuple} the child element keys are the indexes of the available items, or the value of items theselves. The root node object is always a C{dict}. For example: >>> backend = Backend() >>> root = backend.new() >>> backend.set(root, "foo", "bar") 'bar' >>> egg = backend.set(root, "egg", [1, 2, 3]) >>> backend.set(egg, 0, 10) 10 >>> root {'foo': 'bar', 'egg': [10, 2, 3]} cCtr$NotImplementedErrorr%rrrrz Backend.newcCrr$r)r r7rrrrrz Backend.loadcCrr$r)r r7r]rrrr>rz Backend.savecCst|tur|||}|St|ttfvr1sz"Backend.remove..N)rFrrArIrrD)r rJrPrfrZrrrrds,   zBackend.removecCst|ttfvr t|S|S)zCopy a node or a value.)rFrrAr@deepcopy)r rWrrrr@7s z Backend.copycCs| S)z.Whether the given node object has no children.r)r rJrrrre=sz Backend.emptycCst|dd}|r ||StS)z?Whether the given node object contains the given child element. __contains__N)getattrrD)r rJrPcontainsrrrrYAs z Backend.hascCs2t|dd}|r |St|turtt|StS)z?Return the keys of the child elements of the given node object.r[N)rrFrArangerErD)r rJr[rrrr[Hs   z Backend.keysN)r rrrorrr>r?rCrHrdr@rerYr[rrrrrs  rc@,eZdZddZddZddZddZd S) rcCddlm}||_dS)Nr)cPickle)landscape.lib.compatr_pickle)r rrrrr"T  zPickleBackend.__init__cCiSr$rr%rrrrXrzPickleBackend.newcCs:t|d}|j|WdS1swYdSNrb)openrrr r7fdrrrr[s  $zPickleBackend.loadcCs@t|d}|j||dWddS1swYdS)Nwb)rrdumpr r7r]rrrrr>_s "zPickleBackend.saveNr rrr"rrr>rrrrrR  rc@r) rcCr)Nr)bpickle) landscape.libr_bpickle)r rrrrr"frzBPickleBackend.__init__cCrr$rr%rrrrjrzBPickleBackend.newcCs>t|d}|j|WdS1swYdSr)rrloadsreadrrrrrms $zBPickleBackend.loadcCsBt|d}||j|WddS1swYdS)Nr)rwriterdumpsrrrrr>qs "zBPickleBackend.saveNrrrrrrdrr)rr^r@retwisted.python.compatr__all__objectr?r4r r rrcompilesplitrrrrrrrrrrs( 0 I