o
    ޭh	*                     @  s6  d dl mZ d dlZd dlmZ d dlmZ d dlmZmZm	Z	m
Z
 d dlmZ d dlmZmZmZ d dlmZmZ d d	lmZ d d
lmZmZmZmZ erZd dlmZ d dlmZ eeef Z d<ddZ!d=ddZ"d>d d!Z#G d"d# d#eZ$d?d'd(Z%d?d)d*Z&G d+d, d,Z'G d-d. d.Z(d@d4d5Z)dAd:d;Z*dS )B    )annotationsN)Sequence)copy)TYPE_CHECKINGAnyCallablecast)Table)	CriterionJSONAttributeCriterionTerm)
FieldErrorOperationalError)Field)BackwardFKRelationForeignKeyFieldInstanceManyToManyFieldInstanceRelationalField)Model)QuerySettabler	   related_fieldr   related_field_namestrreturnlist[TableCriterionTuple]c           	      C  s&  g }|j jj}t|tr5t|j}||| |jjj	 ||j
 kf ||||j ||j jj	 kf |S t|trb|jjpA|jj}| |krR||   d| }||| | ||j kf |S |jjpi|jj}|jjj|j }|jpw|j}||   d| }|||| | | kf |S )N__)related_model_meta	basetable
isinstancer   r	   throughappendmodeldb_pk_columnbackward_keyforward_keyr   to_field_instancesource_fieldmodel_field_nameas_get_table_namerelation_source_field
fields_map)	r   r   r   required_joinsrelated_tablethrough_tableto_field_source_field
from_fieldfrom_field_source_field r4   Y/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/tortoise/query_utils.pyget_joins_for_related_field    sV   


%
r6   
root_modeltype[Model]lookup_expressionSequence[Field]c                 C  s   | d}g }| }|d d D ] }||jjvrt| dtt|jj| }|| |j}qz||jj|d   W |S  t	yL   t| dw )Nr   z not resolvable)
splitr   fetch_fieldsr   r   r   r-   r"   r   KeyError)r7   r9   field_namesfieldsr#   
field_namefieldr4   r4   r5   expand_lookup_expressionW   s   

rC   r#   rB   4tuple[Term, list[TableCriterionTuple], Field | None]c                 C  s<  g }t | |}|dd D ]-}tt|}|t|||j |j} |jjj}t	|t
r8||  d|j }|}q|d }|j| jjv rxtt|}|jj}	|t|||j |	j}t	|trr||krr||  d|j }||	j }
n!|jr||j }
n||j }
|r|| jjjjd}|r|||
}
|
||fS )z
    Resolves a nested field string like events__participants__name and
    returns the pypika term, required joins and the Field that can be used for
    converting the value.
    Nr;   r   function_cast)rC   r   r   extendr6   r)   r   r   r   r    r   r*   r+   r=   r   r$   r(   get_for_dialectdbcapabilitiesdialect)r#   r   rB   joinsr@   
iter_fieldr   r/   
last_fieldrelated_field_metatermfuncr4   r4   r5   resolve_nested_fieldi   sD   








rQ   c                   @  s*   e Zd ZdddZdddZdd	d
ZdS )EmptyCriterionotherr
   r   c                 C     |S Nr4   selfrS   r4   r4   r5   __or__      zEmptyCriterion.__or__c                 C  rT   rU   r4   rV   r4   r4   r5   __and__   rY   zEmptyCriterion.__and__boolc                 C  s   dS )NFr4   rW   r4   r4   r5   __bool__   rY   zEmptyCriterion.__bool__N)rS   r
   r   r
   )r   r[   )__name__
__module____qualname__rX   rZ   r]   r4   r4   r4   r5   rR      s    

rR   leftr
   rightc                 C  s   | r|s| S | |@ S rU   r4   ra   rb   r4   r4   r5   _and      rd   c                 C  s   | r|s| S | |B S rU   r4   rc   r4   r4   r5   _or   re   rf   c                   @  sJ   e Zd ZdZ			ddd
dZdddZdddZdddZdddZdS )QueryModifierz:
    Internal structure used to generate SQL Queries.
    Nwhere_criterionCriterion | NonerK    list[TableCriterionTuple] | Nonehaving_criterionr   Nonec                 C  s&   |pt  | _|p	g | _|pt  | _d S rU   )rR   rh   rK   rk   )rW   rh   rK   rk   r4   r4   r5   __init__   s   
