B
    ©0H[·Ã  ã               @   s¤   d dl Z d dlZd dlmZ d dlmZmZmZmZ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 e d	¡Zd
d„ Zdd„ ZG dd„ dƒZdS )é    N)Údatetime)ÚColumnsÚForeignKeyNameÚ	IndexNameÚ	StatementÚTable)Úsplit_identifier)ÚIndex)ÚTransactionManagementErrorÚatomic)Útimezone)Úforce_byteszdjango.db.backends.schemac             C   s2   | j }|jrdS |jr&|jdgkr&dS |j|jkS )zz
    When altering the given field, must constraints on its model from the given
    relation be temporarily dropped?
    FNT)ÚfieldÚmany_to_manyÚprimary_keyZ	to_fieldsÚname)ZrelationZaltered_fieldr   © r   úbC:\Users\HIRONO~1\AppData\Local\Temp\pip-install-6bm3nxem\django\django\db\backends\base\schema.pyÚ_is_relevant_relation   s    r   c                s2   t ‡fdd„ˆjjjD ƒ‡ fdd„ˆ jjjD ƒƒS )Nc             3   s   | ]}t |ˆ ƒr|V  qd S )N)r   )Ú.0Úobj)Ú	old_fieldr   r   ú	<genexpr>%   s    z+_related_non_m2m_objects.<locals>.<genexpr>c             3   s   | ]}t |ˆ ƒr|V  qd S )N)r   )r   r   )Ú	new_fieldr   r   r   &   s    )ÚzipÚmodelÚ_metaÚrelated_objects)r   r   r   )r   r   r   Ú_related_non_m2m_objects!   s    r   c               @   sê  e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdpdd„Zdd„ Zdd „ Z dqd"d#„Z!d$d%„ Z"e#d&d'„ ƒZ$drd(d)„Z%d*d+„ Z&d,d-„ Z'd.d/„ Z(d0d1„ Z)d2d3„ Z*d4d5„ Z+d6d7„ Z,d8d9„ Z-d:d;„ Z.d<d=„ Z/d>d?„ Z0d@dA„ Z1dBdC„ Z2dDdE„ Z3dFdG„ Z4dsdHdI„Z5dtdJdK„Z6dLdM„ Z7dudNdO„Z8dPdQ„ Z9dRdS„ Z:dvdUdV„Z;dwdWdX„Z<ddTdTdd!ddYœdZd[„Z=d\d]„ Z>d^d_„ Z?d`da„ Z@dbdc„ ZAddde„ ZBdfdg„ ZCdhdi„ ZDdxdjdk„ZEdydldm„ZFdzdndo„ZGdS ){ÚBaseDatabaseSchemaEditorzÈ
    This class and its subclasses are responsible for emitting schema-changing
    statements to the databases - model creation/removal/alteration, field
    renaming, index fiddling, and so on.
    z'CREATE TABLE %(table)s (%(definition)s)z1ALTER TABLE %(old_table)s RENAME TO %(new_table)sz7ALTER TABLE %(table)s SET TABLESPACE %(new_tablespace)szDROP TABLE %(table)s CASCADEz:ALTER TABLE %(table)s ADD COLUMN %(column)s %(definition)sz!ALTER TABLE %(table)s %(changes)sz%ALTER COLUMN %(column)s TYPE %(type)sz%ALTER COLUMN %(column)s DROP NOT NULLz$ALTER COLUMN %(column)s SET NOT NULLz/ALTER COLUMN %(column)s SET DEFAULT %(default)sz$ALTER COLUMN %(column)s DROP DEFAULTz4ALTER TABLE %(table)s DROP COLUMN %(column)s CASCADEzDALTER TABLE %(table)s RENAME COLUMN %(old_column)s TO %(new_column)szFUPDATE %(table)s SET %(column)s = %(default)s WHERE %(column)s IS NULLz?ALTER TABLE %(table)s ADD CONSTRAINT %(name)s CHECK (%(check)s)z.ALTER TABLE %(table)s DROP CONSTRAINT %(name)szBALTER TABLE %(table)s ADD CONSTRAINT %(name)s UNIQUE (%(columns)s)z|ALTER TABLE %(table)s ADD CONSTRAINT %(name)s FOREIGN KEY (%(column)s) REFERENCES %(to_table)s (%(to_column)s)%(deferrable)sNz9CREATE INDEX %(name)s ON %(table)s (%(columns)s)%(extra)szDROP INDEX %(name)szGALTER TABLE %(table)s ADD CONSTRAINT %(name)s PRIMARY KEY (%(columns)s)zDROP PROCEDURE %(procedure)sFTc             C   s,   || _ || _| jrg | _| j jjo$|| _d S )N)Ú
