a
    xdfP                     @   s|   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 d d	lmZ G d
d deZdS )    N)Decimal)Apps)NotSupportedError)BaseDatabaseSchemaEditor)	Statement)strip_quotes)UniqueConstraint)atomicc                       s   e Zd ZdZdZdZdZdZ fddZ fdd	Z	d
d Z
d$ddZd% fdd	Zd& fdd	Zd'ddZd( fdd	Zdd Zdd Zd)ddZdd Z fd d!Z fd"d#Z  ZS )*DatabaseSchemaEditorzDROP TABLE %(table)sNzEREFERENCES %(to_table)s (%(to_column)s) DEFERRABLE INITIALLY DEFERREDz7CREATE UNIQUE INDEX %(name)s ON %(table)s (%(columns)s)zDROP INDEX %(name)sc                    s   | j  stdt  S )NzSQLite schema editor cannot be used while foreign key constraint checks are enabled. Make sure to disable them before entering a transaction.atomic() context because SQLite does not support disabling them in the middle of a multi-statement transaction.)
connectiondisable_constraint_checkingr   super	__enter__self	__class__ Y/var/www/html/Ranjet/env/lib/python3.9/site-packages/django/db/backends/sqlite3/schema.pyr      s
    
zDatabaseSchemaEditor.__enter__c                    s(   | j   t ||| | j   d S N)r   Zcheck_constraintsr   __exit__enable_constraint_checking)r   exc_type	exc_value	tracebackr   r   r   r   "   s    
zDatabaseSchemaEditor.__exit__c                 C   s   zdd l }||}W n$ ty(   Y n |jy:   Y n0 t|trRtt|S t|tt	tfrjt|S t|trd|
dd S |d u rdS t|tttfrd|  S td|t|f d S )Nr   z'%s''z''ZNULLzX'%s'z*Cannot quote parameter value %r of type %s)sqlite3ZadaptImportErrorZProgrammingError
isinstanceboolstrintr   floatreplacebytes	bytearray
memoryviewhex
ValueErrortype)r   valuer   r   r   r   quote_value'   s$    

z DatabaseSchemaEditor.quote_valueFc           
      C   s   | j  }| j j|D ]l}|r.|j|kr.q| j j||j}| D ]<}|d \}}	||krH|du sp|	|krH  W d   dS qHqW d   n1 s0    Y  dS )a  
        Return whether or not the provided table name is referenced by another
        one. If `column_name` is specified, only references pointing to that
        column are considered. If `ignore_self` is True, self-referential
        constraints are ignored.
        Zforeign_keyNTF)r   cursorZintrospectionZget_table_listnameZ_get_foreign_key_constraintsvalues)
r   
table_nameZcolumn_nameignore_selfr,   Zother_tableconstraints
constraintZconstraint_tableZconstraint_columnr   r   r   _is_referenced_by_fk_constraintC   s    6z4DatabaseSchemaEditor._is_referenced_by_fk_constraintTc                    sf   | j jjsR|rR| |rR| j jr,td| | j   t ||| | j 	  nt ||| d S )NzRenaming the %r table while in a transaction is not supported on SQLite < 3.26 because it would break referential integrity. Try adding `atomic = False` to the Migration class.)
r   features!supports_atomic_references_renamer3   in_atomic_blockr   r   r   alter_db_tabler   )r   modelZold_db_tableZnew_db_tabledisable_constraintsr   r   r   r7   V   s    

z#DatabaseSchemaEditor.alter_db_tablec              	      s  |j }|jj}| \}}|j |kr|| jjjs|| j||ddr|| jjr`t	d|jj|f t
| jj t j||||d | j }	|	d d }
|	d d| }| d	 }|| }|| }|	d
||f |	d|
d	   |	d |	d W d    n1 s0    Y  W d    n1 s:0    Y  | j }	|	d W d    n1 sp0    Y  nt j||||d d S )NT)r0   zRenaming the %r.%r column while in a transaction is not supported on SQLite < 3.26 because it would break referential integrity. Try adding `atomic = False` to the Migration class.)strictzPRAGMA schema_versionr   zPRAGMA writable_schema = 1z REFERENCES "%s" ("%%s")    z3UPDATE sqlite_master SET sql = replace(sql, %s, %s)zPRAGMA schema_version = %dzPRAGMA writable_schema = 0zPRAGMA integrity_checkZVACUUM)r-   _metadb_tableZget_attname_columnr   r4   r5   r3   r6   r   r	   aliasr   alter_fieldr,   executeZfetchone)r   r8   	old_field	new_fieldr:   Zold_field_namer/   _Zold_column_namer,   Zschema_versionZreferences_templateZnew_column_namesearchreplacementr   r   r   r?   e   s:    