zQueryModifier.__init__rS   c                 C  s,   | j t| j|j| j|j t| j|jdS )N)rh   rK   rk   )	__class__rd   rh   rK   rk   rV   r4   r4   r5   rZ      s
   
zQueryModifier.__and__r
   c                 C  s   t | j| jS rU   )rd   rh   rk   r\   r4   r4   r5   _and_criterion   s   zQueryModifier._and_criterionc                 C  sb   d  }}| j s
|j rt|  | }n| jr |jr | j|jB n| jp%|j}| || j|j |S rU   )rk   rf   ro   rh   rn   rK   )rW   rS   rh   rk   r4   r4   r5   rX      s   
zQueryModifier.__or__c                 C  s@   d  }}| j r| j| j @  }n| jr| j }| || j|S rU   )rk   rh   negatern   rK   )rW   rh   rk   r4   r4   r5   
__invert__   s   
zQueryModifier.__invert__)NNN)rh   ri   rK   rj   rk   ri   r   rl   )rS   rg   r   rg   )r   r
   )r   rg   )	r^   r_   r`   __doc__rm   rZ   ro   rX   rq   r4   r4   r4   r5   rg      s    



rg   c                   @  s*   e Zd ZdZdZddddZdddZdS )PrefetchaA  
    Prefetcher container. One would directly use this when wanting to attach a custom QuerySet
    for specialised prefetching.

    :param relation: Related field name.
    :param queryset: Custom QuerySet to use for prefetching.
    :param to_attr: Sets the result of the prefetch operation to a custom attribute.
    )relationquerysetto_attrNrt   r   ru   r   rv   
str | Noner   rl   c                 C  s*   || _ || _|| _t| jjjj| j_d S rU   )rv   rt   ru   r   r#   r   	basequeryquery)rW   rt   ru   rv   r4   r4   r5   rm      s   zPrefetch.__init__c                 C  s   | j d\}}}||jjjvrtd| d|jjj d|r<||jvr+t |j|< |j| 	t
|| j| jd dS |j|g | j| jf dS )z
        Called internally to generate prefetching query.

        :param queryset: Custom QuerySet to use for prefetching.
        :raises OperationalError: If field does not exist in model.
        r   z	relation z for z
 not found)rv   N)rt   	partitionr#   r   r=   r   db_table_prefetch_mapsetaddrs   ru   rv   _prefetch_queries
setdefaultr"   )rW   ru   first_level_fieldr   forwarded_prefetchr4   r4   r5   resolve_for_queryset   s   


zPrefetch.resolve_for_querysetrU   )rt   r   ru   r   rv   rw   r   rl   )ru   r   r   rl   )r^   r_   r`   rr   	__slots__rm   r   r4   r4   r4   r5   rs      s
    	rs   valuedict[str, Any]operator_keywords#dict[str, Callable[..., Criterion]]5tuple[list[str | int], Any, Callable[..., Criterion]]c                 C  sP   |   \\}}dd |dD }|d |v r |t|d ntj}|||fS )zZ
    Extracts the key parts, filter value and operator from a JSON filter dictionary.
    c                 S  s$   g | ]}|  rt|nt|qS r4   )isdigitintr   ).0itemr4   r4   r5   
<listcomp>  s   $ z,get_json_filter_operator.<locals>.<listcomp>r   r;   )itemsr<   r   popoperatoreq)r   r   keyfilter_value	key_parts	operator_r4   r4   r5   get_json_filter_operator  s   

r   
field_termr   r   list[str | int]c                 C  s
   t | |S )z
    Resolves a JSON path from a list of key parts, e.g. converting
    (field, ['a', 'b', 'c']) to field->'a'->'b'->>'c'. Returns a pypika Term.
    )r   )r   r   r4   r4   r5   resolve_field_json_path!  s   
r   )r   r	   r   r   r   r   r   r   )r7   r8   r9   r   r   r:   )r#   r8   r   r	   rB   r   r   rD   )ra   r
   rb   r
   r   r
   )r   r   r   r   r   r   )r   r   r   r   r   r   )+
__future__r   r   collections.abcr   r   typingr   r   r   r   pypika_tortoiser	   pypika_tortoise.termsr
   r   r   tortoise.exceptionsr   r   tortoise.fields.baser   tortoise.fields.relationalr   r   r   r   tortoise.modelsr   tortoise.querysetr   tupleTableCriterionTupler6   rC   rQ   rR   rd   rf   rg   rs   r   r   r4   r4   r4   r5   <module>   s0    

7
7

.
,