3
7^V6                 @   s   d dl Z d dlZd dl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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 G dd deZdS )    N)	lru_cache)chain)settings)
FieldError)utils)BaseDatabaseOperations)
aggregatesfields)Col)timezone)
parse_dateparse_datetime
parse_time)duration_microseconds)cached_propertyc                   sV  e Zd ZdZdddZdZdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zed+d, ZdNd.d/Zd0d1 Zd2d3 Z fd4d5Zd6d7 Zd8d9 Z d:d; Z!d<d= Z"d>d? Z#d@dA Z$dBdC Z% fdDdEZ&dFdG Z'dHdI Z(dJdK Z)dO fdLdM	Z*  Z+S )PDatabaseOperationstextZTEXT)	DateFieldDateTimeFieldzEXPLAIN QUERY PLANc             C   s:   t |dkrdS t |dkr.| jjjt | S t |S dS )z
        SQLite has a compile-time default (SQLITE_LIMIT_VARIABLE_NUMBER) of
        999 variables per query.

        If there's only a single field to insert, the limit is 500
        (SQLITE_MAX_COMPOUND_SELECT).
           i  N)len
connectionfeaturesZmax_query_params)selfr	   objs r   G/tmp/pip-build-8app2_gc/Django/django/db/backends/sqlite3/operations.pybulk_batch_size   s
    z"DatabaseOperations.bulk_batch_sizec             C   s   t jt jt jf}tjtjtjtjf}t	||rtxD|j
 D ]8}y
|j}W n tk
rZ   Y q8X t	||r8tjdq8W t	|tjrt|jdkrtjdd S )Nz{You cannot use Sum, Avg, StdDev, and Variance aggregations on date/time fields in sqlite3 since date/time is saved as text.r   zTSQLite doesn't support DISTINCT on aggregate functions accepting multiple arguments.)r	   r   r   	TimeFieldr   ZSumZAvgZVarianceZStdDev
isinstanceZget_source_expressionsoutput_fieldr   r   ZNotSupportedErrorZ	Aggregater   Zsource_expressions)r   
expressionZ
bad_fieldsZbad_aggregatesexprr    r   r   r   check_expression_support*   s    



z+DatabaseOperations.check_expression_supportc             C   s   d|j  |f S )z
        Support EXTRACT with a user-defined function django_date_extract()
        that's registered in connect(). Use single quotes because this is a
        string and could otherwise cause a collision with a field name.
        zdjango_date_extract('%s', %s))lower)r   lookup_type
field_namer   r   r   date_extract_sqlB   s    z#DatabaseOperations.date_extract_sqlc             C   s   t t|S )N)strr   )r   	timedeltar   r   r   date_interval_sqlJ   s    z$DatabaseOperations.date_interval_sqlc             C   s   |S )z>Do nothing since formatting is handled in the custom function.r   )r   sqlr   r   r   format_for_duration_arithmeticM   s    z1DatabaseOperations.format_for_duration_arithmeticc             C   s   d|j  |f S )Nzdjango_date_trunc('%s', %s))r$   )r   r%   r&   r   r   r   date_trunc_sqlQ   s    z!DatabaseOperations.date_trunc_sqlc             C   s   d|j  |f S )Nzdjango_time_trunc('%s', %s))r$   )r   r%   r&   r   r   r   time_trunc_sqlT   s    z!DatabaseOperations.time_trunc_sqlc             C   s   t jrd| S dS )Nz'%s'NULL)r   USE_TZ)r   tznamer   r   r   _convert_tzname_to_sqlW   s    z)DatabaseOperations._convert_tzname_to_sqlc             C   s   d|| j |f S )Nz!django_datetime_cast_date(%s, %s))r2   )r   r&   r1   r   r   r   datetime_cast_date_sqlZ   s    z)DatabaseOperations.datetime_cast_date_sqlc             C   s   d|| j |f S )Nz!django_datetime_cast_time(%s, %s))r2   )r   r&   r1   r   r   r   datetime_cast_time_sql_   s    z)DatabaseOperations.datetime_cast_time_sqlc             C   s   d|j  || j|f S )Nz%django_datetime_extract('%s', %s, %s))r$   r2   )r   r%   r&   r1   r   r   r   datetime_extract_sqld   s    z'DatabaseOperations.datetime_extract_sqlc             C   s   d|j  || j|f S )Nz#django_datetime_trunc('%s', %s, %s))r$   r2   )r   r%   r&   r1   r   r   r   datetime_trunc_sqli   s    z%DatabaseOperations.datetime_trunc_sqlc             C   s   d|j  |f S )Nzdjango_time_extract('%s', %s))r$   )r   r%   r&   r   r   r   time_extract_sqln   s    z#DatabaseOperations.time_extract_sqlc             C   s   dS )Nr/   r   )r   r   r   r   pk_default_valueq   s    z#DatabaseOperations.pk_default_valuec          
   C   s   d}t ||krPf }x6tdt ||D ]"}||||  }|| j|7 }q&W |S ddjdgt |  }| jjj }z|j||j S |j  X dS )zV
        Only for last_executed_query! Don't use this to execute SQL queries!
        i  r   zSELECT z, zQUOTE(?)N)	r   range%_quote_params_for_last_executed_queryjoinr   cursorexecuteZfetchoneclose)r   paramsZ
