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.