
    h:                         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mZmZ d dlmZ d dlmZ  G d de      Zy)    N)	lru_cache)chain)settings)
FieldError)DatabaseErrorNotSupportedErrormodels)BaseDatabaseOperations)Col)timezone)
parse_dateparse_datetime
parse_time)duration_microseconds)cached_propertyc                   $    e Zd ZdZdddZdZd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zed        ZddddZd Zd Zd Z fdZd  Z d! Z!d" Z"d# Z#d$ Z$d% Z%d& Z& fd'Z'd( Z(d) Z)d* Z*d, fd+	Z+ xZ,S )-DatabaseOperationstextTEXT)	DateFieldDateTimeFieldzEXPLAIN QUERY PLANc                     t        |      dk(  ryt        |      dkD  r,| j                  j                  j                  t        |      z  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).
           i  )len
connectionfeaturesmax_query_params)selffieldsobjss      h/var/www/html/ranktracker/api/venv/lib/python3.12/site-packages/django/db/backends/sqlite3/operations.pybulk_batch_sizez"DatabaseOperations.bulk_batch_size   sG     v;![1_??++<<FKKt9    c                 (   t         j                  t         j                  t         j                  f}t         j                  t         j
                  t         j                  t         j                  f}t        ||      r9|j                         D ]&  }	 |j                  }t        ||      st        d       t        |t         j                        r1|j                  r$t!        |j"                        dkD  rt        d      y y y # t        t        f$ r Y w xY w)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   	TimeFieldSumAvgVarianceStdDev
isinstanceget_source_expressionsoutput_fieldr   AttributeErrorr   	Aggregatedistinctr   source_expressions)r   
expression
bad_fieldsbad_aggregatesexprr,   s         r!   check_expression_supportz+DatabaseOperations.check_expression_support)   s    &&(<(<f>N>NO
 **fjj&//6==Qj.1"99; #'#4#4L ",
;/@  z6#3#34
--.2#0  3   5 '
3  s   C??DDc                 0    d|j                         d|d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('', )lowerr   lookup_type
field_names      r!   date_extract_sqlz#DatabaseOperations.date_extract_sqlE   s     3>2C2C2EzRRr#   c                 *    t        t        |            S N)strr   )r   	timedeltas     r!   date_interval_sqlz$DatabaseOperations.date_interval_sqlM   s    (344r#   c                     |S )z>Do nothing since formatting is handled in the custom function. )r   sqls     r!   format_for_duration_arithmeticz1DatabaseOperations.format_for_duration_arithmeticP   s    
r#   c                 0    d|j                         d|dS )Nzdjango_date_trunc('r7   r8   r9   r;   s      r!   date_trunc_sqlz!DatabaseOperations.date_trunc_sqlT       0;0A0A0CZPPr#   c                 0    d|j                         d|dS )Nzdjango_time_trunc('r7   r8   r9   r;   s      r!   time_trunc_sqlz!DatabaseOperations.time_trunc_sqlW   rJ   r#   c                 `    t         j                  rd|z  d| j                  j                  z  fS y)N'%s')NULLrO   )r   USE_TZr   timezone_name)r   tznames     r!   _convert_tznames_to_sqlz*DatabaseOperations._convert_tznames_to_sqlZ   s*    ??F?FT__-J-J$JJJr#   c                 2    d|g| j                  |      z  S )Nz%django_datetime_cast_date(%s, %s, %s)rS   r   r=   rR   s      r!   datetime_cast_date_sqlz)DatabaseOperations.datetime_cast_date_sql_   *    6:
55f=:
 
 	
r#   c                 2    d|g| j                  |      z  S )Nz%django_datetime_cast_time(%s, %s, %s)rU   rV   s      r!   datetime_cast_time_sqlz)DatabaseOperations.datetime_cast_time_sqld   rX   r#   c                 P    d|j                         |g| j                  |      z  S )Nz)django_datetime_extract('%s', %s, %s, %s)r:   rS   r   r<   r=   rR   s       r!   datetime_extract_sqlz'DatabaseOperations.datetime_extract_sqli   s5    :>
.2.J.J6.R>
 
 	
r#   c                 P    d|j                         |g| j                  |      z  S )Nz'django_datetime_trunc('%s', %s, %s, %s)r\   r]   s       r!   datetime_trunc_sqlz%DatabaseOperations.datetime_trunc_sqln   s5    8<
.2.J.J6.R<
 
 	
r#   c                 0    d|j                         d|dS )Nzdjango_time_extract('r7   r8   r9   r;   s      r!   time_extract_sqlz#DatabaseOperations.time_extract_sqls   s    2=2C2C2EzRRr#   c                      y)NrO   rE   r   s    r!   pk_default_valuez#DatabaseOperations.pk_default_valuev   s    r#   c                    d}t        |      |kD  r;d}t        dt        |      |      D ]  }||||z    }|| j                  |      z  }  |S ddj                  dgt        |      z        z   }| j                  j                  j                         }	 |j                  ||      j                         |j                          S # |j                          w xY w)zV
        Only for last_executed_query! Don't use this to execute SQL queries!
        i  rE   r   zSELECT , zQUOTE(?))	r   range%_quote_params_for_last_executed_queryjoinr   cursorexecutefetchoneclose)r   params
