spiral-sdk 0.1.11

Rust SDK for Spiral resource and table APIs
Documentation
// Generated by tools/service-contracts/rust.py. Do not edit.
#![doc = "Transport-independent service interface for local and remote calls."]

use async_trait::async_trait;
use spiral_contract::auth::AuthHeader;
use spiral_contract::call::CallError;
use spiral_contract::stream::ByteStream;

use super::objects::*;
/// Service implementations authenticate Authorization headers and enforce resource permissions.
#[async_trait]
pub trait ScandalApi: Send + Sync + 'static {
    /// Discard an upload's stored parts. An abort never removes a stored object, so the attempt's
    /// binding allows it. Aborting an upload that no longer exists succeeds.
    async fn abort_blob_upload(
        &self,
        auth_header: AuthHeader,
        request: AbortBlobUploadRequest,
    ) -> Result<(), CallError<ScandalError>>;
    /// Write Arrow rows as new files of a Table, for a successor of `base` or, without a base, for
    /// the Table's first version. The rows stay invisible until a version that includes them is
    /// prepared, registered and committed. Appends to one Table may run in parallel. With an
    /// `attempt`, the Table's binding is the one the Tables API issued for that attempt, which
    /// creates files only in its directory.
    async fn append_rows(
        &self,
        auth_header: AuthHeader,
        request: AppendRowsRequest,
        body: ByteStream,
    ) -> Result<AppendedFragments, CallError<ScandalError>>;
    /// Write values of new columns for every row one file of a Table version keeps, as column files
    /// attached to that file, which leaves its existing files as they are. The service writes the
    /// rows as they arrive, holding what it has not yet written in the request's memory budget. The
    /// values stay invisible until a version that includes the receipt is prepared on an `edit`
    /// base, registered and committed.
    async fn attach_columns(
        &self,
        auth_header: AuthHeader,
        request: AttachColumnsRequest,
        body: ByteStream,
    ) -> Result<AttachedColumns, CallError<ScandalError>>;
    /// Return the output schema of named expressions over an input schema, without any data.
    async fn bind_projection(
        &self,
        auth_header: AuthHeader,
        request: BindProjectionRequest,
    ) -> Result<ArrowSchema, CallError<ScandalError>>;
    /// Join an upload's parts into its blob and return the blob, whose digest merges the parts'
    /// hashes, so no byte is read again. The blob becomes part of the Table only when a committed
    /// row references it.
    async fn complete_blob_upload(
        &self,
        auth_header: AuthHeader,
        request: CompleteBlobUploadRequest,
    ) -> Result<Blob, CallError<ScandalError>>;
    /// Record the deletion of rows of a Table version, addressed by row ID, without rewriting the
    /// rows it keeps. The deletions stay invisible until a version that includes the receipts is
    /// prepared on an `edit` base, registered and committed.
    async fn delete_rows(
        &self,
        auth_header: AuthHeader,
        request: DeleteRowsRequest,
        body: ByteStream,
    ) -> Result<AppendedFragments, CallError<ScandalError>>;
    /// Evaluate named expressions over the Arrow rows in the body and stream the results back row
    /// for row. Expressions read blobs from the Tables in `tables`, and from other URIs resolved by
    /// the execution host. A failure after the response starts ends the stream without the Arrow
    /// end-of-stream marker.
    async fn evaluate(
        &self,
        auth_header: AuthHeader,
        request: EvaluateRequest,
        body: ByteStream,
    ) -> Result<ByteStream, CallError<ScandalError>>;
    /// Prepare a Table version from the files that appends wrote, writing only its metadata; the
    /// files stay where the appends put them. Deletes select stable row IDs and write deletion
    /// files through their separate attempt binding. Register the version with the Tables API and
    /// commit it to publish it. The Table binding authorizes publication.
    async fn finalize_write(
        &self,
        auth_header: AuthHeader,
        request: FinalizeWriteRequest,
    ) -> Result<PreparedWriteReceipt, CallError<ScandalError>>;
    /// List the SPQL functions this service can run.
    async fn list_functions(
        &self,
        auth_header: AuthHeader,
    ) -> Result<FunctionCatalog, CallError<ScandalError>>;
    /// Store the inline payloads of the `spql.Blob` columns in the Arrow rows of the body as blobs
    /// of a Table, packed as the rows of `append_rows` are, and return the rows with each payload
    /// replaced by its address, `spiral://<table-id>/<key>`, its offset, size and BLAKE3 digest.
    /// Payloads share packs in the Table's `blobs/` directory, or in the attempt's; one of 4 MiB or
    /// more is an object of its own. Other values are returned as they are. The response starts
    /// once every pack is stored. The blobs become part of the Table only when a committed row
    /// references them. With an `attempt`, the binding the Tables API issued for that attempt is
    /// enough.
    async fn pack_blobs(
        &self,
        auth_header: AuthHeader,
        request: PackBlobsRequest,
        body: ByteStream,
    ) -> Result<ByteStream, CallError<ScandalError>>;
    /// Write new values for existing rows of a Table version, addressed by row ID, as patch files
    /// beside the data. The rows keep their row IDs and positions. The service writes the rows in
    /// bounded chunks as they arrive, holding each chunk in the request's memory budget. The values
    /// stay invisible until a version that includes the receipts is prepared on an `edit` base,
    /// registered and committed.
    async fn patch_rows(
        &self,
        auth_header: AuthHeader,
        request: PatchRowsRequest,
        body: ByteStream,
    ) -> Result<AppendedFragments, CallError<ScandalError>>;
    /// Plan how one version of a Table changed since an earlier one, without reading column values:
    /// for each file of the later version, whether the earlier version has it, with the row IDs
    /// patched and deleted since, or it was added since, with the row IDs appended since and those
    /// a rewrite carried over. Planning reads version metadata, the row IDs that patches and
    /// deletes target, and the stored row IDs of files whose row IDs are not ranges. Read the rows
    /// a plan names with a scan's `rowIds`.
    async fn plan_changes(
        &self,
        auth_header: AuthHeader,
        request: PlanChangesRequest,
    ) -> Result<ChangePlan, CallError<ScandalError>>;
    /// Plan a scan of one Table version: its output schema, how exactly it can enforce each filter
    /// clause, and one split for each file that statistics do not prune, in stored order. Planning
    /// reads only metadata, and refuses an emit it cannot run before any rows are read.
    async fn plan_scan(
        &self,
        auth_header: AuthHeader,
        request: PlanScanRequest,
    ) -> Result<ScanPlan, CallError<ScandalError>>;
    /// Stream the bytes of a blob that a Table owns, or of a byte range of it. Check a whole read
    /// against the blob's digest and a range against its length; a stream that ends early is
    /// incomplete.
    async fn read_blob(
        &self,
        auth_header: AuthHeader,
        request: ReadBlobRequest,
    ) -> Result<ByteStream, CallError<ScandalError>>;
    /// Read legacy keyed table rows using metadata resolved by the Tables API and a scoped storage
    /// binding. ScanDAL merges key-space and column-group fragments, WAL patches and deletions
    /// through the legacy native reader. It calls no control-plane service. Returns an Arrow IPC
    /// stream, including its schema when limit is zero. Hosted ScanDAL rejects local file roots
    /// with the same policy as Arbor reads.
    async fn read_legacy_table(
        &self,
        auth_header: AuthHeader,
        request: ReadLegacyTableRequest,
    ) -> Result<ByteStream, CallError<ScandalError>>;
    /// Read one split of a planned scan as an Arrow IPC stream, in stored order. Every batch ends
    /// with two dictionary columns that arrive even with a batch of no rows: `scandal.next_row`,
    /// the stored row of the split's file to resume from, and `scandal.metrics`, the counters as
    /// JSON that the read accrued since the previous batch, when the scan collects them. A last
    /// batch of no rows then carries the counters that accrued after the last rows. A client adds
    /// the counters of every batch it receives, so a read that stops early still counts the batches
    /// it delivered. With an emit, the batches hold the split's partial results, which are complete
    /// only at the end of the stream, and `scandal.next_row` is the split's end. A failure after
    /// the stream starts ends it without the Arrow end-of-stream marker.
    async fn read_scan(
        &self,
        auth_header: AuthHeader,
        request: ReadScanRequest,
    ) -> Result<ByteStream, CallError<ScandalError>>;
    /// Search an immutable vector index and refine its candidates against exact source vectors. The
    /// manifest must match the requested index, source version, and embedding field. Both resource
    /// storage bindings must grant reads. The runtime calls no control-plane service. Rows use
    /// stable source RowIDs and exact float64 distances, with RowID order as the tie breaker. The
    /// source filter and exclusions apply before the final result limit. The Arrow schema
    /// records provenance and fixed recall controls in `scandal.vector_search`. An error after the
    /// stream starts omits the Arrow end marker. Stream cancellation stops further reads.
    async fn search_vectors(
        &self,
        auth_header: AuthHeader,
        request: SearchVectorsRequest,
    ) -> Result<ByteStream, CallError<ScandalError>>;
    /// Start a multipart upload of one blob into a write attempt, for a payload too large for one
    /// request. Send its parts to any instance, in any order and each retried on its own, then
    /// complete it for a blob that a row appended in the same write can carry. A binding the Tables
    /// API issued for the attempt is enough.
    async fn start_blob_upload(
        &self,
        auth_header: AuthHeader,
        request: StartBlobUploadRequest,
    ) -> Result<BlobUpload, CallError<ScandalError>>;
    /// Report what storage holds for a blob that a Table owns, without reading its bytes.
    async fn stat_blob(
        &self,
        auth_header: AuthHeader,
        request: StatBlobRequest,
    ) -> Result<BlobStat, CallError<ScandalError>>;
    /// Read rows of planned splits by position, as an Arrow IPC stream in request order: each
    /// take's rows in the order of its positions, a repeated position's row again, and the takes
    /// one after another. Each split's rows are read in one pass, so positions that share storage
    /// share its reads. Every batch ends with the two dictionary columns of `read_scan`:
    /// `scandal.next_row` holds how many of the request's positions, counted across its takes, the
    /// batches so far delivered, so a client resumes by sending the positions after them;
    /// `scandal.metrics` holds the counters of the split reads as in `read_scan`, with a last batch
    /// of no rows. A position past a split's rows fails the request before any output. A failure
    /// after the stream starts ends it without the Arrow end-of-stream marker.
    async fn take_rows(
        &self,
        auth_header: AuthHeader,
        request: TakeRowsRequest,
    ) -> Result<ByteStream, CallError<ScandalError>>;
    /// Store one part of an upload from the request body. Every part but the last holds exactly the
    /// upload's `partBytes`. Sending a part again replaces it. The part counts against the
    /// request's memory budget.
    async fn upload_blob_part(
        &self,
        auth_header: AuthHeader,
        request: UploadBlobPartRequest,
        body: ByteStream,
    ) -> Result<BlobPart, CallError<ScandalError>>;
    /// Write the mirror of one file of a version of another Table, as an Enrichment's values are
    /// written, so a scan of that version can read it at its own positions. The service writes the
    /// rows as they arrive, holding what it has not yet written in the request's memory budget. The
    /// mirror stays invisible until a version that includes its receipt is prepared on an `aligned`
    /// base, registered and committed.
    async fn write_aligned(
        &self,
        auth_header: AuthHeader,
        request: WriteAlignedRequest,
        body: ByteStream,
    ) -> Result<AlignedFragment, CallError<ScandalError>>;
    /// Store the request body as a new blob of a Table, under its `blobs/` directory, and return
    /// its reference. The service stops reading and fails the request when the body exceeds
    /// `maxBytes`. The blob becomes part of the Table only when a committed row references it. A
    /// publication binding from the Tables API is enough.
    async fn write_blob(
        &self,
        auth_header: AuthHeader,
        request: WriteBlobRequest,
        body: ByteStream,
    ) -> Result<Blob, CallError<ScandalError>>;
}