B
    .`K9                 @   s
  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d	lm
Z dd
lmZ ddlmZ ddlmZ dd	lm
Z
 ejejjddG dd de	jZG dd dejZG dd deZG dd deeZdd ZG dd deZdS )zDynamic collection API.

Dynamic collections act like Query() objects for read operations and support
basic add/delete mutation.

   )
attributes)exc)
interfaces)object_mapper)object_session)
properties)
strategies)util)Query   )logdynamic)Zlazyc               @   s   e Zd Zdd ZdS )
DynaLoaderc          	   C   sl   d| _ | jstd| j n$| jjtjtjfkrBt	
d| j  tj| j|dt| jj| jj| jjd d S )NTztOn relationship %s, 'dynamic' loaders cannot be used with many-to-one/one-to-one relationships and/or uselist=False.zOn relationship %s, 'dynamic' loaders cannot be used with many-to-one/one-to-one relationships and/or uselist=False.  This warning will be an exception in a future release.)Z	useobjectZ
impl_classtarget_mapperorder_byquery_class)Zis_class_levelZuselistr   ZInvalidRequestErrorZparent_property	directionr   Z	ONETOMANYZ
MANYTOMANYr	   warnr   Z_register_attributeDynamicAttributeImplmapperr   r   )selfr    r   E/home/dcms/DCMS/lib/python3.7/site-packages/sqlalchemy/orm/dynamic.pyinit_class_attribute    s&    

zDynaLoader.init_class_attributeN)__name__
__module____qualname__r   r   r   r   r   r      s   r   c                   s  e Zd ZdZdZdZdZdZd& fdd	Ze	j
fddZde	jfdd	Zejd
d Zejdd Zd'ddZd(ddZdd Zde	j
dddfddZdd Zdd Ze	j
fddZe	jfddZe	j
fddZe	j
fd d!Ze	j
fd"d#Ze	j
fd$d%Z  ZS ))r   TFNc       	         sT   t t| j||||f| || _|| _|s2t| _nt| krF|| _n
t	|| _d S )N)
superr   __init__r   r   AppenderQueryr   AppenderMixinmromixin_user_query)	r   class_keyZtypecallabledispatchr   r   r   kw)	__class__r   r   r   E   s    
zDynamicAttributeImpl.__init__c             C   s*   |t j@ s| |t jjS | | |S d S )N)r   SQL_OK_get_collection_historyPASSIVE_NO_INITIALIZEadded_itemsr   )r   statedict_passiver   r   r   get\   s    
zDynamicAttributeImpl.getc             C   s.   |t j@ s| ||jS | ||}|jS d S )N)r   r(   r)   r+   added_plus_unchanged)r   r,   r-   	user_datar.   historyr   r   r   get_collectiond   s    
z#DynamicAttributeImpl.get_collectionc             C   s   t | t jS )N)r   EventZ	OP_APPEND)r   r   r   r   _append_tokenq   s    z"DynamicAttributeImpl._append_tokenc             C   s   t | t jS )N)r   r4   Z	OP_REMOVE)r   r   r   r   _remove_tokenu   s    z"DynamicAttributeImpl._remove_tokenc             C   sh   |d kr|  ||}|| x"| jjD ]}||||p:| j}q(W | jrd|d k	rd| t||d d S )NT)	_modified_event	add_addedr%   appendr5   trackparentsethasparentr   instance_state)r   r,   r-   value	initiatorcollection_historyfnr   r   r   fire_append_eventy   s    
z&DynamicAttributeImpl.fire_append_eventc             C   sh   |d kr|  ||}|| | jr@|d k	r@| t||d x"| jjD ]}||||p\| j qJW d S )NF)	r7   add_removedr:   r;   r   r<   r%   remover6   )r   r,   r-   r=   r>   r?   r@   r   r   r   fire_remove_event   s    
z&DynamicAttributeImpl.fire_remove_eventc             C   sD   | j |jkrt| ||j| j < ||| tj d|| j < |j| j  S )NT)r$   committed_stateCollectionHistoryr7   r   Z	NEVER_SET)r   r,   r-   r   r   r   r7      s
    
z$DynamicAttributeImpl._modified_eventc	             C   s   |r|j | j krd S |r$|d kr$d S |}	t|	}
|jrHt| ||}| ||}|jsb|j}n||j}tj}|	|
}||

|}|
|}x(|
D ] }||kr| j|||d |d qW x |D ]}| j|||d |d qW d S )N)r?   )Zparent_tokenlisthas_identityr	   ZIdentitySetr/   r7   r+   unionintersection
differencerA   rD   )r   r,   r-   r=   r>   r.   Z	check_oldpopZ_adaptiterableZ
new_valuesZold_collectionr?   Zidset	constantsZ	additionsZremovalsmemberr   r   r   set   s@    



zDynamicAttributeImpl.setc             O   s
   t  d S )N)NotImplementedError)r   argskwargsr   r   r   delete   s    zDynamicAttributeImpl.deletec             C   s   t dd S )Nz7Dynamic attributes don't support collection population.)rQ   )r   r,   r-   r=   r   r   r   set_committed_value   s    z(DynamicAttributeImpl.set_committed_valuec             C   s   |  ||}| S )N)r)   
as_history)r   r,   r-   r.   cr   r   r   get_history   s    z DynamicAttributeImpl.get_historyc             C   s   |  ||}dd |jD S )Nc             S   s   g | ]}t ||fqS r   )r   r<   ).0xr   r   r   
<listcomp>   s    z8DynamicAttributeImpl.get_all_pending.<locals>.<listcomp>)r)   	all_items)r   r,   r-   r.   rW   r   r   r   get_all_pending   s    z$DynamicAttributeImpl.get_all_pendingc             C   sJ   | j |jkr|j| j  }n
t| |}|jrB|tj@ rBt| ||dS |S d S )N)apply_to)r$   rE   rF   rH   r   ZINIT_OK)r   r,   r.   rW   r   r   r   r)      s    
z,DynamicAttributeImpl._get_collection_historyc             C   s   || k	r|  |||| d S )N)rA   )r   r,   r-   r=   r>   r.   r   r   r   r9      s    zDynamicAttributeImpl.appendc             C   s   || k	r|  |||| d S )N)rD   )r   r,   r-   r=   r>   r.   r   r   r   rC      s    zDynamicAttributeImpl.removec             C   s   | j |||||d d S )N)r.   )rC   )r   r,   r-   r=   r>   r.   r   r   r   rL      s    zDynamicAttributeImpl.pop)N)N)N)r   r   r   Zuses_objectsZdefault_accepts_scalar_loaderZsupports_populationZ
collectionr   r   r   ZPASSIVE_OFFr/   r*   r3   r	   Zmemoized_propertyr5   r6   rA   rD   r7   rP   rT   rU   rX   r]   r)   r9   rC   rL   __classcell__r   r   )r'   r   r   >   s6   


-r   c                   sp   e Zd ZdZ fddZdd Zeedd Zdd	 Zd
d Zdd Z	dddZ
dd Zdd Zdd Z  ZS )r    Nc                s~   t t| |jd  |  | _}|| _t|}|j| jj	 }|j
d k	rX|jj|j
f| _|j|dd| _| jjrz| jj| _d S )NF)Zalias_secondary)r   r    r   r   objinstanceattrr   Z_propsr$   Z	secondaryr   Z
selectable	_from_objZ_with_parent
_criterionr   	_order_by)r   rb   r,   ra   r   prop)r'   r   r   r   	  s    
zAppenderMixin.__init__c             C   sH   t | j}|d k	r0| jr0|jr0| j|kr0|  t| js@d S |S d S )N)r   ra   	autoflushflushorm_utilrH   )r   sessr   r   r   session  s    

zAppenderMixin.sessionc             C   s   d S )Nr   )srZ   r   r   r   <lambda>-      zAppenderMixin.<lambda>c             C   s>   | j }|d kr,t| jt| jtjjS t| 	|S d S )N)
rk   iterrb   r)   r   r<   ra   r*   r+   _clone)r   rj   r   r   r   __iter__/  s    
zAppenderMixin.__iter__c             C   s@   | j }|d kr,| jt| jtj|S | |	|S d S )N)
rk   rb   r)   r   r<   ra   r*   indexedrp   __getitem__)r   indexrj   r   r   r   rs   ;  s    
zAppenderMixin.__getitem__c             C   s>   | j }|d kr,t| jt| jtjjS | 	|
 S d S )N)rk   lenrb   r)   r   r<   ra   r*   r+   rp   count)r   rj   r   r   r   rv   E  s    
zAppenderMixin.countc             C   s~   | j }|d kr:t|}|d kr:tdt|| jjf | jrT| j| jj	|d}n|
| jj	}| j|_| j|_| j|_|S )NzParent instance %s is not bound to a Session, and no contextual session is established; lazy load operation of attribute '%s' cannot proceed)rk   )ra   r   orm_excZDetachedInstanceErrorri   Zinstance_strrb   r$   r   r   queryrd   rc   re   )r   rj   ra   rx   r   r   r   rp   Q  s    zAppenderMixin._clonec             C   s4   x.|D ]&}| j t| jt| j|d  qW d S )N)rb   r9   r   r<   ra   instance_dict)r   iteratoritemr   r   r   extendk  s    


zAppenderMixin.extendc             C   s&   | j t| jt| j|d  d S )N)rb   r9   r   r<   ra   ry   )r   r{   r   r   r   r9   t  s
    

zAppenderMixin.appendc             C   s&   | j t| jt| j|d  d S )N)rb   rC   r   r<   ra   ry   )r   r{   r   r   r   rC   |  s
    

zAppenderMixin.remove)N)r   r   r   r   r   rk   propertyrq   rs   rv   rp   r|   r9   rC   r_   r   r   )r'   r   r      s   

	r    c               @   s   e Zd ZdZdS )r   zBA dynamic query that supports basic collection storage operations.N)r   r   r   __doc__r   r   r   r   r     s   r   c             C   s   d| j  }t|t| fd| iS )zAReturn a new class with AppenderQuery functionality layered over.ZAppenderr   )r   typer    )clsnamer   r   r   r"     s    
r"   c               @   sR   e Zd ZdZdddZedd Zedd Zd	d
 Zdd Z	dd Z
dd ZdS )rF   zDOverrides AttributeHistory to receive append/remove events directly.Nc             C   s`   |r8t ||d}t|| _|j| _|j| _d| _n$t | _t | _t | _d| _d S )NFT)r   rg   r	   ZOrderedIdentitySetunchanged_itemsr+   deleted_items_reconcile_collection)r   rb   r,   r^   Zcollr   r   r   r     s    


