U
    ccU>                     @   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
 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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)relationships)
strategies)util)Query   )log)result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-unpacked-wheel-8u86ls_i/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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   TFr   Nc           	         s\   t t| j||||f| || _|r.t|| _|s:t| _nt|	 krN|| _n
t
|| _d S N)superr   __init__r   tupler   AppenderQueryr   AppenderMixinmromixin_user_query)	r   class_keyZtypecallabledispatchr   r   r   kw	__class__r   r   r    G   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   s4   |t j@ s| ||j}n| ||}|j}t|S r   )r   r,   r-   r/   added_plus_unchangedDynamicCollectionAdapter)r   r0   r1   	user_datar2   datahistoryr   r   r   get_collectiong   s
    
z#DynamicAttributeImpl.get_collectionc                 C   s   t | t jS r   )r   EventZ	OP_APPENDr   r   r   r   _append_tokenu   s    z"DynamicAttributeImpl._append_tokenc                 C   s   t | t jS r   )r   r:   Z	OP_REMOVEr;   r   r   r   _remove_tokeny   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(   appendr<   trackparentsethasparentr   instance_stater   r0   r1   value	initiatorcollection_historyfnr   r   r   fire_append_event}   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_removedrB   rC   r   rD   r(   remover=   rE   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   r0   r1   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)rH   )Zparent_tokenlisthas_identityr	   ZIdentitySetr3   r?   r/   unionintersection
differencerJ   rM   )r   r0   r1   rF   rG   r2   Z	check_oldpopZ_adaptiterableZ
new_valuesZold_collectionrH   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.rZ   )r   r0   r1   rF   r   r   r   set_committed_value   s    z(DynamicAttributeImpl.set_committed_valuec                 C   s   |  ||}| S r   )r-   
as_historyr   r0   r1   r2   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   rD   ).0xr   r   r   
<listcomp>   s     z8DynamicAttributeImpl.get_all_pending.<locals>.<listcomp>)r-   	all_itemsra   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'   rN   rO   rQ   r   ZINIT_OK)r   r0   r2   rb   r   r   r   r-      s    
z,DynamicAttributeImpl._get_collection_historyc                 C   s   || k	r|  |||| d S r   )rJ   r   r0   r1   rF   rG   r2   r   r   r   rA      s    zDynamicAttributeImpl.appendc                 C   s   || k	r|  |||| d S r   )rM   rj   r   r   r   rL      s    zDynamicAttributeImpl.removec                 C   s   | j |||||d d S )N)r2   )rL   rj   r   r   r   rU     s    zDynamicAttributeImpl.pop)N)N)N) r   r   r   Zuses_objectsZdefault_accepts_scalar_loaderZsupports_populationZ
collectionr   r   r    r   ZPASSIVE_OFFr3   r.   r9   r	   Zmemoized_propertyr<   r=   rJ   rM   r?   rY   r^   r_   rc   rh   r-   rA   rL   rU   __classcell__r   r   r*   r   r   ?   sN   
 


 
 

6


r   c                   @   s<   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZeZ	dS )r5   z9simplified CollectionAdapter for internal API consistencyc                 C   s
   || _ d S r   )r7   )r   r7   r   r   r   r      s    z!DynamicCollectionAdapter.__init__c                 C   s
   t | jS r   )iterr7   r;   r   r   r   __iter__  s    z!DynamicCollectionAdapter.__iter__c                 C   s   d S r   r   r;   r   r   r   _reset_empty  s    z%DynamicCollectionAdapter._reset_emptyc                 C   s
   t | jS r   )lenr7   r;   r   r   r   __len__  s    z DynamicCollectionAdapter.__len__c                 C   s   dS r>   r   r;   r   r   r   __bool__  s    z!DynamicCollectionAdapter.__bool__N)
r   r   r   __doc__r    rm   rn   rp   rq   __nonzero__r   r   r   r   r5   
  s   r5   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	rZ|j |j
