U
    dwB                     @   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mZ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mZ d dlmZ G dd deZdS )    N)	lru_cache)chain)settings)
FieldError)DatabaseErrorNotSupportedErrormodels)BaseDatabaseOperations)
OnConflict)Col)timezone)
parse_dateparse_datetime
parse_time)cached_propertyc                       s  e Zd ZdZdddZdZedddgZdd	 Zd
d Z	dd Z
dd Zdd ZdYddZdZd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/d0 Zd1d1d2d3d4Zd5d6 Zd7d8 Zd9d: Z  fd;d<Z!d=d> Z"d?d@ Z#dAdB Z$dCdD Z%dEdF Z&dGdH Z'dIdJ Z( fdKdLZ)dMdN Z*dOdP Z+dQdR Z,d[ fdSdT	Z-dUdV Z. fdWdXZ/  Z0S )\DatabaseOperationstextZTEXT)	DateFieldDateTimeFieldzEXPLAIN QUERY PLANnullfalsetruec                 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)selffieldsobjs r   I/tmp/pip-unpacked-wheel-7vj2equ7/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||rr|	 D ]:}z
|j
}W n ttfk
r\   Y q6X t||r6tdq6t|t jr|jrt|jdkrt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   	TimeFieldZSumZAvgZVarianceZStdDev
isinstanceZget_source_expressionsoutput_fieldAttributeErrorr   r   Z	AggregateZdistinctr   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| d|  f|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, )lowerr   lookup_typesqlparamsr   r   r    date_extract_sqlH   s    z#DatabaseOperations.date_extract_sqlc                 C   s   |  S )z
        Given a cursor object that has just performed an INSERT...RETURNING
        statement into a table, return the list of returned data.
        )fetchall)r   cursorr   r   r    fetch_returned_insert_rowsP   s    z-DatabaseOperations.fetch_returned_insert_rowsc                 C   s   |S )z>Do nothing since formatting is handled in the custom function.r   )r   r.   r   r   r    format_for_duration_arithmeticW   s    z1DatabaseOperations.format_for_duration_arithmeticNc                 C   s"   d| d|  f|| |fS )Nzdjango_date_trunc(%s, 	, %s, %s)r+   _convert_tznames_to_sqlr   r-   r.   r/   tznamer   r   r    date_trunc_sql[   s    
z!DatabaseOperations.date_trunc_sqlc                 C   s"   d| d|  f|| |fS )Nzdjango_time_trunc(%s, r5   r6   r8   r   r   r    time_trunc_sqlb   s    
z!DatabaseOperations.time_trunc_sqlc                 C   s   |rt jr|| jjfS dS N)NN)r   USE_TZr   Ztimezone_name)r   r9   r   r   r    r7   i   s    
z*DatabaseOperations._convert_tznames_to_sqlc                 C   s   d| d||  |fS )Nzdjango_datetime_cast_date(r5   r7   r   r.   r/   r9   r   r   r    datetime_cast_date_sqln   s    
z)DatabaseOperations.datetime_cast_date_sqlc                 C   s   d| d||  |fS )Nzdjango_datetime_cast_time(r5   r>   r?   r   r   r    datetime_cast_time_sqlt   s    
z)DatabaseOperations.datetime_cast_time_sqlc                 C   s"   d| d|  f|| |fS )Nzdjango_datetime_extract(%s, r5   r6   r8   r   r   r    datetime_extract_sqlz   s    
z'DatabaseOperations.datetime_extract_sqlc                 C   s"   d| d|  f|| |fS )Nzdjango_datetime_trunc(%s, r5   r6   r8   r   r   r    datetime_trunc_sql   s    
z%DatabaseOperations.datetime_trunc_sqlc                 C   s   d| d|  f|fS )Nzdjango_time_extract(%s, r)   r*   r,   r   r   r    time_extract_sql   s    z#DatabaseOperations.time_extract_sqlc                 C   s   dS )NZNULLr   r   r   r   r    pk_default_value   s    z#DatabaseOperations.pk_default_valuec                 C   s   d}t ||krLd}tdt ||D ]"}||||  }|| |7 }q$|S dddgt |  }| jj }z||| W S |  X dS )zV
        Only for last_executed_query! Don't use this to execute SQL queries!
        i  r   r   zSELECT , zQUOTE(?)N)	r   range%_quote_params_for_last_executed_queryjoinr   r2   closeexecuteZfetchone)r   r/   Z
