U
     5ųiJ&  ć                   @   sH   d dl Z d dlZd dlZd dlmZ d dlmZmZ G dd deZdS )é    N)ŚDatabaseError)ŚBaseDatabaseSchemaEditorŚ_related_non_m2m_objectsc                       sŚ   e Zd ZdZdZdZdZdZdZeZ	dZ
dZd	Zd
ZdZdd Z fddZ fddZd+ fdd	Z fddZ fddZdd Zdd Zdd Z fdd Z fd!d"Zd#d$ Zd%d& Zd'd( Z fd)d*Z  ZS ),ŚDatabaseSchemaEditorz3ALTER TABLE %(table)s ADD %(column)s %(definition)szMODIFY %(column)s %(type)szMODIFY %(column)s NULLzMODIFY %(column)s NOT NULLz%MODIFY %(column)s DEFAULT %(default)szMODIFY %(column)s DEFAULT NULLz'MODIFY %(column)s %(type)s%(collation)sz,ALTER TABLE %(table)s DROP COLUMN %(column)szHCONSTRAINT %(name)s REFERENCES %(to_table)s(%(to_column)s)%(deferrable)sz(DROP TABLE %(table)s CASCADE CONSTRAINTSz9CREATE INDEX %(name)s ON %(table)s (%(columns)s)%(extra)sc                 C   s~   t |tjtjtjfrd| S t |tr@d| dd” dd” S t |tttfr\d| 	”  S t |t
rr|rndS dS t|S d S )Nz'%s'ś'z''ś%z%%Ś1Ś0)Ś
isinstanceŚdatetimeŚdateŚtimeŚstrŚreplaceŚbytesŚ	bytearrayŚ
memoryviewŚhexŚbool©ŚselfŚvalue© r   śD/tmp/pip-unpacked-wheel-gcyiijx6/django/db/backends/oracle/schema.pyŚquote_value   s    

z DatabaseSchemaEditor.quote_valuec                    s6   |   |jj|j”r$|  |jj|j” t  ||” d S ©N)Ś_is_identity_columnŚ_metaŚdb_tableŚcolumnŚ_drop_identityŚsuperŚremove_field)r   ŚmodelŚfield©Ś	__class__r   r   r"   '   s    z!DatabaseSchemaEditor.remove_fieldc                    s0   t   |” |  dd| jj |jj”i ” d S )NaK  
            DECLARE
                i INTEGER;
            BEGIN
                SELECT COUNT(1) INTO i FROM USER_SEQUENCES
                    WHERE SEQUENCE_NAME = '%(sq_name)s';
                IF i = 1 THEN
                    EXECUTE IMMEDIATE 'DROP SEQUENCE "%(sq_name)s"';
                END IF;
            END;
        /Zsq_name)r!   Śdelete_modelŚexecuteŚ
connectionŚopsZ_get_no_autofield_sequence_namer   r   )r   r#   r%   r   r   r'   .   s    
öz!DatabaseSchemaEditor.delete_modelFc              
      sĄ   zt   ||||” W n¤ tk
rŗ } zt|}d|ks@d|krP|  |||” nZd|kr||  |jj|j” |  ||||” n.d|krØ|j	rØ| j
|dd |  |||” n W 5 d }~X Y nX d S )Nz	ORA-22858z	ORA-22859z	ORA-30675z	ORA-30673T)Śstrict)r!   Śalter_fieldr   r   Ś_alter_field_type_workaroundr    r   r   r   Śprimary_keyZ_delete_primary_key)r   r#   Ś	old_fieldŚ	new_fieldr+   ŚeŚdescriptionr%   r   r   r,   >   s    z DatabaseSchemaEditor.alter_fieldc                    s^  t  |”}| ” dk|_|  |j”|_|  ||” |  |j”}| | j	”}t
 d|”rbd| }d}t
 d|”rŖ| ” }|dkrd| }n"|dkrd	| }n|d
krŖd| }|  d|  |jj”|  |j”|f ” |  ||” t  |||” | | j	”}|jr|js|jrZ|jrZ||krZt||D ],\}	}
|
jjr,|  |  |
j|
jd”” q,dS )aĮ  
        Oracle refuses to change from some type to other type.
        What we need to do instead is:
        - Add a nullable version of the desired field with a temporary name. If
          the new column is an auto field, then the temporary column can't be
          nullable.
        - Update the table to transfer values from old to new
        - Drop old column
        - Rename the new column and possibly drop the nullable property
        )Ś	AutoFieldŚBigAutoFieldŚSmallAutoFieldz^N?CLOBzTO_CHAR(%s)ZVARCHAR2z^N?VARCHAR2Z	DateFieldzTO_DATE(%s, 'YYYY-MM-DD')ZDateTimeFieldz,TO_TIMESTAMP(%s, 'YYYY-MM-DD HH24:MI:SS.FF')Z	TimeFieldzCTO_TIMESTAMP(CONCAT('1900-01-01 ', %s), 'YYYY-MM-DD HH24:MI:SS.FF')zUPDATE %s set %s=%sZ_fkN)ŚcopyŚdeepcopyŚget_internal_typeŚnullŚ_generate_temp_namer   Z	add_fieldŚ
