o 3aX @sdZddlZddlZddlZddlZddlmZddlmZddl m Z ddl m Z ddl mZddlmZdd lmZmZdd lmZd d Zed dgzddlZWneyfZze dedZ[wwddlmZddlmZddlm Z ddl!m"Z"ddl#m$Z$ddl%m&Z&ddl'm(Z(m)Z)ddl*m+Z+eddZ,GdddZ-GdddeZ.Gdd d Z/Gd!d"d"Z0Gd#d$d$Z1dS)%ze Oracle database backend for Django. Requires cx_Oracle: https://oracle.github.io/python-cx_Oracle/ N)contextmanager)settings)ImproperlyConfigured)IntegrityError)BaseDatabaseWrapper) async_unsafe) force_bytes force_str)cached_propertyc Cs|tdr6zddl}Wnty!}ztd|d}~ww|d}|D] \}}|||q)dSt j |dS)NCYGWINrz_Error loading ctypes: %s; the Oracle backend requires ctypes to operate correctly under Cygwin.kernel32) platformsystemupper startswithctypes ImportErrorrCDLLSetEnvironmentVariableAosenvironupdate)rrer namevaluer@/usr/lib/python3/dist-packages/django/db/backends/oracle/base.py_setup_environments   r)NLS_LANGz .AL32UTF8)ORA_NCHAR_LITERAL_REPLACETRUEz"Error loading cx_Oracle module: %s)DatabaseClient)DatabaseCreation)DatabaseFeatures)DatabaseIntrospection)DatabaseOperations)DatabaseSchemaEditor)Oracle_datetimedsn)DatabaseValidationc csvzdVWdStjy:}z&|jd}t|dr5t|dr5|jdkr5d|jvs.d|jvr5tt|jd}~ww)Nrcodemessagei+z ORA-02291z ORA-00001)Database DatabaseErrorargshasattrr+r,rtuple)rxrrrwrap_oracle_errors?s   r3c@seZdZdddZdS)!_UninitializedOperatorsDescriptorNcCs&|durtd||jdS)Nz*operators not available as class attribute operators)AttributeErrorcursorclose__dict__)selfinstanceclsrrr__get__[s  z)_UninitializedOperatorsDescriptor.__get__N)__name__ __module__ __qualname__r=rrrrr4Ysr4cseZdZdZdZiddddddd d d d d ddddddddd dd dddddddddd d!d"d ddddd d#dddd$d%d& Zd'd(d'd)d)d)d*Zd+ZeZ d,d-d.d/d0d1d2d3d.d.d/d/d4 Z ie d5d6d5d5d6d6d7Z d8Z d9d:d;dd?Z d@dAe DZdBdAe DZeZeZeZeZeZeZeZeZfdCdDZ dEdFZ!e"dGdHZ#dIdJZ$e"d\dLdMZ%dNdOZ&dPdQZ'dRdSZ(d\dTdUZ)dVdWZ*e+dXdYZ,e+dZd[Z-Z.S)]DatabaseWrapperoracleOracle AutoFieldz3NUMBER(11) GENERATED BY DEFAULT ON NULL AS IDENTITY BigAutoFieldz3NUMBER(19) GENERATED BY DEFAULT ON NULL AS IDENTITY BinaryFieldBLOB BooleanFieldz NUMBER(1) CharFieldzNVARCHAR2(%(max_length)s) DateFieldDATE DateTimeField TIMESTAMP DecimalFieldz*NUMBER(%(max_digits)s, %(decimal_places)s) DurationFieldzINTERVAL DAY(9) TO SECOND(6) FileField FilePathField FloatFieldzDOUBLE PRECISION IntegerFieldz NUMBER(11) JSONFieldNCLOBBigIntegerFieldz NUMBER(19)IPAddressFieldz VARCHAR2(15)GenericIPAddressFieldz VARCHAR2(39)z2NUMBER(5) GENERATED BY DEFAULT ON NULL AS IDENTITYzVARCHAR2(%(max_length)s)z VARCHAR2(32)) NullBooleanField OneToOneFieldPositiveBigIntegerFieldPositiveIntegerFieldPositiveSmallIntegerField SlugFieldSmallAutoFieldSmallIntegerField TextField TimeFieldURLField UUIDFieldz%(qn_column)s IN (0,1)z%(qn_column)s IS JSONz%(qn_column)s >= 0)rIrUrZr\r]r^)clobnclobblobz= %sz = UPPER(%s)zFLIKE TRANSLATE(%s USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS)zMLIKE UPPER(TRANSLATE(%s USING NCHAR_CS)) ESCAPE TRANSLATE('\' USING NCHAR_CS)z> %sz>= %sz< %sz<= %s) exactiexactcontains icontainsgtgteltlterendswith istartswith iendswithzLIKEC %s ESCAPE '\'zLIKEC UPPER(%s) ESCAPE '\')rkrlrrqrrrsz@REPLACE(REPLACE(REPLACE({}, '\', '\\'), '%%', '\%%'), '_', '\_')z'%%' || {} || '%%'z'%%' || UPPER({}) || '%%'z {} || '%%'zUPPER({}) || '%%'z '%%' || {}z'%%' || UPPER({}))rkrlrrrrqrscCi|] \}}|d|dqS)zLIKE TRANSLATE( z5 USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS)r.0kvrrr szDatabaseWrapper.cCrt)zLIKEC z ESCAPE '\'rrurrrryscs0tj|i||jddd}||j_dS)NOPTIONSuse_returning_intoT)super__init__ settings_dictgetfeaturescan_return_columns_from_insert)r:r/kwargsr{ __class__rrr}s zDatabaseWrapper.__init__cCs |jd}d|vr|d=|S)Nrzr{)r~copyr: conn_paramsrrrget_connection_paramssz%DatabaseWrapper.get_connection_paramscCs*tjd|jd|jdt|jd|S)NUSERPASSWORD)userpasswordr)r)r-connectr~r)rrrrget_new_connectionsz"DatabaseWrapper.get_new_connectioncCs|}|d|dtjrdnd|d|jvrO|}z|d|jddgWntjyB|j |_ |j |_ Yn w|j|_ |j |_ |d |j_|s]|dSdS) 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'r5z!SELECT 1 FROM DUAL WHERE DUMMY %srkX) create_cursorexecuterUSE_TZr8r9_standard_operatorsr-r._likec_operatorsr5_likec_pattern_ops pattern_ops_standard_pattern_ops connection stmtcachesizeget_autocommitcommitr:r7rrrinit_connection_states6     z%DatabaseWrapper.init_connection_stateNcC t|jSr>)FormatStylePlaceholderCursorr)r:rrrrrs zDatabaseWrapper.create_cursorcCsB|jdurt |jWdS1swYdSdSr>)rr3rr:rrr_commits $zDatabaseWrapper._commitcCs,|jr|jd|j|dddSdS)Nz-- RELEASE SAVEPOINT %s (faked)z0.000)sqltime)queries_logged queries_logappendops quote_name)r:sidrrr_savepoint_commits  z!DatabaseWrapper._savepoint_commitcCs4|j ||j_WddS1swYdSr>)wrap_database_errorsr autocommit)r:rrrr_set_autocommit&s "zDatabaseWrapper._set_autocommitcCsB|}|d|dWddS1swYdS)zl Check constraints by setting them to immediate. Return them to deferred afterward. zSET CONSTRAINTS ALL IMMEDIATEzSET CONSTRAINTS ALL DEFERREDN)r7r)r: table_namesr7rrrcheck_constraints*s   "z!DatabaseWrapper.check_constraintscCs(z|jWdStjyYdSw)NFT)rpingr-Errorrrrr is_usable3s  zDatabaseWrapper.is_usablecCstddtjdDS)Ncs|]}t|VqdSr>intrvr2rrr =z4DatabaseWrapper.cx_oracle_version...)r1r-versionsplitrrrrcx_oracle_version;z!DatabaseWrapper.cx_oracle_versioncCsH|tdd|jjdDWdS1swYdS)Ncsrr>rrrrrrBrz1DatabaseWrapper.oracle_version..r)temporary_connectionr1rrrrrrroracle_version?s $zDatabaseWrapper.oracle_versionr>)/r?r@rAvendor display_name data_typesdata_type_check_constraints_limited_data_typesr4r5rr pattern_esc _pattern_opsitemsrrr-r'SchemaEditorClassr" client_classr#creation_classr$features_classr%introspection_classr& ops_classr*validation_classr}rrrrrrrrrrr rr __classcell__rrrrrBfs          (    rBc@seZdZdZdddZdS) 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. FcCstjrt|tjrt|tst|}d}|durd}n|dur"d}t|dr.|||_n$t|t j tj fr;||_nt ||j ||_t|jtrRtt||j |}t|dr]|j|_dS|dkrgt j|_dSt|tjrst j|_dSd|_dS)NrTr!Fbind_parameter input_sizei)rr isinstancedatetimer( from_datetimer0rrr-Binary timedeltar charsetstrlenrCLOBrN)r:paramr7 strings_only string_sizerrrr}Os.         zOracleParam.__init__NF)r?r@rA__doc__r}rrrrrEs rc@s0eZdZdZddZddZddZdd Zd 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. cCs ||_dSr>var)r:rrrrr}{ zVariableWrapper.__init__cCs|jSr>rrrrrr~szVariableWrapper.bind_parametercC t|j|Sr>)getattrr)r:keyrrr __getattr__ zVariableWrapper.__getattr__cCs(|dkr ||j|<dSt|j||dS)Nr)r9setattrr)r:rrrrr __setattr__szVariableWrapper.__setattr__N)r?r@rArr}rrrrrrrrss  rc@seZdZdZdZddZeddZeddZed d Z d d Z d dZ ddZ d#ddZ d$ddZd$ddZddZddZddZdd Zd!d"ZdS)%rz 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". zutf-8cCs||_|j|j_dSr>)r7_output_type_handleroutputtypehandler)r:rrrrr}s z%FormatStylePlaceholderCursor.__init__cCsd|vr t|St|S)Nr)decimalDecimalr)rrrr_output_number_converterrz5FormatStylePlaceholderCursor._output_number_convertercs8|dkrtStj|dtd| fddS)Nr)precr!cst|jdS)N)context)rrquantize)rxrquantize_valuerrzEFormatStylePlaceholderCursor._get_decimal_converter..)rrContextrscaleb) precisionscalerrr_get_decimal_converters  z3FormatStylePlaceholderCursor._get_decimal_convertercCs^|tjkr-|dkr|dkrtj}nt}n|dkrt||}ntj}|jtjd|j|dSdS)zx Called for each db column fetched from cursors. Return numbers as the appropriate Python type. ir)size arraysize outconverterN) r-NUMBERrrfloatrrSTRINGr)r7r defaultTypelengthrrrrrrrs z1FormatStylePlaceholderCursor._output_type_handlercsBz fdd|DWSty tfdd|DYSw)Ncsi|] \}}|t|dqS)Trrurrrrysz?FormatStylePlaceholderCursor._format_params..c3s|] }t|dVqdS)TNrrvprrrrsz>FormatStylePlaceholderCursor._format_params..)rr6r1r:paramsrrr_format_paramss  z+FormatStylePlaceholderCursor._format_paramscCst|ddr-i}|D]}|D] \}}|jr|j||<qq |r+|jdi|dSdSdgt|d}|D]}t|D] \}}|jrJ|j||<q>q8|rU|j|dSdS)Nrkeysr)r0rr setinputsizesr enumerate)r: params_listsizesr rwrirrr_guess_input_sizess*  z/FormatStylePlaceholderCursor._guess_input_sizescCs*t|drdd|DSdd|DS)NrcSsi|]\}}||jqSrrrurrrryszAFormatStylePlaceholderCursor._param_generator..cSsg|]}|jqSrrr rrr szAFormatStylePlaceholderCursor._param_generator..)r0rr rrr_param_generators z-FormatStylePlaceholderCursor._param_generatorFcs|ds |dr|dd}|durg}nKt|dr(dd|D}||}n:|rQ|rQddtt|Dfdd |D}d dD}|t|}nd d tt|D}|t|}|| |fS) N;/rcSsi|]}|d|qS)z:%sr)rvrwrrrryz@FormatStylePlaceholderCursor._fix_for_params..cSsi|] \}}|d|qSz:arg%dr)rvrrrrrryscsg|]}|qSrr)rvr params_dictrrrrz@FormatStylePlaceholderCursor._fix_for_params..cSsi|]\}}||qSrr)rvrrrrrryrcSsg|]}d|qSrr)rvrrrrrr) rqr0rdictfromkeysrr1rangerr )r:queryr unify_by_valuesr/rrr_fix_for_paramss"     z,FormatStylePlaceholderCursor._fix_for_paramsNcCs^|j||dd\}}||gt|j|||WdS1s(wYdS)NT)r#)r$rr3r7rr)r:r"r rrrrs  $z$FormatStylePlaceholderCursor.executecs|sdSt|}|t|\}}|gfdd|D}|tj|fdd|DWdS1s?wYdS)Ncg|]}|qSr)r r rrrrrz.cr%r)rr rrrrr)iterr$nextrr3r7 executemany)r:r"r  params_iter firstparams formattedrrrr( s $z(FormatStylePlaceholderCursor.executemanycCs(z|jWdStjyYdSwr>)r7r8r-InterfaceErrorrrrrr8s z"FormatStylePlaceholderCursor.closecGt|jj|Sr>)rr7rr:r/rrrr"z FormatStylePlaceholderCursor.varcGr-r>)rr7arrayvarr.rrrr0%r/z%FormatStylePlaceholderCursor.arrayvarcCrr>)rr7)r:attrrrrr(rz(FormatStylePlaceholderCursor.__getattr__cCrr>)r&r7rrrr__iter__+rz%FormatStylePlaceholderCursor.__iter__rr>)r?r@rArrr} staticmethodrrrr rrr$rr(r8rr0rr2rrrrrs*      "  r)2rrrrr contextlibr django.confrdjango.core.exceptionsr django.dbrdjango.db.backends.base.baserdjango.utils.asynciordjango.utils.encodingrr django.utils.functionalr r cx_Oracler-rrclientr"creationr#rr$ introspectionr% operationsr&schemar'utilsr(r) validationr*r3r4rBrrrrrrrsP                  `.