Arcadic.Transport.Bolt (Arcadic v0.7.1)

Copy Markdown View Source

Bolt transport for ArcadeDB via the boltx driver (Bolt v4). Verified interop (spec §15 P19/P20). Build the transport_options with Arcadic.Transport.Bolt.setup/1 — it returns [bolt: pool, bolt_opts: resolved], so both the query hot path (:bolt) AND query_stream/4 (:bolt_opts) work from one call and cannot drift to different hosts/creds. (start_link/1 returns only the pool ref — use setup/1 if you also stream.)

Supports the query hot path (execute/4), native fun-based transactions (transaction/3), and a RETURN 1 health check (ready?/1). Server admin (create/drop/list database) is an HTTP/server operation, not a Bolt one — those callbacks return {:error, %Arcadic.Error{reason: :not_supported}}; use an HTTP conn for admin.

Read/write semantics differ from the HTTP transport. Bolt has no /query vs /command endpoint split, so Arcadic.query/4 on a Bolt conn does NOT enforce read-only — the HTTP transport's non-idempotent rejection is the ArcadeDB /query endpoint's server-side behavior, which Bolt lacks. arcadic is statement-agnostic by design (params-only; it never parses statement semantics), so a write issued through query/4 on Bolt executes. Use command/4 for writes on Bolt.

Never enable boltx debug logging against arcadic. config :boltx, log: true (or :log_hex) makes boltx debug-log the full HELLO payload — including the auth credentials (the password). arcadic drives the HELLO itself and never enables this; keep it off so a credential cannot reach a log line (Critical Rule 3).

Summary

Functions

Start a Bolt pool AND return the transport_options for a Conn in one call, so the pool (:bolt, for execute/transaction/ready?) and the per-stream connect opts (:bolt_opts, for query_stream) cannot drift to different hosts/credentials. Accepts the same opts as start_link/1, including :scheme / :ssl_opts for TLS (see there).

Start a boltx connection with ArcadeDB-correct defaults. Opts: :hostname, :port (default 7687), :username, :password, :scheme, :ssl_opts, plus most boltx options (:uri is rejected — arcadic must own the scheme, see :scheme below). Pins Bolt to v4 (ArcadeDB speaks v4; boltx defaults to v5 → version_negotiation_error).

Functions

setup(opts)

@spec setup(keyword()) :: {:ok, keyword()} | {:error, term()}

Start a Bolt pool AND return the transport_options for a Conn in one call, so the pool (:bolt, for execute/transaction/ready?) and the per-stream connect opts (:bolt_opts, for query_stream) cannot drift to different hosts/credentials. Accepts the same opts as start_link/1, including :scheme / :ssl_opts for TLS (see there).

{:ok, topts} = Arcadic.Transport.Bolt.setup(hostname: h, port: p, username: "root", password: pw)
conn = Arcadic.connect(url, db, auth: {"root", pw}, transport: Arcadic.Transport.Bolt, transport_options: topts)

# TLS, verify_peer against a private CA:
{:ok, topts} = Arcadic.Transport.Bolt.setup(scheme: "bolt+s", ssl_opts: [cacertfile: "/ca.pem"], hostname: h, port: p, username: "root", password: pw)

start_link(opts)

@spec start_link(keyword()) :: {:ok, pid()} | {:error, term()}

Start a boltx connection with ArcadeDB-correct defaults. Opts: :hostname, :port (default 7687), :username, :password, :scheme, :ssl_opts, plus most boltx options (:uri is rejected — arcadic must own the scheme, see :scheme below). Pins Bolt to v4 (ArcadeDB speaks v4; boltx defaults to v5 → version_negotiation_error).

Transport security (:scheme)

  • "bolt" (default) — plaintext. ArcadeDB's Bolt is plaintext unless the server is configured with arcadedb.bolt.ssl + a keystore.
  • "bolt+s" — TLS, secure by default: the server certificate is verified against the OS trust store (verify_peer). Pass ssl_opts: [cacertfile: "/path/ca.pem"] to trust a private CA. To opt out of verification, pass ssl_opts: [verify: :verify_none] explicitly — this encrypts but does NOT authenticate the peer (MITM-able: an attacker on the Bolt path can present any certificate and every param/row flows to it), so it is a deliberate caller opt-in, never a silent default.

boltx's own scheme→verify mapping is INVERTED (its bolt+s forces verify_none), so arcadic translates "bolt+s" to boltx's "bolt+ssc" to get verify_peer. Callers use only "bolt" / "bolt+s"; "bolt+ssc" is not a caller scheme.