3
(hF                 @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
 ddl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)connections)Q)CURSORGET_ITERATOR_CHUNK_SIZE
NO_RESULTS)Query)sixDeleteQueryUpdateQueryInsertQueryAggregateQueryc               @   s.   e Zd ZdZdZdd Zd
ddZdd	 ZdS )r
   zo
    Delete queries are done through this class, since they are more constrained
    than general queries.
    ZSQLDeleteCompilerc             C   s,   |g| _ || _| j|jt}|r(|jS dS )Nr   )tableswhereget_compilerexecute_sqlr   rowcount)selftabler   usingcursor r   C/tmp/pip-install-q3hcpn_q/Django/django/db/models/sql/subqueries.pydo_query   s    zDeleteQuery.do_queryNc          	   C   s|   d}|s| j  j}xdtdt|tD ]P}| j | _| jtf |j	d |||t  i || j
| j  j| j|d7 }q$W |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   where_classr   add_qr   Zattnamer   Zdb_table)r   pk_listr   fieldZnum_deletedoffsetr   r   r   delete_batch   s    

 zDeleteQuery.delete_batchc                s   |j   j  | j   fdd jD }| s:|| jkrD j| _nt|jjj}t| jj	st
|jddd}|stdS | j||S  j  |j| j g _ }| j | _| jt|d | j|jt}|r|jS dS )z
        Delete the queryset in one SQL query (if possible). For simple queries
        this is done by copying the query.query.where to self.query, for
        complex queries by using subquery.
        c                s   g | ]} j | r|qS r   )Zalias_refcount).0t)innerqr   r   
<listcomp><   s    z)DeleteQuery.delete_qs.<locals>.<listcomp>r   T)Zflatr   )pk__in)queryZget_initial_aliasr   r   model_metar   r   featuresZupdate_can_self_selectlistZvalues_listr#   Zclear_select_clauseZget_colselectr   r   r   r   r   r   r   )r   r)   r   Zinnerq_used_tablesr   valuesr   r   )r&   r   	delete_qs1   s&    


zDeleteQuery.delete_qs)N)__name__
__module____qualname____doc__compilerr   r#   r0   r   r   r   r   r
      s
   
c                   sb   e Zd ZdZdZ fddZdd Zd fdd		Zd
d Zdd Z	dd Z
dd Zdd Z  ZS )r   z+
    Represents an "update" SQL query.
    ZSQLUpdateCompilerc                s   t t| j|| | j  d S )N)superr   __init___setup_query)r   argskwargs)	__class__r   r   r7   \   s    zUpdateQuery.__init__c             C   s    g | _ d| _t| dsi | _dS )z
        Runs on initialization and after cloning. Any attributes that would
        normally be set in __init__ should go in here, instead, so that they
        are also set up after a clone() call.
        Nrelated_updates)r/   related_idshasattrr<   )r   r   r   r   r8   `   s    
zUpdateQuery._setup_queryNc                s"   t t| j|fd| jj i|S )Nr<   )r6   r   cloner<   copy)r   klassr:   )r;   r   r   r?   k   s    zUpdateQuery.clonec             C   s^   | j | xNtdt|tD ]:}| j | _| jt|||t  d | j|j	t
 qW d S )Nr   )r(   )add_update_valuesr   r   r   r   r   r   r   r   r   r   )r   r    r/   r   r"   r   r   r   update_batchn   s
    

zUpdateQuery.update_batchc             C   s   g }xt j|D ]\}}| j j|}|jo2|j  p<|j }|jjj}| sZ|j	rf|j
rftd| || j jk	r| j||| q|j|||f qW | j|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).)r	   	iteritemsr   	get_fieldZauto_createdZconcreter*   r+   Zconcrete_modelZis_relationZmany_to_manyr   add_related_updateappendadd_update_fields)r   r/   
values_seqnamevalr!   directr*   r   r   r   rB   u   s    
zUpdateQuery.add_update_valuesc             C   s   | j j| 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.
        N)r/   extend)r   rI   r   r   r   rH      s    zUpdateQuery.add_update_fieldsc             C   s   | j j|g j|d|f dS )z
        Adds (name, value) to an update query for an ancestor model.

        Updates are coalesced so that we only run one update query per ancestor.
        N)r<   
setdefaultrG   )r   r*   r!   valuer   r   r   rF      s    zUpdateQuery.add_related_updatec             C   s^   | j s
g S g }xJtj| j D ]:\}}t|}||_| jdk	rL|jd| jf |j| qW |S )z
        Returns 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.
        Nr(   )r<   r	   rD   r   r/   r=   Z
add_filterrG   )r   resultr*   r/   r)   r   r   r   get_related_updates   s    
zUpdateQuery.get_related_updates)N)r1   r2   r3   r4   r5   r7   r8   r?   rC   rB   rH   rF   rQ   __classcell__r   r   )r;   r   r   U   s   c                   s8   e Zd ZdZ fddZd
 fdd	Zddd	Z  ZS )r   ZSQLInsertCompilerc                s"   t t| j|| g | _g | _d S )N)r6   r   r7   fieldsobjs)r   r9   r:   )r;   r   r   r7      s    zInsertQuery.__init__Nc                s@   | j d d  | jd d  | jd}|j| tt| j|f|S )N)rS   rT   raw)rS   rT   rU   updater6   r   r?   )r   rA   r:   extras)r;   r   r   r?      s
    

zInsertQuery.cloneFc             C   s   || _ || _|| _dS )a  
        Set up the insert query from the 'insert_values' dictionary. The
        dictionary gives the model field names and their target values.

        If 'raw_values' is True, the values in the 'insert_values' dictionary
        are inserted directly into the query, rather than passed as SQL
        parameters. This provides a way to insert NULL and DEFAULT keywords
        into the query, for example.
        N)rS   rT   rU   )r   rS   rT   rU   r   r   r   insert_values   s    
zInsertQuery.insert_values)N)F)r1   r2   r3   r5   r7   r?   rX   rR   r   r   )r;   r   r      s   	c               @   s   e Zd ZdZdZdd ZdS )r   z
    An AggregateQuery takes another query as a parameter to the FROM
    clause and only selects the elements in the provided list.
    ZSQLAggregateCompilerc             C   s    |j |jddd\| _| _d S )NT)Zwith_col_aliasessubquery)r   Zas_sqlrY   Z
sub_params)r   r)   r   r   r   r   add_subquery   s    
zAggregateQuery.add_subqueryN)r1   r2   r3   r4   r5   rZ   r   r   r   r   r      s   N)r4   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.models.query_utilsr   Zdjango.db.models.sql.constantsr   r   r   Zdjango.db.models.sql.queryr   Zdjango.utilsr	   __all__r
   r   r   r   r   r   r   r   <module>   s   DX 