Created
September 5, 2020 16:25
-
-
Save DrBluefall/d7f20b6394a5c1db25e42f27939b0f04 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! Database-specific traits. | |
//! | |
//! The main traits for implementing a database within Telephone. Backends for the bot should implement [`Database`], along with all the relevant | |
//! database operation traits in this module for the types they wish to use with the backend. | |
use serenity::futures::future::BoxFuture as BoxedFuture; | |
use serenity::futures::FutureExt; | |
use sqlx::Acquire; | |
#[cfg(any( | |
feature = "with-postgres", | |
feature = "with-mysql", | |
feature = "with-sqlite" | |
))] | |
impl<'c, A: 'c> Database<'c> for A | |
where | |
A: Acquire<'c> + Send, | |
for<'e> &'e mut <A::Database as sqlx::Database>::Connection: sqlx::Executor<'e>, | |
{ | |
type Error = sqlx::Error; | |
type Backend = &'c mut sqlx::Transaction<'c, <A as Acquire<'c>>::Database>; | |
fn create<T: Create<'c, Self>>(self, key: T::Key) -> BoxedFuture<'c, Result<(), Self::Error>> { | |
async move { | |
let tx = self.begin().await?; | |
match T::create(key, &mut tx).await { | |
Ok(v) => { | |
tx.commit().await; | |
Ok(()) | |
} | |
Err(e) => { | |
tx.rollback().await; | |
Err(e) | |
} | |
} | |
}.boxed() | |
/* | |
error[E0308]: mismatched types | |
--> src/util/database.rs:36:11 | |
| | |
36 | }.boxed() | |
| ^^^^^ one type is more general than the other | |
| | |
= note: expected type `sqlx::Acquire<'_>` | |
found type `sqlx::Acquire<'c>` | |
*/ | |
} | |
fn read<T: Read<'c, Self>>(self, key: T::Key) -> BoxedFuture<'c, Result<Option<T>, Self::Error>> { | |
todo!() | |
} | |
fn update<T: Update<'c, Self>>(self, target: T) -> BoxedFuture<'c, Result<(), Self::Error>> { | |
todo!() | |
} | |
fn delete<T: Delete<'c, Self>>(self, target: T) -> BoxedFuture<'c, Result<(), Self::Error>> { | |
todo!() | |
} | |
} | |
/// The main trait for backends. | |
/// | |
/// This is the main trait for backends to implement in order to be used with the bot, and allows for a generic interface between the discord frontend and | |
/// database backend. | |
pub trait Database<'c>: Send + Sized { | |
type Error: std::error::Error; | |
type Backend; | |
fn create<T: Create<'c, Self>>(self, key: T::Key) -> BoxedFuture<'c, Result<(), Self::Error>>; | |
fn read<T: Read<'c, Self>>(self, key: T::Key) -> BoxedFuture<'c, Result<Option<T>, Self::Error>>; | |
fn update<T: Update<'c, Self>>(self, target: T) -> BoxedFuture<'c, Result<(), Self::Error>>; | |
fn delete<T: Delete<'c, Self>>(self, target: T) -> BoxedFuture<'c, Result<(), Self::Error>>; | |
} | |
/// Trait for creating a database object. | |
pub trait Create<'c, T: Database<'c>>: Sized { | |
type Key: Send + Sync; | |
fn create(key: Self::Key, db: T::Backend) -> BoxedFuture<'c, Result<(), T::Error>>; | |
} | |
/// Trait for reading an object from the database. | |
pub trait Read<'c, T: Database<'c>>: Sized { | |
type Key: Send + Sync; | |
fn read(key: Self::Key, db: T::Backend) -> BoxedFuture<'c, Result<Option<Self>, T::Error>>; | |
} | |
/// Trait for updating a database object. | |
pub trait Update<'c, T: Database<'c>>: Sized + Send { | |
fn update(self, db: T::Backend) -> BoxedFuture<'c, Result<(), T::Error>>; | |
} | |
/// Trait for deleting a database object. | |
pub trait Delete<'c, T: Database<'c>>: Sized + Send { | |
fn delete(self, db: T::Backend) -> BoxedFuture<'c, Result<(), T::Error>>; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment