Migrating from ADS

OpenADS is an open-source, ADS-compatible engine for applications built against the Advantage Database Server (ADS) and the Advantage Client Engine (ACE) API. If your data is DBF/ADT with CDX/NTX/ADI indexes and your app uses rddads, the ACE C API, X#’s AXDBFCDX, or the PHP advantage extension, you can move without rewriting it. This guide maps each piece of an Advantage install to its OpenADS counterpart.

Concept map

Advantage OpenADS Notes
Advantage Database Server (service) openads_serverd TCP server; installs as a Windows Service / Linux systemd / macOS launchd.
Advantage Local Server the engine DLL itself ace64.dll runs the engine in-process; no separate adsloc DLL.
ace32.dll / ace64.dll (client) ace64.dll / ace32.dll (drop-in) Same name, same C ABI. Also shipped as openace64.dll for side-by-side installs.
Advantage Data Architect (ARC) Studio web console Browser UI: tables, SQL, structure, data dictionary. Launch with openads-studio.bat/.sh.
ads.cfg / server settings openads.ini Written by openads_serverd --setup, read with --config.
Data dictionary .add / .ai same .add / .ai Opened and managed natively.
Connection path \\srv\vol\data tcp://srv:6262/data Remote URI; local stays a filesystem path.
Default TCP port 6262 6262 Identical, so keep it — unless ADS still runs on the same host (see below).

Server side — install like the old setup did

The old ADS installer asked for a port, a data folder, a code page and whether to start as a service. OpenADS does the same through a console wizard:

openads_serverd --setup

It writes an openads.ini and, if you ask it to, registers the auto-start service for your platform. Run it later straight from that file:

openads_serverd --config openads.ini

Running OpenADS and ADS on the same machine? Both default to TCP 6262. Either stop the Advantage service first, or give OpenADS another port (port = 6263 in the ini, or --port 6263). The server prints a clear hint if the bind clashes.

Code page. OpenADS serves UTF-8 / CP437 today; a selectable server code page (CP850, Windows-1252) is on the roadmap. If your DBFs are CP850, test a copy before going live.

Rollback to SAP ACE is not automatic. OpenADS writes CDX files in Harbour’s DBFCDX-compatible format (magic RCHB at offset 0x14 in the structure-tag header). SAP ACE does not recognize this layout and returns error 7017 (Corrupt .ADI, .CDX, or .IDX index) on any table whose CDX has been touched by OpenADS. OpenADS reads SAP-built CDX files fine as long as you do not write through OpenADS.

If you may need SAP ACE again later (rollback, mixed environment, or side-by-side benchmarking), either keep the original SAP-built .cdx files backed up before pointing the app at OpenADS, or, after rolling back to SAP, delete the OpenADS-written .cdx files and rebuild all tags under SAP. NTX and ADI indexes follow the same one-way rule once OpenADS has written them.

Client side — point your app at OpenADS

You do not relink for the common case:

  1. Put ace64.dll (32-bit app → ace32.dll) next to your .exe, or on the PATH ahead of any existing copy.
  2. Run the app. rddads / FiveWin / xBase++ binaries that load Advantage by the canonical name now use OpenADS unchanged.

If you link a fresh build, use the import lib for your compiler under lib/ (MSVC, MinGW, Borland). Ordinal-linked legacy binaries: see ordinal-compat.md. RDD specifics: rddads-compat.md.

Remote connections use a URI in place of a UNC path:

AdsConnect60("tcp://dbhost:6262/apps/sales/sales.add",
             user, pass, ADS_REMOTE_SERVER, &hConn);

Legacy absolute paths (legacy_paths)

ERP apps that open tables by absolute local path — USE "E:\CLIENT\FILE.DBF" in Harbour/xHarbour, or full paths from X#/xBase++ — can run unchanged against a single server instance. Start the server with the legacy resolver:

openads_serverd --data E:\ --legacy-paths --port 6262
# or in openads.ini:  legacy_paths = 1

With legacy_paths on, every client-supplied path (tables, indexes, memos, the connect dir itself, and remote file functions) is resolved against the --data roots case-insensitively and ignoring the drive letter:

  • A path that starts with a data root is stripped and re-joined under that root: C:/TEMP/Sub/t.dbf with --data C:\temp serves C:\temp\Sub\t.dbf.
  • Any other absolute path loses its drive letter and is joined under the root: E:\CREATIVE.RAM\C0000001\B5643DS1.dbf serves <root>\CREATIVE.RAM\C0000001\B5643DS1.dbf — so several client folders on the same disk are all served by one root, and the same app binary still runs against local DBFCDX.

