
v^iY                 @   s  d  Z  d d l Z 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
 d d l 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   Z e d' d( g  y d d l Z Wn5 e k
 rZ z e
 d e   WYd d Z [ Xn Xd d l m Z d d l m Z d d l m  Z  d d l! m" Z" d d l# m$ Z$ d d l% m& Z& d d l m' Z' d d l( m) Z) e d d    Z* Gd d   d  Z+ Gd d    d  e  Z, Gd! d"   d"  Z- Gd# d$   d$  Z. Gd% d&   d&  Z/ d S))ze
Oracle database backend for Django.

Requires cx_Oracle: https://oracle.github.io/python-cx_Oracle/
    N)contextmanager)settings)ImproperlyConfigured)utils)BaseDatabaseWrapper)async_unsafe)force_bytes	force_str)cached_propertyc             C   s   t  j   j   j d  r y d d  l } Wn5 t k
 rb } z t d |   WYd  d  } ~ Xn X| j d  } x7 |  D] \ } } | j | |  qy Wn t	 j
 j |   d  S)NZCYGWINr   z_Error loading ctypes: %s; the Oracle backend requires ctypes to operate correctly under Cygwin.kernel32)platformsystemupper
startswithctypesImportErrorr   CDLLZSetEnvironmentVariableAosenvironupdate)r   r   er   namevalue r   @/tmp/pip-build-8lau8j11/django/django/db/backends/oracle/base.py_setup_environment   s    r   NLS_LANG	.AL32UTF8ORA_NCHAR_LITERAL_REPLACETRUEz"Error loading cx_Oracle module: %s   )DatabaseClient)DatabaseCreation)DatabaseFeatures)DatabaseIntrospection)DatabaseOperations)DatabaseSchemaEditor)Oracle_datetime)DatabaseValidationc              c   s   y	 d  VWn t  j k
 r }  zi |  j d } t | d  r t | d  r | j d k r d | j k r t j t |  j       WYd  d  }  ~  Xn Xd  S)Nr   codemessagei+  z	ORA-02291)	DatabaseDatabaseErrorargshasattrr)   r*   r   ZIntegrityErrortuple)r   xr   r   r   wrap_oracle_errors?   s    	<r1   c               @   s   e  Z d  Z d d d  Z d S)!_UninitializedOperatorsDescriptorNc             C   s3   | d  k r t  d   | j   j   | j d S)Nz*operators not available as class attribute	operators)AttributeErrorcursorclose__dict__)selfinstanceclsr   r   r   __get__S   s    z)_UninitializedOperatorsDescriptor.__get__)__name__
__module____qualname__r;   r   r   r   r   r2   Q   s   r2   c            6       s  e  Z d  Z d Z d Z d d d d d d d	 d
 d d d d d d d d d d d d d d d d d d d d d d d d  d! d
 d" d d# d d$ d d% d d& d' d( d d) d* d+ d d, d- d. d/ i Z d	 d0 d! d0 d# d1 d$ d1 i Z dp Z e   Z	 d5 d6 d7 d8 d9 d: d; d< d= d> d? d@ dA dB dC dD dE d: dF d: dG d< dH d< i Z
 e
 d9 dI d; dJ dE dI dF dI dG dJ dH dJ i  Z dK Z d9 dL d; dM dE dN dG dO dF dP dH dQ i Z dR dS   e j   D Z dT dS   e j   D Z e Z e Z e Z e Z e Z e Z e Z e Z   f dU dV   Z  dW dX   Z! dY dZ   Z" d[ d\   Z# e$ d] d^    Z% d_ d`   Z& e$ da db dc   Z' dd de   Z( df dg   Z) dh di   Z* da dj dk  Z+ dl dm   Z, e- dn do    Z.   S)qDatabaseWrapperZoracleZOracleZ	AutoFieldz3NUMBER(11) GENERATED BY DEFAULT ON NULL AS IDENTITYZBigAutoFieldz3NUMBER(19) GENERATED BY DEFAULT ON NULL AS IDENTITYZBinaryFieldZBLOBZBooleanFieldz	NUMBER(1)Z	CharFieldzNVARCHAR2(%(max_length)s)Z	DateFieldZDATEZDateTimeField	TIMESTAMPZDecimalFieldz*NUMBER(%(max_digits)s, %(decimal_places)s)ZDurationFieldzINTERVAL DAY(9) TO SECOND(6)Z	FileFieldZFilePathFieldZ
