Query builder that generates dllb SQL strings.
Provides functions to construct CREATE, SELECT, UPDATE, DELETE, RELATE, and DEFINE statements for the dllb query language. All functions return plain query strings ready to be sent over the wire.
Summary
Functions
Builds a COUNT <table> [WHERE <clause>] statement.
Builds a CREATE statement for inserting a new record.
Builds a CREATE statement with an explicit record ID.
Builds a DEFINE FIELD statement.
Builds a DEFINE INDEX statement.
Builds a DEFINE TABLE statement.
Builds a DELETE statement for a record.
Builds a GRAPH COMMUNITIES statement for native community detection.
Builds a GRAPH COMPONENTS <edge_table> statement for native connected-
components detection.
Passes through a raw query string without modification.
Builds a RELATE statement to create a graph edge between two records.
Builds a SELECT statement with optional clauses.
Builds an UPDATE statement for an existing record.
Builds an UPDATE <table> SET ... WHERE <clause> statement that updates
every row matching the (already-built) WHERE clause.
Builds a CREATE ... ON CONFLICT UPDATE statement for idempotent upserts.
Types
Functions
Builds a COUNT <table> [WHERE <clause>] statement.
Options
:where- optional WHERE clause string
Examples
iex> Dllb.Query.count("user")
"COUNT user"
iex> Dllb.Query.count("user", where: "age = 30")
"COUNT user WHERE age = 30"
Builds a CREATE statement for inserting a new record.
Examples
iex> Dllb.Query.create("user", %{name: "Alice", age: 30})
"CREATE user SET age = 30, name = 'Alice'"
Builds a CREATE statement with an explicit record ID.
Examples
iex> Dllb.Query.create_with_id("user", "u1", %{name: "Alice"})
"CREATE user:u1 SET name = 'Alice'"
Builds a DEFINE FIELD statement.
Options
:required- iftrue, appends ASSERT $value IS NOT NONE
Examples
iex> Dllb.Query.define_field("user", "name", "string", required: true)
"DEFINE FIELD name ON user TYPE string ASSERT $value IS NOT NONE"
Builds a DEFINE INDEX statement.
Supported index types: :btree, :fulltext, :hnsw.
Options (for HNSW vector indexes)
:dimension- vector dimension:dist- distance metric (e.g."COSINE","EUCLIDEAN")
Examples
iex> Dllb.Query.define_index("user", "idx_name", ["name"], :btree)
"DEFINE INDEX idx_name ON user FIELDS name SEARCH ANALYZER btree"
iex> Dllb.Query.define_index("ast_node", "idx_src_embed", ["source_embedding"], :hnsw, dimension: 768, dist: "COSINE")
"DEFINE INDEX idx_src_embed ON ast_node FIELDS source_embedding HNSW DIMENSION 768 DIST COSINE"
Builds a DEFINE TABLE statement.
Mode can be :schemafull or :schemaless.
Examples
iex> Dllb.Query.define_table("user", :schemafull)
"DEFINE TABLE user SCHEMAFULL"
Builds a DELETE statement for a record.
Examples
iex> Dllb.Query.delete("user:u1")
"DELETE user:u1"
Builds a GRAPH COMMUNITIES statement for native community detection.
Delegates computation to the dllb engine (Rust Louvain / Label Propagation), which runs in O(E) per iteration — orders of magnitude faster than the equivalent pure-Elixir implementation on large graphs.
Options
:algorithm-:louvain(default) or:lp(label propagation):max_iter- maximum optimisation passes (default: 10):resolution- Louvain resolution γ; values < 1.0 → fewer, larger communities; > 1.0 → more, smaller communities (default: 1.0)
Examples
iex> Dllb.Query.graph_communities("calls")
"GRAPH COMMUNITIES calls"
iex> Dllb.Query.graph_communities("calls", algorithm: :lp, max_iter: 20)
"GRAPH COMMUNITIES calls ALGORITHM lp MAX_ITER 20"
iex> Dllb.Query.graph_communities("calls", algorithm: :louvain, resolution: 0.5)
"GRAPH COMMUNITIES calls ALGORITHM louvain RESOLUTION 0.5"
Builds a GRAPH COMPONENTS <edge_table> statement for native connected-
components detection.
Delegates computation to the dllb engine (Rust union-find over the edge
table, treated as undirected). The server returns a compact summary
(component_count, largest, nodes) rather than full membership.
Examples
iex> Dllb.Query.graph_components("calls")
"GRAPH COMPONENTS calls"
Passes through a raw query string without modification.
Examples
iex> Dllb.Query.raw("INFO FOR DB")
"INFO FOR DB"
Builds a RELATE statement to create a graph edge between two records.
Examples
iex> Dllb.Query.relate("user:a", "follows", "user:b", %{since: "2024"})
"RELATE user:a->follows->user:b SET since = '2024'"
@spec select(String.t(), select_opts()) :: String.t()
Builds a SELECT statement with optional clauses.
Options
:fields- list of field names to select (default["*"]):where- WHERE clause string:order- ORDER BY clause string:limit- LIMIT value:fetch- graph traversal fetch clause (e.g."->calls->fn_node")
Examples
iex> Dllb.Query.select("user", where: "age > 25", limit: 10)
"SELECT * FROM user WHERE age > 25 LIMIT 10"
Builds an UPDATE statement for an existing record.
Examples
iex> Dllb.Query.update("user:u1", %{name: "Bob"})
"UPDATE user:u1 SET name = 'Bob'"
Builds an UPDATE <table> SET ... WHERE <clause> statement that updates
every row matching the (already-built) WHERE clause.
Only the listed fields are changed (partial-update semantics). An empty WHERE string updates all rows in the table.
Examples
iex> Dllb.Query.update_where("ast_node", %{arity: 1}, "kind = 'function_def'")
"UPDATE ast_node SET arity = 1 WHERE kind = 'function_def'"
Builds a CREATE ... ON CONFLICT UPDATE statement for idempotent upserts.
If the record already exists (by table + id), updates the fields instead of failing.
Examples
iex> Dllb.Query.upsert("user", "u1", %{name: "Alice", age: 30})
"CREATE user:u1 SET age = 30, name = 'Alice' ON CONFLICT UPDATE"