Skip to content

Commit

Permalink
Add new property "instance_name" on connections.
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-tuininga committed Jul 20, 2023
1 parent d195065 commit 3e83ab1
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 3 deletions.
10 changes: 10 additions & 0 deletions doc/src/api_manual/connection.rst
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,16 @@ Connection Attributes
This attribute is an extension to the DB API definition.


.. attribute:: Connection.instance_name

This read-only attribute specifies the Oracle Database instance name
associated with the connection. It is the same value as the SQL expression
``sys_context('userenv', 'instance_name')``.

.. note::

This attribute is an extension to the DB API definition.

.. attribute:: Connection.internal_name

This read-write attribute specifies the internal name that is used by the
Expand Down
4 changes: 4 additions & 0 deletions doc/src/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ Thick Mode Changes
Common Changes
++++++++++++++

#) Added new property :attr:`Connection.instance_name` which provides the
Oracle Database instance name associated with the connection. This is the
same value as the SQL expression
``sys_context('userenv', 'instance_name')``.
#) Added support for automatically retrying a query if the error
``ORA-00932: inconsistent data types`` is raised (which can occur if a
table or view is recreated with a data type that is incompatible with
Expand Down
11 changes: 11 additions & 0 deletions src/oracledb/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,17 @@ def inputtypehandler(self, value: Callable) -> None:
self._verify_connected()
self._impl.inputtypehandler = value

@property
def instance_name(self) -> str:
"""
Returns the instance name associated with the connection. This is the
equivalent of the SQL expression:
sys_context('userenv', 'instance_name')
"""
self._verify_connected()
return self._impl.get_instance_name()

@property
def internal_name(self) -> str:
"""
Expand Down
6 changes: 5 additions & 1 deletion src/oracledb/impl/base/connection.pyx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#------------------------------------------------------------------------------
# Copyright (c) 2020, 2022, Oracle and/or its affiliates.
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
#
# This software is dual-licensed to you under the Universal Permissive License
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
Expand Down Expand Up @@ -223,6 +223,10 @@ cdef class BaseConnImpl:
def get_handle(self):
pass

@utils.CheckImpls("getting the instance name")
def get_instance_name(self):
pass

@utils.CheckImpls("getting the internal name")
def get_internal_name(self):
pass
Expand Down
11 changes: 10 additions & 1 deletion src/oracledb/impl/thick/connection.pyx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#------------------------------------------------------------------------------
# Copyright (c) 2020, 2022, Oracle and/or its affiliates.
# Copyright (c) 2020, 2023, Oracle and/or its affiliates.
#
# This software is dual-licensed to you under the Universal Permissive License
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
Expand Down Expand Up @@ -490,6 +490,15 @@ cdef class ThickConnImpl(BaseConnImpl):
_raise_from_odpi()
return <uint64_t> handle

def get_instance_name(self):
cdef:
uint32_t value_length
const char *value
if dpiConn_getInstanceName(self._handle, &value, &value_length) < 0:
_raise_from_odpi()
if value is not NULL:
return value[:value_length].decode()

def get_internal_name(self):
cdef:
uint32_t value_length
Expand Down
2 changes: 1 addition & 1 deletion src/oracledb/impl/thick/odpi
Submodule odpi updated 78 files
+1 −0 .gitignore
+16 −0 .readthedocs.yaml
+2 −0 doc/requirements.txt
+9 −0 doc/src/.static/custom.css
+51 −0 doc/src/_ext/parameters_table.py
+93 −0 doc/src/_ext/table_with_summary.py
+0 −109 doc/src/_themes/oracle/page.html
+ doc/src/_themes/oracle/static/favicon.ico
+0 −77 doc/src/_themes/oracle/static/theme.css
+0 −28 doc/src/_themes/oracle/theme.conf
+36 −31 doc/src/conf.py
+35 −21 doc/src/enums/dpiAuthMode.rst
+19 −12 doc/src/enums/dpiConnCloseMode.rst
+19 −12 doc/src/enums/dpiCreateMode.rst
+23 −15 doc/src/enums/dpiDeqMode.rst
+20 −14 doc/src/enums/dpiDeqNavigation.rst
+28 −16 doc/src/enums/dpiEventType.rst
+30 −22 doc/src/enums/dpiExecMode.rst
+29 −20 doc/src/enums/dpiFetchMode.rst
+19 −12 doc/src/enums/dpiJsonOptions.rst
+17 −10 doc/src/enums/dpiMessageDeliveryMode.rst
+19 −10 doc/src/enums/dpiMessageState.rst
+55 −38 doc/src/enums/dpiNativeTypeNum.rst
+31 −20 doc/src/enums/dpiOpCode.rst
+121 −123 doc/src/enums/dpiOracleTypeNum.rst
+16 −9 doc/src/enums/dpiPoolCloseMode.rst
+27 −21 doc/src/enums/dpiPoolGetMode.rst
+17 −9 doc/src/enums/dpiPurity.rst
+30 −27 doc/src/enums/dpiShutdownMode.rst
+22 −16 doc/src/enums/dpiSodaFlags.rst
+18 −12 doc/src/enums/dpiStartupMode.rst
+52 −34 doc/src/enums/dpiStatementType.rst
+12 −6 doc/src/enums/dpiSubscrGroupingClass.rst
+15 −7 doc/src/enums/dpiSubscrGroupingType.rst
+16 −10 doc/src/enums/dpiSubscrNamespace.rst
+22 −14 doc/src/enums/dpiSubscrProtocol.rst
+28 −22 doc/src/enums/dpiSubscrQOS.rst
+19 −9 doc/src/enums/dpiTpcBeginFlags.rst
+15 −7 doc/src/enums/dpiTpcEndFlags.rst
+16 −8 doc/src/enums/dpiVisibility.rst
+3 −0 doc/src/enums/index.rst
+986 −670 doc/src/functions/dpiConn.rst
+128 −85 doc/src/functions/dpiContext.rst
+212 −98 doc/src/functions/dpiData.rst
+269 −178 doc/src/functions/dpiDeqOptions.rst
+74 −46 doc/src/functions/dpiEnqOptions.rst
+58 −35 doc/src/functions/dpiJson.rst
+223 −143 doc/src/functions/dpiLob.rst
+307 −201 doc/src/functions/dpiMsgProps.rst
+264 −178 doc/src/functions/dpiObject.rst
+21 −10 doc/src/functions/dpiObjectAttr.rst
+51 −30 doc/src/functions/dpiObjectType.rst
+325 −202 doc/src/functions/dpiPool.rst
+91 −56 doc/src/functions/dpiQueue.rst
+27 −15 doc/src/functions/dpiRowid.rst
+422 −280 doc/src/functions/dpiSodaColl.rst
+34 −19 doc/src/functions/dpiSodaCollCursor.rst
+180 −123 doc/src/functions/dpiSodaDb.rst
+120 −80 doc/src/functions/dpiSodaDoc.rst
+34 −18 doc/src/functions/dpiSodaDocCursor.rst
+528 −351 doc/src/functions/dpiStmt.rst
+29 −16 doc/src/functions/dpiSubscr.rst
+194 −127 doc/src/functions/dpiVar.rst
+3 −0 doc/src/functions/index.rst
+6 −2 doc/src/index.rst
+4 −0 doc/src/releasenotes.rst
+3 −0 doc/src/structs/index.rst
+3 −0 doc/src/unions/index.rst
+16 −11 doc/src/user_guide/data_types.rst
+23 −8 doc/src/user_guide/debugging.rst
+0 −10 doc/src/user_guide/index.rst
+52 −33 doc/src/user_guide/installation.rst
+14 −0 doc/src/user_guide/introduction.rst
+302 −294 doc/src/user_guide/round_trips.rst
+5 −1 include/dpi.h
+14 −1 src/dpiConn.c
+2 −1 src/dpiImpl.h
+4 −5 src/dpiJson.c
3 changes: 3 additions & 0 deletions src/oracledb/impl/thick/odpi.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,9 @@ cdef extern from "impl/thick/odpi/embed/dpi.c":

int dpiConn_getHandle(dpiConn *conn, void **handle) nogil

int dpiConn_getInstanceName(dpiConn *conn, const char **value,
uint32_t *valueLength) nogil

int dpiConn_getInternalName(dpiConn *conn, const char **value,
uint32_t *valueLength) nogil

Expand Down
4 changes: 4 additions & 0 deletions src/oracledb/impl/thin/connection.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ cdef class ThinConnImpl(BaseConnImpl):
str _current_schema
bint _current_schema_modified
str _edition
str _instance_name
str _internal_name
str _external_name
array.array _cursors_to_close
Expand Down Expand Up @@ -350,6 +351,9 @@ cdef class ThinConnImpl(BaseConnImpl):
def get_external_name(self):
return self._external_name

def get_instance_name(self):
return self._instance_name

def get_internal_name(self):
return self._internal_name

Expand Down
2 changes: 2 additions & 0 deletions src/oracledb/impl/thin/messages.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,8 @@ cdef class AuthMessage(Message):
<uint32_t> int(self.session_data["AUTH_SESSION_ID"])
self.conn_impl._serial_num = \
<uint32_t> int(self.session_data["AUTH_SERIAL_NUM"])
self.conn_impl._instance_name = \
self.session_data.get("AUTH_INSTANCENAME")
self.conn_impl._server_version = \
"%d.%d.%d.%d.%d" % self._get_version_tuple(buf)

Expand Down
10 changes: 10 additions & 0 deletions tests/test_1100_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,5 +609,15 @@ def test_1139_invalid_params(self):
self.assertRaisesRegex(oracledb.ProgrammingError, "^DPY-2025:",
oracledb.connect, params={"number": 7})

def test_1140_instance_name(self):
"1140 - test connection instance name"
connection = test_env.get_connection()
cursor = connection.cursor()
cursor.execute("""
select upper(sys_context('userenv', 'instance_name'))
from dual""")
instance_name, = cursor.fetchone()
self.assertEqual(connection.instance_name.upper(), instance_name)

if __name__ == "__main__":
test_env.run_test_cases()

0 comments on commit 3e83ab1

Please sign in to comment.