BATCH_SIZEresultsindexchunkr+   r<   r   r   r   r:   t   s    	z8DatabaseOperations._quote_params_for_last_executed_queryc             C   sR   |rJt |ttfr| j|}n$t|j }| j|}tt||}|| S |S d S )N)r   listtupler:   valuesdictzip)r   r<   r+   r?   rE   r   r   r   last_executed_query   s    
z&DatabaseOperations.last_executed_queryc             C   s    |j dr|jdr|S d| S )N"z"%s")
startswithendswith)r   namer   r   r   
quote_name   s    zDatabaseOperations.quote_namec             C   s   dS )Nr   r   )r   r   r   r   no_limit_value   s    z!DatabaseOperations.no_limit_valuec          
   C   sB   d}|ddf}| j j  }|j||}dd |j D S Q R X d S )Nz
        WITH tables AS (
            SELECT %s name
            UNION
            SELECT sqlite_master.name
            FROM sqlite_master
            JOIN tables ON (sql REGEXP %s || tables.name || %s)
        ) SELECT name FROM tables;
        z(?i)\s+references\s+("|\')?z("|\')?\s*\(c             S   s   g | ]}|d  qS )r   r   ).0rowr   r   r   
<listcomp>   s    z9DatabaseOperations.__references_graph.<locals>.<listcomp>)r   r<   r=   Zfetchall)r   Z
table_namequeryr?   r<   r@   r   r   r   Z__references_graph   s    	z%DatabaseOperations.__references_graphc             C   s   t dd| jS )Ni   )maxsize)r   %_DatabaseOperations__references_graph)r   r   r   r   _references_graph   s    z$DatabaseOperations._references_graphFc                s<   |r$|r$t tj fdd|D } fdd|D }|S )Nc             3   s   | ]} j |V  qd S )N)rV   )rP   table)r   r   r   	<genexpr>   s    z/DatabaseOperations.sql_flush.<locals>.<genexpr>c                s2   g | ]*}d j dj dj j|f qS )z	%s %s %s;DELETEZFROM)ZSQL_KEYWORDZ	SQL_FIELDrM   )rP   rW   )r   styler   r   rR      s   z0DatabaseOperations.sql_flush.<locals>.<listcomp>)setr   from_iterable)r   rZ   Ztables	sequencesZallow_cascader+   r   )r   rZ   r   	sql_flush   s
    zDatabaseOperations.sql_flushc             C   sL   |d krd S t |dr|S tj|rDtjr<tj|| jj}ntdt|S )Nresolve_expressionzNSQLite backend does not support timezone-aware datetimes when USE_TZ is False.)	hasattrr   is_awarer   r0   Z
make_naiver   
ValueErrorr(   )r   valuer   r   r   adapt_datetimefield_value   s    

