B
    ©0H[ƒ]  ã               @   sŒ   d dl Z d dlZd dl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 ddlmZ dd	lmZmZmZ G d
d„ deƒZdS )é    N)Úsettings)ÚBaseDatabaseOperations)Ústrip_quotesÚtruncate_name)Útimezone)Úforce_bytesé   )ÚDatabase)ÚBulkInsertMapperÚInsertIdVarÚOracle_datetimec                   s  e Zd ZdZddddddœZeejdd�ZdZd	Z	d
d„ Z
dd„ Zdd„ Zdd„ Ze d¡Zdd„ Zdd„ Z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'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zed/d0„ ƒZ ed1d2„ ƒZ!d3d4„ Z"d5d6„ Z#d7d8„ Z$‡ fd9d:„Z%d;d<„ Z&dud>d?„Z'd@dA„ Z(dBdC„ Z)dDdE„ Z*dFdG„ Z+dHdI„ Z,dJdK„ Z-dLdM„ Z.dNdO„ Z/dPdQ„ Z0dRdS„ Z1dTdU„ Z2dvdWdX„Z3dwdYdZ„Z4d[d\„ Z5d]d^„ Z6d_d`„ Z7dxdadb„Z8dcdd„ Z9dedf„ Z:dgdh„ Z;‡ fdidj„Z<dkdl„ Z=dmdn„ Z>dodp„ Z?‡ fdqdr„Z@dsdt„ ZA‡  ZBS )yÚDatabaseOperationsz"django.db.backends.oracle.compiler)lýÿÿÿÿgí] l   ÿgí] )lûÿÿÿÿÏ9V l   ÿÏ9V )r   l   ÿgí] )ZSmallIntegerFieldZIntegerFieldZBigIntegerFieldZPositiveSmallIntegerFieldZPositiveIntegerFieldÚMINUS)Ú
differenceaï  
DECLARE
    table_value integer;
    seq_value integer;
    seq_name user_tab_identity_cols.sequence_name%%TYPE;
BEGIN
    BEGIN
        SELECT sequence_name INTO seq_name FROM user_tab_identity_cols
        WHERE  table_name = '%(table_name)s' AND
               column_name = '%(column_name)s';
        EXCEPTION WHEN NO_DATA_FOUND THEN
            seq_name := '%(no_autofield_sequence_name)s';
    END;

    SELECT NVL(MAX(%(column)s), 0) INTO table_value FROM %(table)s;
    SELECT NVL(last_number - cache_size, 0) INTO seq_value FROM user_sequences
           WHERE sequence_name = seq_name;
    WHILE table_value > seq_value LOOP
        EXECUTE IMMEDIATE 'SELECT "'||seq_name||'".nextval FROM DUAL'
        INTO seq_value;
    END LOOP;
END;
/zNVARCHAR2(2000)c             C   s   dS )Nz 
            SELECT cache_key
              FROM (SELECT cache_key, rank() OVER (ORDER BY cache_key) AS rank FROM %s)
             WHERE rank = %%s + 1
        © )Úselfr   r   úhC:\Users\HIRONO~1\AppData\Local\Temp\pip-install-6bm3nxem\django\django\db\backends\oracle\operations.pyÚcache_key_culling_sql8   s    z(DatabaseOperations.cache_key_culling_sqlc             C   sD   |dkrd| S |dkr d| S |dkr0d| S d|  ¡ |f S d S )NZweek_dayzTO_CHAR(%s, 'D')ÚweekzTO_CHAR(%s, 'IW')ÚquarterzTO_CHAR(%s, 'Q')zEXTRACT(%s FROM %s))Úupper)r   Úlookup_typeÚ
field_namer   r   r   Údate_extract_sql?   s    z#DatabaseOperations.date_extract_sqlc             C   s   d|  ¡  S )zT
        NUMTODSINTERVAL converts number to INTERVAL DAY TO SECOND literal.
        zNUMTODSINTERVAL(%06f, 'SECOND'))Útotal_seconds)r   Ú	timedeltar   r   r   Údate_interval_sqlL   s    z$DatabaseOperations.date_interval_sqlc             C   s4   |dkrd||  ¡ f S |dkr(d| S d| S d S )N)ÚyearÚmonthzTRUNC(%s, '%s')r   zTRUNC(%s, 'Q')z	TRUNC(%s))r   )r   r   r   r   r   r   Údate_trunc_sqlR   s
    z!DatabaseOperations.date_trunc_sqlz^[\w/:+-]+$c             C   s.   t js
|S | j |¡s"td| ƒ‚d||f S )NzInvalid time zone name: %sz:CAST((FROM_TZ(%s, '0:00') AT TIME ZONE '%s') AS TIMESTAMP))r   ÚUSE_TZÚ
_tzname_reÚmatchÚ
ValueError)r   r   Útznamer   r   r   Ú_convert_field_to_tza   s
    z'DatabaseOperations._convert_field_to_tzc             C   s   |   ||¡}d| S )Nz	TRUNC(%s))r%   )r   r   r$   r   r   r   Údatetime_cast_date_sqlj   s    z)DatabaseOperations.datetime_cast_date_sqlc             C   s   |   ||¡S )N)r%   )r   r   r$   r   r   r   Údatetime_cast_time_sqln   s    z)DatabaseOperations.datetime_cast_time_sqlc             C   s   |   ||¡}|  ||¡S )N)r%   r   )r   r   r   r$   r   r   r   Údatetime_extract_sqls   s    z'DatabaseOperations.datetime_extract_sqlc             C   sz   |   ||¡}|dkr&d|| ¡ f }nP|dkr8d| }n>|dkrJd| }n,|dkr\d| }n|d	krnd
| }nd| }|S )N)r   r   zTRUNC(%s, '%s')r   zTRUNC(%s, 'Q')Údayz	TRUNC(%s)ÚhourzTRUNC(%s, 'HH24')ÚminutezTRUNC(%s, 'MI')zCAST(%s AS DATE))r%   r   )r   r   r   r$   Úsqlr   r   r   Údatetime_trunc_sqlw   s    



z%DatabaseOperations.datetime_trunc_sqlc             C   s8   |dkrd| }n"|dkr$d| }n|dkr4d| }|S )Nr*   zTRUNC(%s, 'HH24')r+   zTRUNC(%s, 'MI')ÚsecondzCAST(%s AS DATE)r   )r   r   r   r,   r   r   r   Útime_trunc_sqlˆ   s    

z!DatabaseOperations.time_trunc_sqlc                sÔ   t ƒ  |¡}|j ¡ }|dkr,| | j¡ n‚|dkrB| | j¡ nl|dkrX| | j¡ nV|dkrn| | j¡ n@|dkr„| | j	¡ n*|dkrš| | j
¡ n|dkr®| | j¡ |jjrÐ| |dkrÈ| jn| j¡ |S )NZ	TextFieldZBinaryField)ZBooleanFieldZNullBooleanFieldZDateTimeFieldÚ	DateFieldZ	TimeFieldZ	UUIDField)ÚsuperÚget_db_convertersZoutput_fieldÚget_internal_typeÚappendÚconvert_textfield_valueÚconvert_binaryfield_valueÚconvert_booleanfield_valueÚconvert_datetimefield_valueÚconvert_datefield_valueÚconvert_timefield_valueÚconvert_uuidfield_valueÚfieldZempty_strings_allowedÚconvert_empty_bytesÚconvert_empty_string)r   Ú
expressionÚ
convertersÚinternal_type)Ú	__class__r   r   r2   ”   s*    
z$DatabaseOperations.get_db_convertersc             C   s   t |tjƒr| ¡ }|S )N)Ú
isinstancer	   ÚLOBÚread)r   Úvaluer?   Ú
connectionr   r   r   r5   °   s    z*DatabaseOperations.convert_textfield_valuec             C   s   t |tjƒrt| ¡ ƒ}|S )N)rC   r	   rD   r   rE   )r   rF   r?   rG   r   r   r   r6   µ   s    z,DatabaseOperations.convert_binaryfield_valuec             C   s   |dkrt |ƒ}|S )N)r   r   )Úbool)r   rF   r?   rG   r   r   r   r7   º   s    z-DatabaseOperations.convert_booleanfield_valuec             C   s"   |d k	rt jrt || jj¡}|S )N)r   r    r   Z
make_awarerG   )r   rF   r?   rG   r   r   r   r8   Ã   s    z.DatabaseOperations.convert_datetimefield_valuec             C   s   t |tjƒr| ¡ }|S )N)rC   r	   Ú	TimestampÚdate)r   rF   r?   rG   r   r   r   r9   É   s    z*DatabaseOperations.convert_datefield_valuec             C   s   t |tjƒr| ¡ }|S )N)rC   r	   rI   Útime)r   rF   r?   rG   r   r   r   r:   Î   s    z*DatabaseOperations.convert_timefield_valuec             C   s   |d k	rt  |¡}|S )N)ÚuuidÚUUID)r   rF   r?   rG   r   r   r   r;   Ó   s    
z*DatabaseOperations.convert_uuidfield_valuec             C   s   | d krdS | S )NÚ r   )rF   r?   rG   r   r   r   r>   Ø   s    z'DatabaseOperations.convert_empty_stringc             C   s   | d krdS | S )Nó    r   )rF   r?   rG   r   r   r   r=   Ü   s    z&DatabaseOperations.convert_empty_bytesc             C   s   dS )Nz DEFERRABLE INITIALLY DEFERREDr   )r   r   r   r   Údeferrable_sqlà   s    z!DatabaseOperations.deferrable_sqlc             C   s   t |j ¡ ƒS )N)ÚintZ_insert_id_varÚgetvalue)r   Úcursorr   r   r   Úfetch_returned_insert_idã   s    z+DatabaseOperations.fetch_returned_insert_idc             C   s   |r|  d¡rdS dS d S )NrD   zDBMS_LOB.SUBSTR(%s)z%s)Úendswith)r   Zdb_typerA   r   r   r   Úfield_cast_sqlæ   s    z!DatabaseOperations.field_cast_sqlc                s   |j }tƒ  |||¡S )N)Ú	statementr1   Úlast_executed_query)r   rS   r,   ÚparamsrW   )rB   r   r   rX   ì   s    z&DatabaseOperations.last_executed_queryc             C   s,   |   |t|ƒ|¡}| d| ¡ | ¡ d S )Nz"%s".currvalr   )Ú_get_sequence_namer   ÚexecuteÚfetchone)r   rS   Ú
table_nameÚpk_nameZsq_namer   r   r   Úlast_insert_idô   s    z!DatabaseOperations.last_insert_idNc             C   s   |dkrdS dS )N)ZiexactZ	icontainsZistartswithZ	iendswithz	UPPER(%s)z%sr   )r   r   rA   r   r   r   Úlookup_castù   s    zDatabaseOperations.lookup_castc             C   s   dS )Niè  r   )r   r   r   r   Úmax_in_list_sizeþ   s    z#DatabaseOperations.max_in_list_sizec             C   s   dS )Né   r   )r   r   r   r   Úmax_name_length  s    z"DatabaseOperations.max_name_lengthc             C   s   dS )NÚNULLr   )r   r   r   r   Úpk_default_value  s    z#DatabaseOperations.pk_default_valuec             C   s   |S )Nr   )r   Úxr   r   r   Úprep_for_iexact_query  s    z(DatabaseOperations.prep_for_iexact_queryc             C   s   |d krdS |  ¡ S )NrN   )rE   )r   rF   r   r   r   Úprocess_clob
  s    zDatabaseOperations.process_clobc             C   s>   |  d¡s*| d¡s*dt| ¡ |  ¡ ƒ }| dd¡}| ¡ S )Nú"z"%s"ú%z%%)Ú
startswithrU   r   r   rc   Úreplace)r   Únamer   r   r   Ú
quote_name  s    zDatabaseOperations.quote_namec             C   s   dS )NzDBMS_RANDOM.RANDOMr   )r   r   r   r   Úrandom_function_sql  s    z&DatabaseOperations.random_function_sqlc             C   s   |dkrd}nd}d| S )NÚregexz'c'z'i'zREGEXP_LIKE(%%s, %%s, %s)r   )r   r   Zmatch_optionr   r   r   Úregex_lookup  s    zDatabaseOperations.regex_lookupc             C   s   dt ƒ ffS )NzRETURNING %s INTO %%s)r   )r   r   r   r   Úreturn_insert_id&  s    z#DatabaseOperations.return_insert_idc             C   s   d|   |¡ S )Nz
SAVEPOINT )rn   )r   Úsidr   r   r   Úsavepoint_create_sql)  s    z'DatabaseOperations.savepoint_create_sqlc             C   s   d|   |¡ S )NzROLLBACK TO SAVEPOINT )rn   )r   rs   r   r   r   Úsavepoint_rollback_sql,  s    z)DatabaseOperations.savepoint_rollback_sqlFc          	   C   sB   | j  ¡ �.}|r"| d||f¡ n| d|f¡ | ¡ S Q R X d S )Na†  
                    SELECT
                        user_tables.table_name, rcons.constraint_name
                    FROM
                        user_tables
                    JOIN
                        user_constraints cons
                        ON (user_tables.table_name = cons.table_name AND cons.constraint_type = ANY('P', 'U'))
                    LEFT JOIN
                        user_constraints rcons
                        ON (user_tables.table_name = rcons.table_name AND rcons.constraint_type = 'R')
                    START WITH user_tables.table_name = UPPER(%s)
                    CONNECT BY NOCYCLE PRIOR cons.constraint_name = rcons.r_constraint_name
                    GROUP BY
                        user_tables.table_name, rcons.constraint_name
                    HAVING user_tables.table_name != UPPER(%s)
                    ORDER BY MAX(level) DESC
                a6  
                    SELECT
                        cons.table_name, cons.constraint_name
                    FROM
                        user_constraints cons
                    WHERE
                        cons.constraint_type = 'R'
                        AND cons.table_name = UPPER(%s)
                )rG   rS   r[   Zfetchall)r   r]   Ú	recursiverS   r   r   r   Ú_foreign_key_constraints/  s    
z+DatabaseOperations._foreign_key_constraintsc                s¸   |r°dd„ |D ƒ}t ƒ }xD|D ]<}x6ˆ j||d�D ]$\}}	|rH| |¡ | ||	f¡ q2W qW ‡ ‡fdd„|D ƒ‡ ‡fdd„|D ƒ ‡ ‡fdd„|D ƒ }
|
 ˆ  ˆ|¡¡ |
S g S d S )Nc             S   s   h | ]}|  ¡ ’qS r   )r   )Ú.0Útabler   r   r   ú	<setcomp>R  s    z/DatabaseOperations.sql_flush.<locals>.<setcomp>)rv   c                sd   g | ]\\}}d ˆ  d¡ˆ  d¡ˆ ˆ  |¡¡ˆ  d¡ˆ  d¡ˆ ˆ  |¡¡ˆ  d¡ˆ  d¡f ‘qS )z%s %s %s %s %s %s %s %s;ÚALTERÚTABLEZDISABLEÚ
CONSTRAINTZKEEPZINDEX)ÚSQL_KEYWORDÚ	SQL_FIELDrn   )rx   ry   Ú
constraint)r   Ústyler   r   ú
<listcomp>_  s   	z0DatabaseOperations.sql_flush.<locals>.<listcomp>c          
      s2   g | ]*}d ˆ  d¡ˆ  d¡ˆ ˆ  |¡¡f ‘qS )z	%s %s %s;ZTRUNCATEr|   )r~   r   rn   )rx   ry   )r   r�   r   r   r‚   j  s   c                sT   g | ]L\}}d ˆ  d¡ˆ  d¡ˆ ˆ  |¡¡ˆ  d¡ˆ  d¡ˆ ˆ  |¡¡f ‘qS )z%s %s %s %s %s %s;r{   r|   ZENABLEr}   )r~   r   rn   )rx   ry   r€   )r   r�   r   r   r‚   p  s   )Úsetrw   ÚaddÚextendÚsequence_reset_by_name_sql)r   r�   ÚtablesÚ	sequencesZallow_cascadeZtruncated_tablesÚconstraintsry   Zforeign_tabler€   r,   r   )r   r�   r   Ú	sql_flushP  s    

&
zDatabaseOperations.sql_flushc       	      C   sl   g }xb|D ]Z}|   |d ¡}|  |d ¡}|  |d p8d¡}| j|||t|ƒt|ƒdœ }| |¡ q
W |S )Nry   ÚcolumnÚid)Úno_autofield_sequence_namery   r‹   r]   Úcolumn_name)Ú_get_no_autofield_sequence_namern   Ú_sequence_reset_sqlr   r4   )	r   r�   rˆ   r,   Zsequence_infor�   ry   r‹   Úqueryr   r   r   r†   €  s    
z-DatabaseOperations.sequence_reset_by_name_sqlc             C   sð   ddl m} g }| j}xÔ|D ]Ì}xh|jjD ]\}t||jƒr*|  |jj¡}|  	|jj¡}	|  	|j
¡}
| |||	|
t|	ƒt|
ƒdœ ¡ P q*W x\|jjD ]P}|jjs”|  | ¡ ¡}|  	| ¡ ¡}	|  	d¡}
| |||	|
t|	ƒddœ ¡ q”W qW |S )Nr   )Úmodels)r�   ry   r‹   r]   rŽ   rŒ   ZID)Z	django.dbr’   r�   Z_metaZlocal_fieldsrC   Z	AutoFieldr�   Zdb_tablern   r‹   r4   r   Zmany_to_manyZremote_fieldZthroughZm2m_db_table)r   r�   Z
model_listr’   Úoutputr‘   ÚmodelÚfr�   ry   r‹   r   r   r   Úsequence_reset_sql�  s8    

z%DatabaseOperations.sequence_reset_sqlc             C   s   dS )NrN   r   )r   r   r   r   Ústart_transaction_sql²  s    z(DatabaseOperations.start_transaction_sqlc             C   s$   |rd|   |¡ S d|   |¡ S d S )NzUSING INDEX TABLESPACE %szTABLESPACE %s)rn   )r   Z
tablespaceÚinliner   r   r   Útablespace_sqlµ  s    z!DatabaseOperations.tablespace_sqlc             C   s   |S )zô
        Transform a date value to an object compatible with what is expected
        by the backend driver for date columns.
        The default implementation transforms the date to text, but that is not
        necessary for Oracle.
        r   )r   rF   r   r   r   Úadapt_datefield_value»  s    z(DatabaseOperations.adapt_datefield_valuec             C   sN   |dkrdS t |dƒr|S t |¡rDtjr<t || jj¡}ntdƒ‚t 	|¡S )aE  
        Transform a datetime value to an object compatible with what is expected
        by the backend driver for datetime columns.

        If naive datetime is passed assumes that is in UTC. Normally Django
        models.DateTimeField makes sure that if USE_TZ is True passed datetime
        is timezone aware.
        NÚresolve_expressionzNOracle backend does not support timezone-aware datetimes when USE_TZ is False.)
Úhasattrr   Úis_awarer   r    Z
make_naiverG   r#   r   Zfrom_datetime)r   rF   r   r   r   Úadapt_datetimefield_valueÄ  s    


z,DatabaseOperations.adapt_datetimefield_valuec             C   s`   |d krd S t |dƒr|S t|tƒr2tj |d¡S t |¡rDtdƒ‚tddd|j	|j
|j|jƒS )Nr›   z%H:%M:%Sz5Oracle backend does not support timezone-aware times.il  r   )rœ   rC   ÚstrÚdatetimeÚstrptimer   r�   r#   r   r*   r+   r.   Úmicrosecond)r   rF   r   r   r   Úadapt_timefield_valueÞ  s    


