
b]c           @   sx  d  Z  d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m	 Z	 d	   Z
 d
 e f d     YZ d e f d     YZ d e f d     YZ d e f d     YZ d e e f d     YZ d e f d     YZ d e f d     YZ d e f d     YZ d e f d     YZ d e f d     YZ d e f d     YZ d  S(!   s   The internals for the unit of work system.

The session's flush() process passes objects to a contextual object
here, which assembles flush tasks based on mappers and their properties,
organizes them in order of dependency, and executes.

i   (   t
   attributes(   t   exc(   t   persistence(   t   utili   (   t   event(   t   topologicalc            s   | j      f d   }   f d   }   f d   } t j |  d | d t d t t j |  d | d t d t t j |  d | d t d t d	 S(
   s\   Establish event listeners on object attributes which handle
    cascade-on-set/append.

    c            s   | d  k r d  S|  j } | r | j r8 | j d  n  |  j j j   } t j |  } | j	 j
 r | j s~   | j k r | j |  r | j |  q n  | S(   Ns   collection append(   t   Nonet   sessiont   _warn_on_eventst   _flush_warningt   managert   mappert   _propsR    t   instance_statet   _cascadet   save_updatet   cascade_backrefst   keyt   _contains_statet   _save_or_update_state(   t   statet   itemt	   initiatort   sesst   propt
   item_state(   R   (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   append    s    		c            s   | d  k r d  S|  j } |  j j j   } | rZ | j rZ | j | j rP d n d  n  | d  k	 r | t j	 k	 r | t j
 k	 r | j j r t j |  } | j j |  r | r | | j k r | j |  q t | _ q n  d  S(   Ns   collection removes   related attribute delete(   R   R   R
   R   R   R   R	   t   uselistR    t	   NEVER_SETt   PASSIVE_NO_RESULTR   t   delete_orphanR   t
   _is_orphant   _newt   expunget   Truet   _orphaned_outside_of_session(   R   R   R   R   R   R   (   R   (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   remove6   s"    	
c            s-  | | k r | S|  j  } | r)| j r8 | j d  n  |  j j j   } | d  k	 r t j |  } | j	 j
 r | j s   | j k r | j |  r | j |  q n  | d  k	 r)| t j k	 r)| t j k	 r)| j	 j r)t j |  } | | j k r&| j j |  r&| j |  q&q)n  | S(   Ns   related attribute set(   R   R   R	   R
   R   R   R   R    R   R   R   R   R   R   R   R   R   R   R    R   R!   (   R   t   newvaluet   oldvalueR   R   R   t   newvalue_statet   oldvalue_state(   R   (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   set_X   s,    			R   t   rawt   retvalR$   t   setN(   R   R   t   listenR"   (   t
   descriptorR   R   R$   R)   (    (   R   s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   track_cascade_events   s    	"%t   UOWTransactionc           B   s   e  Z d    Z e d    Z d   Z d   Z d   Z d   Z e	 j
 d  Z d   Z d   Z e e e d d d	  Z d
   Z d   Z e j d    Z d   Z d   Z d   Z d   Z d   Z RS(   c         C   sv   | |  _  i  |  _ t j t  |  _ t j t  |  _ i  |  _ i  |  _ t   |  _	 i  |  _
 t j d    |  _ d  S(   Nc           S   s   t    t    f S(   N(   R,   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   <lambda>   t    (   R   R    R   t   defaultdictR,   t   depst   mapperst   presort_actionst   postsort_actionst   dependenciest   statest   post_update_states(   t   selfR   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   __init__   s    					c         C   s   t  |  j  S(   N(   t   boolR9   (   R;   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   has_work   s    c         C   sR   | j  rN y | j | t j  WqN t j k
 rJ |  j j | g  t SXn  t	 S(   sV   return true if the given state is expired and was deleted
        previously.
        (
   t   expiredt   _load_expiredR    t   PASSIVE_OFFt   orm_exct   ObjectDeletedErrorR   t   _remove_newly_deletedR"   t   False(   R;   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   was_already_deleted   s    	c         C   s   | |  j  k o |  j  | d S(   sW   return true if the given state is marked as deleted
        within this uowtransaction.i    (   R9   (   R;   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt
   is_deleted   s    c         C   s6   | |  j  k r |  j  | S|   |  j  | <} | Sd  S(   N(   R    (   R;   R   t	   callable_t   ret(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   memo   s    c         C   s(   |  j  | d } | t f |  j  | <d S(   s;   remove pending actions for a state from the uowtransaction.i    N(   R9   R"   (   R;   R   t   isdelete(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   remove_state_actions   s    c   	      C   s.  d | | f } | |  j  k r |  j  | \ } } } | t  j @r*| t  j @r*| j | j } | j | | j t  j t  j B } | r | j r | j	   } n | } | | | f |  j  | <q*ni | j | j } | j | | j | t  j B } | r| j r| j	   } n | } | | | f |  j  | <| S(   sO   facade to attributes.get_state_history(), including
        caching of results.t   history(
   R    t   SQL_OKR
   t   implt   get_historyt   dictRA   t   LOAD_AGAINST_COMMITTEDt   uses_objectst   as_state(	   R;   R   R   t   passivet   hashkeyRM   t   state_historyt   cached_passiveRO   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   get_attribute_history   s,    c         C   s   | t  f |  j k S(   N(   R"   R6   (   R;   t	   processor(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   has_dep  s    c         C   s8   | | f } | |  j  k r4 t | |  |  j  | <n  d  S(   N(   R6   t
   Preprocess(   R;   RZ   t
   fromparentR   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   register_preprocessor  s    c         C   s   |  j  j |  sR | j rN | d  k	 rN t j d t j |  | | f  n  t S| |  j	 k r | j
 j } | |  j k r |  j |  n  |  j | j |  | | f |  j	 | <n) | r | s | r | t f |  j	 | <n  t S(   NsJ   Object of type %s not in session, %s operation along '%s' will not proceed(   R   R   t   deletedR   R   t   warnt   orm_utilt   state_class_strRE   R9   R
   R   R5   t   _per_mapper_flush_actionst   addR"   (   R;   R   RK   t   listonlyt   cancel_deletet	   operationR   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   register_object  s    	c         C   s@   | j  j j } |  j | \ } } | j |  | j |  d  S(   N(   R
   R   t   base_mapperR:   Rd   t   update(   R;   R   t   post_update_colsR   R9   t   cols(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   register_post_update-  s    c         C   s   t  |  | j  } t |  | j  } |  j j | | f  x | j D] } | j |   qD Wx6 | j D]+ } | j rz qe n  | j	 } | j |   qe Wd  S(   N(
   t   SaveUpdateAllRi   t	   DeleteAllR8   Rd   t   _dependency_processorst   per_property_preprocessorst   relationshipst   viewonlyt   _dependency_processor(   R;   R   t   savest   deletest   depR   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyRc   3  s    		c         C   s   t  j d    S(   s  return a dynamic mapping of (Mapper, DependencyProcessor) to
        True or False, indicating if the DependencyProcessor operates
        on objects of that Mapper.

        The result is stored in the dictionary persistently once
        calculated.

        c         S   s(   |  d j  j |  d j  |  d j k S(   Ni    i   (   R   t   getR   R   (   t   tup(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR1   L  R2   (   R   t   PopulateDict(   R;   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   _mapper_for_depA  s    
c         C   s6   |  j  } g  | D]" } | | j j | f r | ^ q S(   sm   Filter the given list of InstanceStates to those relevant to the
        given DependencyProcessor.

        (   R{   R
   R   (   R;   Rw   R9   t   mapper_for_dept   s(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   filter_states_for_depO  s    	c         c   sZ   | | f } xG | j  j D]9 } x0 |  j | D]! } |  j | | k r- | Vq- q- Wq Wd  S(   N(   Ri   t   self_and_descendantsR5   R9   (   R;   R   RK   Re   t   checktupR   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   states_for_mapper_hierarchyW  s
    c            s  xR t  rT t } x5 t   j j    D] } | j    r% t  } q% q% W| s Pq q Wt j   j t   j	 j       _
 } | rt   f d   | D  } xt   j  D] } d | k s | d j s | d j s | j |  r   j j |  q | d | k rV  j j |  x | | d D]  }   j j | | d f  q/Wq | d | k r   j j |  x3 | | d D]  }   j j | d | f  qWq q Wn  t g    j	 j   D] } | j s| ^ q j |  S(   s}   Generate the full, unsorted collection of PostSortRecs as
        well as dependency pairs for this UOWTransaction.

        c         3   s*   |  ]  } | t  | j     f Vq d  S(   N(   R,   t   per_state_flush_actions(   t   .0t   rec(   R;   (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pys	   <genexpr>w  s    i    i   N(   R"   RE   t   listR6   t   valuest   executeR   t   find_cyclesR8   R7   t   cyclesRQ   R   t   disabledt
   issupersetR$   Rd   R,   t
   difference(   R;   RI   t   actionR   t   convertt   edgeRw   t   a(    (   R;   s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   _generate_actions^  s:    	%!(.c         C   s   |  j    } |  j ra xv t j |  j |  D]/ } x& | rY | j   } | j |  |  q4 Wq+ Wn- x* t j |  j |  D] } | j |   qw Wd  S(   N(	   R   R   R   t   sort_as_subsetsR8   t   popt   execute_aggregatet   sortR   (   R;   R7   R)   t   nR   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    
			c         C   s   |  j  s d St |  j   } t d   |  j  j   D  } | j |  } | rc |  j j |  n  | r| |  j j |  n  d S(   s   mark processed objects as clean / deleted after a successful
        flush().

        this method is called within the flush() method after the
        execute() method has succeeded and the transaction has been committed.

        Nc         s   s'   |  ] \ } \ } } | r | Vq d  S(   N(    (   R   R}   RK   Re   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pys	   <genexpr>  s    (   R9   R,   t   itemsR   R   RD   t   _register_persistent(   R;   R9   t   isdelt   other(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   finalize_flush_changes  s    	N(   t   __name__t
   __module__R<   t   propertyR>   RF   RG   RJ   RL   R    t   PASSIVE_NO_INITIALIZERY   R[   R^   RE   R   Rh   Rm   Rc   R   t   memoized_propertyR{   R~   R   R   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR0      s,   	-				.							4	t   IterateMappersMixinc           B   s   e  Z d    Z RS(   c            s@     j  r/ t    f d     j j j D  S  j j j Sd  S(   Nc         3   s+   |  ]! }  j  |   j f r | Vq d  S(   N(   R{   t   dependency_processor(   R   t   m(   R;   t   uow(    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pys	   <genexpr>  s   (   R]   t   iterR   t   parentR   R   (   R;   R   (    (   R;   R   s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   _mappers  s
    	(   R   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s   R\   c           B   s    e  Z d Z d   Z d   Z RS(   R   R]   t	   processedt   setup_flush_actionsc         C   s+   | |  _  | |  _ t   |  _ t |  _ d  S(   N(   R   R]   R,   R   RE   R   (   R;   R   R]   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR<     s    		c         C   sU  t    } t    } xz |  j |  D]i } x` | j | j |  j  D]E } | j | \ } } | sB | rw | j |  q | j |  qB qB Wq" W| r |  j j | |  |  j j	 |  n  | r |  j j
 | |  |  j j	 |  n  | s | rM|  j rI|  j j | | t  s-|  j j | | t  rI|  j j |  t |  _ n  t St Sd  S(   N(   R,   R   R5   R   R   R9   Rd   R   t   presort_deletesRj   t   presort_savesR   t   prop_has_changesR"   RE   t   per_property_flush_actions(   R;   R   t   delete_statest   save_statesR   R   RK   Re   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s2    		 
		(   R   R]   R   R   (   R   R   t	   __slots__R<   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR\     s      	t   PostSortRecc           B   s    e  Z d Z d   Z d   Z RS(   R   c         G   sR   |  f | } | | j  k r' | j  | St j |   | j  | <} t | _ | Sd  S(   N(   R7   t   objectt   __new__RE   R   (   t   clsR   t   argsR   RI   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    	c         C   s   |  j  |  d  S(   N(   R   (   R;   R   t   recs(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    (   R   (   R   R   R   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s   		t
   ProcessAllc           B   s;   e  Z d Z d   Z d   Z d   Z d   Z d   Z RS(	   R   RK   R]   c         C   s9   | |  _  | |  _ | |  _ | j | j j j |  d  S(   N(   R   RK   R]   R4   R   Ri   Rd   (   R;   R   R   RK   R]   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR<     s
    			c         C   sE   |  j  |  } |  j r. |  j j | |  n |  j j | |  d  S(   N(   t	   _elementsRK   R   t   process_deletest   process_saves(   R;   R   R9   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    	c         C   s
   t  g   S(   N(   R   (   R;   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    c         C   s   d |  j  j |  j |  j f S(   Ns   %s(%s, isdelete=%s)(   t	   __class__R   R   RK   (   R;   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   __repr__%  s    	c         c   sg   x` |  j  |  D]O } xF | j | D]7 } | j | \ } } | |  j k r$ | r$ | Vq$ q$ Wq Wd  S(   N(   R   R5   R9   RK   (   R;   R   R   R   RK   Re   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR   ,  s
    (   R   RK   R]   (   R   R   R   R<   R   R   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s   				t   PostUpdateAllc           B   s    e  Z d Z d   Z d   Z RS(   R   RK   c         C   s   | |  _  | |  _ d  S(   N(   R   RK   (   R;   R   R   RK   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR<   7  s    	c         C   sf   | j  |  j \ } } g  | D]& } | j | d |  j k r | ^ q } t j |  j | | |  d  S(   Ni    (   R:   R   R9   RK   R   t   post_update(   R;   R   R9   Rl   R}   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR   ;  s    3(   R   RK   (   R   R   R   R<   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR   4  s   	Rn   c           B   s2   e  Z d Z d   Z d   Z d   Z d   Z RS(   R   c         C   s"   | |  _  | | j k s t  d  S(   N(   R   Ri   t   AssertionError(   R;   R   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR<   E  s    	c         C   s,   t  j |  j | j |  j t t  |  d  S(   N(   R   t   save_objR   R   RE   (   R;   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR   I  s    c   	      c   s   t  | j |  j t t   } |  j j } t | |  } x8 | D]0 } t | |  } | j j | | f  | Vq@ Wx= | j	 |  j D]+ } | j
 | |  } | j | | t  q Wd  S(   N(   R   R   R   RE   Ri   Ro   t   SaveUpdateStateR8   Rd   R4   R~   R   (	   R;   R   R9   Ri   t
   delete_allR   R   Rw   t   states_for_prop(    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR   P  s    	c         C   s   d |  j  j |  j f S(   Ns   %s(%s)(   R   R   R   (   R;   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR   a  s    (   R   (   R   R   R   R<   R   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyRn   B  s
   			Ro   c           B   s2   e  Z d Z d   Z d   Z d   Z d   Z RS(   R   c         C   s"   | |  _  | | j k s t  d  S(   N(   R   Ri   R   (   R;   R   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR<   h  s    	c         C   s,   t  j |  j | j |  j t t  |  d  S(   N(   R   t
   delete_objR   R   R"   RE   (   R;   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR   l  s    c   	      c   s   t  | j |  j t t   } |  j j } t | |  } x8 | D]0 } t | |  } | j j	 | | f  | Vq@ Wx= | j
 |  j D]+ } | j | |  } | j | | t  q Wd  S(   N(   R   R   R   R"   RE   Ri   Rn   t   DeleteStateR8   Rd   R4   R~   R   (	   R;   R   R9   Ri   t   save_allR   R   Rw   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR   s  s    	c         C   s   d |  j  j |  j f S(   Ns   %s(%s)(   R   R   R   (   R;   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    (   R   (   R   R   R   R<   R   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyRo   e  s
   			t   ProcessStatec           B   s)   e  Z d Z d   Z d   Z d   Z RS(   R   RK   R   c         C   s   | |  _  | |  _ | |  _ d  S(   N(   R   RK   R   (   R;   R   R   RK   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR<     s    		c   	      C   s   |  j  } |  j } |  j } g  | D]9 } | j  | k r" | j | k r" | j | k r" | ^ q" } | j |  |  j g g  | D] } | j ^ q~ } | r | j | |  n | j | |  d  S(   N(   R   R   RK   t   difference_updateR   R   R   (	   R;   R   R   t   cls_R   RK   t   rt   our_recsR9   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    			
&c         C   s,   d |  j  j |  j t j |  j  |  j f S(   Ns   %s(%s, %s, delete=%s)(   R   R   R   Ra   t	   state_strR   RK   (   R;   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s
    	(   R   RK   R   (   R   R   R   R<   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s   		R   c           B   s)   e  Z d Z d   Z d   Z d   Z RS(   R   R   c         C   s   | |  _  | j j |  _ d  S(   N(   R   R   Ri   (   R;   R   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR<     s    	c         C   s   |  j  } |  j } g  | D]* } | j  | k r | j | k r | ^ q } | j |  t j | |  j g g  | D] } | j ^ qo |  d  S(   N(   R   R   R   R   R   R   (   R;   R   R   R   R   R   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    		7c         C   s    d |  j  j t j |  j  f S(   Ns   %s(%s)(   R   R   Ra   R   R   (   R;   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    	(   R   R   (   R   R   R   R<   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s   		R   c           B   s)   e  Z d Z d   Z d   Z d   Z RS(   R   R   c         C   s   | |  _  | j j |  _ d  S(   N(   R   R   Ri   (   R;   R   R   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR<     s    	c   	      C   s   |  j  } |  j } g  | D]* } | j  | k r | j | k r | ^ q } | j |  |  j g g  | D] } | j ^ qf } t j | g  | D] } | j | d r | ^ q |  d  S(   Ni    (   R   R   R   R   R   R   R9   (	   R;   R   R   R   R   R   R   R9   R}   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    		7&c         C   s    d |  j  j t j |  j  f S(   Ns   %s(%s)(   R   R   Ra   R   R   (   R;   (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s    	(   R   R   (   R   R   R   R<   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyR     s   		N(   t   __doc__R2   R    R   RB   R   R   Ra   R   R   R/   R   R0   R   R\   R   R   R   Rn   Ro   R   R   R   (    (    (    s8   lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyt   <module>   s(   	i =2(###