From ba57083204d5b74926bfb7671edfbddca4fcb5c7 Mon Sep 17 00:00:00 2001 From: Anthony Tuininga Date: Fri, 28 May 2021 15:00:33 -0600 Subject: [PATCH 1/6] Update ODPI-C to 4.2.1 in preparation for releasing cx_Oracle 8.2.1. --- doc/src/conf.py | 2 +- doc/src/release_notes.rst | 8 ++++++++ odpi | 2 +- setup.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/src/conf.py b/doc/src/conf.py index 92389cd..bfb5a13 100644 --- a/doc/src/conf.py +++ b/doc/src/conf.py @@ -42,7 +42,7 @@ # The short X.Y version. version = '8.2' # The full version, including alpha/beta/rc tags. -release = '8.2.0' +release = '8.2.1' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index 72891fd..12be751 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -7,6 +7,14 @@ cx_Oracle Release Notes For any deprecations, see :ref:`Deprecations `. +Version 8.2.1 (June 2021) +------------------------- + +#) Updated embedded ODPI-C to `version 4.2.1 + `__. + + Version 8.2 (May 2021) ---------------------- diff --git a/odpi b/odpi index 5574630..9f4744f 160000 --- a/odpi +++ b/odpi @@ -1 +1 @@ -Subproject commit 5574630dcf41ce0c09124059b8ee2ba5bc07efb9 +Subproject commit 9f4744fd2591f0274ae8c2bbc2a8bce8def6e11c diff --git a/setup.py b/setup.py index 53c5afc..381d4cf 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ pkg_resources.require("setuptools>=40.6.0") # define build constants -BUILD_VERSION = "8.2.0" +BUILD_VERSION = "8.2.1" # setup extra link and compile args extra_link_args = [] From acd1709eb16d41cc7459a31c242c53c54f619cf2 Mon Sep 17 00:00:00 2001 From: Anthony Tuininga Date: Fri, 28 May 2021 15:01:28 -0600 Subject: [PATCH 2/6] Fix a typo in one of the comments. --- src/cxoConnection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cxoConnection.c b/src/cxoConnection.c index 474c45a..b394993 100644 --- a/src/cxoConnection.c +++ b/src/cxoConnection.c @@ -623,7 +623,7 @@ static int cxoConnection_init(cxoConnection *conn, PyObject *args, // determine if session callback should be invoked; this takes place if // the connection is newly created by the pool or if the requested tag - // does not match the actal tag + // does not match the actual tag invokeSessionCallback = 0; if (dpiCreateParams.outNewSession || dpiCreateParams.outTagLength != params.tagBuffer.size || From 7c51c67179c1375150b236ed3102e77de88a3b83 Mon Sep 17 00:00:00 2001 From: Anthony Tuininga Date: Fri, 28 May 2021 15:02:28 -0600 Subject: [PATCH 3/6] Fixed crash when using the deprecated parameter name keywordParameters with Cursor.callproc(); added to test suite to verify deprecations. --- doc/src/release_notes.rst | 3 +++ src/cxoCursor.c | 3 ++- test/test_1200_cursor.py | 30 ++++++++++++++++++++++++++++++ test/test_2400_session_pool.py | 17 +++++++++++++++++ test/test_2700_aq.py | 8 ++++++++ test/test_3000_subscription.py | 15 +++++++++++++++ 6 files changed, 75 insertions(+), 1 deletion(-) diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index 12be751..2783c32 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -13,6 +13,9 @@ Version 8.2.1 (June 2021) #) Updated embedded ODPI-C to `version 4.2.1 `__. +#) Fixed crash when using the deprecated parameter name `keywordParameters` + with :meth:`Cursor.callproc()`. +#) Improved test suite. Version 8.2 (May 2021) diff --git a/src/cxoCursor.c b/src/cxoCursor.c index 170b224..e3a02a0 100644 --- a/src/cxoCursor.c +++ b/src/cxoCursor.c @@ -1263,7 +1263,8 @@ static PyObject *cxoCursor_callProc(cxoCursor *cursor, PyObject *args, // parse arguments listOfArguments = keywordArguments = keywordArgumentsDeprecated = NULL; if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "O|OOO", keywordList, - &name, &listOfArguments, &keywordArguments)) + &name, &listOfArguments, &keywordArguments, + &keywordArgumentsDeprecated)) return NULL; if (keywordArgumentsDeprecated) { if (keywordArguments) { diff --git a/test/test_1200_cursor.py b/test/test_1200_cursor.py index c663345..b28733f 100644 --- a/test/test_1200_cursor.py +++ b/test/test_1200_cursor.py @@ -1001,5 +1001,35 @@ def test_1284_parse_dml(self): self.assertEqual(self.cursor.statement, sql) self.assertEqual(self.cursor.description, None) + def test_1285_executemany_with_plsql_binds(self): + "1285 - test executing plsql statements multiple times (with binds)" + var = self.cursor.var(int, arraysize=5) + self.cursor.setinputsizes(var) + data = [[25], [30], [None], [35], [None]] + exepected_data = [25, 30, None, 35, None] + self.cursor.executemany("declare t number; begin t := :1; end;", data) + self.assertEqual(var.values, exepected_data) + + def test_1286_encodingErrors_deprecation(self): + "1286 - test to verify encodingErrors is deprecated" + errors = 'strict' + self.assertRaises(oracledb.ProgrammingError, self.cursor.var, + oracledb.NUMBER, encoding_errors=errors, + encodingErrors=errors) + + def test_1287_keywordParameters_deprecation(self): + "1287 - test to verify keywordParameters is deprecated" + out_value = self.cursor.var(oracledb.NUMBER) + kwargs = dict(a_OutValue=out_value) + self.assertRaises(oracledb.ProgrammingError, self.cursor.callproc, + "proc_Test", ("hi", 5), kwargs, + keywordParameters=kwargs) + extra_amount = self.cursor.var(oracledb.NUMBER) + extra_amount.setvalue(0, 5) + kwargs = dict(a_ExtraAmount=extra_amount, a_String="hi") + self.assertRaises(oracledb.ProgrammingError, self.cursor.callfunc, + "func_Test", oracledb.NUMBER, [], kwargs, + keywordParameters=kwargs) + if __name__ == "__main__": test_env.run_test_cases() diff --git a/test/test_2400_session_pool.py b/test/test_2400_session_pool.py index 0344b7f..c674a45 100644 --- a/test/test_2400_session_pool.py +++ b/test/test_2400_session_pool.py @@ -441,5 +441,22 @@ def test_2417_setting_each_pool_param(self): self.assertEqual(pool.stmtcachesize, 25, "stmtcachesize (25)") self.assertEqual(pool.ping_interval, 25, "ping_interval (25)") + def test_2418_deprecations(self): + "2418 - test to verify deprecations" + callback = "pkg_SessionCallback.TheCallback" + self.assertRaises(oracledb.ProgrammingError, test_env.get_pool, + min=1, max=2, increment=1, wait_timeout=10, + waitTimeout=10) + self.assertRaises(oracledb.ProgrammingError, test_env.get_pool, + min=1, max=2, increment=1, max_lifetime_session=20, + maxLifetimeSession=20) + self.assertRaises(oracledb.ProgrammingError, test_env.get_pool, + min=1, max=2, increment=1, max_sessions_per_shard=1, + maxSessionsPerShard=1) + self.assertRaises(oracledb.ProgrammingError, test_env.get_pool, + min=2, max=8, increment=3, + getmode=oracledb.SPOOL_ATTRVAL_NOWAIT, + session_callback=callback, sessionCallback=callback) + if __name__ == "__main__": test_env.run_test_cases() diff --git a/test/test_2700_aq.py b/test/test_2700_aq.py index b01f428..54741e4 100644 --- a/test/test_2700_aq.py +++ b/test/test_2700_aq.py @@ -371,5 +371,13 @@ def test_2715_enqueue_transformation(self): otherPrice = book.PRICE self.assertEqual(otherPrice, expectedPrice) + def test_2716_payloadType_deprecation(self): + "2716 - test to verify payloadType is deprecated" + self.__clear_books_queue() + books_type = self.connection.gettype(self.book_type_name) + self.assertRaises(oracledb.ProgrammingError, self.connection.queue, + self.book_queue_name, books_type, + payloadType=books_type) + if __name__ == "__main__": test_env.run_test_cases() diff --git a/test/test_3000_subscription.py b/test/test_3000_subscription.py index 7eb5e4c..8f8592e 100644 --- a/test/test_3000_subscription.py +++ b/test/test_3000_subscription.py @@ -119,5 +119,20 @@ def test_3000_subscription(self): (test_env.get_main_user(), test_env.get_connect_string()) self.assertEqual(str(sub), expected) + def test_3001_deprecations(self): + "3001 - test to verify deprecations" + connection = test_env.get_connection(threaded=True, events=True) + self.assertRaises(oracledb.ProgrammingError, connection.subscribe, + ip_address='www.oracle.in', + ipAddress='www.oracle.in') + self.assertRaises(oracledb.ProgrammingError, connection.subscribe, + grouping_class=1, groupingClass=1) + self.assertRaises(oracledb.ProgrammingError, connection.subscribe, + grouping_value=3, groupingValue=3) + self.assertRaises(oracledb.ProgrammingError, connection.subscribe, + grouping_type=2, groupingType=2) + self.assertRaises(oracledb.ProgrammingError, connection.subscribe, + client_initiated=True, clientInitiated=True) + if __name__ == "__main__": test_env.run_test_cases() From 4ca3dfda5350417fc65776962f35484b59485cf1 Mon Sep 17 00:00:00 2001 From: Anthony Tuininga Date: Fri, 28 May 2021 15:02:54 -0600 Subject: [PATCH 4/6] Use PEP 8 variable names. --- doc/src/user_guide/bind.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/src/user_guide/bind.rst b/doc/src/user_guide/bind.rst index 27fbfc1..5ba4303 100644 --- a/doc/src/user_guide/bind.rst +++ b/doc/src/user_guide/bind.rst @@ -724,11 +724,11 @@ statement can be built up as follows: .. code-block:: python - bindValues = ["Gates", "Marvin", "Fay"] - bindNames = [":" + str(i + 1) for i in range(len(bindValues))] + bind_values = ["Gates", "Marvin", "Fay"] + bind_names = [":" + str(i + 1) for i in range(len(bind_values))] sql = "select employee_id, first_name, last_name from employees " + \ - "where last_name in (%s)" % (",".join(bindNames)) - cursor.execute(sql, bindValues) + "where last_name in (%s)" % (",".join(bind_names)) + cursor.execute(sql, bind_values) for row in cursor: print(row) From 76b855e98fc665b52eea4339646d39e6ec8dd718 Mon Sep 17 00:00:00 2001 From: Anthony Tuininga Date: Tue, 1 Jun 2021 11:46:00 -0600 Subject: [PATCH 5/6] Update SODA documentation. --- doc/src/api_manual/soda.rst | 71 +++++++++++++++++++++++++------------ doc/src/user_guide/soda.rst | 28 +++++++-------- 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/doc/src/api_manual/soda.rst b/doc/src/api_manual/soda.rst index f71d06f..1e4baf7 100644 --- a/doc/src/api_manual/soda.rst +++ b/doc/src/api_manual/soda.rst @@ -256,11 +256,16 @@ SODA Collection Object The hint parameter, if specified, supplies a hint to the database when processing the SODA operation. This is expected to be a string in the same - format as SQL hints but without any comment characters, for example - ``hint="MONITOR"``. While you could use this to pass any SQL hint, the - hints ``MONITOR`` (turn on monitoring) and ``NO_MONITOR`` (turn off - monitoring) are the most useful. Use of the hint parameter requires Oracle - Client 21.3 or higher (or Oracle Client 19 from 19.11). + format as a SQL hint but without any comment characters, for example + ``hint="MONITOR"``. Pass only the hint ``"MONITOR"`` (turn on monitoring) + or ``"NO_MONITOR"`` (turn off monitoring). See the Oracle Database SQL + Tuning Guide documentation `MONITOR and NO_MONITOR Hints + `__ + and `Monitoring Database Operations + `__ + for more information. .. note:: @@ -270,7 +275,8 @@ SODA Collection Object .. versionchanged:: 8.2 - The parameter `hint` was added. + The parameter `hint` was added. Use of the hint parameter requires + Oracle Client 21.3 or higher (or Oracle Client 19 from 19.11). .. method:: SodaCollection.insertOne(doc) @@ -290,17 +296,23 @@ SODA Collection Object The hint parameter, if specified, supplies a hint to the database when processing the SODA operation. This is expected to be a string in the same - format as SQL hints but without any comment characters, for example - ``hint="MONITOR"``. While you could use this to pass any SQL hint, the - hints ``MONITOR`` (turn on monitoring) and ``NO_MONITOR`` (turn off - monitoring) are the most useful. Use of the hint parameter requires Oracle - Client 21.3 or higher (or Oracle Client 19 from 19.11). + format as a SQL hint but without any comment characters, for example + ``hint="MONITOR"``. Pass only the hint ``"MONITOR"`` (turn on monitoring) + or ``"NO_MONITOR"`` (turn off monitoring). See the Oracle Database SQL + Tuning Guide documentation `MONITOR and NO_MONITOR Hints + `__ + and `Monitoring Database Operations + `__ + for more information. .. versionadded:: 7.0 .. versionchanged:: 8.2 - The parameter `hint` was added. + The parameter `hint` was added. Use of the hint parameter requires + Oracle Client 21.3 or higher (or Oracle Client 19 from 19.11). .. attribute:: SodaCollection.metadata @@ -343,11 +355,16 @@ SODA Collection Object The hint parameter, if specified, supplies a hint to the database when processing the SODA operation. This is expected to be a string in the same - format as SQL hints but without any comment characters, for example - ``hint="MONITOR"``. While you could use this to pass any SQL hint, the - hints ``MONITOR`` (turn on monitoring) and ``NO_MONITOR`` (turn off - monitoring) are the most useful. Use of the hint parameter requires Oracle - Client 21.3 or higher (or Oracle Client 19 from 19.11). + format as a SQL hint but without any comment characters, for example + ``hint="MONITOR"``. Pass only the hint ``"MONITOR"`` (turn on monitoring) + or ``"NO_MONITOR"`` (turn off monitoring). See the Oracle Database SQL + Tuning Guide documentation `MONITOR and NO_MONITOR Hints + `__ + and `Monitoring Database Operations + `__ + for more information. This method requires Oracle Client 19.9 or higher in addition to the usual SODA requirements. @@ -356,7 +373,8 @@ SODA Collection Object .. versionchanged:: 8.2 - The parameter `hint` was added. + The parameter `hint` was added. Use of the hint parameter requires + Oracle Client 21.3 or higher (or Oracle Client 19 from 19.11). .. method:: SodaCollection.truncate() @@ -565,15 +583,22 @@ SODA Operation Object .. method:: SodaOperation.hint(value) Specifies a hint that will be provided to the SODA operation when it is - performed. This is expected to be a string in the same format as SQL hints - but without any comment characters. While you could use this to pass any SQL - hint, the hints ``MONITOR`` (turn on monitoring) and ``NO_MONITOR`` (turn - off monitoring) are the most useful. Use of this method requires Oracle - Client 21.3 or higher (or Oracle Client 19 from 19.11). + performed. This is expected to be a string in the same format as a SQL hint + but without any comment characters, for example ``hint("MONITOR")``. Pass + only the hint ``"MONITOR"`` (turn on monitoring) or ``"NO_MONITOR"`` (turn + off monitoring). See the Oracle Database SQL Tuning Guide documentation + `MONITOR and NO_MONITOR Hints + `__ + and `Monitoring Database Operations + `__ + for more information. As a convenience, the SodaOperation object is returned so that further criteria can be specified by chaining methods together. + Use of this method requires Oracle Client 21.3 or higher (or Oracle Client + 19 from 19.11). + .. versionadded:: 8.2 diff --git a/doc/src/user_guide/soda.rst b/doc/src/user_guide/soda.rst index 552aa6e..490cafc 100644 --- a/doc/src/user_guide/soda.rst +++ b/doc/src/user_guide/soda.rst @@ -130,18 +130,6 @@ SODA metadata can be cached to improve the performance of :meth:`SodaDatabase.openCollection()` by reducing :ref:`round-trips ` to the database. Caching is available with Oracle Client 21.3 (or later). The feature is also available in Oracle Client 19 from 19.11 onwards. -Note: if collection metadata changes are made externally, the cache can become -invalid. If this happens, the cache can be cleared by calling -:meth:`SessionPool.reconfigure()` with ``soda_metadata_cache`` set to `False`, -or by setting the attribute :attr:`SessionPool.soda_metadata_cache` to `False`. -A second call to ``reconfigure()`` or a direct setting of the -``soda_metadata_cache`` attribute can then be performed to re-enable the cache. - -Caching can be enabled for pooled connections but not standalone -connections. Applications using standalone connections should retain and reuse -the :ref:`collection ` returned from ``createCollection()`` or -``openCollection()`` wherever possible, instead of making repeated calls to -those methods. The metadata cache can be turned on when creating a connection pool with :meth:`cx_Oracle.SessionPool()`. Each pool has its own cache: @@ -153,8 +141,13 @@ The metadata cache can be turned on when creating a connection pool with dsn="dbhost.example.com/orclpdb1", soda_metadata_cache=True) -Note the cache is not used by ``createCollection()`` when explicitly passing -metadata. In this case, instead of using only ``createCollection()`` and +The cache is not available for standalone connections. Applications using these +should retain and reuse the :ref:`collection ` returned from +``createCollection()`` or ``openCollection()`` wherever possible, instead of +making repeated calls to those methods. + +The cache is not used by ``createCollection()`` when explicitly passing +metadata. In this case, instead of using only ``createCollection()`` and relying on its behavior of opening an existing collection like: .. code-block:: python @@ -173,6 +166,13 @@ you will find it more efficient to use logic similar to: collection = soda.createCollection("mycollection", mymetadata) collection.insertOne(mycontent) +If collection metadata changes are made externally, the cache can become +invalid. If this happens, the cache can be cleared by calling +:meth:`SessionPool.reconfigure()` with ``soda_metadata_cache`` set to `False`, +or by setting the attribute :attr:`SessionPool.soda_metadata_cache` to `False`. +Use a second call to ``reconfigure()`` or set ``soda_metadata_cache`` to +re-enable the cache. + Committing SODA Work ==================== From 3cfa06383593aefd2272e579f1555f253beebf66 Mon Sep 17 00:00:00 2001 From: Anthony Tuininga Date: Tue, 1 Jun 2021 11:47:31 -0600 Subject: [PATCH 6/6] Update ODPI-C and tweak release notes in preparation for release of cx_Oracle 8.2.1. --- doc/src/release_notes.rst | 9 +++++++-- odpi | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index 2783c32..e4d8267 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -12,10 +12,15 @@ Version 8.2.1 (June 2021) #) Updated embedded ODPI-C to `version 4.2.1 `__. + version-4-2-1-june-1-2021>`__. +#) Added support for caching the database version in pooled connections with + Oracle Client 19 and earlier (later Oracle Clients handle this caching + internally). This optimization eliminates a round-trip previously often + required when reusing a pooled connection. +#) Fixed a regression with error messages when creating a connection fails. #) Fixed crash when using the deprecated parameter name `keywordParameters` with :meth:`Cursor.callproc()`. -#) Improved test suite. +#) Improved documentation and the test suite. Version 8.2 (May 2021) diff --git a/odpi b/odpi index 9f4744f..e2e5f7a 160000 --- a/odpi +++ b/odpi @@ -1 +1 @@ -Subproject commit 9f4744fd2591f0274ae8c2bbc2a8bce8def6e11c +Subproject commit e2e5f7ad1a17ee12b8055709326bd3c394cc94c8