z(DatabaseOperations.adapt_timefield_valuec                sš   |\}}|dkrdd  |¡ S |dkr4dd  |¡ S |dkrJd||dœ S |d	kr`d
||dœ S |dkrvd||dœ S |dkrŒdd  |¡ S tƒ  ||¡S )Nz%%zMOD(%s)ú,ú&z
BITAND(%s)ú|z"BITAND(-%(lhs)s-1,%(rhs)s)+%(lhs)s)ÚlhsÚrhsz<<z(%(lhs)s * POWER(2, %(rhs)s))z>>z"FLOOR(%(lhs)s / POWER(2, %(rhs)s))ú^z	POWER(%s))Újoinr1   Úcombine_expression)r   Z	connectorZsub_expressionsr§   r¨   )rB   r   r   r«   ð  s    z%DatabaseOperations.combine_expressionc             C   s"   |   ¡ d }dtt|ƒ|ƒ ¡  S )z‹
        Manually created sequence name to keep backward compatibility for
        AutoFields that aren't Oracle identity columns.
        é   z%s_SQ)rc   r   r   r   )r   ry   Zname_lengthr   r   r   r�      s    z2DatabaseOperations._get_no_autofield_sequence_namec             C   s2   |  d||g¡ | ¡ }|d kr*|  |¡S |d S )Nzš
            SELECT sequence_name
            FROM user_tab_identity_cols
            WHERE table_name = UPPER(%s)
            AND column_name = UPPER(%s)r   )r[   r\   r�   )r   rS   ry   r^   Úrowr   r   r   rZ     s    z%DatabaseOperations._get_sequence_namec       	      C   sš   g }x†|D ]~}g }x`t |ƒD ]T\}}|| rVt|| d|| ƒ ¡ }tj |d¡| }|sfd||f }| |¡ qW | dd |¡ ¡ q
