a
    ¥Q•hn_  ã                   @   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eZdZdZdZ	‡ fdd„Z
‡ fd	d
„Z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‡ fdd„Z‡ f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 DEFERREDz,ALTER TABLE %(table)s DROP COLUMN %(column)sz7CREATE 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__© úZ/var/www/sistema_ama/venv/lib/python3.9/site-packages/django/db/backends/sqlite3/schema.pyr      s
    
ÿzDatabaseSchemaEditor.__enter__c                    s(   | j  ¡  tƒ  |||¡ | j  ¡  d S ©N)r   Ú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''ÚNULLzX'%s'z*Cannot quote parameter value %r of type %s)Úsqlite3ÚadaptÚImportErrorÚProgrammingErrorÚ
isinstanceÚboolÚstrÚintr   ÚfloatÚreplaceÚbytesÚ	bytearrayÚ
memoryviewÚhexÚ
ValueErrorÚtype)r   Úvaluer   r   r   r   Úquote_value*   s(    

ÿz DatabaseSchemaEditor.quote_valuec                 C   s
   |   |¡S r   )r/   )r   r.   r   r   r   Úprepare_defaultI   s    z$DatabaseSchemaEditor.prepare_defaultFc           	      C   s¢   | j  ¡ �„}| j j |¡D ]d}|r.|j|kr.q| j j ||j¡}| ¡ D ]4\}}||krH|du sh||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.
        NTF)r   ÚcursorÚintrospectionÚget_table_listÚnameÚget_relationsÚvalues)	r   Ú
table_nameÚcolumn_nameÚignore_selfr1   Zother_tableÚ	relationsZconstraint_columnZconstraint_tabler   r   r   Ú_is_referenced_by_fk_constraintL   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_renamer;   Úin_atomic_blockr   r   r   Úalter_db_tabler   )r   ÚmodelZold_db_tableZnew_db_tableÚdisable_constraintsr   r   r   r?   c   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)r9   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_checkÚVACUUM)Z_field_should_be_alteredr4   Ú_metaÚdb_tableÚget_attname_columnr   r<   r=   r;   r>   r   r	   Úaliasr   Úalter_fieldr1   ÚexecuteÚfetchone)r   r@   Ú	old_fieldÚ	new_fieldrB   Úold_field_namer7   Ú_Zold_column_namer1   Zschema_versionZreferences_templateZnew_column_nameÚsearchÚreplacementr   r   r   rI   z   sP    ÿþÿý
ûÿÿ
þ
J,z DatabaseSchemaEditor.alter_fieldc              	      sr  ‡fdd„‰‡fdd„ˆj jD ƒ}‡fdd„ˆj jD ƒ}i ‰d}|pFg }t|ddƒsftd	d
„ |D ƒƒr¶t| ¡ ƒD ]B\‰}|jrrt‡fdd
„|D ƒƒsrd|_|}|jrr|ˆ= ||j= qr|ræ|||j	< |j
sæ|jræˆ ˆ |¡¡||j< |D ]Ž}	|	\}
}| |
j	d¡ | |
jd¡ |||j	< |
j�rZ|j�sZdˆ |
j¡ˆ ˆ |¡¡dœ }|||j< nˆ |
j¡||j< |j	ˆ|
j	< qêˆ �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 ]}ˆ #|¡ �qJg ˆ_'|�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   )Úis_relationÚremote_fieldr@   )Úf)r@   r   r   Úis_self_referentialÅ   s    z?DatabaseSchemaEditor._remake_table.<locals>.is_self_referentialc                    s$   i | ]}|j ˆ |ƒr| ¡ n|“qS r   )r4   Úclone©Ú.0rT   )rU   r   r   Ú
<dictcomp>É   s   ÿz6DatabaseSchemaEditor._remake_table.<locals>.<dictcomp>c                    s   i | ]}|j ˆ  |j ¡“qS r   )ÚcolumnÚ
quote_namerW   r   r   r   rY   Ï   s   ÿNÚprimary_keyFc                 s   s   | ]\}}t |d dƒV  qdS )r\   FN)Úgetattr©rX   rO   rM   r   r   r   Ú	<genexpr>Ù   s   z5DatabaseSchemaEditor._remake_table.<locals>.<genexpr>c                 3   s   | ]\}}ˆ |j kV  qd S r   ©r4   r^   r`   r   r   r_   Ý   s   ÿzcoalesce(%(col)s, %(default)s))ÚcolÚdefaultc                    s   g | ]}‡ fd d„|D ƒ‘qS )c                    s   g | ]}ˆ   ||¡‘qS r   ©Úget©rX   Ún©Úrename_mappingr   r   Ú
<listcomp>  ó    úADatabaseSchemaEditor._remake_table.<locals>.<listcomp>.<listcomp>r   )rX   Úuniquerg   r   r   ri     s   ÿz6DatabaseSchemaEditor._remake_table.<locals>.<listcomp>c                    s   g | ]}‡ fd d„|D ƒ‘qS )c                    s   g | ]}ˆ   ||¡‘qS r   rc   re   rg   r   r   ri     rj   rk   r   ©rX   Úindexrg   r   r   ri     s   ÿc                    s   g | ]}ˆ j |jvr|‘qS r   )r4   Úfieldsrm   ©Údelete_fieldr   r   ri     s   )Ú	app_labelrF   Úunique_togetherÚindex_togetherÚindexesÚconstraintsÚappsÚMetar   Ú
__module__znew__%szNew%sú%INSERT INTO %s (%s) SELECT %s FROM %sú, c                 3   s   | ]}ˆ   |¡V  qd S r   )r[   )rX   Úxr   r   r   r_   R  rj   )Úhandle_autom2m)rA   T)(rE   Úlocal_concrete_fieldsr]   ÚanyÚlistÚitemsr\   Úauto_createdrZ   r4   Úmany_to_manyÚconcreter0   Úeffective_defaultÚpopÚnullr[   rS   ÚthroughÚdelete_modelr   rs   rt   ru   rv   ÚcopyÚdeepcopyrr   rF   r-   ry   Úobject_nameÚ	__bases__r   Úcreate_modelrJ   Újoinr6   r?   Údeferred_sql)r   r@   Úcreate_fieldrq   Úalter_fieldsÚbodyÚmappingZrestore_pk_fieldÚfieldrI   rL   rM   Úcase_sqlrw   rs   rt   ru   rv   Z	body_copyÚmeta_contentsÚmetaÚ	new_modelÚsqlr   )rq   rU   r@   r4   rh   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   r‰   rJ   Úsql_delete_tabler[   rE   rF   r€   r�   r"   r   Zreferences_tableÚremove)r   r@   r}   rš   r   r   r   r‰   k  s    ÿÿÿÿz!DatabaseSchemaEditor.delete_modelc                    sd   |j r"|jjjjr"|  |jj¡ n>|jsB|jsB|jrB|  	|¡durR| j
||d� ntƒ  ||¡ dS )zCreate a field on a model.N)r‘   )rƒ   rS   rˆ   rE   r‚   rŽ   r\   rl   r‡   r…   r›   r   Ú	add_field©r   r@   r•   r   r   r   rŸ   }  s    ýü	÷
özDatabaseSchemaEditor.add_fieldc                    s†   |j r"|jjjjr‚|  |jj¡ n`| jjjrZ|j	sZ|j
sZ|jsZ|jrJ|jsZtƒ  ||¡ n(|j| jd�d du rtd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-   Nrp   )rƒ   rS   rˆ   rE   r‚   r‰   r   r<   Úcan_alter_table_drop_columnr\   rl   Údb_indexÚdb_constraintr   Úremove_fieldÚdb_parametersr›   r    r   r   r   r¤   ’  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gd� | d¡}	| d¡}
|j�r\||ks¢|	|
k�r\tƒ }|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�rF|jD ]2}|j|k�r&�q|jjj	j�r| |jj¡ �q|D ]}|  |¡ �qJdS )z3Perform a "physical" (non-ManyToMany) field update.©r’   Ú	collationN)r   r<   Úcan_alter_table_rename_columnrZ   Z
column_sqlrS   r£   rJ   Z_rename_field_sqlrE   rF   r›   rd   rl   Úsetr@   Úrelated_objectsÚrelated_modelrƒ   Ú
field_namer4   Úaddr\   rˆ   r‚   )r   r@   rL   rM   Zold_typeÚnew_typeZold_db_paramsZnew_db_paramsrB   Zold_collationZnew_collationÚrelated_modelsÚoptsrS   rƒ   r«   r   r   r   Ú_alter_field®  sZ    ÿ
þýûúùøÿÿ