connectionÚcollect_sqlÚcollected_sqlÚfeaturesÚcan_rollback_ddlÚatomic_migration)Úselfr    r!   r   r   r   r   Ú__init__W   s
    z!BaseDatabaseSchemaEditor.__init__c             C   s(   g | _ | jr$t| jjƒ| _| j ¡  | S )N)Údeferred_sqlr%   r   r    ÚaliasÚ	__enter__)r&   r   r   r   r*   `   s
    
z"BaseDatabaseSchemaEditor.__enter__c             C   s<   |d kr"x| j D ]}|  |¡ qW | jr8| j |||¡ d S )N)r(   Úexecuter%   r   Ú__exit__)r&   Úexc_typeÚ	exc_valueÚ	tracebackÚsqlr   r   r   r,   g   s
    z!BaseDatabaseSchemaEditor.__exit__r   c          	   C   sº   | j s | jjr | jjjs tdƒ‚t|ƒ}tjd||||dœd� | j r”| 	d¡rTdnd}|dk	r‚| j
 |tt| j|ƒƒ | ¡ q¶| j
 || ¡ n"| j ¡ �}| ||¡ W dQ R X dS )z:Execute the given SQL statement, with optional parameters.ziExecuting DDL statements while in a transaction on databases that can't perform a rollback is prohibited.z%s; (params %r))Úparamsr0   )Úextraú;Ú N)r!   r    Zin_atomic_blockr#   r$   r
   ÚstrÚloggerÚdebugÚendswithr"   ÚappendÚtupleÚmapÚquote_valueÚcursorr+   )r&   r0   r1   Zendingr=   r   r   r   r+   p   s    "z BaseDatabaseSchemaEditor.executec             C   s   | j j |¡S )N)r    ÚopsÚ
quote_name)r&   r   r   r   r   r?   ‡   s    z#BaseDatabaseSchemaEditor.quote_namec             G   s4   t  ¡ }x|D ]}| t|ƒ¡ qW | ¡ dd… S )zw
        Generate a 32-bit digest of a set of arguments that can be used to
        shorten identifying names.
        Né   )ÚhashlibÚmd5Úupdater   Ú	hexdigest)ÚclsÚargsÚhÚargr   r   r   Ú_digestŠ   s    
z BaseDatabaseSchemaEditor._digestc       
      C   s(  |j | jd�}|d }g }|dkr&dS |j}|o:|  |¡ }|r‚|  |¡}|dk	r‚| jjjrp|d|  |¡ 7 }n|d7 }||g7 }|jrœ|j	sœ| jjj
rœd}|r´| jjjs´|d7 }n|sÀ|d7 }|j	rÐ|d	7 }n|jrÞ|d
7 }|jpê|jj}	|	�r | jjj�r |j�r |d| jjj|	dd� 7 }||fS )z‹
        Take a field and return its column definition.
        The field must already have had set_attributes_from_name() called.
        )r    ÚtypeN)NNz DEFAULT %sTz NULLz	 NOT NULLz PRIMARY KEYz UNIQUEz %s)Úinline)Údb_parametersr    ÚnullÚskip_defaultÚeffective_defaultr#   Úrequires_literal_defaultsÚprepare_defaultÚempty_strings_allowedr   Ú!interprets_empty_strings_as_nullsZimplied_column_nullÚuniqueÚdb_tablespacer   Zsupports_tablespacesr>   Útablespace_sql)
r&   r   r   Úinclude_defaultÚ	db_paramsr0   r1   rM   Údefault_valueZ
tablespacer   r   r   Ú
column_sql—   s:    





z#BaseDatabaseSchemaEditor.column_sqlc             C   s   dS )z�
        Some backends don't accept default values for certain columns types
        (i.e. MySQL longtext and longblob).
        Fr   )r&   r   r   r   r   rN   Ç   s    z%BaseDatabaseSchemaEditor.skip_defaultc             C   s   t dƒ‚dS )zU
        Only used for backends which have requires_literal_defaults feature
        z€subclasses of BaseDatabaseSchemaEditor for backends which have requires_literal_defaults must provide a prepare_default() methodN)ÚNotImplementedError)r&   Úvaluer   r   r   rQ   Î   s    z(BaseDatabaseSchemaEditor.prepare_defaultc             C   s¼   |  ¡ r| ¡ }nŠ|js@|jr@|jr@| ¡ dkr8tƒ }qœtƒ }n\t|ddƒsXt|ddƒr˜t	 
¡ }| ¡ }|dkrx|j}qœ|dkrˆ|j}qœ|dkrœtj
}nd}t|ƒrª|ƒ }| || j¡}|S )	z2Return a field's effective database default value.ZBinaryFieldZauto_nowFZauto_now_addZ	DateFieldZ	TimeFieldZDateTimeFieldN)Úhas_defaultZget_defaultrM   ZblankrR   Úget_internal_typeÚbytesr5   Úgetattrr   ÚnowÚdateÚtimer   ÚcallableZget_db_prep_saver    )r&   r   ÚdefaultZinternal_typer   r   r   rO   ×   s(    
z*BaseDatabaseSchemaEditor.effective_defaultc             C   s
   t ƒ ‚dS )aX  
        Return a quoted version of the value so it's safe to use in an SQL
        string. This is not safe against injection from user code; it is
        intended only for use in making SQL scripts or preparing default values
        for particularly tricky backends (defaults are not user-defined, though,
        so this is safe).
        N)r[   )r&   r\   r   r   r   r<   ó   s    z$BaseDatabaseSchemaEditor.quote_valuec                s,  g }g }�x@ˆ j jD �]2}|  ˆ |¡\}}|dkr4q|j| jd�}|d rZ|d|d  7 }|j| jd�}|rx|d| 7 }| |¡ |jrü|jrü|jj	j j
}	|jj	j  |jj¡j}
| jrÜ|d| j|  |	¡|  |
¡dœ  7 }n | jjjrü| j |  ˆ |d¡¡ | d	|  |j¡|f ¡ | ¡ d
kr| jj ˆ j j
|j¡}|r| j |¡ qW x8ˆ j jD ],}‡ fdd„|D ƒ}| j |  ˆ |¡¡ �qVW | j|  ˆ j j
¡d |¡dœ }ˆ j j�rÔ| jj ˆ j j¡}|�rÔ|d| 7 }|  ||�pâd¡ | j |  ˆ ¡¡ x.ˆ j j D ]"}|jj!j j"�r|  #|jj!¡ �qW dS )zr
        Create a table and any accompanying indexes or unique constraints for
        the given `model`.
        N)r    Úcheckz CHECK (%s)z %sú )Úto_tableÚ	to_columnz_fk_%(to_table)s_%(to_column)sz%s %s)Z	AutoFieldZBigAutoFieldc                s   g | ]}ˆ j  |¡j‘qS r   )r   Ú	get_fieldÚcolumn)r   r   )r   r   r   ú
<listcomp>.  s    z9BaseDatabaseSchemaEditor.create_model.<locals>.<listcomp>z, )ÚtableÚ
definition)$r   Úlocal_fieldsrZ   rL   r    Zdb_type_suffixÚextendÚremote_fieldÚdb_constraintr   Údb_tablerj   Ú
field_namerk   Úsql_create_inline_fkr?   r#   Úsupports_foreign_keysr(   r9   Ú_create_fk_sqlr^   r>   Úautoinc_sqlZunique_togetherÚ_create_unique_sqlÚsql_create_tableÚjoinrU   rV   r+   Ú_model_indexes_sqlÚlocal_many_to_manyÚthroughÚauto_createdÚcreate_model)r&   r   Zcolumn_sqlsr1   r   rn   Zextra_paramsrX   Zcol_type_suffixrh   ri   rx   ÚfieldsÚcolumnsr0   rV   r   )r   r   r€   ÿ   sX    




z%BaseDatabaseSchemaEditor.create_modelc             C   s†   x*|j jD ]}|jjj jr
|  |jj¡ q
W |  | jd|  |j j	¡i ¡ x6t
| jƒD ](}t|tƒrV| |j j	¡rV| j |¡ qVW dS )z!Delete a model from the database.rm   N)r   r}   rq   r~   r   Údelete_modelr+   Úsql_delete_tabler?   rs   Úlistr(   Ú
isinstancer   Zreferences_tableÚremove)r&   r   r   r0   r   r   r   rƒ   D  s    z%BaseDatabaseSchemaEditor.delete_modelc             C   s   |   | || ¡¡ dS )zAdd an index on a model.N)r+   Ú
create_sql)r&   r   Úindexr   r   r   Ú	add_indexT  s    z"BaseDatabaseSchemaEditor.add_indexc             C   s   |   | || ¡¡ dS )zRemove an index from a model.N)r+   Z
remove_sql)r&   r   r‰   r   r   r   Úremove_indexX  s    z%BaseDatabaseSchemaEditor.remove_indexc                s‚   dd„ |D ƒ}dd„ |D ƒ}x(|  |¡D ]}|  ˆ |ddi| j¡ q(W x6|  |¡D ](}‡ fdd„|D ƒ}|  |  ˆ |¡¡ qRW dS )	z°
        Deal with a model changing its unique_together. The input
        unique_togethers must be doubly-nested, not the single-nested
        ["foo", "bar"] format.
        c             S   s   h | ]}t |ƒ’qS r   )r:   )r   r�   r   r   r   ú	<setcomp>b  s    zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c             S   s   h | ]}t |ƒ’qS r   )r:   )r   r�   r   r   r   rŒ   c  s    rT   Tc                s   g | ]}ˆ j  |¡j‘qS r   )r   rj   rk   )r   r   )r   r   r   rl   i  s    zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)Ú
differenceÚ_delete_composed_indexÚsql_delete_uniquer+   ry   )r&   r   Zold_unique_togetherZnew_unique_togetherÚoldsÚnewsr�   r‚   r   )r   r   Úalter_unique_together\  s    z.BaseDatabaseSchemaEditor.alter_unique_togetherc                s†   dd„ |D ƒ}dd„ |D ƒ}x(|  |¡D ]}|  ˆ |ddi| j¡ q(W x:|  |¡D ],}‡ fdd„|D ƒ}|  | jˆ |dd	�¡ qRW d
S )z®
        Deal with a model changing its index_together. The input
        index_togethers must be doubly-nested, not the single-nested
        ["foo", "bar"] format.
        c             S   s   h | ]}t |ƒ’qS r   )r:   )r   r�   r   r   r   rŒ   r  s    z@BaseDatabaseSchemaEditor.alter_index_together.<locals>.<setcomp>c             S   s   h | ]}t |ƒ’qS r   )r:   )r   r�   r   r   r   rŒ   s  s    r‰   Tc                s   g | ]}ˆ j  |¡‘qS r   )r   rj   )r   r   )r   r   r   rl   y  s    zABaseDatabaseSchemaEditor.alter_index_together.<locals>.<listcomp>Ú_idx)ÚsuffixN)r�   rŽ   Úsql_delete_indexr+   Ú_create_index_sql)r&   r   Zold_index_togetherZnew_index_togetherr�   r‘   r�   Úfield_namesr   )r   r   Úalter_index_togetherl  s    z-BaseDatabaseSchemaEditor.alter_index_togetherc                sj   ‡ fdd„|D ƒ}| j ˆ |f|Ž}t|ƒdkrNtdt|ƒˆ jjd |¡f ƒ‚|  |  |ˆ |d ¡¡ d S )Nc                s   g | ]}ˆ j  |¡j‘qS r   )r   rj   rk   )r   r   )r   r   r   rl   }  s    zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>é   z1Found wrong number (%s) of constraints for %s(%s)z, r   )Ú_constraint_namesÚlenÚ
ValueErrorr   rs   r{   r+   Ú_delete_constraint_sql)r&   r   r�   Zconstraint_kwargsr0   r‚   Úconstraint_namesr   )r   r   rŽ   |  s    z/BaseDatabaseSchemaEditor._delete_composed_indexc             C   sr   ||ks"| j jjr&| ¡ | ¡ kr&dS |  | j|  |¡|  |¡dœ ¡ x$| jD ]}t|t	ƒrP| 
||¡ qPW dS )z#Rename the table a model points to.N)Z	old_tableZ	new_table)r    r#   Zignores_table_name_caseÚlowerr+   Úsql_rename_tabler?   r(   r†   r   Zrename_table_references)r&   r   Zold_db_tableZnew_db_tabler0   r   r   r   Úalter_db_table‡  s    

z'BaseDatabaseSchemaEditor.alter_db_tablec             C   s2   |   | j|  |jj¡|  |¡|  |¡dœ ¡ dS )z)Move a model's table between tablespaces.)rm   Zold_tablespaceZnew_tablespaceN)r+   Úsql_retablespace_tabler?   r   rs   )r&   r   Zold_db_tablespaceZnew_db_tablespacer   r   r   Úalter_db_tablespace–  s    z,BaseDatabaseSchemaEditor.alter_db_tablespacec             C   sJ  |j r |jjjjr |  |jj¡S | j||dd�\}}|dkr@dS |j| jd�}|d rf|d|d  7 }| j	|  
|jj¡|  
|j¡|dœ }|  ||¡ |  |¡sê|  |¡dk	rê| j|d|dd�\}}| j|  
|jj¡|d	œ }|  ||¡ | j |  ||¡¡ |j�r0| jjj�r0|j�r0| j |  ||d
¡¡ | jjj�rF| j ¡  dS )z�
        Create a field on a model. Usually involves adding a column, but may
        involve adding a table instead (for M2M fields).
        T)rW   N)r    rf   z CHECK (%s))rm   rk   rn   )Údrop)rm   Úchangesz_fk_%(to_table)s_%(to_column)s)r   rq   r~   r   r   r€   rZ   rL   r    Úsql_create_columnr?   rs   rk   r+   rN   rO   Ú_alter_column_default_sqlÚsql_alter_columnr(   rp   Ú_field_indexes_sqlr#   rv   rr   r9   rw   Úconnection_persists_old_columnsÚclose)r&   r   r   rn   r1   rX   r0   Úchanges_sqlr   r   r   Ú	add_fieldž  s0    


z"BaseDatabaseSchemaEditor.add_fieldc             C   sø   |j r |jjjjr |  |jj¡S |j| jd�d dkr:dS |jrx| j||j	gdd�}x"|D ]}|  
|  | j||¡¡ qZW | j|  |jj¡|  |j	¡dœ }|  
|¡ | jjjr¸| j ¡  x:t| jƒD ],}t|tƒrÄ| |jj|j	¡rÄ| j |¡ qÄW dS )z…
        Remove a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
        )r    rJ   NT)Úforeign_key)rm   rk   )r   rq   r~   r   r   rƒ   rL   r    rš   rk   r+   r�   Úsql_delete_fkÚsql_delete_columnr?   rs   r#   rª   r«   r…   r(   r†   r   Zreferences_columnr‡   )r&   r   r   Úfk_namesÚfk_namer0   r   r   r   Úremove_fieldÈ  s"    



z%BaseDatabaseSchemaEditor.remove_fieldc       	   
   C   s$  |j | jd�}|d }|j | jd�}|d }|dkr>|jdksP|dkrb|jdkrbtd||f ƒ‚n¦|dkrª|dkrª|jjrª|jjrª|jjjjrª|jjjjrª|  ||||¡S |dkræ|dkræ|jjræ|jjræ|jjjjsæ|jjjjsædS |dksø|dk�rtd||f ƒ‚|  ||||||||¡ dS )a'  
        Allow a field's type, uniqueness, nullability, default, column,
        constraints, etc. to be modified.
        `old_field` is required to compute the necessary changes.
        If `strict` is True, raise errors if the old column does not match
        `old_field` precisely.
        )r    rJ   NzqCannot alter field %s into %s - they do not properly define db_type (are you using a badly-written custom field?)z�Cannot alter field %s into %s - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields))	rL   r    rq   rœ   r~   r   r   Ú_alter_many_to_manyÚ_alter_field)	r&   r   r   r   ÚstrictÚold_db_paramsÚold_typeÚnew_db_paramsÚnew_typer   r   r   Úalter_fieldæ  s2    	z$BaseDatabaseSchemaEditor.alter_fieldc	       &      C   sÒ  t ƒ }	|jr„|jr„| j||jgdd�}
|rRt|
ƒdkrRtdt|
ƒ|jj|jf ƒ‚x0|
D ](}|	 	|jf¡ |  
|  | j||¡¡ qXW |j�r|jr¢|j�s|j�r| j||jgdd�}|rât|ƒdkrâtdt|ƒ|jj|jf ƒ‚x"|D ]}|  
|  | j||¡¡ qèW |j�r|j�s&|j�o,|j�o,||k}|�rŽxXt||ƒD ]J\}}| j|j|jjgdd�}x&|D ]}|  
|  | j|j|¡¡ �qfW �q@W |j�r|j�s|j�r®|j�rdd„ |jjD ƒ}| j||jgdtjd	�}x2|D ]*}||k�rð�qÞ|  
|  | j||¡¡ �qÞW |d
 |d
 k�r’|d
 �r’| j||jgdd�}|�rlt|ƒdk�rltdt|ƒ|jj|jf ƒ‚x$|D ]}|  
|  | j||¡¡ �qrW |j|jk�rî|  
|  |jj|||¡¡ x2| jD ](}t|tƒ�rÂ| |jj|j|j¡ �qÂW g }g }g }||k�r,|  ||||¡\}}| |¡ |  |¡ |  !|¡}|  !|¡}|j"�op|j" �op||k�op|dk	�op|  #|¡ }|�rŒ| |  $|||¡¡ |j"|j"k�r¸|  %|||¡}|�r¸| |¡ | &¡ �oÐ|j"�oÐ|j" }|�sÞ|�rÄ|�sì|| }| j'j(j)�r$|�r$t*t+|Ž ƒ\}}d ,|¡t-|g ƒfg}x4|D ],\}}|  
| j.|  /|jj¡|dœ |¡ �q*W |�rÄ|  
| j0|  /|jj¡|  /|j¡ddœ |g¡ x4|D ],\}}|  
| j.|  /|jj¡|dœ |¡ �q”W |�rêx|D ]\}}|  
||¡ �qÐW |j�sú|j�s|j�r(|j�s(|j�r(|  
|  1||jg¡¡ |j�r8|j�r\|j�r\|j�s\|  
|  2||g¡¡ g } |j�rŠ|j�rŠ||k�rŠ|   t||ƒ¡ |j�sú|j�rú|  3||¡ |  
| j4|  /|jj¡|  /| j5|jj|jgdd�¡|  /|j¡dœ ¡ |   t||ƒ¡ x�| D ]ˆ\}!}|jj6| j'd�}"|"d }#|  |j|!j|j|#¡\}}|  
| j.|  /|jjj¡|d dœ |d ¡ x|D ]\}}|  
||¡ �qlW �q W |j�rÆ|	�sª|j�rª|j�sÆ|j�rÆ|  
|  7||d¡¡ |�rxB|j8jj9D ]4}$t:|$|ƒ�rØ|$jj�rØ|  
|  7|$j|$jd¡¡ �qØW |d
 |d
 k�rv|d
 �rv|  
| j;|  /|jj¡|  /| j5|jj|jgdd�¡|  /|j¡|d
 dœ ¡ |�r¸| j$|||dd�\}%}| j.|  /|jj¡|%dœ }|  
||¡ | j'j(j<�rÎ| j' =¡  dS )z3Perform a "physical" (non-ManyToMany) field update.T)r®   r™   z<Found wrong number (%s) of foreign key constraints for %s.%s)rT   z7Found wrong number (%s) of unique constraints for %s.%sc             S   s   h | ]
}|j ’qS r   )r   )r   r‰   r   r   r   rŒ   H  s    z8BaseDatabaseSchemaEditor._alter_field.<locals>.<setcomp>)r‰   Útype_rf   )rf   z6Found wrong number (%s) of check constraints for %s.%sNz, )rm   r¥   z%s)rm   rk   re   Z_pk)r”   )rm   r   r‚   )r    rJ   r   z_fk_%(to_table)s_%(to_column)sZ_fkÚ_check)rm   r   rk   rf   )r¤   )>Úsetrq   rr   rš   rk   r›   rœ   r   rs   Úaddr+   r�   r¯   rT   r   r�   r   Zrelated_modelr   Údb_indexÚindexesr	   r”   r•   Úsql_delete_checkÚ_rename_field_sqlr(   r†   r   Zrename_column_referencesÚ_alter_column_type_sqlr9   rp   rO   rM   rN   r§   Ú_alter_column_null_sqlr]   r    r#   Zsupports_combined_altersr:   r   r{   Úsumr¨   r?   Úsql_update_with_defaultry   r–   Ú_delete_primary_keyÚsql_create_pkÚ_create_index_namerL   rw   r   r   r   Úsql_create_checkrª   r«   )&r&   r   r   r   r¸   rº   r·   r¹   r¶   Zfks_droppedr±   r²   rž   Úconstraint_nameZdrop_foreign_keysZ_old_relZnew_relZrel_fk_namesZmeta_index_namesZindex_namesÚ
index_namer0   ZactionsZnull_actionsZpost_actionsÚfragmentZother_actionsZold_defaultÚnew_defaultZneeds_database_defaultZfour_way_default_alterationr1   Zrels_to_updateZold_relZrel_db_paramsZrel_typeÚrelr¬   r   r   r   rµ     s2   


$ 














 


z%BaseDatabaseSchemaEditor._alter_fieldc             C   s\   | j jjr| ¡ dkrdS |j| j d�}|jr4| jn| j}||  |j	¡|d dœ g fS dS )zÏ
        Hook to specialize column null alteration.

        Return a (sql, params) fragment to set a column to null or non-null
        as required by new_field, or None if no changes are required.
        )Z	CharFieldZ	TextFieldN)r    rJ   )rk   rJ   )
r    r#   rS   r^   rL   rM   Úsql_alter_column_nullÚsql_alter_column_not_nullr?   rk   )r&   r   r   r   r¹   r0   r   r   r   rÅ     s    

z/BaseDatabaseSchemaEditor._alter_column_null_sqlc       
      C   st   |   |¡}d}|g}|rg }n| jjjr6|  |¡}g }|j| jd�}|rN| jn| j}	|	|  |j	¡|d |dœ |fS )zÁ
        Hook to specialize column default alteration.

        Return a (sql, params) fragment to add or drop (depending on the drop
        argument) a default to new_field's column.
        z%s)r    rJ   )rk   rJ   re   )
rO   r    r#   rP   rQ   rL   Úsql_alter_column_no_defaultÚsql_alter_column_defaultr?   rk   )
r&   r   r   r   r¤   rÏ   re   r1   r¹   r0   r   r   r   r§   #  s    



z2BaseDatabaseSchemaEditor._alter_column_default_sqlc             C   s    | j |  |j¡|dœ g fg fS )a–  
        Hook to specialize column type alteration for different backends,
        for cases when a creation type is different to an alteration type
        (e.g. SERIAL in PostgreSQL, PostGIS fields).

        Return a two-tuple of: an SQL fragment of (sql, params) to insert into
        an ALTER TABLE statement and a list of extra (sql, params) tuples to
        run once the field is altered.
        )rk   rJ   )Úsql_alter_column_typer?   rk   )r&   r   r   r   rº   r   r   r   rÄ   B  s
    
z/BaseDatabaseSchemaEditor._alter_column_type_sqlc             C   s¢   |j jjj|j jjjkr:|  |j j|j jjj|j jjj¡ |  |j j|j jj | ¡ ¡|j jj | ¡ ¡¡ |  |j j|j jj | ¡ ¡|j jj | ¡ ¡¡ dS )z*Alter M2Ms to repoint their to= endpoints.N)	rq   r~   r   rs   r¡   r»   rj   Zm2m_reverse_field_nameZm2m_field_name)r&   r   r   r   r¶   r   r   r   r´   W  s    z,BaseDatabaseSchemaEditor._alter_many_to_manyr4   c       
      C   sä   t |ƒ\}}|gt|ƒ }d| j|Ž |f }| jj ¡ p:d}d|d |¡|f }t|ƒ|kr`|S t|ƒ|d kr€|d|d … }|t|ƒ d d }	d|d|	… d |¡d|	… |f }|d	 dksÐ|d	  ¡ ràd
