a
    ÛEb~W  ã                   @   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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 )NzüSQLite 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__© úa/home/ja/django-apps/lartica_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ƒr„d| 
dd¡ S |d u r�dS t|tttfƒr¬d| ¡  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 sœ0    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_constraintH   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 )Nz°Renaming 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   b   s     ÿþýûÿ
z#DatabaseSchemaEditor.alter_db_tablec              	      s¤  |   ||¡sd S |j}|jj}| ¡ \}}|j|k�rŒ| jjj�sŒ| j||dd��rŒ| jj	rpt
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 �sJ0    Y  | j ¡ �}	|	 d¡ W d   ƒ n1 �s€0    Y  ntƒ j||||d� d S )NT)r0   z´Renaming 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)Z_field_should_be_alteredr-   Ú_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?   y   sP    ÿþÿý
ûÿÿ
þ
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`|ršt|d	 ddƒršt| ¡ ƒ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   Í   s   ÿ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>  ó    úADatabaseSchemaEditor._remake_table.<locals>.<listcomp>.<listcomp>r   )rK   ÚuniquerV   r   r   rX     s   ÿz6DatabaseSchemaEditor._remake_table.<locals>.<listcomp>c                    s   g | ]}‡ fd d„|D ƒ‘qS )c                    s   g | ]}ˆ   ||¡‘qS r   rR   rT   rV   r   r   rX     rY   rZ   r   ©rK   ÚindexrV   r   r   rX     s   ÿc                    s   g | ]}ˆ j |jvr|‘qS r   )r-   Úfieldsr\   ©Údelete_fieldr   r   rX     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>J  rY   z5DatabaseSchemaEditor._remake_table.<locals>.<genexpr>)Úhandle_autom2m)r9   T)'r<   Zlocal_concrete_fieldsÚgetattrÚlistÚitemsrO   Ú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   rW   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   c  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_fieldu  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_field  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r¨q˜|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-   ÚaddrO   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‘  sN    ÿ
þýûúùøÿÿ


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È  sH    

ÿÿ
ÿ
ÿøþýÿýÿðÿÿz(DatabaseSchemaEditor._alter_many_to_manyc                    s@   t |tƒr2|js"|js"|js"|jr2tƒ  ||¡ n
|  |¡ d S r   )	r   r   Ú	conditionÚcontains_expressionsÚincludeÚ
deferrabler   Úadd_constraintr�   ©r   r8   r2   r   r   r   r—   ü  s    
ÿþýüz#DatabaseSchemaEditor.add_constraintc                    s@   t |tƒr2|js"|js"|js"|jr2tƒ  ||¡ n
|  |¡ d S r   )	r   r   r“   r”   r•   r–   r   Úremove_constraintr�   r˜   r   r   r   r™     s    
ÿþýüz&DatabaseSchemaEditor.remove_constraintc                 C   s   d| S )NzCOLLATE r   )r   Z	collationr   r   r   Ú_collate_sql  s    z!DatabaseSchemaEditor._collate_sql)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™   rš   Ú__classcell__r   r   r   r   r
      s4   ÿ  ÿ
 ÿ6 ÿ
 6
 ÷
74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   