FloatFieldzDOUBLE PRECISIONZIntegerFieldz
NUMBER(11)ZBigIntegerFieldz
NUMBER(19)ZIPAddressFieldzVARCHAR2(15)ZGenericIPAddressFieldzVARCHAR2(39)ZNullBooleanFieldZOneToOneFieldZPositiveIntegerFieldZPositiveSmallIntegerFieldZ	SlugFieldZSmallAutoFieldz2NUMBER(5) GENERATED BY DEFAULT ON NULL AS IDENTITYZSmallIntegerFieldZ	TextFieldZNCLOBZ	TimeFieldZURLFieldzVARCHAR2(%(max_length)s)Z	UUIDFieldzVARCHAR2(32)z%(qn_column)s IN (0,1)z%(qn_column)s >= 0clobnclobblobexactz= %sZiexactz= UPPER(%s)containszFLIKE TRANSLATE(%s USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS)Z	icontainszMLIKE UPPER(TRANSLATE(%s USING NCHAR_CS)) ESCAPE TRANSLATE('\' USING NCHAR_CS)gtz> %sgtez>= %sltz< %sltez<= %sr   endswithZistartswithZ	iendswithzLIKEC %s ESCAPE '\'zLIKEC UPPER(%s) ESCAPE '\'z@REPLACE(REPLACE(REPLACE({}, '\', '\\'), '%%', '\%%'), '_', '\_')z'%%' || {} || '%%'z'%%' || UPPER({}) || '%%'z
{} || '%%'zUPPER({}) || '%%'z
'%%' || {}z'%%' || UPPER({})c             C   s'   i  |  ] \ } } d  | d |  q S)zLIKE TRANSLATE( z5 USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS)r   ).0kvr   r   r   
<dictcomp>   s   	zDatabaseWrapper.<dictcomp>c             C   s'   i  |  ] \ } } d  | d |  q S)zLIKEC z ESCAPE '\'r   )rK   rL   rM   r   r   r   rN      s   	c                s<   t    j | |   |  j d j d d  } | |  j _ d  S)NOPTIONSuse_returning_intoT)super__init__settings_dictgetfeaturesZcan_return_columns_from_insert)r8   r-   kwargsrP   )	__class__r   r   rR      s    zDatabaseWrapper.__init__c             C   sZ   |  j  } | d j   s# d | d <| d rR t j | d t | d  | d  S| d S)NZHOST	localhostZPORTNAME)rS   stripr+   Zmakedsnint)r8   rS   r   r   r   _dsn   s    	

%zDatabaseWrapper._dsnc             C   s%   d |  j  d |  j  d |  j   f S)Nz
%s/"%s"@%sUSERPASSWORD)rS   r\   )r8   r   r   r   _connect_string   s    zDatabaseWrapper._connect_stringc             C   s*   |  j  d j   } d | k r& | d =| S)NrO   rP   )rS   copy)r8   conn_paramsr   r   r   get_connection_params   s    z%DatabaseWrapper.get_connection_paramsc             C   s3   t  j d |  j d d |  j d d |  j   |  S)Nuserr]   passwordr^   Zdsn)r+   connectrS   r\   )r8   ra   r   r   r   get_new_connection   s
    		z"DatabaseWrapper.get_new_connectionc             C   s   |  j    } | j d  | j d t j r1 d n d  | j   d |  j k r |  j    } y" | j d |  j d d g  Wn- t j k
 r |  j	 |  _
 |  j |  _ Yn X|  j |  _
 |  j |  _ | j   d	 |  j _ |  j   s |  j   d  S)
Nz+ALTER SESSION SET NLS_TERRITORY = 'AMERICA'zmALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'z TIME_ZONE = 'UTC' r3   z!SELECT 1 FROM DUAL WHERE DUMMY %srE   X   )create_cursorexecuter   USE_TZr6   r7   _standard_operatorsr+   r,   _likec_operatorsr3   _likec_pattern_opsZpattern_ops_standard_pattern_ops
connectionZstmtcachesizeZget_autocommitcommit)r8   r5   r   r   r   init_connection_state   s*    
	