|dd…  }|S )z½
        Generate a unique name for an index/unique constraint.

        The name is divided into 3 parts: the table name, the column names,
        and a unique digest and suffix.
        z%s%séÈ   z%s_%s_%sÚ_é   Né   r™   r   zD%séÿÿÿÿ)	r   r…   rI   r    r>   Zmax_name_lengthr{   r›   Úisdigit)
r&   Z
table_nameÚcolumn_namesr”   r×   Z	hash_dataZhash_suffix_partÚ
max_lengthrÍ   Zother_lengthr   r   r   rÊ   l  s"    
z+BaseDatabaseSchemaEditor._create_index_namec             C   sX   |d kr:t |ƒdkr*|d jr*|d j}n|jjr:|jj}|d k	rTd| jj |¡ S dS )Nr™   r   rg   r4   )r›   rU   r   r    r>   rV   )r&   r   r�   rU   r   r   r   Ú_get_index_tablespace_sqlŠ  s    z2BaseDatabaseSchemaEditor._get_index_tablespace_sql)r   r”   ÚusingrU   Úcol_suffixesr0   c               sr   ˆj |||d�}	dd„ |D ƒ}
|p&ˆj}|jj}‡ ‡fdd„}t|t|ˆjƒt||
||ƒ|t||
ˆj|d�|	d�S )z¼
        Return the SQL statement to create the index for one or several fields.
        `sql` can be specified if the syntax differs from the standard (GIS
        indexes, ...).
        )rU   c             S   s   g | ]
}|j ‘qS r   )rk   )r   r   r   r   r   rl   œ  s    z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                 s   ˆ d krˆj | |Ž‰ ˆ ˆ ¡S )N)rÊ   r?   )rF   Úkwargs)r   r&   r   r   Úcreate_index_name   s    zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_name)rà   )rm   r   rß   r‚   r2   )	rÞ   Úsql_create_indexr   rs   r   r   r?   r   r   )r&   r   r�   r   r”   rß   rU   rà   r0   rV   r‚   rã   rm   râ   r   )r   r&   r   r–   ”  s    

