Client

Struct Client 

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

Gel database client.

Internally it contains a connection pool.

To create a client, use create_client function (it gets database connection configuration from environment). You can also use Builder to build custom Config and create a client using that config.

The with_ methods (with_retry_options, with_transaction_options, etc.) let you create a shallow copy of the client with adjusted options.

Implementations§

Source§

impl Client

Source

pub fn new(config: &Config) -> Client

Create a new connection pool.

Note this does not create a connection immediately. Use ensure_connected() to establish a connection and verify that the connection is usable.

Source

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

Ensure that there is at least one working connection to the pool.

This can be used at application startup to ensure that you have a working connection.

Source

pub async fn query_verbose<R, A>( &self, query: impl AsRef<str> + Send, arguments: &A, ) -> Result<ResultVerbose<Vec<R>>, Error>
where A: QueryArgs, R: QueryResult,

Execute a query and return a collection of results and warnings produced by the server.

You will usually have to specify the return type for the query:

let greeting: (Vec<String>, _) = conn.query_with_warnings("select 'hello'", &()).await?;

This method can be used with both static arguments, like a tuple of scalars, and with dynamic arguments gel_protocol::value::Value. Similarly, dynamically typed results are also supported.

Source

pub async fn query<R, A>( &self, query: impl AsRef<str> + Send, arguments: &A, ) -> Result<Vec<R>, Error>
where A: QueryArgs, R: QueryResult,

Execute a query and return a collection of results.

You will usually have to specify the return type for the query:

let greeting = pool.query::<String, _>("SELECT 'hello'", &());
// or
let greeting: Vec<String> = pool.query("SELECT 'hello'", &());

let two_numbers: Vec<i32> = conn.query("select {<int32>$0, <int32>$1}", &(10, 20)).await?;

This method can be used with both static arguments, like a tuple of scalars, and with dynamic arguments gel_protocol::value::Value. Similarly, dynamically typed results are also supported.

Source

pub async fn query_single<R, A>( &self, query: impl AsRef<str> + Send, arguments: &A, ) -> Result<Option<R>, Error>
where A: QueryArgs, R: QueryResult + Send,

Execute a query and return a single result

You will usually have to specify the return type for the query:

let greeting = pool.query_single::<String, _>("SELECT 'hello'", &());
// or
let greeting: Option<String> = pool.query_single(
    "SELECT 'hello'",
    &()
);

This method can be used with both static arguments, like a tuple of scalars, and with dynamic arguments gel_protocol::value::Value. Similarly, dynamically typed results are also supported.

Source

pub async fn query_required_single<R, A>( &self, query: impl AsRef<str> + Send, arguments: &A, ) -> Result<R, Error>
where A: QueryArgs, R: QueryResult + Send,

Execute a query and return a single result

The query must return exactly one element. If the query returns more than one element, a ResultCardinalityMismatchError is raised. If the query returns an empty set, a NoDataError is raised.

You will usually have to specify the return type for the query:

let greeting = pool.query_required_single::<String, _>(
    "SELECT 'hello'",
    &(),
);
// or
let greeting: String = pool.query_required_single(
    "SELECT 'hello'",
    &(),
);

This method can be used with both static arguments, like a tuple of scalars, and with dynamic arguments gel_protocol::value::Value. Similarly, dynamically typed results are also supported.

Source

pub async fn query_json( &self, query: impl AsRef<str>, arguments: &impl QueryArgs, ) -> Result<Json, Error>

Execute a query and return the result as JSON.

Source

pub async fn query_single_json( &self, query: impl AsRef<str>, arguments: &impl QueryArgs, ) -> Result<Option<Json>, Error>

Execute a query and return a single result as JSON.

The query must return exactly one element. If the query returns more than one element, a ResultCardinalityMismatchError is raised.

let query = "select <json>(
    insert Account {
    username := <str>$0
    }) {
    username,
    id
    };";
let json_res: Option<Json> = client
 .query_single_json(query, &("SomeUserName",))
    .await?;
Source

pub async fn query_required_single_json( &self, query: impl AsRef<str>, arguments: &impl QueryArgs, ) -> Result<Json, Error>