z%DatabaseWrapper.init_connection_stateNc             C   s   t  |  j  S)N)FormatStylePlaceholderCursorrq   )r8   r   r   r   r   rj     s    zDatabaseWrapper.create_cursorc          	   C   s1   |  j  d  k	 r- t    |  j  j   SWd  QRXd  S)N)rq   r1   rr   )r8   r   r   r   _commit  s    
zDatabaseWrapper._commitc             C   s9   |  j  r5 |  j j d d |  j j |  d d i  d  S)NZsqlz-- RELEASE SAVEPOINT %s (faked)timez0.000)Zqueries_loggedZqueries_logappendopsZ
quote_name)r8   Zsidr   r   r   _savepoint_commit  s    		z!DatabaseWrapper._savepoint_commitc          	   C   s!   |  j   | |  j _ Wd  QRXd  S)N)Zwrap_database_errorsrq   
autocommit)r8   rz   r   r   r   _set_autocommit%  s    
zDatabaseWrapper._set_autocommitc             C   s*   |  j    j d  |  j    j d  d S)zl
        Check constraints by setting them to immediate. Return them to deferred
        afterward.
        zSET CONSTRAINTS ALL IMMEDIATEzSET CONSTRAINTS ALL DEFERREDN)r5   rk   )r8   Ztable_namesr   r   r   check_constraints)  s    z!DatabaseWrapper.check_constraintsc             C   s5   y |  j  j   Wn t j k
 r, d SYn Xd Sd  S)NFT)rq   Zpingr+   Error)r8   r   r   r   	is_usable1  s
    	zDatabaseWrapper.is_usablec             C   s>   |  j    + t d d   |  j j j d  D  SWd  QRXd  S)Nc             s   s   |  ] } t  |  Vq d  S)N)r[   )rK   r0   r   r   r   	<genexpr><  s    z1DatabaseWrapper.oracle_version.<locals>.<genexpr>.)Ztemporary_connectionr/   rq   versionsplit)r8   r   r   r   oracle_version9  s    zDatabaseWrapper.oracle_version)rA   rB   rC   )/r<   r=   r>   vendorZdisplay_nameZ
data_typesZdata_type_check_constraintsZ_limited_data_typesr2   r3   rm   rn   Zpattern_escZ_pattern_opsitemsrp   ro   r+   r&   ZSchemaEditorClassr!   Zclient_classr"   Zcreation_classr#   Zfeatures_classr$   Zintrospection_classr%   Z	ops_classr(   Zvalidation_classrR   r\   r_   rb   r   rf   rs   rj   ru   ry   r{   r|   r~   r
   r   r   r   )rW   r   r?   ^   s   					(r?   c               @   s%   e  Z d  Z d Z d d d  Z d S)OracleParama  
    Wrapper object for formatting parameters for Oracle. If the string
    representation of the value is large enough (greater than 4000 characters)
    the input size needs to be set as CLOB. Alternatively, if the parameter
    has an `input_size` attribute, then the value of the `input_size` attribute
    will be used instead. Otherwise, no input size will be set for the
    parameter when executing the query.
    Fc             C   s^  t  j r: t | t j  r: t | t  r: t j |  } d } | d k rU d } n | d k rg d } t | d  r | j |  |  _ nl t | t	 j
 t j f  r | |  _ nE t | | j |  |  _ t |  j t  r t t | | j |   } t | d  r| j |  _ nE | d k r0t	 j |  _ n* t | t j  rQt	 j |  _ n	 d  |  _ d  S)Nr   Tr    Fbind_parameter
