U
    e<6                     @   s  d Z ddlZddlZddl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 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" ddl#m$Z$ ddl%m&Z& ddl'm(Z( dd Z)dd Z*dd Z+e,ddj- e,de)e e,de)e e,de)e e,de)e e.ej/e0 e.ej1e* e.eje+ G d d! d!eZ2ed"Z3G d#d$ d$ej4Z5dS )%z@
SQLite backend for the sqlite3 module in the standard library.
    N)Mapping)chaintee)dbapi2)ImproperlyConfigured)IntegrityError)BaseDatabaseWrapper)async_unsafe)
parse_dateparse_datetime
parse_time)_lazy_re_compile   )register)DatabaseClient)DatabaseCreation)DatabaseFeatures)DatabaseIntrospection)DatabaseOperations)DatabaseSchemaEditorc                    s    fddS )zR
    Convert bytestrings from Python's sqlite3 interface to a regular string.
    c                    s    |   S N)decode)sZ	conv_func C/tmp/pip-unpacked-wheel-lctamlir/django/db/backends/sqlite3/base.py<lambda>       zdecoder.<locals>.<lambda>r   r   r   r   r   decoder   s    r   c                 C   s   |   S r   	isoformatvalr   r   r   
adapt_date"   s    r#   c                 C   s
   |  dS )N r   r!   r   r   r   adapt_datetime&   s    r%   bool   1datetimedatetime	timestampc                   @   s2  e Zd ZdZdZdddddddd	d
ddddd
ddddddddddddddZdddddZddddZdddddddd d!d"ddddd#Zd$Z	d%d&d'd(d)d*d+Z
eZeZeZeZeZeZeZd,d- Zd.d/ Zed0d1 ZdGd3d4Zed5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!dHd?d@Z"dAdB Z#dCdD Z$dEdF Z%d2S )IDatabaseWrapperZsqliteZSQLiteintegerZBLOBr&   zvarchar(%(max_length)s)r(   r*   decimalZbigintrealzchar(15)zchar(39)textzbigint unsignedzinteger unsignedzsmallint unsignedZsmallintr)   zchar(32))	AutoFieldBigAutoFieldZBinaryFieldZBooleanFieldZ	CharFieldZ	DateFieldZDateTimeFieldZDecimalFieldZDurationFieldZ	FileFieldZFilePathFieldZ
FloatFieldZIntegerFieldZBigIntegerFieldZIPAddressFieldZGenericIPAddressField	JSONFieldZOneToOneFieldPositiveBigIntegerFieldPositiveIntegerFieldPositiveSmallIntegerFieldZ	SlugFieldSmallAutoFieldZSmallIntegerFieldZ	TextFieldZ	TimeFieldZ	UUIDFieldz"%(column)s" >= 0z2(JSON_VALID("%(column)s") OR "%(column)s" IS NULL))r4   r3   r5   r6   ZAUTOINCREMENT)r1   r2   r7   z= %szLIKE %s ESCAPE '\'z	REGEXP %szREGEXP '(?i)' || %sz> %sz>= %sz< %sz<= %s)exactZiexactcontains	icontainsregexZiregexgtZgteltZlte
startswithendswithistartswith	iendswithz@REPLACE(REPLACE(REPLACE({}, '\', '\\'), '%%', '\%%'), '_', '\_')z"LIKE '%%' || {} || '%%' ESCAPE '\'z)LIKE '%%' || UPPER({}) || '%%' ESCAPE '\'zLIKE {} || '%%' ESCAPE '\'z!LIKE UPPER({}) || '%%' ESCAPE '\'zLIKE '%%' || {} ESCAPE '\'z!LIKE '%%' || UPPER({}) ESCAPE '\')r9   r:   r>   r@   r?   rA   c                 C   sd   | j }|d std|d tjtjB d|d }d|krP|d rPtdt |ddd	 |S )
NNAMEzJsettings.DATABASES is improperly configured. Please supply the NAME value.)ZdatabaseZdetect_typesOPTIONScheck_same_threadzThe `check_same_thread` option was provided and set to True. It will be overridden with False. Use the `DatabaseWrapper.allow_thread_sharing` property instead for controlling thread shareability.FT)rD   uri)	settings_dictr   DatabaseZPARSE_DECLTYPESZPARSE_COLNAMESwarningswarnRuntimeWarningupdate)selfrF   kwargsr   r   r   get_connection_params   s"    
z%DatabaseWrapper.get_connection_paramsc                 C   s   | j jS r   )rG   Zsqlite_version_inforL   r   r   r   get_database_version   s    z$DatabaseWrapper.get_database_versionc                 C   s,   t jf |}t| |d |d |S )NPRAGMA foreign_keys = ONzPRAGMA legacy_alter_table = OFF)rG   connectregister_functionsexecute)rL   Zconn_paramsconnr   r   r   get_new_connection   s
    

z"DatabaseWrapper.get_new_connectionNc                 C   s   | j jtdS )N)factory)
connectioncursorSQLiteCursorWrapper)rL   namer   r   r   create_cursor   s    zDatabaseWrapper.create_cursorc                 C   s   |    |  st|  d S r   )Zvalidate_thread_sharingis_in_memory_dbr   closerO   r   r   r   r^      s    zDatabaseWrapper.closec                 C   s   | j S r   )Zin_atomic_blockrO   r   r   r   _savepoint_allowed   s    z"DatabaseWrapper._savepoint_allowedc              	   C   s,   |r
d }nd}| j  || j_W 5 Q R X d S )N )Zwrap_database_errorsrX   Zisolation_level)rL   Z
autocommitlevelr   r   r   _set_autocommit   s
    zDatabaseWrapper._set_autocommitc              	   C   s:   |   "}|d |d d }W 5 Q R X t| S )NzPRAGMA foreign_keys = OFFzPRAGMA foreign_keysr   )rY   rT   fetchoner&   )rL   rY   Zenabledr   r   r   disable_constraint_checking   s    