BATCH_SIZEresultsindexchunkrF   rk   s           r!   ri   z8DatabaseOperations._quote_params_for_last_executed_queryy   s     
v;#Gq#f+z: MuUZ%784EEeLLM N$))ZL3v;$>?? ++224	>>#v.779LLNFLLNs   C Cc                     |rpt        |t        t        f      r| j                  |      }||z  S t        |j	                               }| j                  |      }t        t        ||            }||z  S |S r@   )r*   listtupleri   valuesdictzip)r   rk   rF   ro   rw   s        r!   last_executed_queryz&DatabaseOperations.last_executed_query   su    
 &4-0CCFK
 < v}}/CCFKc&&12< Jr#   c                 T    |j                  d      r|j                  d      r|S d|z  S )N"z"%s")
startswithendswith)r   names     r!   
quote_namezDatabaseOperations.quote_name   s(    ??3DMM#$6K}r#   c                      y)NrE   rd   s    r!   no_limit_valuez!DatabaseOperations.no_limit_value   s    r#   c                     d}|ddf}| j                   j                         5 }|j                  ||      }|j                         D cg c]  }|d   	 c}cd d d        S c c}w # 1 sw Y   y xY w)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*\(r   )r   rk   rl   fetchall)r   
table_namequeryro   rk   rq   rows          r!   __references_graphz%DatabaseOperations.__references_graph   sw     *

 __##% 	:nnUF3G&-&6&6&89sCF9	: 	:9	: 	:s   %A$AA$A$$A-c                 :     t        d      | j                        S )Ni   )maxsize)r   %_DatabaseOperations__references_graphrd   s    r!   _references_graphz$DatabaseOperations._references_graph   s     &y%d&=&=>>r#   F)reset_sequencesallow_cascadec                    |r)|r't        t        j                   fd|D                    }|D cg c]I  }|j                  d      d|j                  d      d|j	                   j                  |            dK }}|r2|D cg c]  }d|i }}|j                   j                  ||             |S c c}w c c}w )Nc              3   @   K   | ]  }j                  |        y wr@   )r   ).0tabler   s     r!   	<genexpr>z/DatabaseOperations.sql_flush.<locals>.<genexpr>   s     ,_uT-C-CE-J,_s   DELETE FROM;r   )setr   from_iterableSQL_KEYWORD	SQL_FIELDr   extendsequence_reset_by_name_sql)r   styletablesr   r   r   rF   	sequencess   `       r!   	sql_flushzDatabaseOperations.sql_flush   s    m ,,,_X^,__`F
 	  h'f%OODOOE23
  
 7=>e'5)>I>JJt66uiHI
 ?s   AB7B<c                    |sg S |j                  d      d|j                  | j                  d            d|j                  d      d|j                  | j                  d            d|j                  d      d|j                  | j                  d            d|j                  d	      d
dj	                  |D cg c]
  }d|d   z   c}      dgS c c}w )NUPDATEr   sqlite_sequenceSETseqz = 0 WHEREr   INz (rg   rN   r   z);)r   	SQL_TABLEr   r   rj   )r   r   r   sequence_infos       r!   r   z-DatabaseOperations.sequence_reset_by_name_sql   s    I !!(+0A BC!!%( 67!!'* 78!!$'		IR8EF]733 
 	
s   ?C$c                    |y t        |d      r|S t        j                  |      rPt        j                  r5t        j
                  || j                  j                        }t        |      S t        d      t        |      S )Nresolve_expressionzNSQLite backend does not support timezone-aware datetimes when USE_TZ is False.)	hasattrr   is_awarer   rP   
make_naiver   
ValueErrorrA   r   values     r!   adapt_datetimefield_valuez,DatabaseOperations.adapt_datetimefield_value   ss    = 5./L U# ++E4??3K3KL 5z !!qrr5zr#   c                 z    |y t        |d      r|S t        j                  |      rt        d      t	        |      S )Nr   z5SQLite backend does not support timezone-aware times.)r   r   r   r   rA   r   s     r!   adapt_timefield_valuez(DatabaseOperations.adapt_timefield_value   sB    = 5./L U#TUU5zr#   c                    t         |   |      }|j                  j                         }|dk(  r|j	                  | j
                         |S |dk(  r|j	                  | j                         |S |dk(  r|j	                  | j                         |S |dk(  r"|j	                  | j                  |             |S |dk(  r|j	                  | j                         |S |dv r|j	                  | j                         |S )Nr   r   r%   DecimalField	UUIDField)NullBooleanFieldBooleanField)superget_db_convertersr,   get_internal_typeappendconvert_datetimefield_valueconvert_datefield_valueconvert_timefield_valueget_decimalfield_converterconvert_uuidfield_valueconvert_booleanfield_value)r   r1   
convertersinternal_type	__class__s       r!   r   z$DatabaseOperations.get_db_converters  s   W.z:
"//AACO+d>>?  k)d::;  k)d::;  n,d==jIJ
 	 k)d::;  BBd==>r#   c                     |tt        |t        j                        st        |      }t        j                  r?t        j                  |      s*t        j                  || j                  j
                        }|S r@   )	r*   datetimer   r   rP   r   r   