input_sizei  )r   rl   
isinstancedatetimer'   Zfrom_datetimer.   r   r   r+   Binary	timedeltar	   charsetstrlenr   ZCLOBr@   )r8   paramr5   Zstrings_onlyZstring_sizer   r   r   rR   I  s,    	zOracleParam.__init__N)r<   r=   r>   __doc__rR   r   r   r   r   r   ?  s   r   c               @   sF   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z d
 S)VariableWrappera	  
    An adapter class for cursor variables that prevents the wrapped object
    from being converted into a string when used to instantiate an OracleParam.
    This can be used generally for any other object that should be passed into
    Cursor.execute as-is.
    c             C   s   | |  _  d  S)N)var)r8   r   r   r   r   rR   u  s    zVariableWrapper.__init__c             C   s   |  j  S)N)r   )r8   r5   r   r   r   r   x  s    zVariableWrapper.bind_parameterc             C   s   t  |  j |  S)N)getattrr   )r8   keyr   r   r   __getattr__{  s    zVariableWrapper.__getattr__c             C   s3   | d k r | |  j  | <n t |  j | |  d  S)Nr   )r7   setattrr   )r8   r   r   r   r   r   __setattr__~  s    zVariableWrapper.__setattr__N)r<   r=   r>   r   rR   r   r   r   r   r   r   r   r   m  s
   r   c               @   s   e  Z d  Z d Z d Z d d   Z e d d    Z e d d    Z e d	 d
    Z	 d d   Z
 d d   Z d d   Z d d d  Z d d d  Z d d d  Z d d   Z d d   Z d d   Z d d    Z d! d"   Z d S)#rt   z
    Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var"
    style. This fixes it -- but note that if you want to use a literal "%s" in
    a query, you'll need to use "%%s".
    zutf-8c             C   s"   | j    |  _  |  j |  j  _ d  S)N)r5   _output_type_handlerZoutputtypehandler)r8   rq   r   r   r   rR     s    z%FormatStylePlaceholderCursor.__init__c             C   s#   d |  k r t  j |   St |   S)Nr   )decimalDecimalr[   )r   r   r   r   _output_number_converter  s    z5FormatStylePlaceholderCursor._output_number_converterc                sN   | d k r t  St j d |     t j d  j |      f d d   S)Nr   Zprecr    c                s   t  j |   j  d   S)Ncontext)r   r   Zquantize)rM   )r   quantize_valuer   r   <lambda>  s    zEFormatStylePlaceholderCursor._get_decimal_converter.<locals>.<lambda>)r[   r   ZContextr   Zscaleb)	precisionscaler   )r   r   r   _get_decimal_converter  s
    z3FormatStylePlaceholderCursor._get_decimal_converterc             C   s   | t  j k r | d k r< | d k r3 t j } qf t } n* | d k r] t j | |  } n	 t j } |  j t  j d d d |  j d | Sd S)	zx
        Called for each db column fetched from cursors. Return numbers as the
        appropriate Python type.
           r   size   	arraysizeoutconverterNi)	r+   NUMBERrt   r   floatr   r   STRINGr   )r5   r   ZdefaultTypelengthr   r   r   r   r   r   r     s    				z1FormatStylePlaceholderCursor._output_type_handlerc                sW   y!   f d d   | j    D SWn/ t k
 rR t   f d d   | D  SYn Xd  S)Nc                s+   i  |  ]! \ } } t  |   d   |  q S)T)r   )rK   rL   rM   )r8   r   r   rN     s   	 z?FormatStylePlaceholderCursor._format_params.<locals>.<dictcomp>c             3   s!   |  ] } t  |   d   Vq d S)TN)r   )rK   p)r8   r   r   r     s    z>FormatStylePlaceholderCursor._format_params.<locals>.<genexpr>)r   r4   r/   )r8   paramsr   )r8   r   _format_params  s    !z+FormatStylePlaceholderCursor._format_paramsc             C   s   t  | d d  rs i  } xA | D]9 } x0 | j   D]" \ } } | j r3 | j | | <q3 Wq  W| r |  j |   nn d  g t | d  } xA | D]9 } x0 t |  D]" \ } } | j r | j | | <q Wq W| r |  j |   d  S)Nr   keys)r.   r   r   Zsetinputsizesr   	enumerate)r8   Zparams_listZsizesr   rL   r   ir   r   r   _guess_input_sizes  s    		z/FormatStylePlaceholderCursor._guess_input_sizesc             C   s;   t  | d  r& d d   | j   D Sd d   | D Sd  S)Nr   c             S   s"   i  |  ] \ } } | j  |  q Sr   )r   )rK   rL   rM   r   r   r   rN     s   	 zAFormatStylePlaceholderCursor._param_generator.<locals>.<dictcomp>c             S   s   g  |  ] } | j   q Sr   )r   )rK   r   r   r   r   
