U
     5øiŒ7  ã                   @   sd   d dl mZ d dlZd dlmZ d dlmZmZm	Z	 d dl
mZ edejd ƒZG dd	„ d	eƒZdS )
é    )Ú
namedtupleN)Úmodels)ÚBaseDatabaseIntrospectionÚ	FieldInfoÚ	TableInfo)Úcached_propertyr   )Úis_autofieldÚis_jsonc                       sn   e Zd ZdZedd„ ƒZ‡ fdd„Zdd„ Zdd	„ Zd
d„ Z	ddd„Z
dd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )ÚDatabaseIntrospectioné   c                 C   s¨   | j jdk rXtjdtjdtjdtjdtjdtjdtj	dtj
dtjdtjdtjdtjd	iS tjdtjdtjdtjdtjdtjdtjdtjdtjdtjdtjd	tjdiS d S )
N)é   ZBinaryFieldZ	TextFieldZ	DateFieldZ	CharFieldZDurationFieldÚ
FloatFieldZDecimalFieldZDateTimeField)Ú
connectionZcx_oracle_versionÚ	cx_OracleZBLOBZCLOBZDATETIMEZ
FIXED_CHARZFIXED_NCHARZINTERVALZNATIVE_FLOATZNCHARÚNCLOBÚNUMBERÚSTRINGÚ	TIMESTAMPZDB_TYPE_DATEZDB_TYPE_BINARY_DOUBLEZDB_TYPE_BLOBZDB_TYPE_CHARZDB_TYPE_CLOBZDB_TYPE_INTERVAL_DSZDB_TYPE_NCHARZDB_TYPE_NCLOBZDB_TYPE_NVARCHARZDB_TYPE_NUMBERZDB_TYPE_TIMESTAMPZDB_TYPE_VARCHAR©Úself© r   úK/tmp/pip-unpacked-wheel-gcyiijx6/django/db/backends/oracle/introspection.pyÚdata_types_reverse   sf                ô            ôz(DatabaseIntrospection.data_types_reversec                    s¦   |t jkr„|dd… \}}|dkrv|dkr8|jr4dS dS d|  k rLdk rZn n
|jrZdS |dkrfd	S |jrpd
S dS q˜|dkr˜dS n|t jkr˜|jr˜dS tƒ  ||¡S )Né   é   r   é   ZBigAutoFieldZBigIntegerFieldr   ZSmallAutoFieldZBooleanFieldÚ	AutoFieldZIntegerFieldi�ÿÿÿr   Z	JSONField)r   r   r   r   r	   ÚsuperÚget_field_type)r   Z	data_typeÚdescriptionZ	precisionZscale©Ú	__class__r   r   r   3   s"    
z$DatabaseIntrospection.get_field_typec                    s    |  d¡ ‡ fdd„| ¡ D ƒS )z>Return a list of table and view names in the current database.a¨  
            SELECT table_name, 't'
            FROM user_tables
            WHERE
                NOT EXISTS (
                    SELECT 1
                    FROM user_mviews
                    WHERE user_mviews.mview_name = user_tables.table_name
                )
            UNION ALL
            SELECT view_name, 'v' FROM user_views
            UNION ALL
            SELECT mview_name, 'v' FROM user_mviews
        c                    s$   g | ]}t ˆ  |d  ¡|d ƒ‘qS )r   r   )r   Úidentifier_converter©Ú.0Úrowr   r   r   Ú
<listcomp>X   s     z8DatabaseIntrospection.get_table_list.<locals>.<listcomp>)ÚexecuteÚfetchall)r   Úcursorr   r   r   Úget_table_listH   s    
z$DatabaseIntrospection.get_table_listc                 C   sÐ   |  d|g¡ dd„ | ¡ D ƒ}|  jd7  _|  d | jj |¡| j¡¡ g }|jD ]t}|d }|| \}}}	}
}|i  }| t	|  
|¡f|dd… ||d p¢d|d	 p¬df|d
d… ||	|
|fžŽ ¡ qV|S )zi
        Return a description of the table with the DB-API cursor.description
        interface.
        a>  
            SELECT
                user_tab_cols.column_name,
                user_tab_cols.data_default,
                CASE
                    WHEN user_tab_cols.collation = user_tables.default_collation
                    THEN NULL
                    ELSE user_tab_cols.collation
                END collation,
                CASE
                    WHEN user_tab_cols.char_used IS NULL
                    THEN user_tab_cols.data_length
                    ELSE user_tab_cols.char_length
                END as internal_size,
                CASE
                    WHEN user_tab_cols.identity_column = 'YES' THEN 1
                    ELSE 0
                END as is_autofield,
                CASE
                    WHEN EXISTS (
                        SELECT  1
                        FROM user_json_columns
                        WHERE
                            user_json_columns.table_name = user_tab_cols.table_name AND
                            user_json_columns.column_name = user_tab_cols.column_name
                    )
                    THEN 1
                    ELSE 0
                END as is_json
            FROM user_tab_cols
            LEFT OUTER JOIN
                user_tables ON user_tables.table_name = user_tab_cols.table_name
            WHERE user_tab_cols.table_name = UPPER(%s)
        c                 S   s4   i | ],\}}}}}}|||d kr$|nd|||f“qS )ZNULLNr   )r$   ÚcolumnÚdefaultÚ	collationÚinternal_sizer   r	   r   r   r   Ú
