WIP: feat: one-to-many relation helper
This commit is contained in:
parent
32ef1f7b33
commit
bdcbccee71
23 changed files with 662 additions and 99 deletions
18
lib/sqlxgentools_misc/Cargo.toml
Normal file
18
lib/sqlxgentools_misc/Cargo.toml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "sqlxgentools_misc"
|
||||
description = "Various misc class to use in applications that use sqlxgentools"
|
||||
publish = true
|
||||
edition.workspace = true
|
||||
authors.workspace = true
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
sqlx-core = { version = "=0.8.6" }
|
||||
sqlx-sqlite = { version = "=0.8.6", features = ["offline"] }
|
||||
|
||||
[lib]
|
||||
|
||||
[lints.clippy]
|
||||
uninlined_format_args = "allow"
|
||||
75
lib/sqlxgentools_misc/src/lib.rs
Normal file
75
lib/sqlxgentools_misc/src/lib.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
use std::error::Error;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use sqlx_core::any::{Any, AnyArgumentBuffer};
|
||||
use sqlx_core::database::Database;
|
||||
use sqlx_core::decode::Decode;
|
||||
use sqlx_core::encode::{Encode, IsNull};
|
||||
use sqlx_core::error::BoxDynError;
|
||||
use sqlx_core::types::Type;
|
||||
use sqlx_sqlite::{Sqlite, SqliteArgumentValue};
|
||||
|
||||
|
||||
pub trait DatabaseLine {
|
||||
fn id(&self) -> String;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ForeignRef<T: Sized + DatabaseLine> {
|
||||
pub target_type: PhantomData<T>,
|
||||
pub target_id: String
|
||||
}
|
||||
|
||||
impl<T: Sized + DatabaseLine> ForeignRef<T> {
|
||||
pub fn new(entity: &T) -> ForeignRef<T> {
|
||||
ForeignRef {
|
||||
target_type: PhantomData,
|
||||
target_id: entity.id()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GenericModel {
|
||||
}
|
||||
|
||||
|
||||
impl<'r, DB: Database, T: Sized + DatabaseLine> Decode<'r, DB> for ForeignRef<T>
|
||||
where
|
||||
// we want to delegate some of the work to string decoding so let's make sure strings
|
||||
// are supported by the database
|
||||
&'r str: Decode<'r, DB>
|
||||
{
|
||||
fn decode(
|
||||
value: <DB as Database>::ValueRef<'r>,
|
||||
) -> Result<ForeignRef<T>, Box<dyn Error + 'static + Send + Sync>> {
|
||||
let value = <&str as Decode<DB>>::decode(value)?;
|
||||
|
||||
let ref_val: String = value.parse()?;
|
||||
|
||||
Ok(ForeignRef::<T> {
|
||||
target_type: PhantomData,
|
||||
target_id: ref_val
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DatabaseLine + Sized> Encode<'_, Any> for ForeignRef<T> {
|
||||
fn encode_by_ref(&self, buf: &mut AnyArgumentBuffer) -> Result<IsNull, BoxDynError> {
|
||||
<String as Encode<'_, Any>>::encode_by_ref(&self.target_id.to_string(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DatabaseLine + Sized> Type<Sqlite> for ForeignRef<T> {
|
||||
fn type_info() -> <Sqlite as Database>::TypeInfo {
|
||||
<String as Type<Sqlite>>::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DatabaseLine + Sized> Encode<'_, Sqlite> for ForeignRef<T> {
|
||||
fn encode_by_ref(&self, args: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(self.target_id.clone().into()));
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue