OpenADS Release Notes
Complete history of releases with categorized improvements.
v1.8.96 — 2026-08-21
New Features
remote_only_access = logaudit mode (Pritpal Bedi) — deny mode (1) raises the RTE wherever the first local open happens, and an app whose error handler itself opens tables via ADSCDX dies from Harbour error-handler recursion (“recursive call” error). The newlog(or2) mode writes aLOCALACCESS="OPEN|CREATE" ASKED="..." VIA=LOCALline to the audit console /log_fileand lets the access proceed, so the full inventory of legacy local paths is collected in one run before switching to deny mode.
v1.8.95 — 2026-08-20
New Features
- Client settings in
openads.ini(Pritpal Bedi) — everyOPENADS_*client setting now also reads fromopenads.ini(env var wins):remote_only_access,resolve_verbose,log,log_file,trace,wire_trace,arc_trace,tls_insecure,adi_v2,adt_cdx_index. The client DLL looks for the file next to itself, then in the app working directory;OPENADS_INIpoints at an explicit path. The file is re-read when it changes. Seeopenads.ini.sample.
v1.8.94 — 2026-08-20
New Features
OPENADS_REMOTE_ONLY_ACCESS=1client guard (Pritpal Bedi) — remote-only deployments can now forbid legacy local-path access through ACE. With the env var set on the client process, a localAdsOpenTable/AdsCreateTablefails withAE_ACCESS_DENIED(rddads raises a Harbour runtime error) instead of silently reading/writing a.dbfnext to the app. Remote and SQL-backend connections are unaffected, as is local I/O through another RDD. See Migrating from ADS.
v1.8.93 — 2026-08-19
New Features
OAds_Mutex*Harbour wrappers — the server-side distributed mutex service (v1.8.92, remote connections only) is now callable from Harbour PRG code without RDDADS viacontrib/oads_hb/oads_hb.c:OAds_MutexCreate( [hConn], cName ),OAds_MutexLock( [hConn], cName, nTimeoutMs ),OAds_MutexTryLock( [hConn], cName ),OAds_MutexUnlock( [hConn], cName ),OAds_MutexDestroy( [hConn], cName ). OmittinghConnuses the default connection set withOAds_SetConnection()(Pritpal Bedi).
Documentation
- API reference — new section 26 “Distributed Mutex (server-side,
remote only)” with the Harbour signatures;
last_updatedtimestamp added to the front matter.
v1.8.89 — 2026-08-17
New Features
- Process-wide audit sequence — each
RESOLVEDline is nowCONN ENTRY SEQ TIMESTAMP ….ENTRYstill restarts per connection;SEQis a single incrementing number for the process so two connections no longer look like a repeated counter (Pritpal Bedi).
v1.8.88 — 2026-08-17
Bug Fixes
oads_hb.cincludes"ace.h"— Harbour drop-in glue now uses the same header ascontrib/rddads, so it compiles in a consumer project without editing the file each time (Pritpal Bedi).
Packaging
- Windows ZIP names — only
openads-<ver>-windows-x64.zip/windows-x86.zip. The parallel*-win-*.zipslim kit is no longer published (it was a differentace64.dlland confused downloads).
v1.8.87 — 2026-08-17
New Features
- Resolve audit trail — every table-path resolve is a fixed-width
line (
CONN6 ENTRY8 TIMESTAMP RESOLVED=... asked=... via=local|remote). Console default is onlyRESOLVED. SetOPENADS_RESOLVE_VERBOSE=1for detail lines;OPENADS_LOG_FILEstores onlyRESOLVED(Pritpal Bedi).
Bug Fixes
- Remote is safe storage — a remote-server connection no longer
opens a leftover host-absolute path.
--legacy-pathsremounts under--data; otherwise the open fails with the normal RDD error (Pritpal Bedi).
v1.8.79 — 2026-08-15
New Features
-
Connection switching + optional hConn for OAds_F* —
OAds_SetConnection( hConn )sets the thread-local default connection;OAds_GetConnection()retrieves it. AllOAds_F*Harbour functions (OAds_FOpen,OAds_FCreate,OAds_CheckExistence,OAds_DeleteFile,OAds_RenameFile,OAds_GetFileSize,OAds_GetFileDate,OAds_GetFileTime,OAds_DirMake,OAds_DirRemove,OAds_DirExist,OAds_Directory,OAds_FExist) now accept hConn as optional. When omitted, the thread-local default is used. Backward compatible — existing code passing hConn continues to work.Use case: single-connection apps set the default once; multi-connection apps switch via
OAds_SetConnection(hConn)before each call — handy for transparent backup across two endpoints.
Bug Fixes
- macOS build —
arc2_stamp()now useslocaltime_ron POSIX (was Windows-onlylocaltime_s); trace log uses/tmp/ace_calls.logon POSIX.AE_NO_MATCHING_FILE(5059) added to the error enum.
v1.8.78 — 2026-08-15
New Features
- Multi-port server — A single
openads_serverdinstance can now listen on multiple TCP ports, each with its own data directory. Configure additional ports with[port:NNNN]sections inopenads.ini, each specifying adatapath. Matches LetoDB’sPort=/DataPath=capability: one process, one config file, multiple logical servers.
Bug Fixes
- CDX index corruption on record update (macOS) —
sync_all_indexes_()silently discarded the B-tree erase result when updating a record, so the old index entry stayed in the tree and the new entry was inserted on top — creating duplicate/stale keys that corrupted B-tree separators. The erase error is now propagated so the caller can abort before inserting. For fresh appends, the blank-key snapshot (fields not yet set) is tolerated because those keys were never inserted. (Commitdf9c2cc.)
Tests
abi_alternating_append_test: 4 cases — alternating local/remote appends maintain all CDX tag keys.abi_adt_scope_validation_test: M5 stress append + index order + memo round-trip.- Full unit suite: 524/524 on Windows, same on macOS.
v1.8.77 — 2026-08-14
Bug Fixes
- Remote
ordListClear()+ordListAdd()left the workarea without an order — The client-side remoteAdsCloseAllIndexesclosed the indexes on the server but never invalidated the cached tag/handle map in the ACE client DLL. The nextAdsOpenIndex/SET ORDER TOreused dead server wire-ids (SetOrder5000 on run 2) or found no order at all (ADSCDX/301 “Workarea not indexed” ondbSeekon run 1). The client cache is now dropped on close-all. (Reported by Pritpal Bedi — Harbour 32-bitTestIndexes().) OrdCount()stale afterOrdCreate()without reopen — The remote create path never registered the new tag in the client’s index handle list, soAdsGetNumIndexes/AdsGetIndexHandlelagged until close+reopen. After a successfulcreate_indexthe client now refreshes the whole bag from the server (ADS semantics: creating a tag opens every tag in the bag), in bag order. (Reported by Pritpal Bedi.)- x86
openads_serverdcrashed at startup —dll_probe_acecalledAdsGetVersionthrough a mismatched calling convention whenever anace32.dll/openace32.dllsat next to the exe. The probe now identifies OpenADS builds via the OpenADS-onlyoads_*exports before calling anything, and calls__cdecl. (Reported by Pritpal Bedi: “Server does not launch”.) - x86 undecorated exports restored to the
__cdeclimplementations (v1.8.74 behavior) — The stdcall rework had aliased the plainAdsXxxexport names to the__stdcallwrappers, so__cdeclcallers (FWH apps such asB_BIG.exe,GetProcAddressprobes, Xbase++) crashed withACCESS_VIOLATIONon the first ACE call (ADS_GETFUNCTABLE). The plain names now target the__cdeclimplementations again;_AdsXxx@Nremains on the__stdcallwrappers. (Reported by Pritpal Bedi.) - Release CI unblocked — C4100 in
AdsFindNextTable/AdsFindClose(MSVC/WX), UUID buffer worst-case%llxsizing (clang-Wformat-truncation), and sign-conversion casts insession.cpptransaction dispatch (clang-Wsign-conversion).
Tests
abi_remote_index_reopen_test: 2 cases — remoteordListClear+ordListAddleaves a usable order (created bag and auto-opened bag variants).- Fixed iterator-of-two-temporaries UB in
abi_server_fs_test/abi_remote_index_reopen_test(flakyvector too long). - Import libraries under
dist/import-libsregenerated from the current DLLs.
v1.8.75 — 2026-08-13
New Features
- ADS-compatible replication (Phase 1) — One-way async replication between OpenADS servers via publications, articles, and subscriptions. The DataDict now supports
Publication,Article, andSubscriptionobject types with full CRUD and round-trip persistence. A durable CRC-32C queue (ReplQueue) captures INSERT/UPDATE/DELETE mutations through best-effort capture hooks, andrepl_apply_once()drains the queue to apply changes to a local target table. 35 unit tests (464 assertions). - M12.33 remote FindTables —
AdsOpenTableand the serverOpenTabledispatcher now striptcp://host:port/URI prefixes that legacy Delphi TAdsTable components embed in table names.
Tests
repl_queue_test: 10 cases — append, read_from, CRC corruption, empty filerepl_catalog_test: 8 cases — DD round-trip, table_is_published, cascade, rejectsabi_repl_capture_test: 1 case — capture hooks fire on INSERT/UPDATE/DELETErepl_apply_test: 23 cases — subscription resolution, INSERT/UPDATE/DELETE apply, mixed batches, idempotency, last_lsn persistence, error paths
v1.8.74 — 2026-08-12
Bug Fixes
- INDEX ON bag remounted through table’s connection —
AdsCreateIndex61/AdsCreateIndex/AdsOpenIndexnow remount the index bag through the table’s connection the same way as the.dbf. FixesINDEX ONwriting.z01next to the app while the.dbfremounted under--legacy-paths. - Explicit local Connection handle no longer hijacked — An explicit local
Connectionhandle is no longer hijacked by “any liveRemoteConnection” (in-process server ABI twin + mixed local/remote apps).
Tests
AdsCreateIndex61 remounts client-absolute .z01 under legacy_pathsremote INDEX ON remounts client-absolute .z01 under legacy-paths jail
v1.8.73 — 2026-08-12
Bug Fixes
--legacy-pathsnow remounts every client-absolute path under--data— Previously, host files that already existed outside--datacould still be opened. Every client-absolute open/create now remounts under--datafirst; the host-absolute OPEN/CREATE exceptions apply only in strict mode.
Documentation
- Documented the
--data/ URI /--legacy-pathscontract (forward slashes recommended) incookbook/docs/local-and-remote.mdandconnection-strings.md.
Tests
session_connection_test: host-absolute file outside the jail must not win whenlegacy_pathsis on.abi_mt_create_vs_dbfcdx_test: Harbour helpers are Windows-only so clang-Werror(Linux/macOS) does not fail on unused stubs.
v1.8.72 — 2026-08-11
Performance
- ADSCDX multi-thread create ~30x faster than Harbour DBFCDX — Measured on 40 tables / 4 threads, 10 rows + 3-tag CDX each:
- Harbour DBFCDX: ~4 s (baseline)
- OpenADS ADSCDX: ~0.13 s (~30x faster)
- Harbour ADSCDX (rddads): ~0.15 s (~27x faster)
- No per-op FlushFileBuffers — Default is page-write only; set
OPENADS_FSYNC=1to restore the old power-fail-safe path. - AdsCreateIndex61 no longer holds state().mu across bulk build — Only index_bindings_mu around map mutations, so multi-thread INDEX ON scales.
- CDX write-lock wait uses a condition variable — Not 100 us poll; always releases the batch join on flush error paths.
Tests
abi_mt_create_vs_dbfcdx_test.cpp— every ADSCDX speed run paired with a Harbour DBFCDX baseline.- Build harness:
tests/unit/build_mt_create_bench.bat.
v1.8.68 — 2026-08-09
Bug Fixes
- clang
-Werrorbuild breaks in new test files — Two unused-code warnings (lambda capture, helper functions) failed macOS/Linux CI builds. No product code changes beyond the warning fixes; supersedes v1.8.67 on POSIX.
v1.8.67 — 2026-08-09
Bug Fixes
- CDX B+tree Harbour-exact (key, recno) ordering — Insert descent now compares full (key, recno) pairs. Separators are refreshed on every max-pair change, on insert and on erase.
- Two multithreading defects fixed — CDX write-lock batch now has an owner thread; remote
AdsOpenIndexhandle array overflow fixed. - DBF headers now byte-identical with Harbour DBFCDX — Header length
32 + 32*n + 2with 2-byte terminator. Production-index flag set when CDX bag shares table’s basename.
Tests
cdx_dup_key_split_test: independent raw-page decoder asserting parent-separator == child-max.abi_alternating_append_test: two local connections and a remote server + local client alternating duplicate-key bursts.
v1.8.66 — 2026-08-08
Bug Fixes
- Multi-tag CDX bags: creation and binding — Legacy
AdsCreateIndexno longer truncates the bag when adding a second tag.AdsOpenIndexnow binds all tags regardless of handle array size. - DBF record-count race under concurrent mixed writers —
refresh_record_count_now takes the max of header and size-derived counts.
v1.8.65 — 2026-08-07
Bug Fixes (POSIX)
- SIGPIPE guard —
sock_send()withMSG_NOSIGNALon Linux;SO_NOSIGPIPEon macOS. - ADT byte-lock offset wrap — Offsets ≥ 2^63 folded into positive range.
- CDX write-lock registry per-file mutex — Each
.cdxpath serialises on its own entry mutex.
v1.8.64 — 2026-08-07
Bug Fixes
- Harbour DBFCDX interop: shared-index visibility — Peer CDX updates now detected via file-header version counter.
- Physical write guard (GoHot) — Shared-mode writes require RLock / FLock / exclusive.
- Index corruption under mixed ADS/DBFCDX writers — Lock offsets aligned with Harbour DBFCDX VFP scheme.
v1.8.63 — 2026-08-07
Bug Fixes
- Remote
keynostale after APPEND/WRITE/DELETE/RECALL —keyno_validand prefetch/BOF-EOF flags now cleared.
v1.8.62 — 2026-08-07
Performance
- Server-side
GetKeyNumvia CDX O(1) cache — New wire opcodesGetKeyNum/GetKeyNumAck(0x03/0x04). - Same-record
GotoRecordpreserves keyno —TXBrowse:Refresh()after remote APPEND stays O(1).
v1.8.61 — 2026-08-07
Bug Fixes
- CDX tag-header update counter endianness — Now big-endian to match Harbour DBFCDX.
v1.8.60 — 2026-08-06
Bug Fixes
- CDX page allocator tail reset after recreate — Prevents ~10x sparse-file bloat.
v1.8.59 — 2026-08-05
Performance
- Legacy ADI
CREATE INDEXbottom-up bulk pack — Index ~49% smaller (73,216 → 37,376 bytes for 10,000 keys).
v1.8.58 — 2026-08-05
Documentation
- Error log vs transaction journal paths — Documented
ads_err.dbflocation and relocation options.
v1.8.57 — 2026-08-05
New Features
- ADI v2 tags — Compound/computed/FOR on ADT tables.
AdsGetKeyCountmemoise — Performance improvement.- ADT read-ahead — Prefetch optimization.
- PACK truncate — Efficient table compaction.
v1.8.56 — 2026-08-05
Bug Fixes
- CDX numeric leaves type-dependent trail byte — NUL for FoxNumeric, matching DBFCDX density.
v1.8.55 — 2026-08-04
New Features
- SAP date display format —
AdsGetFieldformatted vsAdsGetStringraw. - Join/union/aggregate temps are ADT — Temporary tables use ADT format.
v1.8.54 — 2026-08-04
Bug Fixes
- Connect no longer fails when data root is not writable — e.g.
--data "C:\".
v1.8.53 — 2026-08-03
Bug Fixes
legacy_pathsremote create/reindex — Fixed un-flagged ABI twin usage.- Drive-letter routing for whole-filesystem servers —
--data "C:\;D:\;E:\".
v1.8.52 — 2026-08-03
New Features
legacy_pathsserver mode — Zero-change ERP ports with absolute path remapping.
v1.8.51 — 2026-08-02
Bug Fixes
- x86
ace32.dllexports cdecl aliases — For MinGW rddads compatibility.
v1.8.50 — 2026-08-01
Bug Fixes
- Empty AOF visible-set returns Limbo —
AdsSeekLastpositions correctly. - AOF index selection — Fixed.
- ADI keycount fix — Fixed.
v1.8.49 — 2026-08-01
Bug Fixes
- Write coalescing broke rollback/CDX/AFTER triggers — Fixed.
- Remote ADT numeric round-trip encoding — Fixed.
v1.8.48 — 2026-08-01
Bug Fixes
- 32-bit toolchain:
ace.h__stdcallon MSVC x86 — All in-tree tools link against exported stdcall names.
v1.8.47 — 2026-08-01
Bug Fixes
- Remote
AtBOF/AtEOFanswered from wrong cursor — Fixed. - Row trailer at BOF fixed phantom duplicate row — Fixed.
v1.8.46 — 2026-08-01
Bug Fixes
DbSetOrder(0)restores natural order — Fixed.- ace32.dll exports stdcall
@Nnames — Fixed. - ADSHANDLE 32-bit — Fixed.
v1.8.45 — 2026-07-31
Bug Fixes
- Remote
KeyNo/RelKeyPosclamps to scope-aware key count — Eliminates phantom rows in xBrowse.
For the full commit-by-commit history see the CHANGELOG.