<listcomp>  s   	 zAFormatStylePlaceholderCursor._param_generator.<locals>.<listcomp>)r.   r   )r8   r   r   r   r   _param_generator  s    z-FormatStylePlaceholderCursor._param_generatorFc                s'  | j  d  s | j  d  r. | d  d  } | d  k rC g  } n t | d  rr d d   | D } | | } n | r | r d d   t t j |   D     f d d	   | D } d
 d     j   D } | t |  } n/ d d	   t t |   D } | t |  } | |  j	 |  f S)N;/r    r   c             S   s   i  |  ] } d  | |  q S)z:%sr   )rK   rL   r   r   r   rN     s   	 z@FormatStylePlaceholderCursor._fix_for_params.<locals>.<dictcomp>c             S   s#   i  |  ] \ } } d  | |  q S)z:arg%dr   )rK   r   r   r   r   r   rN     s   	c                s   g  |  ] }   |  q Sr   r   )rK   r   )params_dictr   r   r     s   	 z@FormatStylePlaceholderCursor._fix_for_params.<locals>.<listcomp>c             S   s   i  |  ] \ } } | |  q Sr   r   )rK   r   r   r   r   r   rN     s   	 c             S   s   g  |  ] } d  |  q S)z:arg%dr   )rK   r   r   r   r   r     s   	 )
rJ   r.   r   dictfromkeysr   r/   ranger   r   )r8   queryr   unify_by_valuesr-   r   )r   r   _fix_for_params  s     		z,FormatStylePlaceholderCursor._fix_for_paramsNc             C   s_   |  j  | | d d \ } } |  j | g  t   ! |  j j | |  j |   SWd  QRXd  S)Nr   T)r   r   r1   r5   rk   r   )r8   r   r   r   r   r   rk     s    
z$FormatStylePlaceholderCursor.executec                s   | s
 d  St  |  }   j | t |   \ } } | g   f d d   | D }   j |  t   +   j j |   f d d   | D  SWd  QRXd  S)Nc                s   g  |  ] }   j  |   q Sr   )r   )rK   r   )r8   r   r   r     s   	 z<FormatStylePlaceholderCursor.executemany.<locals>.<listcomp>c                s   g  |  ] }   j  |   q Sr   )r   )rK   r   )r8   r   r   r     s   	 )iterr   nextr   r1   r5   executemany)r8   r   r   Zparams_iterZfirstparams	formattedr   )r8   r   r     s     
z(FormatStylePlaceholderCursor.executemanyc             C   s-   y |  j  j   Wn t j k
 r( Yn Xd  S)N)r5   r6   r+   ZInterfaceError)r8   r   r   r   r6     s    z"FormatStylePlaceholderCursor.closec             G   s   t  |  j j |    S)N)r   r5   r   )r8   r-   r   r   r   r     s    z FormatStylePlaceholderCursor.varc             G   s   t  |  j j |    S)N)r   r5   arrayvar)r8   r-   r   r   r   r     s    z%FormatStylePlaceholderCursor.arrayvarc             C   s   t  |  j |  S)N)r   r5   )r8   attrr   r   r   r   "  s    z(FormatStylePlaceholderCursor.__getattr__c             C   s   t  |  j  S)N)r   r5   )r8   r   r   r   __iter__%  s    z%FormatStylePlaceholderCursor.__iter__)r<   r=   r>   r   r   rR   staticmethodr   r   r   r   r   r   r   rk   r   r6   r   r   r   r   r   r   r   r   rt     s"   !"rt   )r   r   )r   zTRUE)0r   r   r   r   r   
contextlibr   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backends.base.baser   Zdjango.utils.asyncior   Zdjango.utils.encodingr   r	   Zdjango.utils.functionalr
   r   Z	cx_Oracler+   r   r   clientr!   Zcreationr"   rU   r#   Zintrospectionr$   
operationsr%   Zschemar&   r'   Z
validationr(   r1   r2   r?   r   r   rt   r   r   r   r   <module>   sD   
#.