J,z DatabaseSchemaEditor.alter_fieldc              	      sR  fddfddj jD }fddj jD }i d}t|dds`|rt|d	 ddrt| D ],\}}	|	jrld|	_|	}|	jrl||= ||	j= ql|r|||j< |j	s|j
rʈ|||j< |rZ|\}
}||
jd ||
jd |||j< |
jr<|js<d
|
j|d }|||j< n|
j||j< |j|
j<  r| j= | j=  j	r jjj jr jjS t }fddj jD }fddj jD }j j} r fdd|D }tj j}t|}j jj j|||||d}tdd|}||d< j|d< tj jj| t|}j jdt j j |||||d}tdd|}||d< j|d< tdj j j|}!| "d|j jd#fdd|D d#|$ j jf  jdd j%||j jj jdd j&D ]}"| q*g _&|rNd|_dS )a|  
        Shortcut to transform a model from old_model into new_model

        This follows the correct procedure to perform non-rename or column
        addition operations based on SQLite's documentation

        https://www.sqlite.org/lang_altertable.html#caution

        The essential steps are:
          1. Create a table with the updated definition called "new__app_model"
          2. Copy the data from the existing "app_model" table to the new table
          3. Drop the "app_model" table
          4. Rename the "new__app_model" table to "app_model"
          5. Restore any index of the previous "app_model" table.
        c                    s   | j o| jj u S r   )Zis_relationremote_fieldr8   )f)r8   r   r   is_self_referential   s    z?DatabaseSchemaEditor._remake_table.<locals>.is_self_referentialc                    s$   i | ]}|j  |r| n|qS r   )r-   clone.0rG   )rH   r   r   
<dictcomp>   s   z6DatabaseSchemaEditor._remake_table.<locals>.<dictcomp>c                    s   i | ]}|j  |j qS r   )column
quote_namerJ   r   r   r   rL          Nprimary_keyFr;   zcoalesce(%(col)s, %(default)s))coldefaultc                    s   g | ]} fd d|D qS )c                    s   g | ]}  ||qS r   getrK   nrename_mappingr   r   
<listcomp>   rO   ADatabaseSchemaEditor._remake_table.<locals>.<listcomp>.<listcomp>r   )rK   uniquerW   r   r   rY      s   z6DatabaseSchemaEditor._remake_table.<locals>.<listcomp>c                    s   g | ]} fd d|D qS )c                    s   g | ]}  ||qS r   rS   rU   rW   r   r   rY      rO   rZ   r   rK   indexrW   r   r   rY      s   c                    s   g | ]} j |jvr|qS r   )r-   fieldsr\   delete_fieldr   r   rY      s   )	app_labelr=   unique_togetherindex_togetherindexesr1   appsZMetar   
__module__znew__%szNew%s%INSERT INTO %s (%s) SELECT %s FROM %s, c                 3   s   | ]}  |V  qd S r   )rN   )rK   xr   r   r   	<genexpr>  rO   z5DatabaseSchemaEditor._remake_table.<locals>.<genexpr>)handle_autom2m)r9   T)'r<   Zlocal_concrete_fieldsgetattrlistitemsrP   auto_createdrM   r-   many_to_manyZconcreter+   Zeffective_defaultpopnullrN   rF   throughdelete_modelr   rb   rc   rd   r1   copydeepcopyra   r=   r)   rf   Zobject_name	__bases__r   create_modelr@   joinr.   r7   deferred_sql)r   r8   create_fieldr`   r?   bodymappingZrestore_pk_fieldr-   fieldrA   rB   Zcase_sqlre   rb   rc   rd   r1   Z	body_copyZmeta_contentsmetaZ	new_modelsqlr   )r`   rH   r8   rX   r   r   _remake_table   s    









	

	


z"DatabaseSchemaEditor._remake_tablec                    sh   |rt  | nR| | jd| |jji  t| jD ](}t	|t
r:||jjr:| j| q:d S )Ntable)r   rt   r@   sql_delete_tablerN   r<   r=   rm   rz   r   r   Zreferences_tableremove)r   r8   rk   r   r   r   r   rt   3  s    z!DatabaseSchemaEditor.delete_modelc                 C   s2   |j r |jjjjr | |jjS | j||d dS )z
        Create a field on a model. Usually involves adding a column, but may
        involve adding a table instead (for M2M fields).
        )r{   N)rp   rF   rs   r<   ro   rx   r   r   r8   r~   r   r   r   	add_field@  s    zDatabaseSchemaEditor.add_fieldc                 C   sN   |j r"|jjjjrJ| |jj n(|j| jdd du r<dS | j||d dS )z
        Remove a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
        )r   r)   Nr_   )	rp   rF   rs   r<   ro   rt   Zdb_parametersr   r   r   r   r   r   remove_fieldJ  s    z!DatabaseSchemaEditor.remove_fieldc	                 C   s<  | j jjr`|j|jkr`| ||| ||kr`|jr:|js`|jrF|js`| | |j	j