f| _|j|ddf| _| jjr~| jj| _d S )NF)Zalias_secondary)r   r#   r    r   objinstanceattrr   Z_propsr'   Z	secondaryr   Z__clause_element__	_from_objZ_with_parent_where_criteriar   _order_by_clauses)r   rv   r0   ru   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   ru   	autoflushflushorm_utilrQ   r   sessr   r   r   session=  s    
zAppenderMixin.sessionc                 C   s   d S r   r   )sre   r   r   r   <lambda>K      zAppenderMixin.<lambda>c                 C   s~   | j }|d krlt| j}|jr4tdt|  t	j
t	| jjjg| jt| jtjjdd S | | S d S )NzInstance %s is detached, dynamic relationship cannot return a correct result.   This warning will become a DetachedInstanceError in a future release.T)Z_source_supports_scalars)r   r   rD   ru   Zdetachedr	   r   r}   Z	state_strr   ZIteratorResultZSimpleResultMetaDatarv   r&   r   r-   r.   r/   Zscalars	_generate_iter)r   r   r0   r   r   r   r   M  s$    

	zAppenderMixin._iterc                 C   s@   | j }|d kr,| jt| jtj|S | |	|S d S r   )
r   rv   r-   r   rD   ru   r.   indexedr   __getitem__)r   indexr   r   r   r   r   d  s    
zAppenderMixin.__getitem__c                 C   s>   | j }|d kr,t| jt| jtjjS | 	|
 S d S r   )r   ro   rv   r-   r   rD   ru   r.   r/   r   countr~   r   r   r   r   n  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)r   )ru   r   orm_excZDetachedInstanceErrorr}   Zinstance_strrv   r'   r   r   queryrx   rw   ry   )r   r   ru   r   r   r   r   r   z  s     zAppenderMixin._generatec                 C   s0   |D ]&}| j t| jt| j|d  qd S r   rv   rA   r   rD   ru   instance_dict)r   iteratoritemr   r   r   extend  s    

zAppenderMixin.extendc                 C   s&   | j t| jt| j|d  d S r   r   r   r   r   r   r   rA     s    

zAppenderMixin.appendc                 C   s&   | j t| jt| j|d  d S r   )rv   rL   r   rD   ru   r   r   r   r   r   rL     s    

zAppenderMixin.remove)N)r   r   r   r   r    r   propertyr   r   r   r   r   rA   rL   rk   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   rr   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 )rO   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"   r{   r	   ZOrderedIdentitySetunchanged_itemsr/   deleted_items_reconcile_collection)r   rv   r0   ri   Zcollr   r   r   r      s    


zCollectionHistory.__init__c                 C   s   t | j| jS r   )rP   r/   rR   r   r;   r   r   r   r4     s    z&CollectionHistory.added_plus_unchangedc                 C   s   t | j| j| jS r   )rP   r/   rR   r   r   r;   r   r   r   rg     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/   rT   r   r   rS   r   ZHistoryrP   )r   addedZdeletedZ	unchangedr   r   r   r`     s    
zCollectionHistory.as_historyc                 C   s   t | j| S r   )rP   r/   )r   r   r   r   r   r     s    zCollectionHistory.indexedc                 C   s   | j | d S r   )r/   addr   rF   r   r   r   r@     s    zCollectionHistory.add_addedc                 C   s(   || j kr| j | n| j| d S r   )r/   rL   r   r   r   r   r   r   rK     s    
zCollectionHistory.add_removed)N)r   r   r   rr   r    r   r4   rg   r`   r   r@   rK   r   r   r   r   rO     s   


rO   N)rr    r   r   r   r   r   r   r   r   r	   r}   r   r
   r   Zenginer   Zclass_loggerZRelationshipPropertyZstrategy_forZAbstractRelationshipLoaderr   ZAttributeImplr   objectr5   r#   r"   r%   rO   r   r   r   r   <module>   s0    L 