Architecture
OpenADS is a five-layer system. Each layer is a swap-out point that an application or test can hit independently.
L1 ABI extern "C" Ads* exports
(ace32/64.dll, libace.so/.dylib)
L2 Session Connection / Statement / HandleRegistry / Tx
L3 SQL engine Lexer → Parser → Resolver → Planner → Executor
AEP host, xBase UDFs
L4 Engine core Table / Index / MemoStore / Cursor / LockMgr
TxLog (WAL) / Catalog
L5 Platform File / mmap / byte-range locks / sockets / DLL
Win32 + POSIX implementations
Layer responsibilities
| Layer | What it owns |
|---|---|
| L1 | The only module with a C ABI. Translates Ads* calls into the internal C++ API; converts ACE error codes to/from util::Error; performs OEM / ANSI / UTF-8 / UTF-16 conversions. |
| L2 | Per-connection state — opened tables, prepared SQL statements, transaction stack, AEP procedure registry, encryption key. |
| L3 | Full Advantage SQL dialect — boolean WHERE trees, joins (INNER / LEFT / RIGHT / FULL OUTER), subqueries (correlated + uncorrelated), GROUP BY + HAVING, UNION, window functions, CTEs, CASE, scalar / aggregate / arithmetic projection. |
| L4 | Format-agnostic engine — Table, Index, MemoStore, Cursor, LockMgr, TxLog, Catalog. The Driver trait is the extension point for new file formats. |
| L5 | Cross-platform OS abstraction (Win32 + POSIX). |
Drivers (L4 extension point)
AdtDriver .adt + .adm + .adi (proprietary ADS — out of scope)
CdxDriver .dbf + .cdx + .fpt (FoxPro)
NtxDriver .dbf + .ntx + .dbt (Clipper)
VfpDriver .dbf + .cdx + .fpt (Visual FoxPro variants)
Each driver implements the same trait, so Table::open(path)
returns a polymorphic handle the rest of L4 / L3 doesn’t have
to specialise on.
Phase 2 server
openads_serverd runs L2–L5 in-process and exposes them over
the OpenADS-native wire protocol on a TCP port. The same DLL
that talks to a local data dir can also speak to a remote
openads_serverd via a tcp://host:port/<dir> URI — see
Wire protocol for the on-the-wire bytes.
Phase 2 Studio (web console)
When the daemon is built with OPENADS_WITH_HTTP=ON, an
embedded HTTP server (cpp-httplib) serves a single-page admin
UI on a separate port. Each REST request opens a short-lived
ABI connection, so the web console is just another consumer
of the public ABI — same as a Harbour app.