<dictcomp>‚   s   ÿ z?DatabaseIntrospection.get_table_description.<locals>.<dictcomp>r   z,SELECT * FROM {} WHERE ROWNUM < 2 AND {} > 0r   é   r   é   r   N)r'   r(   Úcache_bust_counterÚformatr   ÚopsZ
quote_namer   Úappendr   r"   )r   r)   Ú
table_nameZ	field_mapr   ÚdescÚnamer.   r,   r-   r   r	   r   r   r   Úget_table_descriptionZ   s>    !ß"þþ
ÿ
  

þ
    þz+DatabaseIntrospection.get_table_descriptionc                 C   s   |  ¡ S )z7Identifier comparison is case insensitive under Oracle.)Úlower)r   r8   r   r   r   r"   •   s    z*DatabaseIntrospection.identifier_converterr   c                 C   sn   |  d|g¡ | ¡ }|rB|  |d ¡|  |¡|  |d ¡dœgS |D ]"}t|tjƒrF||jdœg  S qFg S )Na|  
            SELECT
                user_tab_identity_cols.sequence_name,
                user_tab_identity_cols.column_name
            FROM
                user_tab_identity_cols,
                user_constraints,
                user_cons_columns cols
            WHERE
                user_constraints.constraint_name = cols.constraint_name
                AND user_constraints.table_name = user_tab_identity_cols.table_name
                AND cols.column_name = user_tab_identity_cols.column_name
                AND user_constraints.constraint_type = 'P'
                AND user_tab_identity_cols.table_name = UPPER(%s)
        r   r   )r8   Útabler+   )r;   r+   )r'   Úfetchoner"   Ú
isinstancer   r   r+   )r   r)   r6   Ztable_fieldsr%   Úfr   r   r   Úget_sequences™   s    òýz#DatabaseIntrospection.get_sequencesc                    s,   |  ¡ }| d|g¡ ‡ fdd„| ¡ D ƒS )z—
        Return a dictionary of {field_name: (field_name_other_table, other_table)}
        representing all relationships to the given table.
        ab  
    SELECT ca.column_name, cb.table_name, cb.column_name
    FROM   user_constraints, USER_CONS_COLUMNS ca, USER_CONS_COLUMNS cb
    WHERE  user_constraints.table_name = %s AND
           user_constraints.constraint_name = ca.constraint_name AND
           user_constraints.r_constraint_name = cb.constraint_name AND
           ca.position = cb.positionc                    s.   i | ]&\}}}ˆ   |¡ˆ   |¡ˆ   |¡f“qS r   ©r"   )r$   Ú
field_nameZrel_table_nameZrel_field_namer   r   r   r/   Æ   s
   ýþz7DatabaseIntrospection.get_relations.<locals>.<dictcomp>)Úupperr'   r(   ©r   r)   r6   r   r   r   Úget_relations¸   s    ú
üz#DatabaseIntrospection.get_relationsc                    s(   |  d| ¡ g¡ ‡ fdd„| ¡ D ƒS )Naš  
            SELECT ccol.column_name, rcol.table_name AS referenced_table, rcol.column_name AS referenced_column
            FROM user_constraints c
            JOIN user_cons_columns ccol
              ON ccol.constraint_name = c.constraint_name
            JOIN user_cons_columns rcol
              ON rcol.constraint_name = c.r_constraint_name
            WHERE c.table_name = %s AND c.constraint_type = 'R'c                    s"   g | ]}t ‡ fd d„|D ƒƒ‘qS )c                 3   s   | ]}ˆ   |¡V  qd S )Nr@   )r$   Úcellr   r   r   Ú	<genexpr>×   s     zCDatabaseIntrospection.get_key_columns.<locals>.<listcomp>.<genexpr>)Útupler#   r   r   r   r&   Ö   s   ÿz9DatabaseIntrospection.get_key_columns.<locals>.<listcomp>)r'   rB   r(   rC   r   r   r   Úget_key_columnsÍ   s    ù
