Rust#
Embed peql::Engine when your application needs to manage contracts, supply caller context or work directly with Arrow batches and DataFusion tables.
Add the dependencies#
peQL requires Rust 1.95 or newer. Add these dependencies to your application’s Cargo.toml:
[dependencies]
peql = { git = "https://github.com/griot-cloud/peql", tag = "v0.4.0" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
Query an existing workspace#
After completing the Quickstart, use this as src/main.rs and run your application from the directory containing peql-demo:
use peql::{Caller, Engine};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let engine = Engine::open("peql-demo")?;
// Rust uses the order: ID, tenant, purpose.
let caller = Caller::new("globex-analyst", "globex", "reporting");
let result = engine.query(
r#"SELECT order_id, amount FROM "sales/orders" ORDER BY order_id"#,
&caller,
).await?;
println!("{} rows returned", result.envelope.rows);
for batch in result.batches {
println!("{batch:?}");
}
Ok(())
}
QueryResult contains Arrow record batches and an Envelope describing the execution. The example returns one row: order 2 with amount 80.
Register or supply data#
Call register_contract(source, &schema) with YAML/JSON text and an Arrow schema before using a new contract. Then choose how the data is supplied:
Method |
Use it when |
|---|---|
|
You want peQL to replace the bound Parquet data. |
|
You want to add batches to the bound data. |
|
The data is already in memory. |
|
You have a DataFusion |
on_violation is an OnWriteViolation: Refuse (the default) writes nothing and returns PeqlError::Violated when any row breaks a row rule; Exclude writes only the rows that pass and returns the others in WriteOutcome::excluded, with a _violations column; Warn writes every row. write returns WriteOutcome { report, excluded }. A write that arrives in parts uses begin_write(name, mode, on_violation), write_part, which returns Part { rows_written, excluded }, and finish_write.
Reads never return a row that breaks a row rule. query, plan and view leave such rows out and report them per rule in Resolution::excluded. query_as_of, plan_for, plan_as_of, view_for, view_as_of and check take an OnReadViolation; with Refuse, a read of data that holds any such row returns PeqlError::Violated. See Rows that break a contract.
The binding methods validate the supplied table and keep its manifest in memory. They do not write Parquet. write requires a file binding that points to a directory, rather than a single file or a bound table.
Use register_compiled(document, &compiled, &functions) for a contract the application compiled and vouches for, which peQL never compiles. Use publish(name, tenant) when callers from another tenant need to discover an owned contract.
Configure the engine#
Engine::open(root) persists contracts, functions, budgets and the audit log. Engine::in_memory(base) keeps that state in memory; it can still read and write data files under base.
Builder methods let an application replace individual components:
Builder |
Component |
|---|---|
|
Contract storage and publication records. |
|
Resolution of a contract’s data binding. |
|
Privacy budget ledger. |
|
Audit destination. |
|
Optional query result cache. |
The default engine has no result cache. See How it works for what a cached result depends on.
Handle refusals#
Engine methods return peql::Result<T>. For a query error, error.is_refusal() distinguishes policy outcomes from execution failures. Match individual PeqlError variants when your application needs a specific response; see Reference.
Authentication, endpoint access and permissions for management operations belong in your application. Supply a trusted Caller to query; expose registration, publication and writes only to the operators who should control them.
For the complete Rust API, generate local API documentation from the peQL repository:
cargo doc --no-deps --open