Skip to content

Commit 375c151

Browse files
Added support for Easy Connect strings found in tnsnames.ora files.
1 parent 6e10649 commit 375c151

File tree

4 files changed

+80
-28
lines changed

4 files changed

+80
-28
lines changed

doc/src/release_notes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Thin Mode Changes
1616
#) Added support for Oracle Database 23c feature that can improve the
1717
performance of connection creation by reducing the number of round trips
1818
required for all connections created.
19+
#) Added support for Easy Connect strings found in tnsnames.ora files.
1920
#) Added support for writing UTF-8 encoded bytes to CLOB and NCLOB values and
2021
writing strings to BLOB values in order to be consistent with what is done
2122
for string variables.

src/oracledb/base_impl.pxd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ cdef class ConnectParamsImpl:
414414
cdef object _get_token_expires(self, str token)
415415
cdef str _get_wallet_password(self)
416416
cdef int _parse_connect_string(self, str connect_string) except -1
417+
cdef int _parse_easy_connect_string(self, str connect_string,
418+
object match) except -1
417419
cdef int _process_connect_descriptor(self, dict args) except -1
418420
cdef int _set_access_token(self, object val, int error_num) except -1
419421
cdef int _set_access_token_param(self, object val) except -1

src/oracledb/impl/base/connect_params.pyx

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -350,32 +350,7 @@ cdef class ConnectParamsImpl:
350350
# otherwise, see if the connect string is an EasyConnect string
351351
m = re.search(EASY_CONNECT_PATTERN, connect_string)
352352
if m is not None:
353-
354-
# build up arguments
355-
args = m.groupdict()
356-
connect_string = connect_string[m.end():]
357-
params_pos = connect_string.find("?")
358-
if params_pos >= 0:
359-
params = connect_string[params_pos + 1:]
360-
for part in params.split("&"):
361-
name, value = [s.strip() for s in part.split("=", 1)]
362-
name = name.lower()
363-
name = ALTERNATIVE_PARAM_NAMES.get(name, name)
364-
if value.startswith('"') and value.endswith('"'):
365-
value = value[1:-1]
366-
args[name] = value
367-
368-
# create description list
369-
address = self._default_address.copy()
370-
address.set_from_args(args)
371-
description = self._default_description.copy()
372-
description.set_from_connect_data_args(args)
373-
description.set_from_description_args(args)
374-
description.set_from_security_args(args)
375-
description.children = [AddressList()]
376-
description.children[0].children.append(address)
377-
self.description_list = DescriptionList()
378-
self.description_list.children.append(description)
353+
self._parse_easy_connect_string(connect_string, m)
379354

380355
# otherwise, see if the name is a connect alias in a tnsnames.ora
381356
# configuration file
@@ -386,8 +361,50 @@ cdef class ConnectParamsImpl:
386361
if connect_string is None:
387362
errors._raise_err(errors.ERR_TNS_ENTRY_NOT_FOUND, name=name,
388363
file_name=tnsnames_file.file_name)
389-
_parse_connect_descriptor(connect_string, args)
390-
self._process_connect_descriptor(args)
364+
m = re.search(EASY_CONNECT_PATTERN, connect_string)
365+
if m is not None:
366+
self._parse_easy_connect_string(connect_string, m)
367+
else:
368+
_parse_connect_descriptor(connect_string, args)
369+
self._process_connect_descriptor(args)
370+
371+
cdef int _parse_easy_connect_string(self, str connect_string,
372+
object match) except -1:
373+
"""
374+
Internal method for parsing an Easy Connect string.
375+
"""
376+
cdef:
377+
str params, part, name, value, s
378+
Description description
379+
ssize_t params_pos
380+
Address address
381+
dict args
382+
383+
# determine arguments
384+
args = match.groupdict()
385+
connect_string = connect_string[match.end():]
386+
params_pos = connect_string.find("?")
387+
if params_pos >= 0:
388+
params = connect_string[params_pos + 1:]
389+
for part in params.split("&"):
390+
name, value = [s.strip() for s in part.split("=", 1)]
391+
name = name.lower()
392+
name = ALTERNATIVE_PARAM_NAMES.get(name, name)
393+
if value.startswith('"') and value.endswith('"'):
394+
value = value[1:-1]
395+
args[name] = value
396+
397+
# create description list
398+
address = self._default_address.copy()
399+
address.set_from_args(args)
400+
description = self._default_description.copy()
401+
description.set_from_connect_data_args(args)
402+
description.set_from_description_args(args)
403+
description.set_from_security_args(args)
404+
description.children = [AddressList()]
405+
description.children[0].children.append(address)
406+
self.description_list = DescriptionList()
407+
self.description_list.children.append(description)
391408

392409
cdef int _process_connect_descriptor(self, dict args) except -1:
393410
"""

tests/test_4500_connect_params.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,38 @@ def test_4567(self):
776776
params.set(cclass="")
777777
self.assertEqual(params.cclass, None)
778778

779+
def test_4568(self):
780+
"4568 - test easy connect string with protocol specified"
781+
protocol = "tcp"
782+
host = "my_host_4568"
783+
port = 1668
784+
service_name = "my_service_4568"
785+
connect_string = f"{protocol}://{host}:{port}/{service_name}"
786+
params = oracledb.ConnectParams()
787+
params.parse_connect_string(connect_string)
788+
self.assertEqual(params.protocol, protocol)
789+
self.assertEqual(params.host, host)
790+
self.assertEqual(params.port, port)
791+
self.assertEqual(params.service_name, service_name)
792+
793+
def test_4569(self):
794+
"4569 - test easy connect string in tnsnames.ora"
795+
alias_name = "tns_alias_4569"
796+
host = "my_host4569"
797+
port = 1568
798+
service_name = "my_service_name_4569"
799+
connect_string = f"tcp://{host}:{port}/{service_name}"
800+
alias = f"{alias_name} = {connect_string}"
801+
with tempfile.TemporaryDirectory() as temp_dir:
802+
file_name = os.path.join(temp_dir, "tnsnames.ora")
803+
with open(file_name, "w") as f:
804+
f.write(alias)
805+
params = oracledb.ConnectParams(config_dir=temp_dir)
806+
params.parse_connect_string(alias_name)
807+
self.assertEqual(params.host, host)
808+
self.assertEqual(params.port, port)
809+
self.assertEqual(params.service_name, service_name)
810+
779811

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

0 commit comments

Comments
 (0)