mò &ÜGc@sÝdZdklZdklZlZlZdklZl Z dkl Z d„Z de fd„ƒYZdefd „ƒYZd efd „ƒYZd efd „ƒYZdefd„ƒYZde fd„ƒYZdS(s™bridges the PropertyLoader (i.e. a relation()) and the UOWTransaction together to allow processing of scalar- and list-based dependencies at flush time.(ssync(s ONETOMANYs MANYTOONEs MANYTOMANY(ssqlsutil(ssessioncCsThtt<tt<tt<}|idj ot |ƒSn||i |ƒSdS(N( t ONETOMANYt OneToManyDPt MANYTOONEt ManyToOneDPt MANYTOMANYt ManyToManyDPttypestpropt associationtNonet AssociationDPt direction(RR((t=/home/holguin2/public_html/spyce/sqlalchemy/orm/dependency.pytcreate_dependency_processors!tDependencyProcessorcBsbtZd„Zd„Zd„Zed„Zed„Zd„Zd„Z e d„Z d „Z RS( NcCs›||_|i|_|i|_|i|_|i|_|i|_|i|_|i|_|i |_ |i |_ |i |_ |i |_ |i ƒdS(N(RtselftcascadetmappertparentRt secondaryR t is_backreft post_updatet foreignkeytpassive_deletestkeyt_compile_synchronizers(RR((R t__init__s            cCs tƒ‚dS(sÃtells a UOWTransaction what mappers are dependent on which, with regards to the two or three mappers handled by this PropertyLoader. Also registers itself as a "processor" for one of its mappers, which will be executed after that mapper's objects have been saved or before they've been deleted. The process operation manages attributes and dependent operations upon the objects of one of the involved mappers.N(tNotImplementedError(Rt uowcommit((R tregister_dependencies,scCsA||jodSn)|itjo||fSn ||fSdS(sôgiven an object pair assuming obj2 is a child of obj1, returns a tuple with the dependent object second, or None if they are equal. used by objectstore's object-level topological sort (i.e. cyclical table dependency).N(tobj1tobj2R RR R(RRR((R twhose_dependent_on_who6s  cCs tƒ‚dS(sthis method is called during a flush operation to synchronize data between a parent and child object. it is called within the context of the various mappers and sometimes individual objects sorted according to their insert/update/delete order (topological sort).N(R(RttasktdeplistRtdelete((R tprocess_dependenciesBscCs tƒ‚dS(s¿used before the flushes' topological sort to traverse through related objects and insure every instance which will require save/update/delete is properly added to the UOWTransaction.N(R(RR!R"RR#((R tpreprocess_dependenciesHscCs tƒ‚dS(s§called during a flush to synchronize primary key identifier values between a parent/child object, as well as to an associationrow in the case of many-to-many.N(R(Rtobjtchildtassociationrowt clearkeys((R t _synchronizeMscCs“ti|i|i|iƒ|_|itijo<|ii|i i dt ƒ|ii|i i dt ƒn |ii|i i d|iƒdS(sPassembles a list of 'synchronization rules', which are instructions on how to populate the objects on each side of a relationship. This is done when a DependencyProcessor is first initialized. The list of rules is used within commits by the _synchronize() method when dependent objects are processed.t issecondaryRN(tsynctClauseSynchronizerRRRR t syncrulesRtcompileRt primaryjointFalset secondaryjointTrueR(R((R RRs ! cCstii||id|ƒS(s‘returns the list of objects that are dependent on the given object, as according to the relationship this dependency processor representstpassiveN(t sessionlibtattribute_managert get_historyR&RRR4(RR&RR4((R tget_object_dependencies`scCs…|dj ot|iojxg|D][}|dj oH|i|ƒpt|dƒ o'|i |dt d|i i ƒƒPqqWndS(sðexecute a post_update call. for relations that contain the post_update flag, an additional UPDATE statement may be associated after an INSERT or before a DELETE in order to resolve circular row dependencies. This method will check for the post_update flag being set on a particular relationship, and given a target object and list of one or more related objects, and execute the UPDATE if the given related object list contains INSERTs or DELETEs.t _instance_keyt postupdatetpost_update_colsN( R&R RRtrelatedtxRt is_deletedthasattrtregister_objectR3R.t dest_columns(RR&RR<R=((R t_conditional_post_updatees."( t__name__t __module__RRR R1R$R%R*RR3R8RB(((R Rs      RcBs2tZd„Zed„Zed„Zd„ZRS(NcCs˜|io[t|i|i|iƒ}|i|i|ƒ|i|i|ƒ|i |||iƒn0|i|i|iƒ|i |i||iƒdS(N( RRt MapperStubRRRtstubRtregister_dependencytregister_processor(RRRF((R Rts cCsÍ|o|ii p |ioëxè|D]Ü}|i||dt ƒ}xg|i ƒD]Y}|dj oF|i|ƒt jo0|i||dtƒ|i|||gƒqQqQWxQ|iƒD]C}|dj o0|i||dtƒ|i|||gƒq»q»Wq&WqÉn¼x¸|D]°}|i||dtƒ}|dj o…x@|iƒD]2}|i||dt ƒ|i|||gƒqMWx?|i ƒD]-}|iip|i||dtƒqqWqqWdS(NR4(R#RRt delete_orphanRR"R&R8RR1t childlistt deleted_itemsR'R t hasparentR*R3RBtunchanged_itemst added_items(RR!R"RR#R&RJR'((R R$}s6 #  *    c Csü|oç|ioqø|iioxÅ|D]}|i||dt ƒ}x|i ƒD]s}|dj o`|i|ƒt joJ|i|dtƒx4|iid|ƒD]}|i|dtƒq¦WqTqTWxk|iƒD]]}|dj oJ|i|dtƒx4|iid|ƒD]}|i|dtƒqWqØqØWq)Wqøx´|D]ž}|i||dt ƒ}xH|i ƒD]:}|dj o'|i|ƒt jo|i|ƒqsqsWx2|iƒD]$}|dj o|i|ƒq¾q¾WqHWn x|D]ÿ}|i||dtƒ}|dj oÔx2|iƒD]$}|dj o|i|ƒq-q-Wxœ|i ƒD]Š}|iip|i|dt ƒqb|i|ƒt joJ|i|dtƒx4|iid|ƒD]}|i|dtƒqËWqbqbWqõqõWdS(NR4tisdeleteR#(R#RRRRIR"R&R8RR1RJRKR'R RLR@R3Rtcascade_iteratortcRMRN( RR!R"RR#R&RQRJR'((R R%˜sb   #  ' #       cCsA|}|}|djodSn|ii|||||ƒdS(N( R&tsourceR'tdestR RR.texecuteR)(RR&R'R(R)RSRR((R R*Ås  (RCRDRR1R$R%R*(((R Rss  -RcBs2tZd„Zed„Zed„Zd„ZRS(NcCs˜|io[t|i|i|iƒ}|i|i|ƒ|i|i|ƒ|i |||iƒn0|i|i|iƒ|i |i||iƒdS(N( RRRERRRRFRRGRH(RRRF((R RÍs cCs+|oŒ|io~|ii opxm|D]a}|i|ddt ƒ|i ||dt ƒ}|i|||iƒ|iƒ|iƒƒq&Wq'n•x‘|D]‰}|i ||dt ƒ}|dj o^x*|iƒD]}|i||dt ƒqÒW|i|||iƒ|iƒ|iƒƒqšqšWdS(NR4(R#RRRRIR"R&R*R R3R8RR1RJRBRKRMRNR'(RR!R"RR#R&RJR'((R R$Ös9  c Cs§|iodSn|oÌ|iio»x¸|D]¬}|i||dtƒ}x‹|i ƒ|i ƒD]s}|dj o`|i|ƒtjoJ|i|dtƒx4|iid|ƒD]}|i|dtƒq´WqbqbWq-Wq£n¿x»|D]³}|i|ƒ|iio“|i||dtƒ}xx|i ƒD]f}|i|ƒtjoJ|i|dtƒx4|iid|ƒD]}|i|dtƒqvWq1q1WqìqìWdS(NR4ROR#(RRR#RR"R&R8RR1RJRKRMR'R RLR@R3RRPRQRI( RR!R"RR#R&RQRJR'((R R%ès4  #+   cCsA|}|}|djodSn|ii|||||ƒdS(N( R'RRR&RSR RR.RTR)(RR&R'R(R)RSRR((R R*s  (RCRDRR1R$R%R*(((R RÌs  RcBs2tZd„Zed„Zed„Zd„ZRS(NcCsm|iodSnt|i|i|iƒ}|i|i|ƒ|i|i|ƒ|i |||iƒdS(N( RRRERRRRFRRGRH(RRRF((R Rs  cCs|ii|iƒ} g}g}|owx+|D]h}|i ||dt ƒ} xG| i ƒ| iƒD]/} h}|i|| |t ƒ|i|ƒqdWq/Wn¸x´|D]¬}|i ||ƒ} | djoq¦nx=| iƒD]/} h}|i|| |t ƒ|i|ƒqßWx=| i ƒD]/} h}|i|| |t ƒ|i|ƒqWq¦Wt|ƒo€|iƒ|iitig} |iiD]3}|i|jo| |ti|iƒjqq~ Œƒ} | i| |ƒnt|ƒo#|ii ƒ} | i| |ƒndS(NR4(!Rt transactiont connectionRRtsecondary_deletetsecondary_insertR#R"R&R8R1RJRKRMR'R(R*tappendR RNtlentsortRtsqltand_t_[1]RQRt bindparamt statementRTtinsert(RR!R"RR#R(R&RQRWRJR^RVR`R'RX((R R$sD     b cCsdS(N((RR!R"RR#((R R%9scCsA|}d}|djodSn|ii|||||ƒdS(N( R(RSR RRRR.RTR&R'R)(RR&R'R(R)RSRR((R R*;s  (RCRDRR1R$R%R*(((R Rs  ! R cBstZd„ZRS(NcOs5tt|ƒi||Žt|i_t|i_ dS(N( tsuperR RRtargstkwargsR3RR#RI(RRcRd((R RCs (RCRDR(((R R BsREcBsMtZdZeiZd„Zd„Zd„Zd„Z d„Z d„Z RS(s%poses as a Mapper representing the association table in a many-to-many join, when performing a flush(). The Task objects in the objectstore module treat it just like any other Mapper, but in fact it only serves as a "dependency" placeholder for the many-to-many update task.cCs||_g|_dS(N(RRt_inheriting_mappers(RRRR((R RPs cCsdS(N((RR((R RSscOsdS(N((RRcRd((R tsave_objUscOsdS(N((RRcRd((R t delete_objWscCs|S(N(R(R((R tprimary_mapperYscCs|S(N(R(R((R t base_mapper[s( RCRDt__doc__tutilt ArgSingletont __metaclass__RRRfRgRhRi(((R REHs       N(Rjtsqlalchemy.ormR,tsqlalchemy.orm.syncRRRt sqlalchemyR\RktsessionR5R tobjectRRRRR RE(RR5RR\R RR,RkRRR RRRE((R t? s   XY;;