A TypeDB 3.x driver for Elixir, built on the TypeDB HTTP API.
Getting started
Add the connection to your supervision tree:
children = [
{TypeDB,
url: "http://localhost:8000",
username: "admin",
password: System.fetch_env!("TYPEDB_PASSWORD")}
]
Supervisor.start_link(children, strategy: :one_for_one)Then query. TypeDB is the default connection name:
TypeDB.query!(TypeDB, "social", """
match
$p isa person, has name $name;
select $name;
""")
|> Enum.map(&TypeDB.ConceptRow.typed_value(&1, "name"))
#=> ["Alice", "Bob"]The two ways to run a query
query/4 runs a single query in its own transaction — TypeDB opens it, runs
the query, and commits or closes it in one round trip. Reads never commit;
writes and schema changes commit by default, which commit: false turns off.
Every function takes the connection's registered name as its first argument;
conn below is that name, TypeDB unless you chose another.
TypeDB.query(conn, "social", "insert $p isa person, has name 'Alice';")transaction/5 opens a transaction you can run several queries in, committing
once at the end:
TypeDB.transaction(conn, "social", :write, fn tx ->
TypeDB.Transaction.query!(tx, "insert $p isa person, has name 'Alice';")
TypeDB.Transaction.query!(tx, "insert $p isa person, has name 'Bob';")
end)The block commits on success and rolls back on error or exception. A :read
block never commits.
Answers
Every query returns a TypeDB.Answer — see that module for the three shapes
and how to consume them.
Errors
Every function in this module and in TypeDB.Database, TypeDB.User,
TypeDB.Server and TypeDB.Transaction that can fail has both a
{:ok, _} | {:error, %TypeDB.Error{}} form and a ! form that raises.
TypeDB.Error carries TypeDB's own error :code, which is what you want to
branch on.
The one exception is transaction/5: it returns whatever your block returned,
so its {:error, _} may be your own value rather than an exception, and a
bang form would have to guess whether to raise it.
Logging
The driver logs sparingly: a debug line per transport retry, a debug line
for an unexpected message to a connection, an error when a connection's
transport dies, and a warning when no OS trust store can be found. Nothing
is logged on the happy path — use TypeDB.Telemetry for that.
Every line carries :typedb_connection in its Logger metadata, and retries
additionally carry :typedb_method, :typedb_path, :typedb_attempt and
:typedb_error_kind. Configure your backend to keep them:
config :logger, :default_formatter,
metadata: [:typedb_connection, :typedb_error_kind]Credentials never appear in a log line or in metadata; see TypeDB.Config
for how the connection keeps them out of crash reports too.
Concurrency
Requests run in the calling process, so N processes issue N concurrent
requests; the connection process is consulted only to mint or renew the auth
token. Sockets are pooled by the HTTP adapter — :max_sessions on
TypeDB.HTTP.Httpc caps how many are opened per host.
What this driver covers
Everything in the TypeDB HTTP API v1: sign-in and token renewal, databases, users, servers, version and health, explicit transactions, one-shot queries, and query analysis. TypeDB's gRPC-only features — database import/export and streaming answers — are not available over HTTP and so are not here.
Summary
Types
A connection: the registered name of a TypeDB.Connection process.
Functions
Creates a database. See TypeDB.Database.create/2.
Creates a database, raising on failure. See TypeDB.Database.create!/2.
Lists databases. See TypeDB.Database.list/1.
Lists databases, raising on failure. See TypeDB.Database.list!/1.
Deletes a database and all of its data. See TypeDB.Database.delete/2.
Deletes a database, raising on failure. See TypeDB.Database.delete!/2.
Returns :ok when the server is reachable. See TypeDB.Server.health/1.
Returns :ok when the server is reachable, raising otherwise.
See TypeDB.Server.health!/1.
Runs a single query in a transaction of its own.
Runs a single query, raising TypeDB.Error on failure.
Starts a connection. See TypeDB.Config for options.
Stops a connection, by registered name or pid.
Runs fun inside a transaction, committing on success.
Returns the server distribution and version. See TypeDB.Server.version/1.
Returns the server distribution and version, raising on failure.
See TypeDB.Server.version!/1.
Types
@type conn() :: TypeDB.Connection.t()
A connection: the registered name of a TypeDB.Connection process.
Functions
@spec create_database(conn(), String.t()) :: :ok | {:error, TypeDB.Error.t()}
Creates a database. See TypeDB.Database.create/2.
Creates a database, raising on failure. See TypeDB.Database.create!/2.
@spec databases(conn()) :: {:ok, [String.t()]} | {:error, TypeDB.Error.t()}
Lists databases. See TypeDB.Database.list/1.
Lists databases, raising on failure. See TypeDB.Database.list!/1.
@spec delete_database(conn(), String.t()) :: :ok | {:error, TypeDB.Error.t()}
Deletes a database and all of its data. See TypeDB.Database.delete/2.
Deletes a database, raising on failure. See TypeDB.Database.delete!/2.
@spec health(conn()) :: :ok | {:error, TypeDB.Error.t()}
Returns :ok when the server is reachable. See TypeDB.Server.health/1.
@spec health!(conn()) :: :ok
Returns :ok when the server is reachable, raising otherwise.
See TypeDB.Server.health!/1.
@spec query(conn(), String.t(), String.t(), keyword()) :: {:ok, TypeDB.Answer.t()} | {:error, TypeDB.Error.t()}
Runs a single query in a transaction of its own.
TypeDB opens the transaction, runs the query, then commits or closes it — one HTTP round trip in total, which makes this the cheapest way to run a standalone query.
Options
:transaction_type—:read,:writeor:schema. Defaults to:schema, the only type that accepts every kind of query.A
:schematransaction takes TypeDB's exclusive, database-wide schema lock for the duration of the call. One-shot queries left on the default therefore serialise against each other, and against anything else holding that lock. Passtransaction_type: :readfor reads and:writefor data changes — both are concurrent — and leave the default todefineandundefine. Narrowing also has the server reject an accidental write.:commit— whether to commit a write or schema query. Defaults totrue. Read queries never commit.:given_rows— input rows for the query'sgivenstage; seeTypeDB.Transaction.query/3for how to parameterise a query safely.plus all query and transaction options from
TypeDB.Options, and:timeout.
Raises
Unlike the rest of this module, query/4 has two failure paths. Anything the
server rejects comes back as {:error, %TypeDB.Error{}}; anything rejected
before the request is built raises, because there is no request to fail:
ArgumentErrorfor an invalid:transaction_type— that is a literal in your source, not data.TypeDB.Errorwith kind:configfor a:given_rowsvalue the driver cannot encode, including a negativeTypeDB.Duration.
Examples
TypeDB.query(conn, "social", "match $p isa person; select $p;",
transaction_type: :read,
answer_count_limit: 100
)
# Dry run: execute the write, then throw it away.
TypeDB.query(conn, "social", "insert $p isa person;", commit: false)
# Parameterised, and therefore safe against TypeQL injection.
TypeDB.query(conn, "social", """
given $n: string;
insert $p isa person, has name == $n;
""", given_rows: [%{"n" => user_supplied_name}])
@spec query!(conn(), String.t(), String.t(), keyword()) :: TypeDB.Answer.t()
Runs a single query, raising TypeDB.Error on failure.
@spec start_link(keyword()) :: GenServer.on_start()
Starts a connection. See TypeDB.Config for options.
Stops a connection, by registered name or pid.
@spec transaction( conn(), String.t(), TypeDB.Transaction.type(), (TypeDB.Transaction.t() -> result), keyword() ) :: result | {:error, TypeDB.Error.t()} when result: term()
Runs fun inside a transaction, committing on success.
The transaction is committed when fun returns, rolled back when it returns
{:error, _}, and rolled back before the exception propagates when it raises,
throws or exits. :read transactions are closed rather than committed, since
there is nothing to commit.
Returns whatever fun returned, except that a successful :write/:schema
block whose commit fails returns {:error, %TypeDB.Error{}}.
Options
Transaction options from TypeDB.Options, plus :timeout.
Examples
TypeDB.transaction(conn, "social", :write, fn tx ->
TypeDB.Transaction.query!(tx, "insert $p isa person, has name 'Alice';")
TypeDB.Transaction.query!(tx, "insert $p isa person, has name 'Bob';")
:ok
end)
#=> :ok
# Returning {:error, _} rolls back and returns that error unchanged.
TypeDB.transaction(conn, "social", :write, fn tx ->
case TypeDB.Transaction.query(tx, "insert $p isa person;") do
{:ok, _} -> {:error, :changed_my_mind}
error -> error
end
end)
#=> {:error, :changed_my_mind}
@spec version(conn()) :: {:ok, TypeDB.Server.version()} | {:error, TypeDB.Error.t()}
Returns the server distribution and version. See TypeDB.Server.version/1.
@spec version!(conn()) :: TypeDB.Server.version()
Returns the server distribution and version, raising on failure.
See TypeDB.Server.version!/1.