From c521ac26666a9a2d0b18dda97da8eb660a3e90eb Mon Sep 17 00:00:00 2001 From: photino Date: Tue, 31 Oct 2023 01:12:10 +0800 Subject: [PATCH] Add the tree method for DefaultController --- examples/actix-app/Cargo.toml | 1 - examples/actix-app/src/controller/user.rs | 1 - examples/actix-app/src/router/mod.rs | 1 + examples/axum-app/Cargo.toml | 1 - examples/axum-app/src/controller/user.rs | 1 - examples/axum-app/src/router/mod.rs | 1 + zino-core/Cargo.toml | 6 +-- zino-core/src/lib.rs | 3 ++ zino-dioxus/src/prelude/mod.rs | 2 +- zino/src/controller/mod.rs | 55 +++++++++++++++++++++++ zino/src/lib.rs | 1 + zino/src/prelude/mod.rs | 2 +- 12 files changed, 66 insertions(+), 9 deletions(-) diff --git a/examples/actix-app/Cargo.toml b/examples/actix-app/Cargo.toml index 80d93847..1a9f47e3 100644 --- a/examples/actix-app/Cargo.toml +++ b/examples/actix-app/Cargo.toml @@ -8,7 +8,6 @@ publish = false [dependencies] actix-web = "4.4.0" -fluent = "0.16.0" tracing = "0.1.40" [dependencies.serde] diff --git a/examples/actix-app/src/controller/user.rs b/examples/actix-app/src/controller/user.rs index c206951d..30d91ef6 100644 --- a/examples/actix-app/src/controller/user.rs +++ b/examples/actix-app/src/controller/user.rs @@ -1,4 +1,3 @@ -use fluent::fluent_args; use std::time::Instant; use zino::{prelude::*, Request, Response, Result}; use zino_model::user::User; diff --git a/examples/actix-app/src/router/mod.rs b/examples/actix-app/src/router/mod.rs index ee09d78c..3c55de3c 100644 --- a/examples/actix-app/src/router/mod.rs +++ b/examples/actix-app/src/router/mod.rs @@ -61,6 +61,7 @@ fn tag_router(cfg: &mut ServiceConfig) { .route("/{id}/update", post().to(Tag::update)) .route("/{id}/view", get().to(Tag::view)) .route("/list", get().to(Tag::list)) + .route("/tree", get().to(Tag::tree)) .route("/schema", get().to(Tag::schema)), ); } diff --git a/examples/axum-app/Cargo.toml b/examples/axum-app/Cargo.toml index 5d9eca91..2362e162 100644 --- a/examples/axum-app/Cargo.toml +++ b/examples/axum-app/Cargo.toml @@ -8,7 +8,6 @@ publish = false [dependencies] axum = "0.6.20" -fluent = "0.16.0" tracing = "0.1.40" [dependencies.serde] diff --git a/examples/axum-app/src/controller/user.rs b/examples/axum-app/src/controller/user.rs index d189d30f..8050a90a 100644 --- a/examples/axum-app/src/controller/user.rs +++ b/examples/axum-app/src/controller/user.rs @@ -1,5 +1,4 @@ use crate::model::User; -use fluent::fluent_args; use std::time::Instant; use zino::{prelude::*, Request, Response, Result}; diff --git a/examples/axum-app/src/router/mod.rs b/examples/axum-app/src/router/mod.rs index ea93aab5..0befa69f 100644 --- a/examples/axum-app/src/router/mod.rs +++ b/examples/axum-app/src/router/mod.rs @@ -46,6 +46,7 @@ pub fn routes() -> Vec { .route("/tag/:id/update", post(Tag::update)) .route("/tag/:id/view", get(Tag::view)) .route("/tag/list", get(Tag::list)) + .route("/tag/tree", get(Tag::tree)) .route("/tag/schema", get(Tag::schema)); routes.push(router); diff --git a/zino-core/Cargo.toml b/zino-core/Cargo.toml index 156e773a..415c7fb8 100644 --- a/zino-core/Cargo.toml +++ b/zino-core/Cargo.toml @@ -168,7 +168,7 @@ serde_qs = "0.12.0" sha2 = "0.10.8" sysinfo = "0.29.10" task-local-extensions = "0.1.4" -toml = "0.8.5" +toml = "0.8.6" tracing = "0.1.40" tracing-appender = "0.2.2" url = "2.4.1" @@ -178,7 +178,7 @@ version = "0.5.2" features = ["std"] [dependencies.async-openai] -version = "0.14.3" +version = "0.15.0" optional = true [dependencies.chrono] @@ -301,7 +301,7 @@ data-encoding = "2.4.0" libsm = "0.5.1" sm3 = "0.4.2" smallvec = "1.11.1" -sonic-rs = "0.1.3" +sonic-rs = "0.2.1" tinyvec = { version = "1.6.0", features = ["alloc"] } uuid-simd = "0.8.0" diff --git a/zino-core/src/lib.rs b/zino-core/src/lib.rs index f99e090c..1286567e 100644 --- a/zino-core/src/lib.rs +++ b/zino-core/src/lib.rs @@ -43,6 +43,9 @@ pub mod schedule; pub mod state; pub mod trace; +#[doc(no_inline)] +pub use fluent::fluent_args; + #[doc(no_inline)] pub use serde_json::json; diff --git a/zino-dioxus/src/prelude/mod.rs b/zino-dioxus/src/prelude/mod.rs index dead8680..547af099 100644 --- a/zino-dioxus/src/prelude/mod.rs +++ b/zino-dioxus/src/prelude/mod.rs @@ -1,4 +1,4 @@ -//! Re-exports of dioxus components and common types. +//! Re-exports of components and common types. pub use crate::{ class::Class, diff --git a/zino/src/controller/mod.rs b/zino/src/controller/mod.rs index d701b920..2fed9fbf 100644 --- a/zino/src/controller/mod.rs +++ b/zino/src/controller/mod.rs @@ -35,6 +35,9 @@ pub trait DefaultController { /// Exports model data. async fn export(req: Self::Request) -> Self::Result; + /// Gets the tree hierarchy data. + async fn tree(req: Self::Request) -> Self::Result; + /// Gets the model schema. async fn schema(req: Self::Request) -> Self::Result; } @@ -323,6 +326,57 @@ where Ok(res.into()) } + async fn tree(req: Self::Request) -> Self::Result { + let mut query = Self::default_list_query(); + let extension = req.get_data::<::Extension>(); + Self::before_list(&mut query, extension.as_ref()) + .await + .extract(&req)?; + + let mut res = req.query_validation(&mut query)?; + let parent_id = req.get_query("parent_id").unwrap_or("null"); + query.add_filter("parent_id", parent_id); + + let mut models = if query.populate_enabled() { + Self::fetch(&query).await.extract(&req)? + } else { + let mut models = Self::find(&query).await.extract(&req)?; + let translate_enabled = query.translate_enabled(); + for model in models.iter_mut() { + Self::after_decode(model).await.extract(&req)?; + translate_enabled.then(|| Self::translate_model(model)); + } + models + }; + + let primary_key_name = Self::PRIMARY_KEY_NAME; + let values = models + .iter() + .filter_map(|model| model.get(primary_key_name).cloned()) + .collect::>(); + let mut query = Self::default_snapshot_query(); + query.allow_fields(&["parent_id"]); + query.add_filter("parent_id", Map::from_entry("$in", values)); + query.add_filter("status", Map::from_entry("$ne", "Deleted")); + query.set_sort_order("created_at", true); + query.set_limit(0); + + let mut children = Self::find::(&query).await.extract(&req)?; + let total_rows = children.len(); + for model in models.iter_mut() { + let model_id = model.get(primary_key_name); + let model_children = children + .extract_if(|child| child.get("parent_id") == model_id) + .collect::>(); + model.upsert("children", model_children); + } + + let mut data = Map::data_entries(models); + data.upsert("total_rows", total_rows); + res.set_json_data(data); + Ok(res.into()) + } + async fn schema(req: Self::Request) -> Self::Result { let reader_available = Self::acquire_reader() .await @@ -331,6 +385,7 @@ where .await .is_ok_and(|cp| cp.is_available()); let data = json!({ + "avro_schema": Self::schema(), "model_name": Self::model_name(), "model_namespace": Self::model_namespace(), "table_name": Self::table_name(), diff --git a/zino/src/lib.rs b/zino/src/lib.rs index 89bcdb9c..76875008 100644 --- a/zino/src/lib.rs +++ b/zino/src/lib.rs @@ -6,6 +6,7 @@ #![forbid(unsafe_code)] #![feature(async_fn_in_trait)] #![feature(doc_auto_cfg)] +#![feature(extract_if)] #![feature(lazy_cell)] #![feature(let_chains)] diff --git a/zino/src/prelude/mod.rs b/zino/src/prelude/mod.rs index 41fdda85..bb9ba7e1 100644 --- a/zino/src/prelude/mod.rs +++ b/zino/src/prelude/mod.rs @@ -12,7 +12,7 @@ pub use zino_core::{ error::Error, extension::{JsonObjectExt, JsonValueExt, TomlTableExt}, file::NamedFile, - json, + fluent_args, json, model::{Model, ModelHooks, Mutation, Query, QueryContext}, reject, request::{RequestContext, Validation},