o
    [hC                     @   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 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_property   )Databasec                       s  e Zd ZdZdddZdZeg dZdd Zdd	 Z	d
d Z
dd Zdd ZdWddZdWd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d/d/d0d1d2Zd3d4 Zd5d6 Zd7d8 Z  fd9d:Z!d;d< Z"d=d> Z#d?d@ Z$dAdB Z%dCdD Z&dEdF Z' fdGdHZ(dIdJ Z)dKdL Z*dMdN Z+dW fdOdP	Z,dQdR Z- fdSdTZ.dUdV Z/  Z0S )XDatabaseOperationstextZTEXT)	DateFieldDateTimeFieldzEXPLAIN QUERY PLAN)nullfalsetruec                 C   sN   t tdd |D }t|dkrdS t|dkr#| jjjt| S t|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).
        c                 s   s(    | ]}t |tjr|jn|gV  qd S N)
isinstancer   ZCompositePrimaryKeyfields.0field r    /home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/site-packages/django/db/backends/sqlite3/operations.py	<genexpr>(   s    

z5DatabaseOperations.bulk_batch_size.<locals>.<genexpr>r   i  )listr   from_iterablelen
connectionfeaturesZmax_query_params)selfr   Zobjsr    r    r!   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||r8|	 D ]}z|j
}W n ttfy-   Y qw t||r7tdqt|t jrL|jrNt|jdkrPtdd S d S 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StdDevr   Z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_support8   s0   



z+DatabaseOperations.check_expression_supportc                 C      d| d|  g|R 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_sqlT   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_rows\   s   z-DatabaseOperations.fetch_returned_insert_rowsc                 C   s   |S )z>Do nothing since formatting is handled in the custom function.r    )r(   r6   r    r    r!   format_for_duration_arithmeticc   s   z1DatabaseOperations.format_for_duration_arithmeticNc                 C   &   d| d|  g|| |R fS )Nzdjango_date_trunc(%s, 	, %s, %s)r3   _convert_tznames_to_sqlr(   r5   r6   r7   tznamer    r    r!   date_trunc_sqlg      
z!DatabaseOperations.date_trunc_sqlc                 C   r=   )Nzdjango_time_trunc(%s, r>   r?   rA   r    r    r!   time_trunc_sqln   rD   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(   rB   r    r    r!   r@   u   s   
z*DatabaseOperations._convert_tznames_to_sqlc                 C       d| dg ||  |R fS )Nzdjango_datetime_cast_date(r>   r@   r(   r6   r7   rB   r    r    r!   datetime_cast_date_sqlz   
   z)DatabaseOperations.datetime_cast_date_sqlc                 C   rG   )Nzdjango_datetime_cast_time(r>   rH   rI   r    r    r!   datetime_cast_time_sql   rK   z)DatabaseOperations.datetime_cast_time_sqlc                 C   r=   )Nzdjango_datetime_extract(%s, r>   r?   rA   r    r    r!   datetime_extract_sql   rD   z'DatabaseOperations.datetime_extract_sqlc                 C   r=   )Nzdjango_datetime_trunc(%s, r>   r?   rA   r    r    r!   datetime_trunc_sql   rD   z%DatabaseOperations.datetime_trunc_sqlc                 C   r0   )Nzdjango_time_extract(%s, r1   r2   r4   r    r    r!   time_extract_sql   s   z#DatabaseOperations.time_extract_sqlc                 C      dS )NZNULLr    r(   r    r    r!   pk_default_value      z#DatabaseOperations.pk_default_valuec                 C   s   d}t ||kr&d}tdt ||D ]}||||  }|| |7 }q|S dddgt |  }| jj }z||| W |  S |  w )zV
        Only for last_executed_query! Don't use this to execute SQL queries!
        i  r    r   zSELECT , zQUOTE(?))	r%   range%_quote_params_for_last_executed_queryjoinr&   r:   executeZfetchoneclose)r(   r7   Z
BATCH_SIZEresultsindexchunkr6   r:   r    r    r!   rV      s   	z8DatabaseOperations._quote_params_for_last_executed_queryc                 C   sT   |r(t |ttfr| |}|| S t| }| |}tt||}|| S |S r   )r   r#   tuplerV   valuesdictzip)r(   r:   r6   r7   r^   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   rP   )Nr    rQ   r    r    r!   no_limit_value   rS   z!DatabaseOperations.no_limit_valuec                 C   sZ   d}|ddf}| j  }|||}dd | D W  d    S 1 s&w   Y  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    )r   rowr    r    r!   
<listcomp>       z9DatabaseOperations.__references_graph.<locals>.<listcomp>)r&   r:   rX   r9   )r(   Z
table_namequeryr7   r:   rZ   r    r    r!   Z__references_graph   s   
$z%DatabaseOperations.__references_graphc                 C   s   t dd| jS )Ni   )maxsize)r   %_DatabaseOperations__references_graphrQ   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 r   )ro   r   tablerQ   r    r!   r"      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_FIELDrf   rr   r(   styler    r!   rj      s    z0DatabaseOperations.sql_flush.<locals>.<listcomp>c                 S   s   g | ]}d |iqS )rs   r    rr   r    r    r!   rj      rk   )setr   r$   extendsequence_reset_by_name_sql)r(   rx   Ztablesrp   rq   r6   	sequencesr    rw   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WHEREre   INrT   c                 S   s   g | ]}d |d  qS )'%s'rs   r    )r   Zsequence_infor    r    r!   rj     s    zADatabaseOperations.sequence_reset_by_name_sql.<locals>.<listcomp>)ru   Z	SQL_TABLErf   rv   rW   )r(   rx   r|   r    r    r!   r{      s    z-DatabaseOperations.sequence_reset_by_name_sqlc                 C   sD   |d u rd S t |rtjrt || jj }t|S tdt|S )NzNSQLite backend does not support timezone-aware datetimes when USE_TZ is False.)r   is_awarer   rF   Z
make_naiver&   
ValueErrorstrr(   valuer    r    r!   adapt_datetimefield_value  s   
z,DatabaseOperations.adapt_datetimefield_valuec                 C   s&   |d u rd S t |rtdt|S )Nz5SQLite backend does not support timezone-aware times.)r   r   r   r   r   r    r    r!   adapt_timefield_value   s
   
