Skip to content

Commit

Permalink
Add QueryExecutor trait
Browse files Browse the repository at this point in the history
The trait enables writing functions that don't care if they're executed in a transaction or directly on a client
  • Loading branch information
CodesInChaos committed Aug 28, 2024
1 parent 99de7ec commit 612599c
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 0 deletions.
2 changes: 2 additions & 0 deletions edgedb-tokio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ mod sealed;
pub mod state;
mod transaction;
pub mod tutorial;
mod query_executor;

pub use edgedb_derive::{ConfigDelta, GlobalsDelta, Queryable};

Expand All @@ -147,6 +148,7 @@ pub use errors::Error;
pub use options::{RetryCondition, RetryOptions, TransactionOptions};
pub use state::{ConfigDelta, GlobalsDelta};
pub use transaction::Transaction;
pub use query_executor::QueryExecutor;

#[cfg(feature = "unstable")]
pub use builder::get_project_dir;
Expand Down
192 changes: 192 additions & 0 deletions edgedb-tokio/src/query_executor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
use edgedb_protocol::model::Json;
use edgedb_protocol::query_arg::QueryArgs;
use edgedb_protocol::QueryResult;
use std::future::Future;

use crate::{Client, Error, Transaction};

/// Abstracts over different query executors
/// In particular &Client and &mut Transaction
pub trait QueryExecutor {
/// see [Client::query]
fn query<R, A>(self, query: &str, arguments: &A) -> impl Future<Output = Result<Vec<R>, Error>>
where
A: QueryArgs,
R: QueryResult;

/// see [Client::query_single]
fn query_single<R, A>(
self,
query: &str,
arguments: &A,
) -> impl Future<Output = Result<Option<R>, Error>>
where
A: QueryArgs,
R: QueryResult;

/// see [Client::query_required_single]
fn query_required_single<R, A>(
self,
query: &str,
arguments: &A,
) -> impl Future<Output = Result<R, Error>>
where
A: QueryArgs,
R: QueryResult;

/// see [Client::query_json]
fn query_json(
self,
query: &str,
arguments: &impl QueryArgs,
) -> impl Future<Output = Result<Json, Error>>;

/// see [Client::query_single_json]
fn query_single_json(
&mut self,
query: &str,
arguments: &impl QueryArgs,
) -> impl Future<Output = Result<Option<Json>, Error>>;

/// see [Client::query_required_single_json]
fn query_required_single_json(
&mut self,
query: &str,
arguments: &impl QueryArgs,
) -> impl Future<Output = Result<Json, Error>>;

/// see [Client::execute]
fn execute<A>(&mut self, query: &str, arguments: &A) -> impl Future<Output = Result<(), Error>>
where
A: QueryArgs;
}

impl QueryExecutor for &Client {
fn query<R, A>(self, query: &str, arguments: &A) -> impl Future<Output = Result<Vec<R>, Error>>
where
A: QueryArgs,
R: QueryResult,
{
Client::query(self, query, arguments)
}

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

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

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

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

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

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

impl QueryExecutor for &mut Transaction {
fn query<R, A>(self, query: &str, arguments: &A) -> impl Future<Output = Result<Vec<R>, Error>>
where
A: QueryArgs,
R: QueryResult,
{
Transaction::query(self, query, arguments)
}

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

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

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

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

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

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

0 comments on commit 612599c

Please sign in to comment.