Skip to main content

Table

Struct Table 

Source
pub struct Table { /* private fields */ }
Expand description

A table selected for writes or catalog reads.

The table must already exist for writes. Database and schema default to scopedb and public; override them with Self::with_database and Self::with_schema.

Implementations§

Source§

impl Table

Source

pub fn with_database(self, database: impl Into<String>) -> Self

Examples found in repository?
examples/common/mod.rs (line 63)
50pub fn write_table(client: &Client) -> Result<Table, io::Error> {
51    let table = std::env::var("SCOPEDB_TABLE")
52        .ok()
53        .filter(|value| !value.is_empty())
54        .ok_or_else(|| {
55            io::Error::new(
56                io::ErrorKind::InvalidInput,
57                "set SCOPEDB_TABLE to a disposable table before running this write example",
58            )
59        })?;
60
61    Ok(client
62        .table(table)
63        .with_database(database())
64        .with_schema(schema()))
65}
More examples
Hide additional examples
examples/table.rs (line 23)
18async fn main() -> Result<(), Box<dyn std::error::Error>> {
19    let client = common::client()?;
20    let table_name = std::env::var("SCOPEDB_TABLE").unwrap_or_else(|_| "events".to_string());
21    let table = client
22        .table(table_name)
23        .with_database(common::database())
24        .with_schema(common::schema());
25
26    println!("identifier: {}", table.identifier());
27
28    let description = table.catalog().get().await?.definition;
29    for column in description.columns {
30        println!("{}: {:?}", column.name, column.data_type);
31    }
32
33    Ok(())
34}
Source

pub fn with_schema(self, schema: impl Into<String>) -> Self

Examples found in repository?
examples/common/mod.rs (line 64)
50pub fn write_table(client: &Client) -> Result<Table, io::Error> {
51    let table = std::env::var("SCOPEDB_TABLE")
52        .ok()
53        .filter(|value| !value.is_empty())
54        .ok_or_else(|| {
55            io::Error::new(
56                io::ErrorKind::InvalidInput,
57                "set SCOPEDB_TABLE to a disposable table before running this write example",
58            )
59        })?;
60
61    Ok(client
62        .table(table)
63        .with_database(database())
64        .with_schema(schema()))
65}
More examples
Hide additional examples
examples/table.rs (line 24)
18async fn main() -> Result<(), Box<dyn std::error::Error>> {
19    let client = common::client()?;
20    let table_name = std::env::var("SCOPEDB_TABLE").unwrap_or_else(|_| "events".to_string());
21    let table = client
22        .table(table_name)
23        .with_database(common::database())
24        .with_schema(common::schema());
25
26    println!("identifier: {}", table.identifier());
27
28    let description = table.catalog().get().await?.definition;
29    for column in description.columns {
30        println!("{}: {:?}", column.name, column.data_type);
31    }
32
33    Ok(())
34}
Source

pub fn identifier(&self) -> String

Examples found in repository?
examples/table.rs (line 26)
18async fn main() -> Result<(), Box<dyn std::error::Error>> {
19    let client = common::client()?;
20    let table_name = std::env::var("SCOPEDB_TABLE").unwrap_or_else(|_| "events".to_string());
21    let table = client
22        .table(table_name)
23        .with_database(common::database())
24        .with_schema(common::schema());
25
26    println!("identifier: {}", table.identifier());
27
28    let description = table.catalog().get().await?.definition;
29    for column in description.columns {
30        println!("{}: {:?}", column.name, column.data_type);
31    }
32
33    Ok(())
34}
Source

pub async fn drop(&self) -> Result<(), Error>

Source

pub async fn append( &self, ndjson: impl Into<String>, ) -> Result<AppendRowsResult, Error>

Writes newline-delimited JSON to this table in one HTTP attempt.

Each line must be a JSON object matching the destination columns. A request allows at most 8 MiB of uncompressed NDJSON and 200,000 rows. The SDK sends it with zstd compression and does not automatically retry it.

Integer inputs must fit in a signed 64-bit integer, including values in uint columns and nested JSON. Larger integers are rejected without narrowing; query results still support the full u64 range.

