From 2010bc68fd7eb3634f89ce0c8a165c03c27cbd5a Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Mon, 13 Jan 2025 18:42:02 +0800 Subject: [PATCH] SeaORM schema metadata --- Cargo.toml | 6 +++++- examples/sqlite/Cargo.toml | 3 +++ src/builder.rs | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 07feaa8..c256227 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,12 +17,13 @@ categories = ["database"] [dependencies] async-graphql = { version = "7.0", features = ["decimal", "chrono", "dataloader", "dynamic-schema"] } -sea-orm = { version = "~1.1.4", default-features = false, features = ["seaography"] } +sea-orm = { version = "~1.1.4", default-features = false, features = ["seaography", "with-json"] } itertools = { version = "0.12.0" } heck = { version = "0.4.1" } thiserror = { version = "1.0.44" } fnv = { version = "1.0.7" } lazy_static = { version = "1.5" } +serde_json = { version = "1.0" } [features] default = ["field-camel-case"] @@ -41,3 +42,6 @@ field-camel-case = [] # [patch.crates-io] # sea-orm = { git = "https://github.com/SeaQL/sea-orm" } # sea-orm-migration = { git = "https://github.com/SeaQL/sea-orm" } + +[patch.crates-io] +sea-orm = { git = "https://github.com/SeaQL/sea-orm" } diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index f931a5e..6847413 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -22,3 +22,6 @@ serde_json = { version = "1.0.103" } [workspace] members = [] + +[patch.crates-io] +sea-orm = { git = "https://github.com/SeaQL/sea-orm" } diff --git a/src/builder.rs b/src/builder.rs index 1802b2d..015e6cd 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -2,7 +2,7 @@ use async_graphql::{ dataloader::DataLoader, dynamic::{Enum, Field, FieldFuture, InputObject, Object, Schema, SchemaBuilder, TypeRef}, }; -use sea_orm::{ActiveEnum, ActiveModelTrait, EntityTrait, IntoActiveModel}; +use sea_orm::{ActiveEnum, ActiveModelTrait, ConnectionTrait, EntityTrait, IntoActiveModel}; use crate::{ ActiveEnumBuilder, ActiveEnumFilterInputBuilder, BuilderContext, ConnectionObjectBuilder, @@ -37,6 +37,9 @@ pub struct Builder { /// holds all entities mutations pub mutations: Vec, + /// holds all entities metadata + pub metadata: std::collections::HashMap, + /// holds a copy to the database connection pub connection: sea_orm::DatabaseConnection, @@ -70,6 +73,7 @@ impl Builder { enumerations: Vec::new(), queries: Vec::new(), mutations: Vec::new(), + metadata: Default::default(), connection, context, depth: None, @@ -119,6 +123,10 @@ impl Builder { }; let query = entity_query_field_builder.to_field::(); self.queries.push(query); + + let schema = sea_orm::Schema::new(self.connection.get_database_backend()); + let metadata = schema.json_schema_from_entity(T::default()); + self.metadata.insert(T::default().to_string(), metadata); } pub fn register_entity_mutations(&mut self) @@ -249,6 +257,32 @@ impl Builder { .into_iter() .fold(query, |query, field| query.field(field)); + const TABLE_NAME: &str = "table_name"; + let field = Field::new( + "_sea_orm_entity_metadata", + TypeRef::named("String"), + move |ctx| { + let metadata_hashmap = self.metadata.clone(); + FieldFuture::new(async move { + let table_name = ctx + .args + .get(TABLE_NAME) + .expect("table_name is required") + .string()?; + if let Some(metadata) = metadata_hashmap.get(table_name) { + Ok(Some(async_graphql::Value::from_json(metadata.to_owned())?)) + } else { + Ok(None) + } + }) + }, + ) + .argument(async_graphql::dynamic::InputValue::new( + TABLE_NAME, + TypeRef::named_nn(TypeRef::STRING), + )); + let query = query.field(field); + // register mutations let mutation = self .mutations