Skip to content

feat(oracledb): finalize advanced surfaces and add native event backends#564

Merged
cofin merged 12 commits into
mainfrom
codex/oracle-advanced-closeout
Jul 1, 2026
Merged

feat(oracledb): finalize advanced surfaces and add native event backends#564
cofin merged 12 commits into
mainfrom
codex/oracle-advanced-closeout

Conversation

@cofin

@cofin cofin commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

Finalizes the Oracle advanced-surface work and adds native Oracle event-channel backends.

Advanced surfaces

  • Add Oracle contract coverage for batch-errors and array DML row-count metadata via per-call StatementConfig.execution_args.
  • Tighten native Oracle pipeline support to async Thin-mode connections on Oracle Database 26ai or newer, with unit coverage for sync, Thick-mode, and pre-26ai rejection plus async Thin 26ai acceptance.

Native event backends (Advanced Queuing + Transactional Event Queues)

  • Repaired the advanced_queue backend. The classic AQ events backend had never been exercised against a live queue — its integration tests silently skipped because the test user was never granted AQ privileges — and it was broken against python-oracledb 4.x. It is now ported to the 4.x AQ API: connection.queue(name, "JSON") for the handle, connection.msgproperties(payload=...) + queue.enqone(message) to enqueue, and in-place queue.deqoptions + queue.deqone() to dequeue.
  • Added a transactional_event_queue backend. A new native backend for Oracle Transactional Event Queues, provisioned with DBMS_AQADM.CREATE_TRANSACTIONAL_EVENT_QUEUE. It shares the classic-AQ client path (subclasses it), so the two backends can't diverge — only the backend label and the provisioning DDL differ.
  • Both backends run in python-oracledb Thin mode with JSON payloads on Oracle 23ai; no Instant Client / Thick mode required. table_queue remains the default backend.
  • Mode-gate guard errors now report the actual backend class name.
  • Documented both backends: selection, Thin mode, the Database 21c+ JSON requirement, DBMS_AQADM privileges, provisioning, and per-channel-queue isolation via the {channel} queue-name template.

Testing

  • Oracle events integration suite passes on the Oracle 23ai container in Thin mode (17 tests): sync + async publish/ack, listen delivery, metadata preservation, and concurrent multi-channel isolation, across both native backends.
  • Unit coverage for backend factory/selection, sync/async mode gates, and the payload envelope round-trip.
  • Advanced-surface contract and pipeline tests as before.
  • make lint and make type-check (mypy + pyright + slotscheck) clean on the changed scope.

Known follow-up

  • The default table_queue backend's integration test connects via a hardcoded DSN instead of the shared container fixture, so it still skips even when the container is running. Tracked separately; not addressed here.

@codecov-commenter

codecov-commenter commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.47368% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.68%. Comparing base (2c89a3f) to head (d3b16b7).

Files with missing lines Patch % Lines
sqlspec/adapters/oracledb/events/backend.py 81.81% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #564      +/-   ##
==========================================
+ Coverage   75.40%   75.68%   +0.27%     
==========================================
  Files         449      449              
  Lines       59979    59986       +7     
  Branches     9144     9144              
==========================================
+ Hits        45226    45398     +172     
+ Misses      11836    11657     -179     
- Partials     2917     2931      +14     
Flag Coverage Δ
integration 59.37% <71.05%> (+0.45%) ⬆️
py3.10 74.08% <89.47%> (+0.27%) ⬆️
py3.11 74.09% <89.47%> (+0.27%) ⬆️
py3.12 74.09% <89.47%> (+0.27%) ⬆️
py3.13 74.09% <89.47%> (+0.27%) ⬆️
py3.14 74.86% <89.47%> (+0.28%) ⬆️
unit 61.81% <65.78%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
sqlspec/adapters/oracledb/config.py 88.46% <100.00%> (ø)
sqlspec/adapters/oracledb/driver.py 67.24% <100.00%> (-1.08%) ⬇️
sqlspec/adapters/oracledb/events/__init__.py 100.00% <ø> (ø)
sqlspec/adapters/oracledb/events/_hub.py 81.86% <100.00%> (+60.10%) ⬆️
sqlspec/adapters/oracledb/events/backend.py 73.91% <81.81%> (+33.07%) ⬆️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cofin cofin changed the title feat(oracledb): finalize advanced surfaces feat(oracledb): finalize advanced surfaces and add native event backends Jul 1, 2026
cofin added 12 commits July 1, 2026 02:59
The advanced_queue backend targeted the legacy cx_Oracle AQ API and never
worked against python-oracledb 4.x. Un-skipping the integration tests (by
granting AQ privileges to the container app user and removing the blanket
skip-on-any-exception) exposed three breaks, now fixed:

- connection.queue() payload type is the string "JSON", not DB_TYPE_JSON
- enqueue builds connection.msgproperties(payload=...) and enqone(message)
- dequeue configures queue.deqoptions in place and calls deqone() with no args

Classic-AQ JSON now round-trips in thin mode on Oracle 23ai.
Adds a distinct transactional_event_queue events backend that shares the
verified classic-AQ client path (queue/enqueue/dequeue) via subclassing, so
the two backends cannot silently diverge. Only the backend label and the
provisioning DDL (DBMS_AQADM.CREATE_TRANSACTIONAL_EVENT_QUEUE) differ.

- OracleEventsBackend literal + docstring gain "transactional_event_queue"
- OracleSync/AsyncTxEventQEventBackend subclass the AQ backends
- create_event_backend factory handles the new literal (sync + async)
- AQ hub takes a backend_name for correct observability labels
…nd-trip

Also makes the backend mode-gate errors class-aware (type(self).__name__) so the
TxEventQ backends report their own name instead of the AQ base class name.
Type the events extension_config dict as dict[str, Any] so the **kwargs
spread is not coerced into the EventsConfig TypedDict, and annotate the
deliberately-mistyped config in the mode-gate guard tests.
@cofin cofin force-pushed the codex/oracle-advanced-closeout branch from 2567e54 to d3b16b7 Compare July 1, 2026 03:03
@cofin cofin marked this pull request as ready for review July 1, 2026 03:14
@cofin cofin merged commit b4a7d05 into main Jul 1, 2026
23 checks passed
@cofin cofin deleted the codex/oracle-advanced-closeout branch July 1, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants