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/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..e4d8267 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -7,6 +7,22 @@ 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 + `__. +#) 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 documentation and the test suite. + + Version 8.2 (May 2021) ---------------------- 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) 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 ==================== diff --git a/odpi b/odpi index 5574630..e2e5f7a 160000 --- a/odpi +++ b/odpi @@ -1 +1 @@ -Subproject commit 5574630dcf41ce0c09124059b8ee2ba5bc07efb9 +Subproject commit e2e5f7ad1a17ee12b8055709326bd3c394cc94c8 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 = [] 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 || 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()