U
    x^J9                     @   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   >/tmp/pip-install-dq5v43_d/SQLAlchemy/sqlalchemy/orm/dynamic.pyinit_class_attribute    s2    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 r   )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 r   )r   r*   r+   r-   added_plus_unchanged)r   r.   r/   	user_datar0   historyr   r   r   get_collectiond   s    
z#DynamicAttributeImpl.get_collectionc                 C   s   t | t jS r   )r   EventZ	OP_APPENDr   r   r   r   _append_tokenq   s    z"DynamicAttributeImpl._append_tokenc                 C   s   t | t jS r   )r   r6   Z	OP_REMOVEr7   r   r   r   _remove_tokenu   s    z"DynamicAttributeImpl._remove_tokenc                 C   sd   |d kr|  ||}|| | jjD ]}||||p8| j}q&| jr`|d k	r`| t||d d S NT)	_modified_event	add_addedr&   appendr8   trackparentsethasparentr   instance_stater   r.   r/   value	initiatorcollection_historyfnr   r   r   fire_append_eventy   s    
z&DynamicAttributeImpl.fire_append_eventc                 C   sd   |d kr|  ||}|| | jr@|d k	r@| t||d | jjD ]}||||pZ| j qHd S )NF)	r;   add_removedr>   r?   r   r@   r&   remover9   rA   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 r:   )r%   committed_stateCollectionHistoryr;   r   Z	NEVER_SET)r   r.   r/   r   r   r   r;      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}|	|
}||

|}|
|}|
D ] }||kr| j|||d |d q|D ]}| j|||d |d qd S )N)rD   )Zparent_tokenlisthas_identityr	   ZIdentitySetr1   r;   r-   unionintersection
differencerF   rI   )r   r.   r/   rB   rC   r0   Z	check_oldpopZ_adaptiterableZ
new_valuesZold_collectionrD   Zidset	constantsZ	additionsZremovalsmemberr   r   r   set   sF    

zDynamicAttributeImpl.setc                 O   s
   t  d S r   NotImplementedError)r   argskwargsr   r   r   delete   s    zDynamicAttributeImpl.deletec                 C   s   t dd S )Nz7Dynamic attributes don't support collection population.rV   )r   r.   r/   rB   r   r   r   set_committed_value   s    z(DynamicAttributeImpl.set_committed_valuec                 C   s   |  ||}| S r   )r+   
as_historyr   r.   r/   r0   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_itemsr]   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%   rJ   rK   rM   r   ZINIT_OK)r   r.   r0   r^   r   r   r   r+      s    
z,DynamicAttributeImpl._get_collection_historyc                 C   s   || k	r|  |||| d S r   )rF   r   r.   r/   rB   rC   r0   r   r   r   r=      s    zDynamicAttributeImpl.appendc                 C   s   || k	r|  |||| d S r   )rI   rf   r   r   r   rH      s    zDynamicAttributeImpl.removec                 C   s   | j |||||d d S )N)r0   )rH   rf   r   r   r   rQ      s    zDynamicAttributeImpl.pop)N)N)N)r   r   r   Zuses_objectsZdefault_accepts_scalar_loaderZsupports_populationZ
collectionr   r   r   ZPASSIVE_OFFr1   r,   r5   r	   Zmemoized_propertyr8   r9   rF   rI   r;   rU   rZ   r[   r_   rd   r+   r=   rH   rQ   __classcell__r   r   r(   r   r   >   sL   
 


 
 

6


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   rj   r.   ri   r   propr(   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 r   )r   ri   	autoflushflushorm_utilrM   r   sessr   r   r   session  s    
zAppenderMixin.sessionc                 C   s   d S r   r   )sra   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 r   )
rt   iterrj   r+   r   r@   ri   r,   r-   _clonerr   r   r   r   __iter__/  s    
zAppenderMixin.__iter__c                 C   s@   | j }|d kr,| jt| jtj|S | |	|S d S r   )
rt   rj   r+   r   r@   ri   r,   indexedry   __getitem__)r   indexrs   r   r   r   r|   ;  s    
zAppenderMixin.__getitem__c                 C   s>   | j }|d kr,t| jt| jtjjS | 	|
 S d S r   )rt   lenrj   r+   r   r@   ri   r,   r-   ry   countrr   r   r   r   r   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)rt   )ri   r   orm_excZDetachedInstanceErrorrq   Zinstance_strrj   r%   r   r   queryrl   rk   rm   )r   rs   ri   r   r   r   r   ry   Q  s     zAppenderMixin._clonec                 C   s0   |D ]&}| j t| jt| j|d  qd S r   rj   r=   r   r@   ri   instance_dict)r   iteratoritemr   r   r   extendk  s    

zAppenderMixin.extendc                 C   s&   | j t| jt| j|d  d S r   r   r   r   r   r   r   r=   t  s    

zAppenderMixin.appendc                 C   s&   | j t| jt| j|d  d S r   )rj   rH   r   r@   ri   r   r   r   r   r   rH   |  s    

zAppenderMixin.remove)N)r   r   r   r   r   rt   propertyrz   r|   r   ry   r   r=   rH   rg   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 )rK   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    ro   r	   ZOrderedIdentitySetunchanged_itemsr-   deleted_items_reconcile_collection)r   rj   r.   re   Zcollr   r   r   r     s    


zCollectionHistory.__init__c                 C   s   t | j| jS r   )rL   r-   rN   r   r7   r   r   r   r2     s    z&CollectionHistory.added_plus_unchangedc                 C   s   t | j| j| jS r   )rL   r-   rN   r   r   r7   r   r   r   rc     s
    zCollectionHistory.all_itemsc                 C   s`   | j r0| j| j}| j| j}| j|}n| j| j| j  }}}tt|t|t|S r   )	r   r-   rP   r   r   rO   r   ZHistoryrL   )r   addedZdeletedZ	unchangedr   r   r   r\     s    
zCollectionHistory.as_historyc                 C   s   t | j| S r   )rL   r-   )r   r}   r   r   r   r{     s    zCollectionHistory.indexedc                 C   s   | j | d S r   )r-   addr   rB   r   r   r   r<     s    zCollectionHistory.add_addedc                 C   s(   || j kr| j | n| j| d S r   )r-   rH   r   r   r   r   r   r   rG     s    
zCollectionHistory.add_removed)N)r   r   r   r   r   r   r2   rc   r\   r{   r<   rG   r   r   r   r   rK     s   


rK   N)r    r   r   r   r   r   r   r   r   r	   rq   r   r
   r   Zclass_loggerZRelationshipPropertyZstrategy_forZAbstractRelationshipLoaderr   ZAttributeImplr   objectr!   r    r#   rK   r   r   r   r   <module>   s*    I