W dd |¡ S )NZtarget_fieldz%sz	%s col_%szSELECT %s FROM DUALz, zSELECT * FROM (%s)z UNION ALL )Ú	enumerateÚgetattrr3   r
   ÚtypesÚgetr4   rª   )	r   ÚfieldsZplaceholder_rowsr‘   r­   ÚselectÚiÚplaceholderrA   r   r   r   Úbulk_insert_sql  s    
z"DatabaseOperations.bulk_insert_sqlc                s<   |dkr,|\}}|\}}d||f || fS t ƒ  |||¡S )Nr0   zNUMTODSINTERVAL(%s - %s, 'DAY'))r1   Úsubtract_temporals)r   rA   r§   r¨   Zlhs_sqlZ
lhs_paramsZrhs_sqlZ
rhs_params)rB   r   r   r·   &  s
    z%DatabaseOperations.subtract_temporalsc             C   s   |r| j jjt|ƒ S t|ƒS )z5Oracle restricts the number of parameters in a query.)rG   ÚfeaturesZmax_query_paramsÚlen)r   r²   Úobjsr   r   r   Úbulk_batch_size-  s    z"DatabaseOperations.bulk_batch_size)N)F)F)F)CÚ__name__Ú
__module__Ú__qualname__Zcompiler_moduleZinteger_field_rangesÚdictr   Zset_operatorsr�   Z"cast_char_field_without_max_lengthr   r   r   r   ÚreÚcompiler!   r%   r&   r'   r(   r-   r/   r2   r5   r6   r7   r8   r9   r:   r;   Ústaticmethodr>   r=   rP   rT   rV   rX   r_   r`   ra   rc   re   rg   rh   rn   ro   rq   rr   rt   ru   rw   rŠ   r†   r–   r—   r™   rš   rž   r£   r«   r�   rZ   r¶   r·   r»   Ú__classcell__r   r   )rB   r   r      s|   
		

!
0"
		r   )r    rÀ   rL   Zdjango.confr   Z"django.db.backends.base.operationsr   Zdjango.db.backends.utilsr   r   Zdjango.utilsr   Zdjango.utils.encodingr   Úbaser	   Úutilsr
   r   r   r   r   r   r   r   Ú<module>   s   