z*BaseDatabaseSchemaEditor._create_index_sqlc                s¦   ˆ j jrˆ j jsˆ j jrg S g }x"ˆ j jD ]}| |  ˆ |¡¡ q*W x8ˆ j jD ],}‡ fdd„|D ƒ}| | j	ˆ |dd�¡ qNW x"ˆ j j
D ]}| | ˆ | ¡¡ qˆW |S )zŠ
        Return a list of all index SQL statements (field indexes,
        index_together, Meta.indexes) for the specified model.
        c                s   g | ]}ˆ j  |¡‘qS r   )r   rj   )r   r   )r   r   r   rl   »  s    z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>r“   )r”   )r   ZmanagedÚproxyZswappedro   rp   r©   Zindex_togetherr9   r–   rÁ   rˆ   )r&   r   Úoutputr   r—   r�   r‰   r   )r   r   r|   ¯  s    z+BaseDatabaseSchemaEditor._model_indexes_sqlc             C   s(   g }|   ||¡r$| |  ||g¡¡ |S )zT
        Return a list of all index SQL statements for the specified field.
        )Ú_field_should_be_indexedr9   r–   )r&   r   r   rå   r   r   r   r©   Â  s    z+BaseDatabaseSchemaEditor._field_indexes_sqlc             C   s   |j o|j S )N)rÀ   rT   )r&   r   r   r   r   r   ræ   Ë  s    z1BaseDatabaseSchemaEditor._field_should_be_indexedc             C   s*   | j |  |¡|  |j¡|  |j¡|dœ S )N)rm   Z
