use derive_builder::Builder; use serde::Serialize; use sqlx::{PgExecutor, postgres::types::Oid, query_as}; use uuid::Uuid; use crate::field::{Field, FieldType}; #[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, } impl Lens { pub fn insertable_builder() -> InsertableLensBuilder { InsertableLensBuilder::default() } pub async fn fetch_by_id<'a, E: PgExecutor<'a>>( id: Uuid, app_db: E, ) -> Result, sqlx::Error> { query_as!( Self, r#" select id, name, base_id, class_oid, display_type as "display_type: LensDisplayType" from lenses where id = $1 "#, id ) .fetch_optional(app_db) .await } pub async fn fetch_by_rel<'a, E: PgExecutor<'a>>( base_id: Uuid, rel_oid: Oid, app_db: E, ) -> Result, sqlx::Error> { query_as!( Self, r#" select id, name, base_id, class_oid, display_type as "display_type: LensDisplayType" from lenses where base_id = $1 and class_oid = $2 "#, base_id, rel_oid ) .fetch_all(app_db) .await } pub async fn fetch_fields<'a, E: PgExecutor<'a>>( &self, app_db: E, ) -> Result, sqlx::Error> { query_as!( Field, r#" select id, name, label, field_type as "field_type: sqlx::types::Json", width_px from fields where lens_id = $1 "#, self.id ) .fetch_all(app_db) .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 { pub async fn insert<'a, E: PgExecutor<'a>>(self, app_db: E) -> Result { 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, display_type as "display_type: LensDisplayType" "#, Uuid::now_v7(), self.base_id, self.class_oid, self.name, self.display_type as LensDisplayType ) .fetch_one(app_db) .await } }