z+DatabaseWrapper.disable_constraint_checkingc              	   C   s"   |   }|d W 5 Q R X d S )NrQ   rY   rT   )rL   rY   r   r   r   enable_constraint_checking   s    
z*DatabaseWrapper.enable_constraint_checkingc                    s     ؉ |dkr" d }nt fdd|D }|D ]\}}}} dj|  | }|dd \}}	j |}
 dj|
j|j|f |f	 \}}t
d	|||||||	f q@W 5 Q R X dS )
a]  
        Check each table name in `table_names` for rows with invalid foreign
        key references. This method is intended to be used in conjunction with
        `disable_constraint_checking()` and `enable_constraint_checking()`, to
        determine if rows with invalid references were entered while constraint
        checks were off.
        NzPRAGMA foreign_key_checkc                 3   s(   | ] }  d j|  V  qdS )zPRAGMA foreign_key_check(%s)N)rT   ops
quote_namefetchall).0
table_namerY   rL   r   r   	<genexpr>   s   z4DatabaseWrapper.check_constraints.<locals>.<genexpr>zPRAGMA foreign_key_list(%s)      z'SELECT %s, %s FROM %s WHERE rowid = %%szThe row in table '%s' with primary key '%s' has an invalid foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s.)rY   rT   ri   r   from_iterablerg   rh   introspectionZget_primary_key_columnrc   r   )rL   Ztable_namesZ
violationsrk   ZrowidZreferenced_table_nameZforeign_key_indexZforeign_keyZcolumn_nameZreferenced_column_nameZprimary_key_column_nameZprimary_key_valueZ	bad_valuer   rl   r   check_constraints   sV    
 


	z!DatabaseWrapper.check_constraintsc                 C   s   dS )NTr   rO   r   r   r   	is_usable"  s    zDatabaseWrapper.is_usablec                 C   s   |   d dS )z
        Start a transaction explicitly in autocommit mode.

        Staying in autocommit mode works around a bug of sqlite3 that breaks
        savepoints when autocommit is disabled.
        ZBEGINNre   rO   r   r   r   #_start_transaction_under_autocommit%  s    z3DatabaseWrapper._start_transaction_under_autocommitc                 C   s   | j | jd S )NrB   )creationr]   rF   rO   r   r   r   r]   .  s    zDatabaseWrapper.is_in_memory_db)N)N)&__name__
__module____qualname__vendorZdisplay_name
data_typesZdata_type_check_constraintsZdata_types_suffix	operatorsZpattern_escZpattern_opsrG   r   ZSchemaEditorClassr   Zclient_classr   Zcreation_classr   Zfeatures_classr   Zintrospection_classr   Z	ops_classrN   rP   r	   rV   r\   r^   r_   rb   rd   rf   rr   rs   rt   r]   r   r   r   r   r,   5   s   		



	
8	r,   z(?<!%)%sc                       s<   e Zd ZdZd
 fdd	Z fddZdddd	Z  ZS )rZ   aQ  
    Django uses the "format" and "pyformat" styles, but Python's sqlite3 module
    supports neither of these styles.

    This wrapper performs the following conversions:

    - "format" style to "qmark" style
    - "pyformat" style to "named" style

    In both cases, if you want to use a literal "%s", you'll need to use "%%s".
    Nc                    sF   |d krt  |S t|tr&t|nd }| j||d}t  ||S Nparam_names)superrT   
isinstancer   listconvert_query)rL   queryparamsr~   	__class__r   r   rT   B  s
    zSQLiteCursorWrapper.executec                    sR   t t|\}}t|d  }r2t|tr2t|}nd }| j||d}t ||S r|   )	r   iternextr   r   r   r   r   executemany)rL   r   Z
param_listZpeekabler   r~   r   r   r   r   J  s    
zSQLiteCursorWrapper.executemanyr}   c                C   s2   |d krt d|ddS |dd |D  S d S )N?z%%%c                 S   s   i | ]}|d | qS ):r   )rj   r[   r   r   r   
<dictcomp>[  s      z5SQLiteCursorWrapper.convert_query.<locals>.<dictcomp>)FORMAT_QMARK_REGEXsubreplace)rL   r   r~   r   r   r   r   U  s    z!SQLiteCursorWrapper.convert_query)N)rv   rw   rx   __doc__rT   r   r   __classcell__r   r   r   r   rZ   5  s   rZ   )6r   r*   r.   rH   collections.abcr   	itertoolsr   r   Zsqlite3r   rG   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backends.base.baser   Zdjango.utils.asyncior	   Zdjango.utils.dateparser
   r   r   Zdjango.utils.regex_helperr   Z
_functionsr   rS   clientr   ru   r   featuresr   rq   r   
operationsr   Zschemar   r   r#   r%   Zregister_converter__eq__Zregister_adapterDecimalstrr(   r,   r   CursorrZ   r   r   r   r   <module>   sD    ~