let result = client
    .table("events")
    .append(r#"{"id": 1, "name": "page_view"}"#)
    .await?;
println!("Written: {} rows", result.num_rows_inserted);
Examples found in repository?
examples/append.rs (line 44)
21async fn main() -> Result<(), Box<dyn std::error::Error>> {
22    let client = common::client()?;
23    let table = common::write_table(&client)?;
24
25    // Direct append sends exactly one caller-owned NDJSON request. Each value
26    // is serialized as one line; JSON arrays are not accepted by this API.
27    let ndjson = [
28        serde_json::json!({
29            "id": 1,
30            "occurred_at": jiff::Timestamp::now(),
31            "name": "first",
32        }),
33        serde_json::json!({
34            "id": 2,
35            "occurred_at": jiff::Timestamp::now(),
36            "name": "second",
37        }),
38    ]
39    .iter()
40    .map(serde_json::to_string)
41    .collect::<Result<Vec<_>, _>>()?
42    .join("\n");
43
44    match table.append(ndjson).await {
45        Ok(result) => {
46            println!("committed remotely: {} rows", result.num_rows_inserted);
47            Ok(())
48        }
49        Err(error) => {
50            if error.kind() == ErrorKind::AppendRowsFailed
51                && matches!(
52                    error.append_details().map(|details| details.status),
53                    Some(AppendState::Unknown)
54                )
55            {
56                eprintln!("commit outcome is unknown; reconcile before replaying this payload");
57            }
58            Err(error.into())
59        }
60    }
61}
Source

pub fn append_stream(&self) -> AppendStreamBuilder

Builds an asynchronous, bounded and concurrent append stream for this table.

Examples found in repository?
examples/append_stream.rs (line 21)
18async fn main() -> Result<(), Box<dyn std::error::Error>> {
19    let client = common::client()?;
20    let table = common::write_table(&client)?;
21    let stream = table.append_stream().build()?;
22
23    let admitted = stream
24        .send_all([
25            serde_json::json!({
26                "id": 1,
27                "occurred_at": jiff::Timestamp::now(),
28                "name": "first",
29            }),
30            serde_json::json!({
31                "id": 2,
32                "occurred_at": jiff::Timestamp::now(),
33                "name": "second",
34            }),
35        ])
36        .await?;
37    println!("accepted locally: {} rows", admitted.accepted_rows);
38
39    // send_all() confirms only local admission. With the default strict policy,
40    // successful shutdown confirms at least one commit acknowledgement per row.
41    // Retrying an unknown outcome can insert duplicates.
42    let report = stream.shutdown().await?;
43    println!("committed remotely: {} rows", report.committed_rows);
44
45    Ok(())
46}
More examples
Hide additional examples
examples/import_ndjson.rs (line 29)
23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24    let path = std::env::args()
25        .nth(1)
26        .ok_or("usage: import_ndjson <events.ndjson>")?;
27    let mut input = BufReader::new(File::open(path)?);
28    let client = common::client()?;
29    let stream = common::write_table(&client)?.append_stream().build()?;
30    let admitted: Result<(), Box<dyn std::error::Error>> = async {
31        let mut line_number = 0;
32        loop {
33            // Bound a single input record as well as the stream's queued bytes.
34            let mut line = String::new();
35            let bytes = input
36                .by_ref()
37                .take(8 * 1024 * 1024 + 1)
38                .read_line(&mut line)?;
39            if bytes == 0 {
40                break;
41            }
42            line_number += 1;
43            if bytes > 8 * 1024 * 1024 {
44                return Err(format!("line {line_number} exceeds 8 MiB").into());
45            }
46            if line.trim().is_empty() {
47                continue;
48            }
49            let row: serde_json::Value = serde_json::from_str(&line)
50                .map_err(|error| format!("line {line_number}: {error}"))?;
51            stream.send(&row).await?;
52        }
53        Ok(())
54    }
55    .await;
56    // Settle the accepted prefix even if parsing or admission failed midway.
57    let settled = stream.shutdown().await;
58    println!("delivery: {:?}", stream.stats());
59    settled?;
60    admitted?;
61    Ok(())
62}
examples/telemetry.rs (line 50)
43async fn main() -> Result<(), Box<dyn std::error::Error>> {
44    let client = common::client()?;
45    let table = common::write_table(&client)?;
46
47    // Continue mode is explicitly best effort: failed or ambiguous batches are
48    // accounted for, released, and do not stop later telemetry batches.
49    let telemetry = table
50        .append_stream()
51        .failure_policy(AppendFailurePolicy::Continue)
52        .circuit_breaker(Some(AppendCircuitBreakerOptions::default()))
53        .target_batch_bytes(1024 * 1024)
54        .max_batch_rows(10_000)
55        .flush_interval(Duration::from_secs(1))
56        .max_buffered_bytes(32 * 1024 * 1024)
57        // This limit applies to each stream; include every application replica.
58        .max_concurrent_batches(1)
59        .attempt_timeout(Duration::from_secs(10))
60        .on_batch_failure(|event| {
61            // A synchronous observer; use a separate diagnostics sink.
62            eprintln!("telemetry append failure: {event:?}");
63        })
64        .build()?;
65
66    let mut dropped_locally = 0_u64;
67    for request in 1..=100 {
68        if !track(&telemetry, request) {
69            dropped_locally += 1;
70        }
71    }
72    println!("locally dropped: {dropped_locally}");
73
74    // In a service, stop and join producer tasks before this settlement barrier.
75    let report = telemetry.shutdown().await?;
76    if report.outcome != AppendDeliveryOutcome::Ok {
77        eprintln!("telemetry loss or ambiguity: {report:?}");
78    }
79    println!("final stream stats: {:?}", telemetry.stats());
80
81    Ok(())
82}
examples/bulk_append.rs (line 30)
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23    let client = common::client()?;
24    let table = common::write_table(&client)?;
25
26    // The default Stop policy gives strict barriers. Local memory and request
27    // concurrency are bounded independently; concurrent batches have no
28    // defined commit order.
29    let stream = table
30        .append_stream()
31        .target_batch_bytes(32 * 1024)
32        .max_batch_rows(10_000)
33        .flush_interval(Duration::from_secs(1))
34        .max_buffered_bytes(1024 * 1024)
35        .max_concurrent_batches(4)
36        .attempt_timeout(Duration::from_secs(30))
37        .build()?;
38
39    let rows = (1..=10_000).map(|id| {
40        serde_json::json!({
41            "id": id,
42            "occurred_at": jiff::Timestamp::now(),
43            "name": format!("example-{id}"),
44        })
45    });
46
47    let admission_error = match stream.send_all(rows).await {
48        Ok(result) => {
49            println!("accepted locally: {} rows", result.accepted_rows);
50            None
51        }
52        Err(error) => {
53            // There is no stream-wide abort or rollback. Settle the already
54            // accepted prefix even if row production or admission stopped.
55            eprintln!("row admission stopped; settling the accepted prefix: {error}");
56            Some(error)
57        }
58    };
59
60    match stream.shutdown().await {
61        Ok(report) => {
62            println!("committed remotely: {} rows", report.committed_rows);
63            println!("final stream stats: {:?}", stream.stats());
64        }
65        Err(error) => {
66            if matches!(
67                error.append_details().map(|details| details.status),
68                Some(AppendState::Unknown)
69            ) {
70                eprintln!("commit outcome is unknown; reconcile before replaying");
71            } else {
72                eprintln!("bulk append failed: {error}");
73            }
74            eprintln!("final stream stats: {:?}", stream.stats());
75            return Err(error.into());
76        }
77    }
78
79    if let Some(error) = admission_error {
80        return Err(error.into());
81    }
82    Ok(())
83}
Source

pub fn catalog(&self) -> CatalogResource<CatalogTable>

Selects this table’s complete definition and ETag for conditional changes.

Examples found in repository?
examples/table.rs (line 28)
18async fn main() -> Result<(), Box<dyn std::error::Error>> {
19    let client = common::client()?;
20    let table_name = std::env::var("SCOPEDB_TABLE").unwrap_or_else(|_| "events".to_string());
21    let table = client
22        .table(table_name)
23        .with_database(common::database())
24        .with_schema(common::schema());
25
26    println!("identifier: {}", table.identifier());
27
28    let description = table.catalog().get().await?.definition;
29    for column in description.columns {
30        println!("{}: {:?}", column.name, column.data_type);
31    }
32
33    Ok(())
34}

Trait Implementations§

Source§

impl Clone for Table

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Table

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !Freeze for Table

§

impl !RefUnwindSafe for Table

§

impl !UnwindSafe for Table

§

impl Send for Table

§

impl Sync for Table

§

impl Unpin for Table

§

impl UnsafeUnpin for Table

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more