spanner-rs

Crates.iospanner-rs
lib.rsspanner-rs
version0.3.0
sourcesrc
created_at2021-09-29 01:47:05.853795
updated_at2022-09-27 03:33:28.285641
descriptionCloud Spanner Rust Client
homepage
repositoryhttps://github.com/plaflamme/spanner-rs/
max_upload_size
id457846
size132,329
Philippe Laflamme (plaflamme)

documentation

README

spanner-rs

An asynchronous Rust client for Cloud Spanner.

Build Status Crates.io Documentation Crates.io

Implementation

The client uses gRPC to interface with Cloud Spanner. As such, this crate uses tonic and related crates (i.e.: prost, tower and tokio).

The client also uses bb8 to maintain a pool of Cloud Spanner sessions (conceptually similar to a connection pool in other databases).

The implementation is heavily inspired by the excellent postgres and related crates.

Status

Spanner is a complex database and this client does not implement all available features. The current focus is on getting idiomatic SQL support for both reads and writes.

It's not recommended to use this in production for any serious workload.

Features

Database Client

  • SQL read-only, single use, time-bounded transactions
  • SQL read-write transactions with retries
  • Type classes to convert Rust values to/from Cloud Spanner values
  • Timestamp and Date type support (chrono feature?)
  • Json type support (serde json feature)
  • Streaming result sets
  • Derive ToSpanner and FromSpanner for structs

Admin Client

  • DDL statements

Example

use spanner_rs::{Client, Error, ReadContext, TransactionContext};

#[tokio::main]
async fn main() -> Result<(), Error> {
    let mut client = Client::configure()
        .project("my-gcp-project")
        .instance("my-instance")
        .database("my-database")
        .connect()
        .await?;

    // assuming the following table:
    //   person(id INT64, name STRING(MAX), data BYTES(MAX))
    client
        .read_write()
        .run(|tx| {
            tx.execute_update(
                "INSERT INTO person(id, name, data) VALUES(@id, @name, NULL)",
                &[("id", &42), ("name", &"ferris")],
            )
        })
        .await?;

    let result_set = client
        .read_only()
        .execute_query("SELECT * FROM person", &[])
        .await?;

    for row in result_set.iter() {
        let id: u32 = row.get("id")?;
        let name: &str = row.get("name")?;
        let data: Option<&[u8]> = row.get("data")?;

        println!("found person: {} {} {:?}", id, name, data);
    }

    Ok(())
}
Commit count: 255

cargo fmt