BATCH_SIZEresultsindexchunkr.   r2   r   r   r    rI      s    	z8DatabaseOperations._quote_params_for_last_executed_queryc                 C   sR   |rJt |ttfr| |}n$t| }| |}tt||}|| S |S d S N)r#   listtuplerI   valuesdictzip)r   r2   r.   r/   rS   r   r   r    last_executed_query   s    
z&DatabaseOperations.last_executed_queryc                 C   s    | dr|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   rE   r   r   r    no_limit_value   s    z!DatabaseOperations.no_limit_valuec              
   C   sN   d}|ddf}| j  ,}|||}dd | D W  5 Q R  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   r2   rL   r1   )r   Z
table_namequeryr/   r2   rM   r   r   r    Z__references_graph   s    
z%DatabaseOperations.__references_graphc                 C   s   t dd| jS )Ni   )maxsize)r   %_DatabaseOperations__references_graphrE   r   r   r    _references_graph   s    z$DatabaseOperations._references_graphF)reset_sequencesallow_cascadec                   s`   |r$|r$t t fdd|D } fdd|D }|r\dd |D }| | |S )Nc                 3   s   | ]}  |V  qd S rP   )re   r_   tablerE   r   r    	<genexpr>   s     z/DatabaseOperations.sql_flush.<locals>.<genexpr>c              
      s2   g | ]*}d  d d |f qS )z	%s %s %s;DELETEZFROM)SQL_KEYWORD	SQL_FIELDr[   rh   r   styler   r    ra      s   z0DatabaseOperations.sql_flush.<locals>.<listcomp>c                 S   s   g | ]}d |iqS )ri   r   rh   r   r   r    ra      s     )setr   from_iterableextendsequence_reset_by_name_sql)r   ro   Ztablesrf   rg   r.   	sequencesr   rn   r    	sql_flush   s    	zDatabaseOperations.sql_flushc                 C   sn   |sg S d| d|| d| d|| d| d|| d| dd	d
d |D f gS )Nz%s %s %s %s = 0 %s %s %s (%s);UPDATEZsqlite_sequenceZSETseqZWHERErZ   INrG   c                 S   s   g | ]}d |d  qS )'%s'ri   r   )r_   Zsequence_infor   r   r    ra     s     zADatabaseOperations.sequence_reset_by_name_sql.<locals>.<listcomp>)rl   Z	SQL_TABLEr[   rm   rJ   )r   ro   rt   r   r   r    rs      s     z-DatabaseOperations.sequence_reset_by_name_sqlc                 C   sL   |d krd S t |dr|S t|rDtjr<t|| 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   r=   Z
make_naiver   
ValueErrorstr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|r,tdt|S )Nrz   z5SQLite backend does not support timezone-aware times.)r{   r   r|   r}   r~   r   r   r   r    adapt_timefield_value  s    

z(DatabaseOperations.adapt_timefield_valuec                    s   t  |}|j }|dkr,|| j np|dkrB|| j nZ|dkrX|| j nD|dkrr|| | n*|dkr|| j	 n|dkr|| j
 |S )Nr   r   r"   ZDecimalFieldZ	UUIDFieldZBooleanField)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    r   (  s    
z$DatabaseOperations.get_db_convertersc                 C   s@   |d k	r<t |tjst|}tjr<t|s<t|| jj}|S rP   )	r#   datetimer   r   r=   r   r|   Z
make_awarer   r   r   r&   r   r   r   r    r   9  s    z.DatabaseOperations.convert_datetimefield_valuec                 C   s    |d k	rt |tjst|}|S rP   )r#   r   dater   r   r   r   r    r   A  s    z*DatabaseOperations.convert_datefield_valuec                 C   s    |d k	rt |tjst|}|S rP   )r#   r   timer   r   r   r   r    r   G  s    z*DatabaseOperations.convert_timefield_valuec                    sN   t jddj t|tr>t d|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$   r   r   r&   r   create_decimalZquantize_valuer   r    	converterV  s
     z@DatabaseOperations.get_decimalfield_converter.<locals>.converterc                    s   | d k	r | S d S rP   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   M  s    

z-DatabaseOperations.get_decimalfield_converterc                 C   s   |d k	rt |}|S rP   )uuidUUIDr   r   r   r    r   d  s    
z*DatabaseOperations.convert_uuidfield_valuec                 C   s   |dkrt |S |S )N)r   r   )boolr   r   r   r    r   i  s    z-DatabaseOperations.convert_booleanfield_valuec                 C   s,   dd |D }d dd |D }d| S )Nc                 s   s   | ]}d  |V  qdS )rG   NrJ   r^   r   r   r    rj   m  s     z5DatabaseOperations.bulk_insert_sql.<locals>.<genexpr>rG   c                 s   s   | ]}d | dV  qdS )(r)   Nr   )r_   r.   r   r   r    rj   n  s     zVALUES r   )r   r   Zplaceholder_rowsZplaceholder_rows_sqlZ
values_sqlr   r   r    bulk_insert_sqll  s    z"DatabaseOperations.bulk_insert_sqlc                    s:   |dkrdd | S |dkr,dd | S t ||S )N^z	POWER(%s),#z
BITXOR(%s))rJ   r   combine_expression)r   	connectorsub_expressionsr   r   r    r   q  s
    z%DatabaseOperations.combine_expressionc                 C   sD   |dkrt d| d| g| }t|dkr6tddd| S )N)+-*/z$Invalid connector for timedelta: %s.ry      z)Too many params for timedelta operations.zdjango_format_dtdelta(%s)rG   )r   r   r}   rJ   )r   r   r   Z	fn_paramsr   r   r    combine_duration_expressionz  s    z.DatabaseOperations.combine_duration_expressionc                 C   s   dS r<   r   )r   r   r   r   r    integer_field_range  s    z&DatabaseOperations.integer_field_rangec           	      C   s@   |\}}|\}}||}|dkr0d||f |fS d||f |fS )Nr"   zdjango_time_diff(%s, %s)zdjango_timestamp_diff(%s, %s)r   )	r   r   lhsrhsZlhs_sqlZ
lhs_paramsZrhs_sqlZ
rhs_paramsr/   r   r   r    subtract_temporals  s    z%DatabaseOperations.subtract_temporalsc                    s   |t jkrdS t j|dS )NzINSERT OR IGNORE INTO)on_conflict)r
   ZIGNOREr   insert_statement)r   r   r   r   r    r     s    
z#DatabaseOperations.insert_statementc                    s,   |sdS  fdd|D }dd | dfS )N) r   c                    s,   g | ]$}d   |jjj  |jf qS )z%s.%s)r[   modelZ_metaZdb_tablecolumnr_   fieldrE   r   r    ra     s   
z<DatabaseOperations.return_insert_columns.<locals>.<listcomp>zRETURNING %srG   r   r   )r   r   columnsr   rE   r    return_insert_columns  s    
z(DatabaseOperations.return_insert_columnsc                    sX   |t jkrF| jjjrFddt| j|ddd t| j|D f S t 	||||S )Nz ON CONFLICT(%s) DO UPDATE SET %srG   c                 S   s   g | ]}| d | qS )z = EXCLUDED.r   r   r   r   r    ra     s   z=DatabaseOperations.on_conflict_suffix_sql.<locals>.<listcomp>)
r
   rv   r   r   Z%supports_update_conflicts_with_targetrJ   mapr[   r   on_conflict_suffix_sql)r   r   r   Zupdate_fieldsZunique_fieldsr   r   r    r     s$    
	z)DatabaseOperations.on_conflict_suffix_sql)N)N)N)1__name__
__module____qualname__Z"cast_char_field_without_max_lengthZcast_data_typesZexplain_prefix	frozensetZjsonfield_datatype_valuesr!   r(   r0   r3   r4   r:   r;   r7   r@   rA   rB   rC   rD   rF   rI   rV   r[   r]   rd   r   re   ru   rs   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r    r      s\   


	r   )r   r   r   	functoolsr   	itertoolsr   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   r   r   Z"django.db.backends.base.operationsr	   Zdjango.db.models.constantsr
   Zdjango.db.models.expressionsr   Zdjango.utilsr   Zdjango.utils.dateparser   r   r   Zdjango.utils.functionalr   r   r   r   r   r    <module>   s   