~eLRddlZddlZddlZddlZddlmZgdZeZGdde Z Gdde Z Gdd Z Gd d Z ejd jZd ZdZGddZGddeZGddeZy)N) StringType)Persist PickleBackendBPickleBackendpath_string_to_tuplepath_tuple_to_string RootedPersist PersistErrorPersistReadOnlyErrorc eZdZy)r N__name__ __module__ __qualname__7/usr/lib/python3/dist-packages/landscape/lib/persist.pyr r ,rr c eZdZy)r Nr rrrr r 0rrr ceZdZdZddZdZdZdZeeeZ eeZ dZ dZ d Z dd Zeefd Zdd Zed d d fdZddZddZddZddZed d fdZddZdZy)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. Nc| t}||_|j|_i|_i|_d|_d|_||_||_ |2tjj|r|j|yyy)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)selfbackendr s r__init__zPersist.__init__Fsx ?$&G         BGGNN8$< IIh %= rc|jSN)rr%s r _get_readonlyzPersist._get_readonly\ ~~rc$t||_yr))boolr)r%flags r _set_readonlyzPersist._set_readonly_s drc|jSr)rr*s r _get_modifiedzPersist._get_modifiedbr,rcd|_y)z(Set the database status as non-modified.FNr2r*s rreset_modifiedzPersist.reset_modifiedhs rc2|jr tdy)zRAssert if the object is writable @raise: L{PersistReadOnlyError} z"Configuration is in readonly mode.N)rr r*s rassert_writablezPersist.assert_writablels >>&'KL L rcfd}tjjtjjs|ryt dtjj dk(r|y j j_y#t$r|rYyt dwxYw)zLoad a persisted database.c dz}tjj|rDtjj|dkDr" jj |_yy#t$rtd|wxYw)N.oldrBroken configuration file at TF) r!r"isfilegetsizerr$r Exceptionr ) filepatholdfilepathr%s rload_oldzPersist.load..load_oldws}"V+K{+GGOOK014 $(MM$6$6{$CDM  !&7 }Es A++BNzFile not found: rr;) r!r" expanduserr<r r=rr$rr>)r%r@rAs`` rr$z Persist.loadts $77%%h/ww~~h'z!1(<= = 77??8 $ ) J  K MM..x8DM Kz!>xjIJ J Ks B))C ;C c|#|j td|j}tjj |}tjj |rtj ||dztjj|}|r4tjj|stj||jj||jy)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!r:) r r r!r"rBr<renamedirnameisdirmakedirsrsaver)r%r@rEs rrHz Persist.saves  }}$"#566}}H77%%h/ 77>>( # IIh6 1 2''//(+ 277==1 KK  8T]]3rc |tur|jj|}t|}t}|}|r|}|j d}|jj ||}|t ur@|r|dt| }tdt|dt|dt|||urn|r||ur#||ur|jj||}|S||ur|}|S t|dkDrt|dturg} ni} n|} |jj|| }|t ur#tdt|dt||s |S|}|j d})NrzCan't traverse z (z): z with )NOTHINGrcopylistpopgetNotImplementedlenr typerstrsetint) r%objr"defaultsetvaluequeuemarkernewobjelemnewvalues r _traversezPersist._traverses 7 "}}))(3HT C99QS0')H')H#+!]]..sD(CF/*-d3i];$$(J>3! !C 99Q|j |j ||}||ur|j |j||}|Sr)) isinstancerrrJr]rrr)r%r"softhardweakrYvalues r _getvaluezPersist._getvalues dJ ''-D NN4==$?E NN4==$?E NN4==$?E NN4==$?Et}}dFCF? NN4==$GE rc|j||||}t}||ury||ury|jj||}|turt dt |d|S)NFTz Can't check z for containment)rdrJrhasrOr rQ) r%r"rcr`rarbrUrYresults rrfz Persist.hassknnT4t4 &= f_""3. ^ #d3i]:JKL L rc|j||||}|turgS|jj|}|turt dt ||S)NzCan't return keys for )rdrJrkeysrOr rQ)r%r"r`rarbrUrgs rriz Persist.keyssZnnT4t4 '>I##C( ^ #!7S {CD D rct|j||||}|tur|S|jj|Sr))rdrJrrK)r%r"rVr`rarbrcs rrNz Persist.gets8tT46 G N}}!!%((rc|sJt|tr t|}|r |j}n2|r |j}n#|j d|_|j}|j|||yNT)rW) r_rrrrr7rrr])r%r"rcr`rbmaps rrSz Persist.setsc t dJ ''-D --C --C  "!DN--C sD51rch|sJt|tr t|}|r |j}n2|r |j}n#|j d|_|j}|r(|j||}t|tur||vry|tjfz}|j|||yrl) r_rrrrr7rrr]rQrLsysmaxsize)r%r"rcuniquer`rbrmcurrents raddz Persist.adds t dJ ''-D --C --C  "!DN--C nnS$/GG}$')9s{{n$ sD51rc>|sJt|tr t|}|r |j}n2|r |j}n#|j d|_|j}t}|r||ur|j||dd}|d}d} n|j||}|}d} d} ||urI|jj||| } | tur$tdj|t||jj!|r ||ur|}n |dd}n | S|r S)NTFzCan't remove {!r} from {!r})r_rrrrr7rrrJr]rremoverOr formatrQempty) r%r"rcr`rbrmrYrUr[isvaluergs rrvzPersist.remove)s, t dJ ''-D --C --C  "!DN--CnnS$s)4BxnnS$/F& --c4A^+&5<zRootedPersist.T[[%9%9rc.|jjSr))rrr*s rrzRootedPersist.rrc8|jjyr))rr7r*s rr7zRootedPersist.assert_writables ##%rFct|tr t|}|jj |j |z||||Sr))r_rrrrfr)r%r"rcr`rarbs rrfzRootedPersist.hass: dJ ''-D{{tyy4/dDIIrct|tr t|}|jj |j |z|||Sr))r_rrrrir)r%r"r`rarbs rrizRootedPersist.keyss: dJ ''-D{{ D 0$dCCrNct|tr t|}|jj |j |z||||Sr))r_rrrrNr)r%r"rVr`rarbs rrNzRootedPersist.gets: dJ ''-D{{tyy4/$dKKrct|tr t|}|jj |j |z|||Sr))r_rrrrSrr%r"rcr`rbs rrSzRootedPersist.sets8 dJ ''-D{{tyy4/dCCrct|tr t|}|jj |j |z||||Sr))r_rrrrsr)r%r"rcrqr`rbs rrszRootedPersist.adds: dJ ''-D{{tyy4/dKKrct|tr t|}|jj |j |z|||Sr))r_rrrrvrrs rrvzRootedPersist.removes: dJ ''-D{{!!$))d"2E4FFrct|tr t|}t|tr t|}|jj |j |z|j |z||Sr))r_rrrr}r)r%r{r|r`rbs rr}zRootedPersist.moves_ gz **73G gz **73G{{ II  II      rct|tr t|}|jj |j |zSr))r_rrrrrrs rrzRootedPersist.root_ats4 dJ ''-D{{""499t#344rrrr)rrrrr'rrrr7rJrfrirNrSrsrvr}rrrrr r hsk 9:H9:H&&EEJ D L D L ")u5G  5rr z(\[-?\d+\])|(?>> 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. .[rru]zInvalid path index: \.) _splitpathappendrT ValueErrorr replacetuple)r"rgtokenstokens rrrs  $3d?w F  F9 Qx359#3IMM#eAbk"23 emmE3789 = "I&)=eY'GHHIs A>>Bcg}|D]P}t|tur|dxxd|ddz cc<'|jt|j ddRdj |S)Nrurdrrr)rQrTrrRrjoin)r"rgr[s rrrsh F9 :  2JAd1XQ- 'J MM#d)++C7 8 9 88F rcPeZdZdZdZdZdZefdZdZ dZ dZ d Z d Z d Zy ) 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]} ctr)NotImplementedErrorr*s rrz Backend.new!!rctr)r)r%r@s rr$z Backend.loadrrctr)r)r%r@rms rrHz Backend.saverrct|tur|j||}|St|ttfvr%t|t ur ||}|S||vr|}|S|}|St}|S#t $r|}Y|SwxYw)z(Lookup a child in the given node object.)rQdictrNrrLrT IndexErrorrO)r%rUr[_markerrZs rrNz Backend.get s 9 WWT7+F #Y5$- 'DzS % YF   ! $F "%$F %sA** A98A9c2t|tur |x}||<|St|turet|turTt |}||kr|j d|}n'|dkr"t ||kDr|jddd}|x}||<|St}|S)z:Set the value of the given child in the given node object.Nr) rQrrLrTrPrabsinsertrO)r%rUr[rcrZlenobjs rrSz Backend.sets 9 !& &FSY #Y$ 4:#4XF~ 4 c$i&0 1d#!& &FSY $F rcd}t|tur ||vr||=d}|St|tur<|st|tur ||=d}|S||vr|Dcgc] }||k7s | c}|ddd}|St }|S#t$rY|SwxYwcc}w)zRemove a the given child in the given node object. @param isvalue: In case the node object is a C{list}, a boolean indicating if C{elem} is the index of the child or the value of the child itself. FTN)rQrrLrTrrO)r%rUr[ryrgxs rrvzBackend.remove.s 9 s{I #Y$ tDzS0D !F %(6AI!6A $F "  7sA4 BB4 BBc^t|ttfvrtj|S|S)zCopy a node or a value.)rQrrLrKdeepcopy)r%rcs rrKz Backend.copyHs& ;4, &==' ' rc| S)z.Whether the given node object has no children.r)r%rUs rrxz Backend.emptyNs wrc<t|dd}|r||StS)z?Whether the given node object contains the given child element. __contains__N)getattrrO)r%rUr[containss rrfz Backend.hasRs#35 D> !rct|dd}|r|St|turtt |St S)z?Return the keys of the child elements of the given node object.riN)rrQrLrangerPrO)r%rUris rriz Backend.keysYs:sFD) 6M #Y$ S? "rN)rrrrrr$rHrJrNrSrvrKrxrfrirrrrrs>>"""&-$"4 rrc$eZdZdZdZdZdZy)rcddlm}||_y)Nr)cPickle)landscape.lib.compatr_pickle)r%rs rr'zPickleBackend.__init__ds 0 rciSr)rr*s rrzPickleBackend.newi rc|t|d5}|jj|cdddS#1swYyxYwNrb)openrr$r%r@fds rr$zPickleBackend.loadls5 (D ! )R<<$$R( ) ) )s2;ct|d5}|jj||ddddy#1swYyxYw)Nwb)rrdumpr%r@rmrs rrHzPickleBackend.saveps9 (D ! *R LL  c2q ) * * *s4=Nrrrr'rr$rHrrrrrcs )*rrc$eZdZdZdZdZdZy)rcddlm}||_y)Nr)bpickle) landscape.libr_bpickle)r%rs rr'zBPickleBackend.__init__vs ) rciSr)rr*s rrzBPickleBackend.new{rrct|d5}|jj|jcdddS#1swYyxYwr)rrloadsreadrs rr$zBPickleBackend.load~s; (D ! 2R==&&rwwy1 2 2 2s )AA ct|d5}|j|jj|dddy#1swYyxYw)Nr)rwriterdumpsrs rrHzBPickleBackend.saves> (D ! /R HHT]]((- . / / /s +AA Nrrrrrrus 2/rr)rKr!rerotwisted.python.compatr__all__objectrJr>r r rr compilesplitrrrrrrrrrrs* ,  ( 9  < q)q)h J5J5ZRZZ0 1 7 7 @~~B*G*$/W/r