|||S | j|||fd |jr8||kr8t }	|jj	}
|
jD ]L}|j|krq|js|j|jkr|	|j q|jr|jj	jr|	|j q|jr"|
jD ],}|j|krq|jjj	jr|	|jj q|	D ]}| | q&dS )z3Perform a "physical" (non-ManyToMany) field update.r?   N)r   r4   Zcan_alter_table_rename_columnrM   Z
column_sqlrF   Zdb_constraintr@   Z_rename_field_sqlr<   r=   r   r[   setr8   Zrelated_objectsrelated_modelrp   
field_namer-   addrP   rs   ro   )r   r8   rA   rB   Zold_typenew_typeZold_db_paramsZnew_db_paramsr:   Zrelated_modelsoptsrF   rp   r   r   r   r   _alter_field\  sD    




z!DatabaseSchemaEditor._alter_fieldc                 C   s   |j jjj|j jjjkrR| j|j j|j jj| |j jj| fd dS | |j j | d| 	|j jjjd
d| | gd
d| | g| 	|j jjjf  | |j j dS )z*Alter M2Ms to repoint their to= endpoints.r   Nrg   rh   id)rF   rs   r<   r=   r   	get_fieldZm2m_reverse_field_namerx   r@   rN   ry   Zm2m_column_nameZm2m_reverse_namert   )r   r8   rA   rB   r:   r   r   r   _alter_many_to_many  s0    	z(DatabaseSchemaEditor._alter_many_to_manyc                    s.   t |tr |jr t || n
| | d S r   )r   r   	conditionr   add_constraintr   r   r8   r2   r   r   r   r     s    z#DatabaseSchemaEditor.add_constraintc                    s.   t |tr |jr t || n
| | d S r   )r   r   r   r   remove_constraintr   r   r   r   r   r     s    z&DatabaseSchemaEditor.remove_constraint)NF)T)F)NNN)T)F)__name__rf   __qualname__r   Zsql_create_fkZsql_create_inline_fkZsql_create_uniqueZsql_delete_uniquer   r   r+   r3   r7   r?   r   rt   r   r   r   r   r   r   __classcell__r   r   r   r   r
      s*   
'
 (
 
$#r
   )ru   decimalr   Zdjango.apps.registryr   Z	django.dbr   Zdjango.db.backends.base.schemar   Z!django.db.backends.ddl_referencesr   Zdjango.db.backends.utilsr   Zdjango.db.modelsr   Zdjango.db.transactionr	   r
   r   r   r   r   <module>   s   