3
[                 @   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j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   B/tmp/pip-install-j7i95hgp/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dsddZdd Zdd  Z f fd!d"Z!d#d$ Z"e#d%d& Z$dtd'd(Z%d)d* Z&d+d, Z'd-d. Z(d/d0 Z)d1d2 Z*d3d4 Z+d5d6 Z,d7d8 Z-d9d: Z.d;d< Z/d=d> Z0d?d@ Z1dAdB Z2dCdD Z3dEdF Z4dudGdHZ5dvdIdJZ6dKdL Z7dwdMdNZ8dOdP Z9dQdR Z:dxdTdUZ;dydVdWZ<ddSdSdf ddXdYdZZ=d[d\ Z>d]d^ Z?d_d` Z@dadb ZAdcdd ZBdedf ZCdgdh ZDdidj ZEdkdl ZFdzdmdnZGd{dodpZHf fdqdrZId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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 ]}| j| qW | jr8| jj||| d S )N)r(   executer%   r   __exit__)r&   exc_type	exc_value	tracebacksqlr   r   r   r,   g   s
    z!BaseDatabaseSchemaEditor.__exit__c          
   C   s   | j  r$| jjr$| jjj r$tdt|}tjd||||dd | j r|j	drXdnd}|dk	r| j
j|tt| j| |  q| j
j||  n"| jj }|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j|S )N)r    ops
quote_name)r&   r   r   r   r   r?      s    z#BaseDatabaseSchemaEditor.quote_namec             G   s4   t j }x|D ]}|jt| qW |j 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:| j| }|r| j|}|dk	r| jjjrp|d| j| 7 }n|d7 }||g7 }|jr|j	 r| jjj
rd}|r| jjj r|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    typeNz DEFAULT %sTz NULLz	 NOT NULLz PRIMARY KEYz UNIQUEz %s)inline)NN)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
        zsubclasses 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   |j  r|j }n|j rB|jrB|jrB|j dkr:t }qt }n\t|ddsZt|ddrt	j
 }|j }|dkrz|j}q|dkr|j}q|dkrtj
}nd}t|r| }|j|| jS )	z2Return a field's effective database default value.ZBinaryFieldZauto_nowFZauto_now_addZ	DateFieldZ	TimeFieldZDateTimeFieldN)has_default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}| j |\}}|dkr4q|j| jd}|d rZ|d|d  7 }|j| jd}|rx|d| 7 }|j| |jr|jr|jj	j j
}	|jj	j j|jjj}
| jr|d| j| j|	| j|
d  7 }n | jjjr| jj| j |d |jd	| j|j|f  |j dkr| jjj j j
|j}|r| jj| qW x8 j jD ],} fdd|D }| jj| j | qVW | j| j j j
dj|d } j jr| jjj j j}|r|d| 7 }| j||pd | jj| j  x. j j D ]"}|jj!j j"r| j#|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	AutoFieldBigAutoFieldc                s   g | ]} j j|jqS r   )r   	get_fieldcolumn)r   r   )r   r   r   
<listcomp>,  s    z9BaseDatabaseSchemaEditor.create_model.<locals>.<listcomp>z, )table
definition)rk   rl   )$r   local_fieldsrZ   rL   r    Zdb_type_suffixextendremote_fielddb_constraintr   db_tablerm   
field_namern   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   rq   Zextra_paramsrX   Zcol_type_suffixri   rj   r{   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j q
W | j| jd| j|j j	i  x6t
| jD ](}t|trV|j|j j	rV| jj| qVW dS )z!Delete a model from the database.rp   N)r   r   rt   r   r   delete_modelr+   sql_delete_tabler?   rv   listr(   
isinstancer   Zreferences_tableremove)r&   r   r   r0   r   r   r   r   B  s    z%BaseDatabaseSchemaEditor.delete_modelc             C   s   | j |j||  dS )zAdd an index on a model.N)r+   
create_sql)r&   r   indexr   r   r   	add_indexR  s    z"BaseDatabaseSchemaEditor.add_indexc             C   s   | j |j||  dS )zRemove an index from a model.N)r+   Z
remove_sql)r&   r   r   r   r   r   remove_indexV  s    z%BaseDatabaseSchemaEditor.remove_indexc                s   dd |D }dd |D }x(|j |D ]}| j |ddi| j q(W x6|j |D ](} fdd|D }| j| j | 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>`  s    zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c             S   s   h | ]}t |qS r   )r:   )r   r   r   r   r   r   a  s    rT   Tc                s   g | ]} j j|jqS r   )r   rm   rn   )r   r   )r   r   r   ro   g  s    zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)
difference_delete_composed_indexsql_delete_uniquer+   r|   )r&   r   Zold_unique_togetherZnew_unique_togetheroldsnewsr   r   r   )r   r   alter_unique_togetherZ  s    z.BaseDatabaseSchemaEditor.alter_unique_togetherc                s   dd |D }dd |D }x(|j |D ]}| j |ddi| j q(W x:|j |D ],} fdd|D }| j| 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   p  s    z@BaseDatabaseSchemaEditor.alter_index_together.<locals>.<setcomp>c             S   s   h | ]}t |qS r   )r:   )r   r   r   r   r   r   q  s    r   Tc                s   g | ]} j j|qS r   )r   rm   )r   r   )r   r   r   ro   w  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_togetherj  s    z-BaseDatabaseSchemaEditor.alter_index_togetherc                sj    fdd|D }| j  |f|}t|dkrNtdt| jjdj|f | j| j| |d  d S )Nc                s   g | ]} j j|jqS r   )r   rm   rn   )r   r   )r   r   r   ro   {  s    zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>   z1Found wrong number (%s) of constraints for %s(%s)z, r   )_constraint_nameslen
ValueErrorr   rv   r~   r+   _delete_constraint_sql)r&   r   r   Zconstraint_kwargsr0   r   constraint_namesr   )r   r   r   z  s    z/BaseDatabaseSchemaEditor._delete_composed_indexc             C   sr   ||ks"| j jjr&|j |j kr&dS | j| j| j|| j|d  x$| jD ]}t|t	rP|j
|| 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|jj| j|| j|d  dS )z)Move a model's table between tablespaces.)rp   Zold_tablespaceZnew_tablespaceN)r+   sql_retablespace_tabler?   r   rv   )r&   r   Zold_db_tablespaceZnew_db_tablespacer   r   r   alter_db_tablespace  s    z,BaseDatabaseSchemaEditor.alter_db_tablespacec             C   sL  |j r |jjjjr | j|jjS | j||dd\}}|dkr@dS |j| jd}|d rf|d|d  7 }| j	| j
|jj| j
|j|d }| j|| | j| r| j|dk	r| j|d|dd\}}| j| j
|jj|d	 }| j|| | jj| j|| |jr2| jjjr2|jr2| jj| j||d
 | jjjrH| j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    rg   z CHECK (%s))rp   rn   rq   )drop)rp   changesz_fk_%(to_table)s_%(to_column)s)r   rt   r   r   r   r   rZ   rL   r    sql_create_columnr?   rv   rn   r+   rN   rO   _alter_column_default_sqlsql_alter_columnr(   rs   _field_indexes_sqlr#   ry   ru   r9   rz   connection_persists_old_columnsclose)r&   r   r   rq   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jS |j| jdd dkr:dS |jrx| j||j	gdd}x"|D ]}| j
| j| j|| qZW | j| j|jj| j|j	d }| j
| | jjjr| jj  x:t| jD ],}t|tr|j|jj|j	r| jj| qW 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)rp   rn   )r   rt   r   r   r   r   rL   r    r   rn   r+   r   sql_delete_fksql_delete_columnr?   rv   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| j||||S |dkr|dkr|jjr|jjr|jjjj r|jjjj rdS |dkp|dkrtd||f | j|||||||| 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?)zCannot 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    rt   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	|jf | j
| j| j|| qXW |jo|j s| j||r| j||jgddd}|rt|dkrtdt||jj|jf x"|D ]}| j
| j| j|| qW |jr|js&|jo,|jo,||k}|rxXt||D ]J\}}| j|j|jjgdd}x&|D ]}| j
| j| j|j| qfW q@W |jr|j r|j s|jrdd	 |jjD }| j||jgdtjd
}x.|D ]&}||kr| j
| j| j|| qW |d |d kr|d r| j||jgdd}|rlt|dkrltdt||jj|jf x$|D ]}| j
| j| j|| qrW |j|jkr| j
| j|jj||| x2| jD ](}t|tr|j|jj|j|j qW g }g }g }||kr,| j||||\}}|j | |j!| | j"|}| j"|}|j#op|j# op||kop|dk	op| j$| }|r|j | j%||| |j#|j#kr| j&|||}|r|j | |j' o|j#o|j# }|s|r|s|| }| j(j)j*r$|r$t+t,| \}}dj-|t.|g fg}x4|D ],\}}| j
| j/| j0|jj|d | q*W |r| j
| j1| j0|jj| j0|jdd |g x4|D ],\}}| j
| j/| j0|jj|d | qW |rx|D ]\}}| j
|| qW |jr|j r| j2|| | j3||r,| j
| j4||jg |j s>|jrd|jrd|j rd| j
| j5||g g } |jr|jr||kr| j!t|| | j||r| j
| j6| j0|jj| j0| j7|jj|jgdd| j0|jd  | j!t|| x| D ]\}!}|jj8| j(d}"|"d }#| j|j|!j|j|#\}}| j
| j/| j0|jjj|d d |d  x|D ]\}}| j
|| qfW qW |jr|	s|j s|j r|jr| j
| j9||d |rxB|j:jj;D ]4}$t<|$|r|$jjr| j
| j9|$j|$jd qW |d |d krt|d rt| j
| j=| j0|jj| j0| j7|jj|jgdd| j0|j|d d  |r| j%|||dd\}%}| j/| j0|jj|%d }| j
|| | j(j)j>r| j(j?  dS )z3Perform a "physical" (non-ManyToMany) field update.T)r   r   z<Found wrong number (%s) of foreign key constraints for %s.%sF)rT   r   z7Found wrong number (%s) of unique constraints for %s.%sc             S   s   h | ]
}|j qS r   )r   )r   r   r   r   r   r   F  s    z8BaseDatabaseSchemaEditor._alter_field.<locals>.<setcomp>)r   type_rg   )rg   z6Found wrong number (%s) of check constraints for %s.%sNz, )rp   r   z%s)rp   rn   rf   Z_pk)r   )rp   r   r   )r    rJ   r   z_fk_%(to_table)s_%(to_column)sZ_fk_check)rp   r   rn   rg   )r   )@setrt   ru   r   rn   r   r   r   rv   addr+   r   r   rT   _field_became_primary_keyr   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   rs   rO   rM   rN   r   _alter_column_null_sqlr]   r    r#   Zsupports_combined_altersr:   r   r~   sumr   r?   sql_update_with_default_delete_primary_key_unique_should_be_addedr|   r   sql_create_pk_create_index_namerL   rz   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   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     s0   


$$














$


z%BaseDatabaseSchemaEditor._alter_fieldc             C   s\   | j jjr|j dkrdS |j| j d}|jr4| jn| j}|| 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.
        	CharField	TextFieldN)r    rJ   )rn   rJ   )r   r   )
r    r#   rS   r_   rL   rM   sql_alter_column_nullsql_alter_column_not_nullr?   rn   )r&   r   r   r   r   r0   r   r   r   r     s    

z/BaseDatabaseSchemaEditor._alter_column_null_sqlc       
      C   st   | j |}d}|g}|rg }n| jjjr6| j|}g }|j| jd}|rN| jn| j}	|	| 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   )rn   rJ   rf   )
rO   r    r#   rP   rQ   rL   sql_alter_column_no_defaultsql_alter_column_defaultr?   rn   )
r&   r   r   r   r   r   rf   r1   r   r0   r   r   r   r     s    



z2BaseDatabaseSchemaEditor._alter_column_default_sqlc             C   s    | j | 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.
        )rn   rJ   )sql_alter_column_typer?   rn   )r&   r   r   r   r   r   r   r   r   <  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 j|j jjj|j |j jjj|j  dS )z*Alter M2Ms to repoint their to= endpoints.N)	rt   r   r   rv   r   r   rm   Zm2m_reverse_field_nameZm2m_field_name)r&   r   r   r   r   r   r   r   r   Q  s    z,BaseDatabaseSchemaEditor._alter_many_to_manyr4   c       	      C   s   t |\}}d| j|f| |f }| jjj p2d}d|dj||f }t||krX|S t||d krx|d|d  }|t| d d }d|d| dj|d| |f }|d	 dks|d	 j rd
|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   rI   r    r>   Zmax_name_lengthr~   r   isdigit)	r&   Z
table_namecolumn_namesr   r   Zhash_suffix_part
max_lengthr   Zother_lengthr   r   r   r   f  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j| S dS )Nr   r   rh   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   )rn   )r   r   r   r   r   ro     s    z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                 s    d krj | | j S )N)r   r?   )rF   kwargs)r   r&   r   r   create_index_name  s    zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_name)r   )rp   r   r   r   r2   )	r   sql_create_indexr   rv   r   r   r?   r   r   )r&   r   r   r   r   r   rU   r   r0   rV   r   r   rp   r   r   )r   r&   r   r     s    

z*BaseDatabaseSchemaEditor._create_index_sqlc                s    j j s j js j jrg S g }x" j jD ]}|j| j | q,W x8 j jD ],} fdd|D }|j| j	 |dd qPW x" j j
D ]}|j|j |  qW |S )z
        Return a list of all index SQL statements (field indexes,
        index_together, Meta.indexes) for the specified model.
        c                s   g | ]} j j|qS r   )r   rm   )r   r   )r   r   r   ro     s    z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>r   )r   )r   ZmanagedproxyZswappedrr   rs   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 }| j ||r$|j| j||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  o|j S )N)r   )r&   r   r   r   r   r   r     s    z2BaseDatabaseSchemaEditor._field_became_primary_keyc             C   s"   |j  r|j p |jo |j o |j S )N)rT   r   )r&   r   r   r   r   r   r     s    z0BaseDatabaseSchemaEditor._unique_should_be_addedc             C   s*   | j | j|| j|j| j|j|d S )N)rp   Z
old_columnZ
new_columnrJ   )sql_rename_columnr?   rn   )r&   rp   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j dS )Nc                 s    j  j| |S )N)r?   r   )rF   r   )r&   r   r   create_fk_name  s    z?BaseDatabaseSchemaEditor._create_fk_sql.<locals>.create_fk_name)rp   r   rn   ri   rj   Z
deferrable)r   rv   rn   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   ri   rj   r   r   )r&   r   rz     s    
z'BaseDatabaseSchemaEditor._create_fk_sqlc                sB    fdd}|j j}t jt| jt||d|t|| jdS )Nc                 s    j  j| |S )N)r?   r   )rF   r   )r&   r   r   create_unique_name  s    zGBaseDatabaseSchemaEditor._create_unique_sql.<locals>.create_unique_nameZ_uniq)rp   r   r   )r   rv   r   sql_create_uniquer   r?   r   r   )r&   r   r   r   rp   r   )r&   r   r|     s    
z+BaseDatabaseSchemaEditor._create_unique_sqlc             C   s   || j |jj| j |d S )N)rp   r   )r?   r   rv   )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|	|jj}
W dQ R X g }x|
j D ]\}}|dksn||d krR|dk	r|d |krqR|dk	r|d |krqR|dk	r|d |krqR|dk	r|d |krqR|dk	r|d	  rqR|dk	r|d
 |krqR|j| qRW |S )z@Return all constraint names matching the columns and conditions.Nc                s   g | ]} j jj|qS r   )r    introspectionZcolumn_name_converter)r   r   )r&   r   r   ro     s   z>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>r   rT   r   r   rg   r   rJ   )r    r=   r   Zget_constraintsr   rv   itemsr9   )r&   r   r   rT   r   r   r   rg   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| j| j|| q<W d S )NT)r   r   z0Found wrong number (%s) of PK constraints for %s)r   r   r   r   rv   r+   r   sql_delete_pk)r&   r   r   r   r   r   r   r   r     s    
z,BaseDatabaseSchemaEditor._delete_primary_keyc             C   s*   | j | j|dj|d }| j| 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)F)F)F)F)r4   )N)NNNNNNN)F)J__name__
__module____qualname____doc__r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rx   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   r   r   rz   r|   r   r   r   r   r   r   r   r   r   *   s   
		
0	E*
*
 z



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

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   
	