z,DatabaseOperations.adapt_datetimefield_valuec             C   s4   |d krd S t |dr|S tj|r,tdt|S )Nr_   z5SQLite backend does not support timezone-aware times.)r`   r   ra   rb   r(   )r   rc   r   r   r   adapt_timefield_value   s    

z(DatabaseOperations.adapt_timefield_valuec                s   t  j|}|jj }|dkr,|j| j np|dkrB|j| j nZ|dkrX|j| j nD|dkrr|j| j| n*|dkr|j| j	 n|dkr|j| j
 |S )	Nr   r   r   ZDecimalFieldZ	UUIDFieldNullBooleanFieldBooleanField)rf   rg   )superget_db_convertersr    Zget_internal_typeappendconvert_datetimefield_valueconvert_datefield_valueconvert_timefield_valueget_decimalfield_converterconvert_uuidfield_valueconvert_booleanfield_value)r   r!   
convertersinternal_type)	__class__r   r   ri      s    
z$DatabaseOperations.get_db_convertersc             C   sB   |d k	r>t |tjst|}tjr>tj| r>tj|| jj}|S )N)	r   datetimer   r   r0   r   ra   Z
make_awarer   )r   rc   r!   r   r   r   r   rk      s    z.DatabaseOperations.convert_datetimefield_valuec             C   s    |d k	rt |tjst|}|S )N)r   rt   dater   )r   rc   r!   r   r   r   r   rl     s    z*DatabaseOperations.convert_datefield_valuec             C   s    |d k	rt |tjst|}|S )N)r   rt   timer   )r   rc   r!   r   r   r   r   rm     s    z*DatabaseOperations.convert_timefield_valuec                sN   t jddj t|tr>t jdj|jj  fdd}n fdd}|S )N   )precr   c                s"   | d k	r | j |jjdS d S )N)context)quantizer    ry   )rc   r!   r   )create_decimalquantize_valuer   r   	converter  s    z@DatabaseOperations.get_decimalfield_converter.<locals>.converterc                s   | d k	r | S d S )Nr   )rc   r!   r   )r{   r   r   r}     s    )	decimalContextcreate_decimal_from_floatr   r
   Decimalscalebr    Zdecimal_places)r   r!   r}   r   )r{   r|   r   rn     s    
z-DatabaseOperations.get_decimalfield_converterc             C   s   |d k	rt j|}|S )N)uuidUUID)r   rc   r!   r   r   r   r   ro   $  s    
z*DatabaseOperations.convert_uuidfield_valuec             C   s   |dkrt |S |S )Nr   r   )r   r   )bool)r   rc   r!   r   r   r   r   rp   )  s    z-DatabaseOperations.convert_booleanfield_valuec             C   s   dj dd |D S )Nz UNION ALL c             s   s   | ]}d dj | V  qdS )z	SELECT %sz, N)r;   )rP   rQ   r   r   r   rX   .  s   z5DatabaseOperations.bulk_insert_sql.<locals>.<genexpr>)r;   )r   r	   Zplaceholder_rowsr   r   r   bulk_insert_sql,  s    z"DatabaseOperations.bulk_insert_sqlc                s$   |dkrddj | S t j||S )N^z	POWER(%s),)r;   rh   combine_expression)r   	connectorsub_expressions)rs   r   r   r   2  s    z%DatabaseOperations.combine_expressionc             C   sF   |d	krt jd| d| g| }t|dkr8tdddj| S )
N+-z$Invalid connector for timedelta: %s.z'%s'   z)Too many params for timedelta operations.zdjango_format_dtdelta(%s)z, )r   r   )r   ZDatabaseErrorr   rb   r;   )r   r   r   Z	fn_paramsr   r   r   combine_duration_expression9  s    z.DatabaseOperations.combine_duration_expressionc             C   s   dS )N)NNr   )r   rr   r   r   r   integer_field_rangeA  s    z&DatabaseOperations.integer_field_rangec             C   s@   |\}}|\}}|dkr,d||f || fS d||f || fS )Nr   zdjango_time_diff(%s, %s)zdjango_timestamp_diff(%s, %s)r   )r   rr   lhsrhsZlhs_sqlZ
lhs_paramsZrhs_sqlZ
rhs_paramsr   r   r   subtract_temporalsE  s
    z%DatabaseOperations.subtract_temporalsc                s   |rdS t  j|S )NzINSERT OR IGNORE INTO)rh   insert_statement)r   Zignore_conflicts)rs   r   r   r   L  s    z#DatabaseOperations.insert_statement)F)F),__name__
__module____qualname__Z"cast_char_field_without_max_lengthZcast_data_typesZexplain_prefixr   r#   r'   r*   r,   r-   r.   r2   r3   r4   r5   r6   r7   r8   r:   rH   rM   rO   rU   r   rV   r^   rd   re   ri   rk   rl   rm   rn   ro   rp   r   r   r   r   r   r   __classcell__r   r   )rs   r   r      sP   
r   )rt   r~   r   	functoolsr   	itertoolsr   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Z"django.db.backends.base.operationsr   Zdjango.db.modelsr   r	   Zdjango.db.models.expressionsr
   Zdjango.utilsr   Zdjango.utils.dateparser   r   r   Zdjango.utils.durationr   Zdjango.utils.functionalr   r   r   r   r   r   <module>   s   