Execute a query and return a single result as JSON.

The query must return exactly one element. If the query returns more than one element, a ResultCardinalityMismatchError is raised. If the query returns an empty set, a NoDataError is raised.

Source

pub async fn execute<A>( &self, query: impl AsRef<str>, arguments: &A, ) -> Result<(), Error>
where A: QueryArgs,

Execute a query and don’t expect result

This method can be used with both static arguments, like a tuple of scalars, and with dynamic arguments gel_protocol::value::Value. Similarly, dynamically typed results are also supported.

Source

pub async fn transaction<T, B, F>(&self, body: B) -> Result<T, Error>
where B: FnMut(RetryingTransaction) -> F, F: Future<Output = Result<T, Error>>,

Execute a transaction and retry.

Transaction body must be encompassed in the closure. The closure may be executed multiple times. This includes not only database queries but also executing the whole function, so the transaction code must be prepared to be idempotent.

§Example
let conn = gel_tokio::create_client().await?;
let val = conn.transaction(|mut tx| async move {
    tx.query_required_single::<i64, _>("
        WITH C := UPDATE Counter SET { value := .value + 1}
        SELECT C.value LIMIT 1
        ", &()
    ).await
}).await?;
§Commit and rollback

If the closure returns Result::Ok, the transaction is committed. If the closure returns Result::Err, the transaction is either retried or aborted, depending on weather the error has `SHOULD_RETRY`` tag set.

To manually abort a transaction, gel_errors::UserError can be returned:

use gel_errors::ErrorKind;
let val = conn.transaction(|mut tx| async move {
    tx.execute("UPDATE Foo SET { x := 1 };", &()).await;
    Err(gel_errors::UserError::build()) // abort transaction
}).await?;
§Returning custom errors

See this example and the documentation of the gel-errors crate for how to return custom error types.

§Panics

Function panics when transaction object passed to the closure is not dropped after closure exists. General rule: do not store transaction anywhere and do not send to another coroutine. Pass to all further function calls by reference.

Source

pub fn with_transaction_options(&self, options: TransactionOptions) -> Self

Returns client with adjusted options for future transactions.

This method returns a “shallow copy” of the current client with modified transaction options.

Both self and returned client can be used after, but when using them transaction options applied will be different.

Transaction options are used by the transaction method.

Source

pub fn with_retry_options(&self, options: RetryOptions) -> Self

Returns client with adjusted options for future retrying transactions.

This method returns a “shallow copy” of the current client with modified transaction options.

Both self and returned client can be used after, but when using them transaction options applied will be different.

Source

pub fn with_globals(&self, globals: impl GlobalsDelta) -> Self

Returns the client with the specified global variables set

Most commonly used with #[derive(GlobalsDelta)].

Note: this method is incremental, i.e. it adds (or removes) globals instead of setting a definite set of variables. Use .with_globals(Unset(["name1", "name2"])) to unset some variables.

This method returns a “shallow copy” of the current client with modified global variables

Both self and returned client can be used after, but when using them transaction options applied will be different.

Source

pub fn with_globals_fn(&self, f: impl FnOnce(&mut GlobalsModifier<'_>)) -> Self

Returns the client with the specified global variables set

This method returns a “shallow copy” of the current client with modified global variables

Both self and returned client can be used after, but when using them transaction options applied will be different.

This is equivalent to .with_globals(Fn(f)) but more ergonomic as it allows type inference for lambda.

Source

pub fn with_aliases(&self, aliases: impl AliasesDelta) -> Self

Returns the client with the specified aliases set

This method returns a “shallow copy” of the current client with modified aliases.

Both self and returned client can be used after, but when using them transaction options applied will be different.

Source

pub fn with_aliases_fn(&self, f: impl FnOnce(&mut AliasesModifier<'_>)) -> Self

Returns the client with the specified aliases set

This method returns a “shallow copy” of the current client with modified aliases.

Both self and returned client can be used after, but when using them transaction options applied will be different.

This is equivalent to .with_aliases(Fn(f)) but more ergonomic as it allows type inference for lambda.

Source

pub fn with_default_module(&self, module: Option<impl Into<String>>) -> Self

Returns the client with the default module set or unset

This method returns a “shallow copy” of the current client with modified default module.

Both self and returned client can be used after, but when using them transaction options applied will be different.

Source

pub fn with_config(&self, cfg: impl ConfigDelta) -> Self

Returns the client with the specified config

Note: this method is incremental, i.e. it adds (or removes) individual settings instead of setting a definite configuration. Use .with_config(Unset(["name1", "name2"])) to unset some settings.

This method returns a “shallow copy” of the current client with modified global variables

Both self and returned client can be used after, but when using them transaction options applied will be different.

Source

pub fn with_config_fn(&self, f: impl FnOnce(&mut ConfigModifier<'_>)) -> Self

Returns the client with the specified config

Most commonly used with #[derive(ConfigDelta)].

This method returns a “shallow copy” of the current client with modified global variables

Both self and returned client can be used after, but when using them transaction options applied will be different.

This is equivalent to .with_config(Fn(f)) but more ergonomic as it allows type inference for lambda.

Source

pub fn with_tag(&self, tag: Option<&str>) -> Result<Self, Error>

Returns the client with the specified query tag.

This method returns a “shallow copy” of the current client with modified query tag.

Both self and returned client can be used after, but when using them query tag applied will be different.

Trait Implementations§

Source§

impl Clone for Client

Source§

fn clone(&self) -> Client

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for Client

Source§

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

Formats the value using the given formatter. Read more
Source§

impl QueryExecutor for &Client

Source§

fn query<R, A>( self, query: impl AsRef<str> + Send, arguments: &A, ) -> impl Future<Output = Result<Vec<R>, Error>>
where A: QueryArgs, R: QueryResult,

Source§

fn query_verbose<R, A>( self, query: impl AsRef<str> + Send, arguments: &A, ) -> impl Future<Output = Result<ResultVerbose<Vec<R>>, Error>> + Send
where A: QueryArgs, R: QueryResult + Send,

Source§

fn query_single<R, A>( self, query: impl AsRef<str> + Send, arguments: &A, ) -> impl Future<Output = Result<Option<R>, Error>>
where A: QueryArgs, R: QueryResult + Send,

Source§

fn query_required_single<R, A>( self, query: impl AsRef<str> + Send, arguments: &A, ) -> impl Future<Output = Result<R, Error>>
where A: QueryArgs, R: QueryResult + Send,

Source§

fn query_json( self, query: &str, arguments: &impl QueryArgs, ) -> impl Future<Output = Result<Json, Error>>

Source§

fn query_single_json( self, query: &str, arguments: &impl QueryArgs, ) -> impl Future<Output = Result<Option<Json>, Error>>

Source§

fn query_required_single_json( self, query: &str, arguments: &impl QueryArgs, ) -> impl Future<Output = Result<Json, Error>>

Source§

fn execute<A>( self, query: &str, arguments: &A, ) -> impl Future<Output = Result<(), Error>>
where A: QueryArgs,

Auto Trait Implementations§

§

impl Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl !UnwindSafe for Client

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> EncoderForExt for T
where T: ?Sized,

Source§

fn to_vec<F>(&self) -> Vec<u8>
where F: 'static, Self: EncoderFor<F>,

Convert this builder into a vector of bytes. This is generally not the most efficient way to perform serialization.
Source§

fn encode_buffer<F>(&self, buf: &mut [u8]) -> Result<usize, usize>
where F: 'static, Self: EncoderFor<F>,

Encode this builder into a given buffer. If the buffer is too small, the function will return the number of bytes required to encode the builder.
Source§

fn encode_buffer_uninit<'a, F>( &self, buf: &'a mut [MaybeUninit<u8>], ) -> Result<&'a mut [u8], usize>
where F: 'static, Self: EncoderFor<F>,

Encode this builder into a given buffer. If the buffer is too small, the function will return the number of bytes required to encode the builder.
Source§

fn measure<F>(&self) -> usize
where F: 'static, Self: EncoderFor<F>,

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

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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
Source§

impl<T> ErasedDestructor for T
where T: 'static,