U
    [hX&                     @  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 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rd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d#ed$Z.G d%d& d&ee. Z/G d'd( d(eZ0ej1j2d)d*G d+d, d,eZ3G d-d. d.ee. Z4G d/d0 d0e4e. ee. Z5d1d2d3d4d5Z6d6S )7zDynamic collection API.

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

.. legacy:: the "dynamic" loader is a legacy feature, superseded by the
 "write_only" loader.


    )annotations)Any)Iterable)Iterator)List)Optional)Tuple)Type)TYPE_CHECKING)TypeVar)Union   )
attributes)exc)relationships)util)PassiveFlag)Query)object_session)AbstractCollectionWriter)WriteOnlyAttributeImpl)WriteOnlyHistory)WriteOnlyLoader   )result)QueryableAttribute)Mapper)_RelationshipOrderByArg)Session)InstanceState)AliasedClass)	_Dispatch)ColumnElement_T)Zboundc                   @  s$   e Zd Zd
dddddddd	ZdS )DynamicCollectionHistoryNDynamicAttributeImplInstanceState[_T]r   z&Optional[DynamicCollectionHistory[_T]]None)attrstatepassiveapply_toreturnc                 C  s`   |r8t ||d}t|| _|j| _|j| _d| _n$t | _t | _t | _d| _d S )NFT)AppenderQuery	autoflushr   ZOrderedIdentitySetZunchanged_itemsadded_itemsZdeleted_itemsZ_reconcile_collection)selfr(   r)   r*   r+   Zcoll r1   <./venv/lib/python3.8/site-packages/sqlalchemy/orm/dynamic.py__init__>   s    


z!DynamicCollectionHistory.__init__)N)__name__
__module____qualname__r3   r1   r1   r1   r2   r$   =   s    r$   c                
   @  s@   e Zd ZU dZee Zded< dddddd	d
dddddZdS )r%   TzType[AppenderMixin[Any]]query_classNz#Union[Type[Any], AliasedClass[Any]]strz"_Dispatch[QueryableAttribute[Any]]z
Mapper[_T]r   z!Optional[Type[AppenderMixin[_T]]]r   r'   )class_keydispatchtarget_mapperorder_byr7   kwr,   c                 K  sZ   t jj| ||d |f| || _|r,t|| _|s8t| _nt|	 krL|| _n
t
|| _d S N)r   ZAttributeImplr3   r<   tupler=   r-   r7   AppenderMixinmromixin_user_query)r0   r9   r:   r;   r<   r=   r7   r>   r1   r1   r2   r3   W   s"    
    
zDynamicAttributeImpl.__init__)N)	r4   r5   r6   Z_supports_dynamic_iterationr$   r   Zcollection_history_cls__annotations__r3   r1   r1   r1   r2   r%   R   s
   
	 r%   Zdynamic)Zlazyc                   @  s   e Zd ZeZdS )
DynaLoaderN)r4   r5   r6   r%   Z
impl_classr1   r1   r1   r2   rE   o   s   rE   c                      s  e Zd ZU dZdZded< ded< ddd	d
 fddZeddddZej	dd	dddZddddZ
erddddZdddddZddd d!Zd4dd"d#d$d%Zd&d	d'd(d)Zd*d	d+d,d-Zd&d	d'd.d/Zd*d	d+d0d1Zd*d	d+d2d3Z  ZS )5rA   zTA mixin that expects to be mixing in a Query class with
    AbstractAppender.


    NzOptional[Type[Query[_T]]]r7   zTuple[ColumnElement[Any], ...]_order_by_clausesr%   r&   r'   )r(   r)   r,   c                   s"   t | |jd  t || d S r?   )r   r3   r<   super)r0   r(   r)   	__class__r1   r2   r3   ~   s    zAppenderMixin.__init__zOptional[Session])r,   c                 C  sB   t | j}|d k	r*|jr*| j|kr*|  t| js:d S |S d S r?   )r   instancer.   flushorm_utilZhas_identityr0   sessr1   r1   r2   session   s    
zAppenderMixin.sessionr   )rO   r,   c                 C  s
   || _ d S r?   )rN   )r0   rO   r1   r1   r2   rO      s    z1Union[result.ScalarResult[_T], result.Result[_T]]c                 C  s   | j }|d krpt| j}|jr4tdt|  t	j
t	| jjjgt| 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)rO   r   instance_staterJ   Zdetachedr   warnrL   Z	state_strr   ZIteratorResultZSimpleResultMetaDatar(   r9   r4   iter_get_collection_historyr   PASSIVE_NO_INITIALIZEr/   Zscalars	_generate_iter)r0   rN   r)   r1   r1   r2   rV      s(    

zAppenderMixin._iterzIterator[_T]c                 C  s   d S r?   r1   )r0   r1   r1   r2   __iter__       zAppenderMixin.__iter__r   zUnion[_T, List[_T]])indexr,   c                 C  s@   | j }|d kr,| jt| jtj|S | 	|
|S d S r?   )rO   r(   rS   r   rP   rJ   r   rT   ZindexedrU   __getitem__)r0   rY   rN   r1   r1   r2   rZ      s    
zAppenderMixin.__getitem__intc                 C  s>   | j }|d kr,t| jt| jtjj	S | 
| S d S r?   )rO   lenr(   rS   r   rP   rJ   r   rT   r/   rU   countrM   r1   r1   r2   r]      s    
zAppenderMixin.countz	Query[_T])rN   r,   c                 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)rO   )rJ   r   orm_excZDetachedInstanceErrorrL   Zinstance_strr(   r:   r7   r<   queryZ_where_criteriaZ	_from_objrF   )r0   rN   rJ   r_   r1   r1   r2   rU      s     zAppenderMixin._generatezIterable[_T])iteratorr,   c                 C  s   |  | dS )a~  Add an iterable of items to this :class:`_orm.AppenderQuery`.

        The given items will be persisted to the database in terms of
        the parent instance's collection on the next flush.

        This method is provided to assist in delivering forwards-compatibility
        with the :class:`_orm.WriteOnlyCollection` collection class.

        .. versionadded:: 2.0

        NZ_add_all_implr0   r`   r1   r1   r2   add_all   s    zAppenderMixin.add_allr#   )itemr,   c                 C  s   |  |g dS )ap  Add an item to this :class:`_orm.AppenderQuery`.

        The given item will be persisted to the database in terms of
        the parent instance's collection on the next flush.

        This method is provided to assist in delivering forwards-compatibility
        with the :class:`_orm.WriteOnlyCollection` collection class.

        .. versionadded:: 2.0

        Nra   r0   rd   r1   r1   r2   add   s    zAppenderMixin.addc                 C  s   |  | dS )zAdd an iterable of items to this :class:`_orm.AppenderQuery`.

        The given items will be persisted to the database in terms of
        the parent instance's collection on the next flush.

        Nra   rb   r1   r1   r2   extend  s    zAppenderMixin.extendc                 C  s   |  |g dS )zAppend an item to this :class:`_orm.AppenderQuery`.

        The given item will be persisted to the database in terms of
        the parent instance's collection on the next flush.

        Nra   re   r1   r1   r2   append  s    zAppenderMixin.appendc                 C  s   |  | dS )zRemove an item from this :class:`_orm.AppenderQuery`.

        The given item will be removed from the parent instance's collection on
        the next flush.

        N)Z_remove_implre   r1   r1   r2   remove  s    zAppenderMixin.remove)N)r4   r5   r6   __doc__r7   rD   r3   propertyrO   setterrV   r
   rW   rZ   r]   rU   rc   rf   rg   rh   ri   __classcell__r1   r1   rH   r2   rA   t   s(   

	
 		rA   c                   @  s   e Zd ZdZdS )r-   zA dynamic query that supports basic collection storage operations.

    Methods on :class:`.AppenderQuery` include all methods of
    :class:`_orm.Query`, plus additional methods used for collection
    persistence.


    N)r4   r5   r6   rj   r1   r1   r1   r2   r-     s   r-   r   ztype[AppenderMixin[Any]])clsr,   c                 C  s   d| j  }t|t| fd| iS )zAReturn a new class with AppenderQuery functionality layered over.ZAppenderr7   )r4   typerA   )rn   namer1   r1   r2   rC   )  s    
rC   N)7rj   Z
__future__r   typingr   r   r   r   r   r   r	   r
   r   r    r   r   r^   r   r   rL   baser   r_   r   rO   r   Z	writeonlyr   r   r   r   Zenginer   r   Zmapperr   r   r   r)   r   r    Zeventr!   Zsql.elementsr"   r#   r$   r%   ZRelationshipPropertyZstrategy_forrE   rA   r-   rC   r1   r1   r1   r2   <module>	   sT    +