Skip to main content

DatabaseClient

Struct DatabaseClient 

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

A client for interacting with a specific Spanner database.

DatabaseClient provides methods to execute transactions and queries.

§Example

    let spanner = Spanner::builder().build().await?;
    let database_client = spanner
        .database_client("projects/my-project/instances/my-instance/databases/my-db")
        .build()
        .await?;

DatabaseClient provides methods to execute transactions and queries. It holds a single multiplexed session for the database.

A DatabaseClient is intended to be a long-lived object, and normally an application will have a single DatabaseClient per database. The client is thread-safe and should be reused for all operations on the database.

Cloning a DatabaseClient is cheap, as it shares the underlying session and channel.

Implementations§

Source§

impl DatabaseClient

Source

pub fn single_use(&self) -> SingleUseReadOnlyTransactionBuilder

Returns a builder for a single-use read-only transaction.

§Example
let db_client = spanner.database_client("projects/p/instances/i/databases/d").build().await?;
let tx = db_client.single_use().build();
let stmt = Statement::builder("SELECT * FROM users WHERE id = @id")
    .add_param("id", &42)
    .build();
let mut rs = tx.execute_query(stmt).await?;

A single-use read-only transaction is optimized for the case where only a single read or query is needed. This is more efficient than using a read-only transaction for a single read or query.

Source

pub fn read_only_transaction(&self) -> MultiUseReadOnlyTransactionBuilder

Returns a builder for a multi-use read-only transaction.

§Example
let db_client = spanner.database_client("projects/p/instances/i/databases/d").build().await?;
let tx = db_client.read_only_transaction().build().await?;
let stmt = Statement::builder("SELECT * FROM users WHERE id = @id")
    .add_param("id", &42)
    .build();
let mut rs = tx.execute_query(stmt).await?;

A read-only transaction can be used to execute multiple reads or queries. These transactions guarantee data consistency across multiple read operations, but don’t permit data modifications. Read-only transactions do not take locks.

Source

pub fn batch_read_only_transaction(&self) -> BatchReadOnlyTransactionBuilder

Returns a builder for a batch read-only transaction.

§Example
let db_client = spanner.database_client("projects/p/instances/i/databases/d").build().await?;
let transaction = db_client.batch_read_only_transaction().build().await?;

A batch read-only transaction is similar to a read-only transaction, but it allows for partitioning a read or query request. Run tasks in parallel over the partitions to execute a large read or query.

Source

pub fn partitioned_dml_transaction(&self) -> PartitionedDmlTransactionBuilder

Returns a builder for a partitioned DML transaction.

§Example
let db_client = spanner.database_client("projects/p/instances/i/databases/d").build().await?;
let transaction = db_client.partitioned_dml_transaction().build().await?;
let statement = Statement::builder("UPDATE users SET active = true WHERE TRUE").build();
let modified_rows = transaction.execute_update(statement).await?;

Partitioned DML is used to execute a single DML statement that may modify a large number of rows. The execution of the statement will automatically be partitioned into smaller transactions by Spanner, which may execute in parallel.

See also: https://docs.cloud.google.com/spanner/docs/dml-partitioned

Source

pub fn read_write_transaction(&self) -> TransactionRunnerBuilder

Returns a builder for a read-write transaction runner.

§Example
let db_client = spanner.database_client("projects/p/instances/i/databases/d").build().await?;
let runner = db_client.read_write_transaction().build().await?;
let result = runner.run(async |transaction| {
    let statement = Statement::builder("UPDATE users SET active = true WHERE id = 1").build();
    transaction.execute_update(statement).await?;
    Ok(())
}).await?;

Read-write transactions can be used to execute multiple queries and updates atomically. If the transaction is aborted by Spanner, the run method will automatically retry the transaction.

Source

pub fn write_only_transaction(&self) -> WriteOnlyTransactionBuilder

Returns a builder for a write-only transaction.

§Example
let client = Spanner::builder().build().await?;
let db = client.database_client("projects/p/instances/i/databases/d").build().await?;

let mutation = Mutation::new_insert_builder("Users")
    .set("UserId").to(&1)
    .set("UserName").to(&"Alice")
    .build();

let response = db.write_only_transaction()
    .set_transaction_tag("my-tag")
    .build()
    .write(vec![mutation])
    .await?;

A write-only transaction is used to execute blind writes using mutations.

Source

pub fn batch_write_transaction(&self) -> BatchWriteTransactionBuilder

Returns a builder for a batch write transaction.

§Example
let client = Spanner::builder().build().await?;
let db = client.database_client("projects/p/instances/i/databases/d").build().await?;

let mutation1a = Mutation::new_insert_builder("Users")
    .set("UserId").to(&1)
    .build();
let mutation1b = Mutation::new_insert_builder("UserRoles")
    .set("UserId").to(&1)
    .set("Role").to(&"Admin")
    .build();
let group1 = MutationGroup::new(vec![mutation1a, mutation1b]);

let mutation2 = Mutation::new_insert_builder("Users")
    .set("UserId").to(&2)
    .build();
let group2 = MutationGroup::new(vec![mutation2]);

let transaction = db.batch_write_transaction().build();
let mut stream = transaction.execute_streaming(vec![group1, group2]).await?;

while let Some(response) = stream.next().await {
    let response = response?;
    if let Some(status) = response.status.as_ref().filter(|s| s.code != Code::Ok as i32) {
        eprintln!("Error applying groups {:?}: {}", response.indexes, status.message);
    } else {
        println!("Applied groups: {:?}", response.indexes);
    }
}

A batch write transaction is used to execute non-atomic writes using mutations. Related mutations should be placed in a group. For example, two mutations inserting rows with the same primary key prefix in both parent and child tables are related. All mutations within a group are applied atomically, but the entire batch is not guaranteed to be atomic.

Trait Implementations§

Source§

impl Clone for DatabaseClient

Source§

fn clone(&self) -> DatabaseClient

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 DatabaseClient

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
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> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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