quote_nameŚdb_typer)   ŚreŚmatchr(   r   r   r"   r!   r,   r.   Śuniquer   r$   Zdb_constraintZ_create_fk_sqlZrelated_model)r   r#   r/   r0   Znew_temp_fieldŚ	new_valueZold_typeZnew_internal_typeŚnew_typeŚ_Śrelr%   r   r   r-   T   sL    



ż’’žžż
z1DatabaseSchemaEditor._alter_field_type_workaroundc                    sX   dddh}|  ” |krF|  ” |krF|  |jj|j”rF|  |jj|j” t  ||||”S )Nr3   r4   r5   )r8   r   r   r   r   r    r!   Ś_alter_column_type_sql)r   r#   r/   r0   rA   Zauto_field_typesr%   r   r   rD      s    

’
žżz+DatabaseSchemaEditor._alter_column_type_sqlc                 C   s2   |   |”}|d dkr.|d dkr.|dd }|S )z
        Get the properly shortened and uppercased identifier as returned by
        quote_name() but without the quotes.
        r   ś"é’’’’é   )r;   )r   ŚnameŚnnr   r   r   Śnormalize_name   s    
z#DatabaseSchemaEditor.normalize_namec                 C   s*   t t| ” dd }|  |d | ”S )z@Generate temporary names for workarounds that need temp columns.rG   NrB   )r   ŚhashŚupperrJ   )r   Zfor_nameŚsuffixr   r   r   r:   ¢   s    z(DatabaseSchemaEditor._generate_temp_namec                 C   s
   |   |”S r   )r   r   r   r   r   Śprepare_default§   s    z$DatabaseSchemaEditor.prepare_defaultc                    s:   t   ||”}| | j”}|d k	r6| ” | jjkr6dS |S )NF)r!   Ś_field_should_be_indexedr<   r)   ŚlowerZ_limited_data_types)r   r#   r$   Zcreate_indexr<   r%   r   r   rO   Ŗ   s
    z-DatabaseSchemaEditor._field_should_be_indexedc                    s   t   ||”o|  ||” S r   )r!   Ś_unique_should_be_addedZ_field_became_primary_key)r   r/   r0   r%   r   r   rQ   ±   s    žz,DatabaseSchemaEditor._unique_should_be_addedc              
   C   sV   | j  ” B}| d|  |”|  |”g” | ” }|r<|d ndW  5 Q R £ S Q R X d S )Nzą
                SELECT
                    CASE WHEN identity_column = 'YES' THEN 1 ELSE 0 END
                FROM user_tab_cols
                WHERE table_name = %s AND
                      column_name = %s
            r   F©r)   Ścursorr(   rJ   Zfetchone)r   Ś
table_nameŚcolumn_namerS   Śrowr   r   r   r   ·   s    śz(DatabaseSchemaEditor._is_identity_columnc                 C   s$   |   d|  |”|  |”d ” d S )Nz5ALTER TABLE %(table)s MODIFY %(column)s DROP IDENTITY)Śtabler   )r(   r;   )r   rT   rU   r   r   r   r    Ć   s    žz#DatabaseSchemaEditor._drop_identityc              
   C   sB   | j  ” .}| d|  |”g” | ” d W  5 Q R £ S Q R X d S )Nz]
                SELECT default_collation FROM user_tables WHERE table_name = %s
            r   rR   )r   rT   rS   r   r   r   Ś_get_default_collationÉ   s
    
žz+DatabaseSchemaEditor._get_default_collationc                    s(   |d kr|   |jj”}t  ||||”S r   )rX   r   r   r!   Ś_alter_column_collation_sql)r   r#   r0   rA   Znew_collationr%   r   r   rY   Š   s    z0DatabaseSchemaEditor._alter_column_collation_sql)F)Ś__name__Ś
__module__Ś__qualname__Zsql_create_columnZsql_alter_column_typeZsql_alter_column_nullZsql_alter_column_not_nullZsql_alter_column_defaultZsql_alter_column_no_defaultZ sql_alter_column_no_default_nullZsql_alter_column_collateZsql_delete_columnZsql_create_column_inline_fkZsql_delete_tableZsql_create_indexr   r"   r'   r,   r-   rD   rJ   r:   rN   rO   rQ   r   r    rX   rY   Ś__classcell__r   r   r%   r   r      s6   9
r   )	r6   r   r=   Z	django.dbr   Zdjango.db.backends.base.schemar   r   r   r   r   r   r   Ś<module>   s
   