zCollectionHistory.__init__c             C   s   t | j| jS )N)rG   r+   rI   r   )r   r   r   r   r0     s    z&CollectionHistory.added_plus_unchangedc             C   s   t | j| j| jS )N)rG   r+   rI   r   r   )r   r   r   r   r\     s    zCollectionHistory.all_itemsc             C   s`   | j r0| j| j}| j| j}| j|}n| j| j| j  }}}tt|t|t|S )N)	r   r+   rK   r   r   rJ   r   ZHistoryrG   )r   addedZdeletedZ	unchangedr   r   r   rV     s    zCollectionHistory.as_historyc             C   s   t | j| S )N)rG   r+   )r   rt   r   r   r   rr     s    zCollectionHistory.indexedc             C   s   | j | d S )N)r+   add)r   r=   r   r   r   r8     s    zCollectionHistory.add_addedc             C   s(   || j kr| j | n| j| d S )N)r+   rC   r   r   )r   r=   r   r   r   rB     s    
zCollectionHistory.add_removed)N)r   r   r   r~   r   r}   r0   r\   rV   rr   r8   rB   r   r   r   r   rF     s   
rF   N)r~    r   r   rw   r   r   r   r   r   r	   ri   rx   r
   r   Zclass_loggerZRelationshipPropertyZstrategy_forZAbstractRelationshipLoaderr   ZAttributeImplr   objectr    r   r"   rF   r   r   r   r   <module>   s*    I