þz%DatabaseIntrospection.get_key_columnsc                 C   s,   |  d|g¡ | ¡ }|r(|  |d ¡S d S )NaŽ  
            SELECT
                cols.column_name
            FROM
                user_constraints,
                user_cons_columns cols
            WHERE
                user_constraints.constraint_name = cols.constraint_name AND
                user_constraints.constraint_type = 'P' AND
                user_constraints.table_name = UPPER(%s) AND
                cols.position = 1
        r   )r'   r<   r"   )r   r)   r6   r%   r   r   r   Úget_primary_key_columnÛ   s
    õz,DatabaseIntrospection.get_primary_key_columnc                 C   s  i }|  d|g¡ | ¡ D ]4\}}}}}|  |¡}| d¡||d||dœ||< q|  d|g¡ | ¡ D ]6\}}}	}
|  |¡}dd|	|
fdd| d¡dœ||< qf|  d|g¡ | ¡ D ]N\}}}}}|  |¡}d|d	kddd
|dkrædn|| d¡| d¡dœ||< q´|S )zu
        Retrieve any constraints or keys (unique, pk, fk, check, index) across
        one or more columns.
        a$  
            SELECT
                user_constraints.constraint_name,
                LISTAGG(LOWER(cols.column_name), ',') WITHIN GROUP (ORDER BY cols.position),
                CASE user_constraints.constraint_type
                    WHEN 'P' THEN 1
                    ELSE 0
                END AS is_primary_key,
                CASE
                    WHEN user_constraints.constraint_type IN ('P', 'U') THEN 1
                    ELSE 0
                END AS is_unique,
                CASE user_constraints.constraint_type
                    WHEN 'C' THEN 1
                    ELSE 0
                END AS is_check_constraint
            FROM
                user_constraints
            LEFT OUTER JOIN
                user_cons_columns cols ON user_constraints.constraint_name = cols.constraint_name
            WHERE
                user_constraints.constraint_type = ANY('P', 'U', 'C')
                AND user_constraints.table_name = UPPER(%s)
            GROUP BY user_constraints.constraint_name, user_constraints.constraint_type
        ú,N)ÚcolumnsÚprimary_keyÚuniqueÚforeign_keyÚcheckÚindexaÞ  
            SELECT
                cons.constraint_name,
                LISTAGG(LOWER(cols.column_name), ',') WITHIN GROUP (ORDER BY cols.position),
                LOWER(rcols.table_name),
                LOWER(rcols.column_name)
            FROM
                user_constraints cons
            INNER JOIN
                user_cons_columns rcols ON rcols.constraint_name = cons.r_constraint_name AND rcols.position = 1
            LEFT OUTER JOIN
                user_cons_columns cols ON cons.constraint_name = cols.constraint_name
            WHERE
                cons.constraint_type = 'R' AND
                cons.table_name = UPPER(%s)
            GROUP BY cons.constraint_name, rcols.table_name, rcols.column_name
        F)rL   rM   rN   rO   rP   rK   að  
            SELECT
                ind.index_name,
                LOWER(ind.index_type),
                LOWER(ind.uniqueness),
                LISTAGG(LOWER(cols.column_name), ',') WITHIN GROUP (ORDER BY cols.column_position),
                LISTAGG(cols.descend, ',') WITHIN GROUP (ORDER BY cols.column_position)
            FROM
                user_ind_columns cols, user_indexes ind
            WHERE
                cols.table_name = UPPER(%s) AND
                NOT EXISTS (
                    SELECT 1
                    FROM user_constraints cons
                    WHERE ind.index_name = cons.index_name
                ) AND cols.index_name = ind.index_name
            GROUP BY ind.index_name, ind.index_type, ind.uniqueness
        rM   TÚnormalÚidx)rL   rM   rN   rO   rP   ÚtyperK   Úorders)r'   r(   r"   Úsplit)r   r)   r6   ÚconstraintsÚ
constraintrK   ÚpkrM   rO   Zother_tableZother_columnÚtype_rT   r   r   r   Úget_constraintsë   sP    è
ú	ð
ú	ï
ø
z%DatabaseIntrospection.get_constraints)r   )Ú__name__Ú
__module__Ú__qualname__r2   r   r   r   r*   r9   r"   r?   rD   rH   rI   rZ   Ú__classcell__r   r   r    r   r
      s   
 ;
r
   )Úcollectionsr   r   Z	django.dbr   Z%django.db.backends.base.introspectionr   r   ZBaseFieldInfor   Zdjango.utils.functionalr   Ú_fieldsr
   r   r   r   r   Ú<module>   s   