ÿÿ


z!DatabaseSchemaEditor._alter_fieldc                 C   sô   |j jjj|j jjjkrz| j|j j|j jj | ¡ ¡|j jj | ¡ ¡f|j jj | ¡ ¡|j jj | ¡ ¡fg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¦   Nrz   r{   Úid)rS   rˆ   rE   rF   r›   Ú	get_fieldÚm2m_reverse_field_nameÚm2m_field_namerŽ   rJ   r[   r�   Úm2m_column_nameÚm2m_reverse_namer‰   )r   r@   rL   rM   rB   r   r   r   Ú_alter_many_to_manyé  sX    

ÿÿ
ÿ
ÿù
ÿ
ÿùôþýÿýÿðÿÿ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   r@   Ú
constraintr   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À   4  s    
ÿþýüz&DatabaseSchemaEditor.remove_constraintc                 C   s   d| S )NzCOLLATE r   )r   r§   r   r   r   Ú_collate_sql?  s    z!DatabaseSchemaEditor._collate_sql)NF)T)F)NNN)T)F)Ú__name__ry   Ú__qualname__r�   Zsql_create_fkZsql_create_inline_fkZsql_create_column_inline_fkZsql_delete_columnZsql_create_uniqueZsql_delete_uniquer   r   r/   r0   r;   r?   rI   r›   r‰   rŸ   r¤   r±   r¸   r½   rÀ   rÁ   Ú__classcell__r   r   r   r   r
      s:   ÿ ÿ
 ÿ6 ÿ
 =% ÷
;@r
   )rŠ   Údecimalr   Zdjango.apps.registryr   Ú	django.dbr   Zdjango.db.backends.base.schemar   Z!django.db.backends.ddl_referencesr   Údjango.db.backends.utilsr   Údjango.db.modelsr   Zdjango.db.transactionr	   r
   r   r   r   r   Ú<module>   s   