U
    e/                     @   s   d Z ddlmZ ddlmZmZmZ ddlmZ ddddgZ	G d	d deZ
G d
d deZG dd deZG dd deZdS )zR
Query subclasses which provide extra functionality beyond simple data retrieval.
    )
FieldError)CURSORGET_ITERATOR_CHUNK_SIZE
NO_RESULTS)QueryDeleteQueryUpdateQueryInsertQueryAggregateQueryc                   @   s$   e Zd ZdZdZdd Zdd ZdS )r   zA DELETE SQL query.ZSQLDeleteCompilerc              
   C   sL   || j | i| _ || _| |t}|rH| |jW  5 Q R  S Q R X dS )Nr   )Z	alias_mapwhereget_compilerexecute_sqlr   Zrowcount)selftabler   usingcursor r   C/tmp/pip-unpacked-wheel-lctamlir/django/db/models/sql/subqueries.pydo_query   s    zDeleteQuery.do_queryc                 C   sl   d}|   j}tdt|tD ]H}|   | |j d|||t   || j|   j	| j
|d7 }q|S )z
        Set up and execute delete queries for all the objects in pk_list.

        More than one physical query may be executed if there are a
        lot of values in pk_list.
        r   Z__in)r   )get_metapkrangelenr   clear_where
add_filterZattnamer   Zdb_tabler   )r   pk_listr   Znum_deletedfieldoffsetr   r   r   delete_batch   s    

  
zDeleteQuery.delete_batchN)__name__
__module____qualname____doc__compilerr   r   r   r   r   r   r      s   	c                       s`   e Zd ZdZdZ fddZdd Z fddZd	d
 Zdd Z	dd Z
dd Zdd Z  ZS )r   zAn UPDATE SQL query.ZSQLUpdateCompilerc                    s   t  j|| |   d S N)super__init___setup_query)r   argskwargs	__class__r   r   r&   5   s    zUpdateQuery.__init__c                 C   s   g | _ d| _i | _dS )z
        Run on initialization and at the end of chaining. Any attributes that
        would normally be set in __init__() should go here instead.
        N)valuesrelated_idsrelated_updates)r   r   r   r   r'   9   s    zUpdateQuery._setup_queryc                    s   t   }| j |_|S r$   )r%   cloner.   copy)r   objr*   r   r   r/   B   s    
zUpdateQuery.clonec                 C   sT   |  | tdt|tD ]4}|   | d|||t   | |t qd S )Nr   pk__in)	add_update_valuesr   r   r   r   r   r   r   r   )r   r   r,   r   r   r   r   r   update_batchG   s    
 zUpdateQuery.update_batchc                 C   s   g }|  D ]\}}|  |}|jo.|j  p8|j }|jjj}|rT|jr`|j	r`t
d| ||  jk	r~| ||| q||||f q| |S )z
        Convert a dictionary of field name to value mappings into an update
        query. This is the entry point for the public update() method on
        querysets.
        zMCannot update model field %r (only non-relations and foreign keys permitted).)itemsr   	get_fieldZauto_createdZconcretemodelZ_metaZconcrete_modelZis_relationZmany_to_manyr   add_related_updateappendadd_update_fields)r   r,   
values_seqnamevalr   directr7   r   r   r   r3   P   s"    
zUpdateQuery.add_update_valuesc                 C   s@   |D ]6\}}}t |dr(|j| ddd}| j|||f qdS )z
        Append a sequence of (field, model, value) triples to the internal list
        that will be used to generate the UPDATE query. Might be more usefully
        called add_update_targets() to hint at the extra information here.
        resolve_expressionFT)Zallow_joinsZfor_saveN)hasattrr?   r,   r9   )r   r;   r   r7   r=   r   r   r   r:   h   s    
zUpdateQuery.add_update_fieldsc                 C   s   | j |g |d|f dS )z
        Add (name, value) to an update query for an ancestor model.

        Update are coalesced so that only one update query per ancestor is run.
        N)r.   
setdefaultr9   )r   r7   r   valuer   r   r   r8   t   s    zUpdateQuery.add_related_updatec                 C   sZ   | j s
g S g }| j  D ]<\}}t|}||_| jdk	rJ|d| j|  || q|S )z
        Return a list of query objects: one for each update required to an
        ancestor model. Each query will have the same filtering conditions as
        the current query but will only update a single table.
        Nr2   )r.   r5   r   r,   r-   r   r9   )r   resultr7   r,   queryr   r   r   get_related_updates|   s    
zUpdateQuery.get_related_updates)r   r    r!   r"   r#   r&   r'   r/   r4   r3   r:   r8   rE   __classcell__r   r   r*   r   r   0   s   		c                       s4   e Zd ZdZdddd fdd
Zd	ddZ  ZS )
r	   ZSQLInsertCompilerN)on_conflictupdate_fieldsunique_fieldsc                   s8   t  j|| g | _g | _|| _|p&g | _|p0g | _d S r$   )r%   r&   fieldsobjsrG   rH   rI   )r   rG   rH   rI   r(   r)   r*   r   r   r&      s    
zInsertQuery.__init__Fc                 C   s   || _ || _|| _d S r$   )rJ   rK   raw)r   rJ   rK   rL   r   r   r   insert_values   s    zInsertQuery.insert_values)F)r   r    r!   r#   r&   rM   rF   r   r   r*   r   r	      s     
c                       s$   e Zd ZdZdZ fddZ  ZS )r
   zu
    Take another query as a parameter to the FROM clause and only select the
    elements in the provided list.
    ZSQLAggregateCompilerc                    s   || _ t | d S r$   )inner_queryr%   r&   )r   r7   rN   r*   r   r   r&      s    zAggregateQuery.__init__)r   r    r!   r"   r#   r&   rF   r   r   r*   r   r
      s   N)r"   Zdjango.core.exceptionsr   Zdjango.db.models.sql.constantsr   r   r   Zdjango.db.models.sql.queryr   __all__r   r   r	   r
   r   r   r   r   <module>   s   $^