Version bump (2026.05.02 → 2026.05.04) reflects the library reaching
feature completeness across Phases 1-16.
Documentation:
* README.md — full rewrite. The previous README was from Phase 1
("cursor() / execute() / fetchone() arrive in Phase 2"). New
README covers: sync + async APIs, connection pool, TLS, full type
matrix, smart-LOBs, fast-path RPC, server-compatibility,
development workflow, and pointers to the protocol research docs.
* docs/USAGE.md — new practical recipe guide. Connecting, cursor
lifecycle, parameter binding, transactions (logged + unlogged),
executemany, smart-LOB read/write, connection pool, async,
TLS, error handling, fast-path RPC, server-side setup steps,
and a migration table from IfxPy / legacy informixdb.
* CHANGELOG.md — new file. Captures the v2026.05.04 release as the
Phase 1-16 completion milestone with a full feature inventory
and known-gap list. Future point-releases append here.
Classifiers updated:
* Development Status: 2 → 4 (Pre-Alpha → Beta)
* Added Framework :: AsyncIO
Keywords: added asyncio, async.
No code changes; tests still pass (69 unit + 163 integration = 232).
Ruff clean.
3.8 KiB
3.8 KiB
Changelog
All notable changes to informix-db. Versioning is CalVer — YYYY.MM.DD for date-based releases, YYYY.MM.DD.N for same-day post-releases per PEP 440.
2026.05.04 — Library completion
The Phase 0 ambition — first pure-Python Informix SQLI driver — reaches feature completeness. Adds async, TLS, connection pool, smart-LOBs, fast-path RPC, composite UDTs.
Added
- Async API (
informix_db.aio) —AsyncConnection,AsyncCursor,AsyncConnectionPoolfor FastAPI / aiohttp / asyncio. Each blocking I/O call is offloaded to a worker thread viaasyncio.to_thread; event loop never blocks. - Connection pool (
informix_db.create_pool) — thread-safe with min/max sizing, lazy growth, health-check on acquire, error-aware eviction. - TLS —
tls=Truefor self-signed dev servers,tls=ssl.SSLContextfor production. Wrapping happens inIfxSocketso the rest of the protocol layer is unaware. - Smart-LOBs (BLOB / CLOB) — full read/write end-to-end via
cursor.read_blob_column()/cursor.write_blob_column()using the server'slotofile/filetoblobSQL functions intercepted at theSQ_FILE(98) protocol level. - Legacy in-row blobs (BYTE / TEXT) — bind + read via the
SQ_BBIND/SQ_BLOB/SQ_FETCHBLOBprotocol family. - Fast-path RPC (
Connection.fast_path_call) — direct stored-procedure invocation bypassing PREPARE/EXECUTE; routine handles cached per-connection. - Composite UDT recognition —
ROW,SET,MULTISET,LISTcolumns return typedRowValue/CollectionValuewrappers exposing schema and raw bytes. - Type codecs —
INTERVAL(both DAY-TO-FRACTION and YEAR-TO-MONTH families),DATETIME(all qualifier ranges),DECIMAL/MONEY(BCD with sign+exp head byte and asymmetric base-100 complement for negatives),DATE,BOOL, all integer / float widths,CHAR/VARCHAR/LVARCHAR. - Transactions — implicit
SQ_BEGINbefore each transaction in non-ANSI logged DBs; transparent no-ops on unlogged DBs. - PEP 249 exception hierarchy — server
SQLCODEmapped to the right exception class (IntegrityErrorfor duplicate-key violations,ProgrammingErrorfor syntax errors, etc.).
Documentation
README.md— overview and quick-startdocs/USAGE.md— practical recipes and migration guidedocs/PROTOCOL_NOTES.md— byte-level wire-format referencedocs/DECISION_LOG.md— phase-by-phase architectural decisions, with the why preserveddocs/JDBC_NOTES.md— index into the decompiled IBM JDBC referencedocs/CAPTURES/— annotated socat hex-dump captures
Test coverage
232 tests total: 69 unit + 163 integration. Unit tests run with no external dependencies; integration tests run against the IBM Informix Developer Edition Docker image.
Known gaps (deferred)
- Full ROW/COLLECTION recursive parsing: Phase 12 ships type recognition + raw-bytes wrapper. Parsing the textual representation into typed Python tuples/sets/lists is deferred — most workloads can use SQL projections (
SELECT row_col.fieldname FROM tbl) instead. - UDT parameter encoding for fast-path: scalar params/returns work; passing a 72-byte BLOB locator as a UDT param requires extending the SQ_BIND encoder with the extended_owner/extended_name preamble for type > 18.
- Native async I/O: Phase 16 ships a thread-pool wrapper that's functionally equivalent for typical FastAPI workloads. Native async (asyncpg-style transport abstraction) would be Phase 17 if a real workload needs it.
2026.05.02 — Phase 1: connection lifecycle
Initial release. connect() / close() works end-to-end. Cursor / execute / fetch arrived in Phase 2 (subsequent commits within the same session).