Whole-filesystem access on a Windows server: list the drive roots, --data "C:\;D:\;E:\" (ini: data = C:\;D:\;E:\). A drive-root entry routes by its drive letter — E:\... lands under the E: root, D:\... under D: — and files that exist are always opened verbatim first, so a server with the same drive layout as the clients needs no folding at all. When the data root itself is not writable (a drive root for a non-elevated server process), connections still succeed — only transaction journaling is disabled (a notice is logged); tables in writable subfolders work normally. Point the error log at a writable folder separately (error_log_path / --error-log-path); it is not the same as the tx journal. Details: Error log and journal paths.

Default is off (strict SAP-compatible resolution). This works for Windows clients against Windows, Linux, or macOS servers.

Client-side guard: OPENADS_REMOTE_ONLY_ACCESS

The mirror image of legacy_paths, on the client. In a remote-only deployment a table opened by local path through ace64.dll/ace32.dll means the app bypassed the server — usually a misconfiguration that silently reads/writes a file next to the app instead of the shared data. Set this on the client process to turn that silent drift into an error:

set OPENADS_REMOTE_ONLY_ACCESS=1
rem or, in an openads.ini next to ace64.dll/ace32.dll (or in the app
rem working directory, or pointed to by OPENADS_INI):
rem   remote_only_access = 1

The environment variable wins over the ini key. The same dual env/ini mechanism covers the other client settings — resolve_verbose, log, log_file, trace, wire_trace, arc_trace, tls_insecure, adi_v2, adt_cdx_index (see openads.ini.sample).

With it on, any AdsOpenTable / AdsCreateTable that would hit the local filesystem (in-process ADS_LOCAL_SERVER connection) fails with AE_ACCESS_DENIED — rddads surfaces it as a Harbour runtime error, so the offending USE is caught immediately instead of writing a stray local .dbf. Remote (tcp:///tls://) and SQL-backend (sqlite://, postgresql://, …) connections are unaffected, and so is any local I/O done through another RDD (e.g. DBFCDX), which never goes through this DLL.

Start with log mode. Deny mode raises the RTE wherever the first local open happens — if your app’s error handler itself opens tables via ADSCDX, the RTE inside the handler recurses and Harbour kills the process (“recursive call” error). Set remote_only_access = log (or 2) instead: every local open/create is written to the audit log as a LOCALACCESS="OPEN|CREATE|OPENIDX" ASKED="..." VIA=LOCAL line (console, or log_file / OPENADS_LOG_FILE) and allowed to proceed, so you get the full inventory of offending paths in one run. Switch to 1 once they are fixed.

Other clients: the PHP extension mirrors the old php_advantage API (bindings/php_ext/), and a portable FFI binding is in bindings/php/.

Administering data — use Studio instead of ARC

Run openads-studio.bat (Windows) or ./openads-studio.sh (Linux/macOS) from the release folder, or, on a running server, start it with --http-port 6263 and open http://SERVER:6263/. Studio covers what you did in ARC: browse and edit rows, run SQL, view/rebuild structure (reindex, pack, zap), and create/edit data-dictionary objects (tables, users, indexes, RI rules). Secure it with --http-user user:password; for public exposure put a TLS proxy in front (see tls-deployment.md).

Checklist

  • Install the server: openads_serverd --setupopenads.ini.
  • Resolve the 6262 port if ADS still runs on the host.
  • Drop ace64.dll/ace32.dll next to your app (or relink with lib/).
  • Back up SAP-built .cdx files if you may need to roll back to SAP ACE.
  • Smoke-test reads/writes/index seeks against a copy of the data.
  • App opens tables by absolute local path (USE "E:\CLIENT\FILE.DBF")? Enable legacy_paths = 1 (see above) — no source changes needed.
  • Verify accented text (code-page caveat above).
  • Use Studio (openads-studio) for day-to-day admin.
  • Set up auto-start (wizard, or service-deployment.md).

Advantage Database Server, the Advantage Client Engine and Advantage Data Architect are names of their respective owners, used here only to describe compatibility. OpenADS is an independent project and is not affiliated with or endorsed by them.


This site uses Just the Docs, a documentation theme for Jekyll.