z(DatabaseOperations.adapt_timefield_valuec                    s   t  |}|j }|dkr|| j |S |dkr#|| j |S |dkr/|| j |S |dkr=|| | |S |dkrI|| j	 |S |dkrS|| 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 urt |tjst|}tjrt|st|| jj}|S r   )	r   datetimer   r   rF   r   r   Z
make_awarer&   r(   r   r-   r&   r    r    r!   r   ;  s   z.DatabaseOperations.convert_datetimefield_valuec                 C       |d urt |tjst|}|S r   )r   r   dater   r   r    r    r!   r   C     z*DatabaseOperations.convert_datefield_valuec                 C   r   r   )r   r   timer   r   r    r    r!   r   I  r   z*DatabaseOperations.convert_timefield_valuec                    sP   t jddj t|tr t d|jj  fdd}|S  fdd}|S )N   )precr   c                    s"   | d ur | j |jjdS d S )N)context)quantizer+   r   r   r-   r&   create_decimalZquantize_valuer    r!   	converterX  s
   z@DatabaseOperations.get_decimalfield_converter.<locals>.converterc                    s   | d ur | S d S r   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   O  s   

z-DatabaseOperations.get_decimalfield_converterc                 C   s   |d ur	t |}|S r   )uuidUUIDr   r    r    r!   r   f  s   
z*DatabaseOperations.convert_uuidfield_valuec                 C   s   |dv rt |S |S )N)r   r   )boolr   r    r    r!   r   k     z-DatabaseOperations.convert_booleanfield_valuec                    s:   |dkrdd | S |dkrdd | S t ||S )N^z	POWER(%s),#z
BITXOR(%s))rW   r   combine_expression)r(   	connectorsub_expressionsr   r    r!   r   n  s
   z%DatabaseOperations.combine_expressionc                 C   sD   |dvr
t d| d| g| }t|dkrtddd| S )N)+-*/z$Invalid connector for timedelta: %s.r      z)Too many params for timedelta operations.zdjango_format_dtdelta(%s)rT   )r   r%   r   rW   )r(   r   r   Z	fn_paramsr    r    r!   combine_duration_expressionw  s   z.DatabaseOperations.combine_duration_expressionc                 C   s   |dv rdS dS )N)ZPositiveBigIntegerFieldZPositiveIntegerFieldZPositiveSmallIntegerField)r       )l         r   r    )r(   r   r    r    r!   integer_field_range  s   z&DatabaseOperations.integer_field_rangec           	      C   sF   |\}}|\}}g ||R }|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(   r   lhsrhsZlhs_sqlZ
lhs_paramsZrhs_sqlZ
rhs_paramsr7   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)rf   model_metaZdb_tablecolumnr   rQ   r    r!   rj     s    
z<DatabaseOperations.return_insert_columns.<locals>.<listcomp>zRETURNING %srT   r    )rW   )r(   r   columnsr    rQ   r!   return_insert_columns  s   
z(DatabaseOperations.return_insert_columnsc                    sX   |t jkr#| jjjr#ddt| j|ddd t| j|D f S t 	||||S )Nz ON CONFLICT(%s) DO UPDATE SET %srT   c                 S   s   g | ]	}| d | qS )z = EXCLUDED.r    r   r    r    r!   rj     s    z=DatabaseOperations.on_conflict_suffix_sql.<locals>.<listcomp>)
r
   r~   r&   r'   Z%supports_update_conflicts_with_targetrW   maprf   r   on_conflict_suffix_sql)r(   r   r   Zupdate_fieldsZunique_fieldsr   r    r!   r     s"   

	z)DatabaseOperations.on_conflict_suffix_sqlc                 C   s   t jdk rdgS g S )N)r   '   zGROUP BY TRUE)r   Zsqlite_version_inforQ   r    r    r!   force_group_by  r   z!DatabaseOperations.force_group_byr   )1__name__
__module____qualname__Z"cast_char_field_without_max_lengthZcast_data_typesZexplain_prefix	frozensetZjsonfield_datatype_valuesr)   r/   r8   r;   r<   rC   rE   r@   rJ   rL   rM   rN   rO   rR   rV   ra   rf   rh   rn   r   ro   r}   r{   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   baser   r   r    r    r    r!   <module>   s     