3
v^p                 @   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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DeleteQueryUpdateQueryInsertQueryAggregateQueryc               @   s,   e Zd ZdZdZdd Zdd Zdd Zd	S )
r	   zA DELETE SQL query.ZSQLDeleteCompilerc             C   s4   || j | i| _ || _| j|jt}|r0|jS dS )Nr   )	alias_mapwhereget_compilerexecute_sqlr   rowcount)selftabler   usingcursor r   C/usr/lib/python3.6/site-packages/django/db/models/sql/subqueries.pydo_query   s    zDeleteQuery.do_queryc          	   C   sx   d}| 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   attnamer   db_table)r   pk_listr   Znum_deletedfieldoffsetr   r   r   delete_batch   s    

 zDeleteQuery.delete_batchc                s   |j   j  | j  t fdd jD }| sB|t| jkrL j| _nt|jjj}t| j	j
st|jddd}|s|d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   )alias_refcount).0t)innerqr   r   
<listcomp>7   s    z)DeleteQuery.delete_qs.<locals>.<listcomp>r   T)flatr   )pk__in)queryget_initial_aliastupler   r   model_metar   r   featuresZupdate_can_self_selectlistZvalues_listr$   clear_select_clauseget_colselectr   r   r   r   r   r   r   )r   r,   r   Zinnerq_used_tablesr   valuesr   r   )r(   r   	delete_qs,   s&    


zDeleteQuery.delete_qsN)__name__
__module____qualname____doc__compilerr   r$   r7   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|| | j  d S )N)super__init___setup_query)r   argskwargs)	__class__r   r   r>   T   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)r6   related_idsrelated_updates)r   r   r   r   r?   X   s    zUpdateQuery._setup_queryc                s   t  j }| jj |_|S )N)r=   clonerD   copy)r   obj)rB   r   r   rE   a   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!   r6   r   r#   r   r   r   update_batchf   s
    

zUpdateQuery.update_batchc             C   s   g }x|j  D ]\}}| j j|}|jo0|j  p:|j }|jjj}| sX|jrd|j	rdt
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).)itemsr   	get_fieldauto_createdconcreter/   r0   concrete_modelis_relationmany_to_manyr   add_related_updateappendadd_update_fields)r   r6   
values_seqnamevalr"   directr/   r   r   r   rH   m   s    
zUpdateQuery.add_update_valuesc             C   sD   x>|D ]6\}}}t |dr*|j| ddd}| jj|||f qW 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)allow_joinsfor_saveN)hasattrrX   r6   rR   )r   rT   r"   r/   rV   r   r   r   rS      s    
zUpdateQuery.add_update_fieldsc             C   s   | j j|g j|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)rD   
setdefaultrR   )r   r/   r"   valuer   r   r   rQ      s    zUpdateQuery.add_related_updatec             C   s\   | j s
g S g }xH| j j D ]:\}}t|}||_| jdk	rJ|jd| jf |j| qW |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.
        Nr+   )rD   rJ   r
   r6   rC   
add_filterrR   )r   resultr/   r6   r,   r   r   r   get_related_updates   s    
zUpdateQuery.get_related_updates)r8   r9   r:   r;   r<   r>   r?   rE   rI   rH   rS   rQ   r`   __classcell__r   r   )rB   r   r
   O   s   	c                   s0   e Zd ZdZdd fdd
ZdddZ  ZS )	r   ZSQLInsertCompilerF)ignore_conflictsc               s$   t  j|| g | _g | _|| _d S )N)r=   r>   fieldsobjsrb   )r   rb   r@   rA   )rB   r   r   r>      s    zInsertQuery.__init__c             C   s   || _ || _|| _d S )N)rc   rd   raw)r   rc   rd   re   r   r   r   insert_values   s    zInsertQuery.insert_values)F)r8   r9   r:   r<   r>   rf   ra   r   r   )rB   r   r      s   c               @   s   e Zd ZdZdZdd ZdS )r   zu
    Take another query as a parameter to the FROM clause and only select the
    elements in the provided list.
    ZSQLAggregateCompilerc             C   s$   d|_ |j|jdd\| _ | _d S )NT)Zwith_col_aliases)subqueryr   as_sqlZ
sub_params)r   r,   r   r   r   r   add_subquery   s    zAggregateQuery.add_subqueryN)r8   r9   r:   r;   r<   ri   r   r   r   r   r      s   N)r;   django.core.exceptionsr   	django.dbr   django.db.models.query_utilsr   django.db.models.sql.constantsr   r   r   django.db.models.sql.queryr   __all__r	   r
   r   r   r   r   r   r   <module>   s   ?Z