make_awarer   r   r   r1   r   s       r!   r   z.DatabaseOperations.convert_datetimefield_value  sW    eX%6%67&u-x'8'8'? ++E4??3K3KLr#   c                 T    |%t        |t        j                        st        |      }|S r@   )r*   r   dater   r   s       r!   r   z*DatabaseOperations.convert_datefield_value   %    eX]]3"5)r#   c                 T    |%t        |t        j                        st        |      }|S r@   )r*   r   timer   r   s       r!   r   z*DatabaseOperations.convert_timefield_value&  r   r#   c                     t        j                  d      j                  t        |t              rAt        j
                  d      j                  |j                  j                         fd}|S fd}|S )N   )precr   c                 d    | - |       j                  |j                  j                        S y )N)context)quantizer,   r   )r   r1   r   create_decimalquantize_values      r!   	converterz@DatabaseOperations.get_decimalfield_converter.<locals>.converter3  s6    $)%099.R\RiRiRqRq9rr %r#   c                     |  |       S y r@   rE   )r   r1   r   r   s      r!   r   z@DatabaseOperations.get_decimalfield_converter.<locals>.converter7  s    $)%00 %r#   )	decimalContextcreate_decimal_from_floatr*   r   Decimalscalebr,   decimal_places)r   r1   r   r   r   s      @@r!   r   z-DatabaseOperations.get_decimalfield_converter,  sf     !b1KKj#&$__Q/66
8O8O8^8^7^_Ns 1 r#   c                 4    |t        j                  |      }|S r@   )uuidUUIDr   s       r!   r   z*DatabaseOperations.convert_uuidfield_value<  s    IIe$Er#   c                 $    |dv rt        |      S |S )N)r   r   )boolr   s       r!   r   z-DatabaseOperations.convert_booleanfield_valueA  s    #votE{858r#   c                 2    dj                  d |D              S )Nz UNION ALL c              3   D   K   | ]  }d dj                  |      z    yw)z	SELECT %srg   Nrj   )r   r   s     r!   r   z5DatabaseOperations.bulk_insert_sql.<locals>.<genexpr>E  s%      "
 $))C.("
s    r   )r   r   placeholder_rowss      r!   bulk_insert_sqlz"DatabaseOperations.bulk_insert_sqlD  s"    !! "
'"
 
 	
r#   c                     |dk(  rddj                  |      z  S |dk(  rddj                  |      z  S t        | 	  ||      S )N^z	POWER(%s),#z
BITXOR(%s))rj   r   combine_expression)r   	connectorsub_expressionsr   s      r!   r   z%DatabaseOperations.combine_expressionJ  sO     /!:::##((?";;;w))_EEr#   c                     |dvrt        d|z        d|z  g|z   }t        |      dkD  rt        d      ddj                  |      z  S )N)+-z$Invalid connector for timedelta: %s.rN      z)Too many params for timedelta operations.zdjango_format_dtdelta(%s)rg   )r   r   r   rj   )r   r   r   	fn_paramss       r!   combine_duration_expressionz.DatabaseOperations.combine_duration_expressionS  sY    J& F RSSi'(?:	y>AHII*TYYy-AAAr#   c                      y)N)NNrE   )r   r   s     r!   integer_field_rangez&DatabaseOperations.integer_field_range[  s    r#   c                 Z    |\  }}|\  }}g ||}|dk(  rd|d|d|fS d|d|d|fS )Nr%   zdjango_time_diff(rg   r8   zdjango_timestamp_diff(rE   )	r   r   lhsrhslhs_sql
lhs_paramsrhs_sql
rhs_paramsro   s	            r!   subtract_temporalsz%DatabaseOperations.subtract_temporals_  sR    !!+:+
+K'18'BFJJ (297CVKKr#   c                 *    |rdS t         |   |      S )NzINSERT OR IGNORE INTO)r   insert_statement)r   ignore_conflictsr   s     r!   r  z#DatabaseOperations.insert_statementg  s    *:&j@XYi@jjr#   )F)-__name__
__module____qualname__"cast_char_field_without_max_lengthcast_data_typesexplain_prefixr"   r5   r>   rC   rG   rI   rL   rS   rW   rZ   r^   r`   rb   re   ri   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  __classcell__)r   s   @r!   r   r      s    )/&O *N8S5QQ








S6$
:& ? ?
 ;@u 
$"" 
9
FBLk kr#   r   )r   r   r   	functoolsr   	itertoolsr   django.confr   django.core.exceptionsr   	django.dbr   r   r	   "django.db.backends.base.operationsr
   django.db.models.expressionsr   django.utilsr   django.utils.dateparser   r   r   django.utils.durationr   django.utils.functionalr   r   rE   r#   r!   <module>r     sF           - > > E , ! I I 7 3Vk/ Vkr#   