U
    d;                     @   sN  d 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 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$e%ddj& e%de$e e%de$e e%de$e e'ej(e) G dd deZ*edZ+G dd dej,Z-dS )z@
SQLite backend for the sqlite3 module in the standard library.
    N)chain)dbapi2)ImproperlyConfigured)IntegrityError)BaseDatabaseWrapper)async_unsafe)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-7vj2equ7/django/db/backends/sqlite3/base.py<lambda>       zdecoder.<locals>.<lambda>r   r   r   r   r   decoder   s    r   bool   1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)dater   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))r*   r)   r+   r,   ZAUTOINCREMENT)r'   r(   r-   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 '\')r/   r0   r4   r6   r5   r7   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)r:   uri)	settings_dictr   DatabaseZPARSE_DECLTYPESZPARSE_COLNAMESwarningswarnRuntimeWarningupdate)selfr<   kwargsr   r   r   get_connection_params   s"    
z%DatabaseWrapper.get_connection_paramsc                 C   s   | j jS r   )r=   Zsqlite_version_inforB   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)r=   connectregister_functionsexecute)rB   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)rB   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   closerE   r   r   r   rT      s    zDatabaseWrapper.closec                 C   s   | j S r   )Zin_atomic_blockrE   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_errorsrN   Zisolation_level)rB   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   )rO   rJ   fetchoner   )rB   rO   Zenabledr   r   r   disable_constraint_checking   s    

z+DatabaseWrapper.disable_constraint_checkingc              	   C   s"   |   }|d W 5 Q R X d S )NrG   rO   rJ   )rB   rO   r   r   r   enable_constraint_checking   s    
z*DatabaseWrapper.enable_constraint_checkingc                    s  j jr ؉ |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 qHW 5 Q R X nĈ  |dkrj	 }|D ]}j	
 |}
|
s0qj	 |}| D ]^\}\}	} d
|
|||||	||	f    D ](}td	||d |||d ||	f qxqF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)rJ   ops
quote_namefetchall).0
table_namerO   rB   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.aD  
                            SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
                            LEFT JOIN `%s` as REFERRED
                            ON (REFERRING.`%s` = REFERRED.`%s`)
                            WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL
                            r   r   )featuresZ!supports_pragma_foreign_key_checkrO   rJ   r_   r   from_iterabler]   r^   introspectionZget_primary_key_columnrY   r   table_namesZget_relationsitems)rB   ri   Z
violationsra   ZrowidZreferenced_table_nameZforeign_key_indexZforeign_keyZcolumn_nameZreferenced_column_nameZprimary_key_column_nameZprimary_key_valueZ	bad_valueZ	relationsZbad_rowr   rb   r   check_constraints   s    
 


	

 
z!DatabaseWrapper.check_constraintsc                 C   s   dS )NTr   rE   r   r   r   	is_usableG  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BEGINNr[   rE   r   r   r   #_start_transaction_under_autocommitJ  s    z3DatabaseWrapper._start_transaction_under_autocommitc                 C   s   | j | jd S )Nr8   )creationrS   r<   rE   r   r   r   rS   S  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_opsr=   r   ZSchemaEditorClassr   Zclient_classr   Zcreation_classr   Zfeatures_classr   Zintrospection_classr   Z	ops_classrD   rF   r   rL   rR   rT   rU   rX   rZ   r\   rk   rl   rm   rS   r   r   r   r   r!   (   s   		



	
j	r!   z(?<!%)%sc                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
rP   z
    Django uses "format" style placeholders, but pysqlite2 uses "qmark" style.
    This fixes it -- but note that if you want to use a literal "%s" in a query,
    you'll need to use "%%s".
    Nc                 C   s0   |d krt j| |S | |}t j| ||S r   )r=   CursorrJ   convert_query)rB   queryparamsr   r   r   rJ   a  s    
zSQLiteCursorWrapper.executec                 C   s   |  |}tj| ||S r   )rv   r=   ru   executemany)rB   rw   Z
param_listr   r   r   ry   g  s    
zSQLiteCursorWrapper.executemanyc                 C   s   t d|ddS )N?z%%%)FORMAT_QMARK_REGEXsubreplace)rB   rw   r   r   r   rv   k  s    z!SQLiteCursorWrapper.convert_query)N)ro   rp   rq   __doc__rJ   ry   rv   r   r   r   r   rP   Z  s   
rP   ).r   r$   r>   	itertoolsr   Zsqlite3r   r=   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backends.base.baser   Zdjango.utils.asyncior   Zdjango.utils.dateparser   r	   Zdjango.utils.regex_helperr
   Z
_functionsr   rI   clientr   rn   r   rf   r   rh   r   
operationsr   Zschemar   r   Zregister_converter__eq__Zregister_adapterDecimalstrr!   r|   ru   rP   r   r   r   r   <module>   s8     1