phonograph/interim-models/src/lens.rs

191 lines
4.1 KiB
Rust
Raw Normal View History

2025-07-08 14:37:03 -07:00
use derive_builder::Builder;
use serde::Serialize;
2025-08-24 23:24:01 -07:00
use sqlx::{postgres::types::Oid, query, query_as, types::Json};
2025-07-08 14:37:03 -07:00
use uuid::Uuid;
2025-08-24 23:24:01 -07:00
use crate::{client::AppDbClient, expression::PgExpressionAny};
2025-07-08 14:37:03 -07:00
#[derive(Clone, Debug, Serialize)]
pub struct Lens {
pub id: Uuid,
pub name: String,
pub base_id: Uuid,
pub class_oid: Oid,
pub display_type: LensDisplayType,
2025-08-24 23:24:01 -07:00
pub filter: Json<Option<PgExpressionAny>>,
2025-07-08 14:37:03 -07:00
}
impl Lens {
pub fn insertable_builder() -> InsertableLensBuilder {
InsertableLensBuilder::default()
}
2025-08-24 23:24:01 -07:00
pub fn update() -> LensUpdateBuilder {
LensUpdateBuilder::default()
}
2025-08-04 13:59:42 -07:00
pub fn with_id(id: Uuid) -> WithIdQuery {
WithIdQuery { id }
}
pub fn belonging_to_base(base_id: Uuid) -> BelongingToBaseQuery {
BelongingToBaseQuery { base_id }
}
}
#[derive(Clone, Debug)]
pub struct WithIdQuery {
id: Uuid,
}
impl WithIdQuery {
pub async fn fetch_optional(
self,
app_db: &mut AppDbClient,
) -> Result<Option<Lens>, sqlx::Error> {
2025-07-08 14:37:03 -07:00
query_as!(
2025-08-04 13:59:42 -07:00
Lens,
2025-07-08 14:37:03 -07:00
r#"
select
id,
name,
base_id,
class_oid,
2025-08-24 23:24:01 -07:00
display_type as "display_type: LensDisplayType",
filter as "filter: Json<Option<PgExpressionAny>>"
2025-07-08 14:37:03 -07:00
from lenses
where id = $1
"#,
2025-08-04 13:59:42 -07:00
self.id
2025-07-08 14:37:03 -07:00
)
2025-08-04 13:59:42 -07:00
.fetch_optional(&mut *app_db.conn)
2025-07-08 14:37:03 -07:00
.await
}
2025-08-04 13:59:42 -07:00
pub async fn fetch_one(self, app_db: &mut AppDbClient) -> Result<Lens, sqlx::Error> {
2025-07-08 14:37:03 -07:00
query_as!(
2025-08-04 13:59:42 -07:00
Lens,
2025-07-08 14:37:03 -07:00
r#"
select
id,
name,
base_id,
class_oid,
2025-08-24 23:24:01 -07:00
display_type as "display_type: LensDisplayType",
filter as "filter: Json<Option<PgExpressionAny>>"
2025-07-08 14:37:03 -07:00
from lenses
2025-08-04 13:59:42 -07:00
where id = $1
2025-07-08 14:37:03 -07:00
"#,
2025-08-04 13:59:42 -07:00
self.id
2025-07-08 14:37:03 -07:00
)
2025-08-04 13:59:42 -07:00
.fetch_one(&mut *app_db.conn)
2025-07-08 14:37:03 -07:00
.await
}
2025-08-04 13:59:42 -07:00
}
2025-07-08 14:37:03 -07:00
2025-08-04 13:59:42 -07:00
#[derive(Clone, Debug)]
pub struct BelongingToBaseQuery {
base_id: Uuid,
}
impl BelongingToBaseQuery {
pub fn belonging_to_rel(self, rel_oid: Oid) -> BelongingToRelQuery {
BelongingToRelQuery {
base_id: self.base_id,
rel_oid,
}
}
}
#[derive(Clone, Debug)]
pub struct BelongingToRelQuery {
base_id: Uuid,
rel_oid: Oid,
}
impl BelongingToRelQuery {
pub async fn fetch_all(self, app_db: &mut AppDbClient) -> Result<Vec<Lens>, sqlx::Error> {
2025-07-08 14:37:03 -07:00
query_as!(
2025-08-04 13:59:42 -07:00
Lens,
2025-07-08 14:37:03 -07:00
r#"
select
id,
2025-07-18 16:20:03 -07:00
name,
2025-08-04 13:59:42 -07:00
base_id,
class_oid,
2025-08-24 23:24:01 -07:00
display_type as "display_type: LensDisplayType",
filter as "filter: Json<Option<PgExpressionAny>>"
2025-08-04 13:59:42 -07:00
from lenses
where base_id = $1 and class_oid = $2
2025-07-08 14:37:03 -07:00
"#,
2025-08-04 13:59:42 -07:00
self.base_id,
self.rel_oid
2025-07-08 14:37:03 -07:00
)
2025-08-04 13:59:42 -07:00
.fetch_all(&mut *app_db.conn)
2025-07-08 14:37:03 -07:00
.await
}
}
#[derive(Clone, Debug, Serialize, sqlx::Type)]
#[sqlx(type_name = "lens_display_type", rename_all = "lowercase")]
pub enum LensDisplayType {
Table,
}
#[derive(Builder, Clone, Debug)]
pub struct InsertableLens {
name: String,
base_id: Uuid,
class_oid: Oid,
display_type: LensDisplayType,
}
impl InsertableLens {
2025-08-04 13:59:42 -07:00
pub async fn insert(self, app_db: &mut AppDbClient) -> Result<Lens, sqlx::Error> {
2025-07-08 14:37:03 -07:00
query_as!(
Lens,
r#"
insert into lenses
(id, base_id, class_oid, name, display_type)
values ($1, $2, $3, $4, $5)
returning
id,
name,
base_id,
class_oid,
2025-08-24 23:24:01 -07:00
display_type as "display_type: LensDisplayType",
filter as "filter: Json<Option<PgExpressionAny>>"
2025-07-08 14:37:03 -07:00
"#,
Uuid::now_v7(),
self.base_id,
self.class_oid,
self.name,
self.display_type as LensDisplayType
)
2025-08-04 13:59:42 -07:00
.fetch_one(&mut *app_db.conn)
2025-07-08 14:37:03 -07:00
.await
}
}
2025-08-24 23:24:01 -07:00
#[derive(Builder, Clone, Debug)]
pub struct LensUpdate {
id: Uuid,
#[builder(setter(strip_option = true))]
filter: Option<Option<PgExpressionAny>>,
}
impl LensUpdate {
pub async fn execute(self, app_db: &mut AppDbClient) -> Result<(), sqlx::Error> {
if let Some(filter) = self.filter {
query!(
"update lenses set filter = $1 where id = $2",
Json(filter) as Json<Option<PgExpressionAny>>,
self.id
)
.execute(&mut *app_db.conn)
.await?;
}
Ok(())
}
}