old_columnZ
new_columnrJ   )Úsql_rename_columnr?   rk   )r&   rm   r   r   rº   r   r   r   rÃ   Î  s
    

z*BaseDatabaseSchemaEditor._rename_field_sqlc       
   
      s    |j j}|j}t|jjj jƒ\}}|jj}‡ fdd„}	tˆ jt|ˆ j	ƒt
||g||g||	ƒt||gˆ j	ƒt|jjj jˆ j	ƒt|jjj j|gˆ j	ƒˆ jj ¡ d�S )Nc                 s   ˆ   ˆ j| |Ž¡S )N)r?   rÊ   )rF   rá   )r&   r   r   Úcreate_fk_nameÜ  s    z?BaseDatabaseSchemaEditor._create_fk_sql.<locals>.create_fk_name)rm   r   rk   rh   ri   Z
deferrable)r   rs   rk   r   Ztarget_fieldr   r   Úsql_create_fkr   r?   r   r   r    r>   Zdeferrable_sql)
r&   r   r   r”   Z
from_tableZfrom_columnr×   rh   ri   rè   r   )r&   r   rw   Ö  s    
z'BaseDatabaseSchemaEditor._create_fk_sqlc             C   s8   |j j}t| jt|| jƒt||d| jƒt||| jƒd�S )NÚ_uniq)rm   r   r‚   )	r   rs   r   Úsql_create_uniquer   r?   r   rÊ   r   )r&   r   r‚   rm   r   r   r   ry   é  s    
z+BaseDatabaseSchemaEditor._create_unique_sqlc             C   s   ||   |jj¡|   |¡dœ S )N)rm   r   )r?   r   rs   )r&   Útemplater   r   r   r   r   r�   ò  s    z/BaseDatabaseSchemaEditor._delete_constraint_sqlc	          	      s   |dk	r‡ fdd„|D ƒ}ˆ j  ¡ �}	ˆ j j |	|jj¡}
W dQ R X g }x²|
 ¡ D ]¦\}}|dksn||d krR|dk	r„|d |kr„qR|dk	rš|d |kršqR|dk	r°|d |kr°qR|dk	rÆ|d |krÆqR|dk	rØ|d	 sØqR|dk	rî|d
 |krîqR| |¡ qRW |S )z@Return all constraint names matching the columns and conditions.Nc                s   g | ]}ˆ j j |¡‘qS r   )r    ÚintrospectionZcolumn_name_converter)r   r   )r&   r   r   rl   þ  s   z>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>r‚   rT   r   r‰   rf   r®   rJ   )r    r=   rí   Zget_constraintsr   rs   Úitemsr9   )r&   r   rÜ   rT   r   r‰   r®   rf   r¼   r=   ÚconstraintsÚresultr   Zinfodictr   )r&   r   rš   ø  s,    
