o
    `©ZhS*  ć                   @   sT   d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	 G dd deZ
dS )é    N)ŚDatabaseError)ŚBaseDatabaseSchemaEditorŚ_related_non_m2m_objects)Śduration_iso_stringc                       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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d d! Zd"d# Zd$d% Zd* fd'd(	Z  ZS )+ŚDatabaseSchemaEditorz3ALTER TABLE %(table)s ADD %(column)s %(definition)sz'MODIFY %(column)s %(type)s%(collation)szMODIFY %(column)s NULLzMODIFY %(column)s NOT NULLz%MODIFY %(column)s DEFAULT %(default)szMODIFY %(column)s DEFAULT NULLz,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jrdt| S t |tr(d| dd” S t |tt	t
fr6d| ”  S t |trA|r?dS dS t|S )Nz'%s'ś'z''Ś1Ś0)Ś
isinstanceŚdatetimeŚdateŚtimeŚ	timedeltar   ŚstrŚreplaceŚbytesŚ	bytearrayŚ
memoryviewŚhexŚbool©ŚselfŚvalue© r   śW/var/www/html/lang_env/lib/python3.10/site-packages/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(   2   s   
’’õ’z!DatabaseSchemaEditor.delete_modelFc              
      s2  zt   ||||” W d S  ty } zt|}d|v s d|v r(|  |||” nPd|v r>|  |jj|j” |  ||||” nAd|v rT|j	rT| j
|dd |  |||” n2d|v rw|j	rw| j
|dd |  ||||” |j	rv|  |  ||”” n W Y d }~d S W Y d }~d S W Y d }~d S W Y d }~d S d }~ww )Nz	ORA-22858z	ORA-22859z	ORA-30675z	ORA-30673T)Śstrictz	ORA-43923)r"   Śalter_fieldr   r   Ś_alter_field_type_workaroundr!   r   r   r    Śprimary_keyZ_delete_primary_keyr)   Z_create_primary_key_sql)r   r$   Ś	old_fieldŚ	new_fieldr,   ŚeŚdescriptionr&   r   r   r-   I   s0   ģńz DatabaseSchemaEditor.alter_fieldc                    sd  t  |”}| ” dv|_|  |j”|_|  ||” |  |j”}| | j	”}t
 d|”r1d| }d}t
 d|”rY| ” }|dkrDd| }n|dkrMd	| }n|d
krYd| }d	| }|  d|  |jj”|  |j”|f ” |  ||” t  |||” | | j	”}|jr|js|jr¬|jr®||krŖt||D ]\}	}
|
jjr©|  |  |
j|
jd”” qdS dS dS 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	TimeFieldzCONCAT('1900-01-01 ', %s)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$   r0   r1   Znew_temp_fieldŚ	new_valueZold_typeZnew_internal_typeŚnew_typeŚ_Śrelr&   r   r   r.   g   s^   



ż’’	’’žž’żżz1DatabaseSchemaEditor._alter_field_type_workaroundc                    sZ   h d£}|  ” |v r"|  ” |vr"|  |jj|j”r"|  |jj|j” t  ||||||”S )N>   r5   r4   r6   )r9   r   r   r   r    r!   r"   Ś_alter_column_type_sql)r   r$   r0   r1   rB   Śold_collationZnew_collationZauto_field_typesr&   r   r   rE   Ŗ   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.rI   NrC   )r   ŚhashŚupperrL   )r   Zfor_nameŚsuffixr   r   r   r;   Ć   s   z(DatabaseSchemaEditor._generate_temp_namec                 C   s   |   |” dd”S )Nś%z%%)r   r   r   r   r   r   Śprepare_defaultČ   s   z$DatabaseSchemaEditor.prepare_defaultc                    s:   t   ||”}| | j”}|d ur| ” | jjv rdS |S )NF)r"   Ś_field_should_be_indexedr=   r*   ŚlowerZ_limited_data_types)r   r$   r%   Zcreate_indexr=   r&   r   r   rR   Ķ   s   z-DatabaseSchemaEditor._field_should_be_indexedc                 C   sb   | j  ” "}| d|  |”|  |”g” | ” }|r|d ndW  d    S 1 s*w   Y  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)   rL   Zfetchone)r   Ś
table_nameŚcolumn_namerU   Ś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   rV   rW   r   r   r   r!   ę   s   ž’’z#DatabaseSchemaEditor._drop_identityc                 C   sN   | j  ” }| d|  |”g” | ” d W  d    S 1 s w   Y  d S )Nza
                SELECT default_collation FROM user_tables WHERE table_name = %s
                r   rT   )r   rV   rU   r   r   r   Ś_get_default_collationļ   s   
ü
$łz+DatabaseSchemaEditor._get_default_collationNc                    s*   |d u r|d ur|   |”}t  |||”S r   )rZ   r"   Ś_collate_sql)r   Z	collationrF   rV   r&   r   r   r[   ł   s   
z!DatabaseSchemaEditor._collate_sql)F)NN)Ś__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_delete_columnZsql_create_column_inline_fkZsql_delete_tableZsql_create_indexr   r#   r(   r-   r.   rE   rL   r;   rQ   rR   r   r!   rZ   r[   Ś__classcell__r   r   r&   r   r      s6    ’C

	
r   )r7   r   r>   Z	django.dbr   Zdjango.db.backends.base.schemar   r   Zdjango.utils.durationr   r   r   r   r   r   Ś<module>   s    