z*BaseDatabaseSchemaEditor._constraint_namesc             C   s^   | j |dd�}|r6t|ƒdkr6tdt|ƒ|jjf ƒ‚x"|D ]}|  |  | j||¡¡ q<W d S )NT)r   r™   z0Found wrong number (%s) of PK constraints for %s)rš   r›   rœ   r   rs   r+   r�   Úsql_delete_pk)r&   r   r¶   rž   rÌ   r   r   r   rÈ     s    
z,BaseDatabaseSchemaEditor._delete_primary_keyc             C   s*   | j |  |¡d |¡dœ }|  |¡ d S )Nú,)Z	procedureÚparam_types)Úsql_delete_procedurer?   r{   r+   )r&   Zprocedure_nameró   r0   r   r   r   Úremove_procedure  s    z)BaseDatabaseSchemaEditor.remove_procedure)FT)r   )F)F)F)F)r4   )N)NNNNNNN)F)r   )HÚ__name__Ú
__module__Ú__qualname__Ú__doc__rz   r    r¢   r„   r¦   r¨   rÕ   rÑ   rÒ   rÔ   rÓ   r°   rç   rÇ   rË   rÂ   rë   r�   ré   ru   r¯   rã   r•   rÉ   rñ   rô   r'   r*   r,   r+   r?   ÚclassmethodrI   rZ   rN   rQ   rO   r<   r€   rƒ   rŠ   r‹   r’   r˜   rŽ   r¡   r£   r­   r³   r»   rµ   rÅ   r§   rÄ   r´   rÊ   rÞ   r–   r|   r©   ræ   rÃ   rw   ry   r�   rš   rÈ   rõ   r   r   r   r   r   *   s�   
		

0	E*
*
 ~



		  


r   )rA   Úloggingr   Z!django.db.backends.ddl_referencesr   r   r   r   r   Zdjango.db.backends.utilsr   Zdjango.db.modelsr	   Zdjango.db.transactionr
   r   Zdjango.utilsr   Zdjango.utils.encodingr   Ú	getLoggerr6   r   r   r   r   r   r   r   Ú<module>   s   
	