mirror of https://github.com/zino-rs/zino
Update zino-core
This commit is contained in:
parent
f9f4c5f3e9
commit
e776372d43
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "axum-app"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
rust-version = "1.68"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
|
|
@ -28,7 +28,7 @@ pub(super) fn every_30s(job_id: Uuid, job_data: &mut Map) -> BoxFuture {
|
|||
.unwrap_or_default();
|
||||
job_data.insert("current".to_string(), DateTime::now().to_string().into());
|
||||
job_data.insert("counter".to_string(), counter.into());
|
||||
println!("job {job_id} is executed every 45 seconds: {job_data:?}");
|
||||
println!("async job {job_id} is executed every 30 seconds: {job_data:?}");
|
||||
|
||||
Box::pin(async {
|
||||
let query = Query::new();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "zino-core"
|
||||
description = "Core types and traits for zino."
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
rust-version = "1.68"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
|
|
@ -15,7 +15,7 @@ pub trait Application {
|
|||
/// Registers routes.
|
||||
fn register(self, routes: HashMap<&'static str, Self::Router>) -> Self;
|
||||
|
||||
/// Spawns a new thread to run jobs.
|
||||
/// Spawns a new thread to run cron jobs.
|
||||
fn spawn(self, jobs: HashMap<&'static str, CronJob>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
|
|
|
@ -96,12 +96,10 @@ impl Mutation {
|
|||
"$append" => {
|
||||
if let Some(update) = value.as_object() {
|
||||
for (key, value) in update.iter() {
|
||||
if fields.contains(key) {
|
||||
if let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {key} || {value}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
if fields.contains(key) && let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {key} || {value}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,12 +107,10 @@ impl Mutation {
|
|||
"$preppend" => {
|
||||
if let Some(update) = value.as_object() {
|
||||
for (key, value) in update.iter() {
|
||||
if fields.contains(key) {
|
||||
if let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {value} || {key}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
if fields.contains(key) && let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {value} || {key}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,12 +118,10 @@ impl Mutation {
|
|||
"$pull" => {
|
||||
if let Some(update) = value.as_object() {
|
||||
for (key, value) in update.iter() {
|
||||
if fields.contains(key) {
|
||||
if let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = array_remove({key}, {value})");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
if fields.contains(key) && let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = array_remove({key}, {value})");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,12 +129,10 @@ impl Mutation {
|
|||
"$inc" => {
|
||||
if let Some(update) = value.as_object() {
|
||||
for (key, value) in update.iter() {
|
||||
if fields.contains(key) {
|
||||
if let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {key} + {value}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
if fields.contains(key) && let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {key} + {value}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,12 +140,10 @@ impl Mutation {
|
|||
"$mul" => {
|
||||
if let Some(update) = value.as_object() {
|
||||
for (key, value) in update.iter() {
|
||||
if fields.contains(key) {
|
||||
if let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {key} * {value}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
if fields.contains(key) && let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {key} * {value}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,12 +151,10 @@ impl Mutation {
|
|||
"$min" => {
|
||||
if let Some(update) = value.as_object() {
|
||||
for (key, value) in update.iter() {
|
||||
if fields.contains(key) {
|
||||
if let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = LEAST({key}, {value})");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
if fields.contains(key) && let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = LEAST({key}, {value})");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,23 +162,19 @@ impl Mutation {
|
|||
"$max" => {
|
||||
if let Some(update) = value.as_object() {
|
||||
for (key, value) in update.iter() {
|
||||
if fields.contains(key) {
|
||||
if let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = GREATEST({key}, {value})");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
if fields.contains(key) && let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = GREATEST({key}, {value})");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if fields.contains(key) {
|
||||
if let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {value}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
if fields.contains(key) && let Some(col) = M::get_column(key) {
|
||||
let value = col.encode_postgres_value(value);
|
||||
let mutation = format!("{key} = {value}");
|
||||
mutations.push(mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -407,8 +407,8 @@ pub trait Schema: 'static + Send + Sync + Model {
|
|||
}
|
||||
}
|
||||
|
||||
/// Fetches the associated data for `Vec<Map>` using a merged select on the primary key,
|
||||
/// which solves the `N+1` problem.
|
||||
/// Fetches the associated data in the corresponding `columns` for `Vec<Map>` using
|
||||
/// a merged select on the primary key, which solves the `N+1` problem.
|
||||
async fn fetch(
|
||||
mut query: Query,
|
||||
data: &mut Vec<Map>,
|
||||
|
@ -483,8 +483,8 @@ pub trait Schema: 'static + Send + Sync + Model {
|
|||
u64::try_from(associations.len()).map_err(|err| Error::Decode(Box::new(err)))
|
||||
}
|
||||
|
||||
/// Fetches the associated data for `Map` using a merged select on the primary key,
|
||||
/// which solves the `N+1` problem.
|
||||
/// Fetches the associated data in the corresponding `columns` for `Map` using
|
||||
/// a merged select on the primary key, which solves the `N+1` problem.
|
||||
async fn fetch_one(mut query: Query, data: &mut Map, columns: &[String]) -> Result<u64, Error> {
|
||||
let pool = Self::init_reader().await.ok_or(Error::PoolClosed)?.pool();
|
||||
let table_name = Self::table_name();
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
//! Core types and traits for zino.
|
||||
//! Core types and traits for [`zino`].
|
||||
//!
|
||||
//! [`zino`]: https://github.com/photino/zino
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(string_leak)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "zino-derive"
|
||||
description = "Derived traits for zino."
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
rust-version = "1.68"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
@ -20,4 +20,4 @@ syn = { version = "1.0.107", features = ["full", "extra-traits"] }
|
|||
|
||||
[dependencies.zino-core]
|
||||
path = "../zino-core"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
//! Derived traits for zino.
|
||||
//! Derived traits for [`zino`].
|
||||
//!
|
||||
//! [`zino`]: https://github.com/photino/zino
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "zino-model"
|
||||
description = "Model types for zino."
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
rust-version = "1.68"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
@ -15,8 +15,8 @@ serde = { version = "1.0.152", features = ["derive"] }
|
|||
|
||||
[dependencies.zino-core]
|
||||
path = "../zino-core"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
|
||||
[dependencies.zino-derive]
|
||||
path = "../zino-derive"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
|
@ -1,4 +1,6 @@
|
|||
//! Model types for zino.
|
||||
//! Model types for [`zino`].
|
||||
//!
|
||||
//! [`zino`]: https://github.com/photino/zino
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(once_cell)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "zino"
|
||||
description = "A minimal web framework."
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
rust-version = "1.68"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
@ -36,4 +36,4 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json", "lo
|
|||
|
||||
[dependencies.zino-core]
|
||||
path = "../zino-core"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
|
@ -1,40 +1,45 @@
|
|||
# zino
|
||||
|
||||
`zino` is a full featured web application framework that focuses on productivity and performance.
|
||||
`zino` is a full featured web application framework which focuses on productivity and performance.
|
||||
|
||||
[![Crates.io](https://img.shields.io/crates/v/zino)][zino]
|
||||
[![Documentation](https://docs.rs/zino/badge.svg)][zino-docs]
|
||||
## Highlights
|
||||
|
||||
## High level features
|
||||
|
||||
- ✨ Full features for web development out of the box.
|
||||
- 💖 Minimal design, modular architecture and ease to use.
|
||||
- 🚀 Embrace practical conventions to get high performance.
|
||||
- 🐘 Built-in ORM for PostgreSQL based on [`sqlx`][sqlx].
|
||||
- 📈 Support for `tracing`, `logging` and `metrics`.
|
||||
- 🚀 Out-of-the-box features for rapid application development.
|
||||
- ✨ Minimal design, modular architecture and high-level abstractions.
|
||||
- ⚡ Embrace practical conventions to get the best performance.
|
||||
- 🐘 Highly optimized ORM for PostgreSQL built with [`sqlx`][sqlx].
|
||||
- ⏲ Lightweight scheduler for sync and async cron jobs.
|
||||
- 📊 Support for `tracing`, `logging` and `metrics`.
|
||||
|
||||
## Getting started
|
||||
|
||||
You can start with the example [`axum-app`][axum-app].
|
||||
You can start with the example [`axum-app`].
|
||||
|
||||
## Documentation
|
||||
## Crates
|
||||
|
||||
`zino` consists of 4 crates:
|
||||
|
||||
- [zino][zino-docs]: Named features.
|
||||
- [zino-core][zino-core-docs]: Core types and traits.
|
||||
- [zino-derive][zino-derive-docs]: Derived traits.
|
||||
- [zino-model][zino-model-docs]: Model types.
|
||||
| Name | Description | Crates.io | Documentation |
|
||||
|-----------------|------------------------|--------------|---------------|
|
||||
| [`zino`] | Named features. | [![crates.io](https://img.shields.io/crates/v/zino)][zino] | [![Documentation](https://docs.rs/zino/badge.svg)][zino-docs] |
|
||||
| [`zino-core`] | Core types and traits. | [![crates.io](https://img.shields.io/crates/v/zino-core)][zino-core] | [![Documentation](https://docs.rs/zino-core/badge.svg)][zino-core-docs] |
|
||||
| [`zino-derive`] | Derived traits. | [![crates.io](https://img.shields.io/crates/v/zino-derive)][zino-derive] | [![Documentation](https://docs.rs/zino-derive/badge.svg)][zino-derive-docs] |
|
||||
| [`zino-model`] | Model types. | [![crates.io](https://img.shields.io/crates/v/zino-model)][zino-model] | [![Documentation](https://docs.rs/zino-model/badge.svg)][zino-model-docs] |
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT license][license].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino/tree/main/zino
|
||||
[`zino-core`]: https://github.com/photino/zino/tree/main/zino-core
|
||||
[`zino-derive`]: https://github.com/photino/zino/tree/main/zino-derive
|
||||
[`zino-model`]: https://github.com/photino/zino/tree/main/zino-model
|
||||
[zino]: https://crates.io/crates/zino
|
||||
[sqlx]: https://crates.io/crates/sqlx
|
||||
[axum-app]: https://github.com/photino/zino/tree/main/examples/axum-app
|
||||
[zino-docs]: https://docs.rs/zino
|
||||
[zino-core]: https://crates.io/crates/zino-core
|
||||
[zino-core-docs]: https://docs.rs/zino-core
|
||||
[zino-derive]: https://crates.io/crates/zino-derive
|
||||
[zino-derive-docs]: https://docs.rs/zino-derive
|
||||
[zino-model]: https://crates.io/crates/zino-model
|
||||
[zino-model-docs]: https://docs.rs/zino-model
|
||||
[sqlx]: https://crates.io/crates/sqlx
|
||||
[`axum-app`]: https://github.com/photino/zino/tree/main/examples/axum-app
|
||||
[license]: https://github.com/photino/zino/blob/main/LICENSE
|
|
@ -13,7 +13,6 @@ use std::{
|
|||
net::SocketAddr,
|
||||
path::Path,
|
||||
sync::{Arc, LazyLock},
|
||||
thread,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tokio::runtime::Builder;
|
||||
|
@ -62,16 +61,17 @@ impl Application for AxumCluster {
|
|||
|
||||
/// Runs the application.
|
||||
fn run(self, async_jobs: HashMap<&'static str, AsyncCronJob>) -> io::Result<()> {
|
||||
let runtime = Builder::new_multi_thread().enable_all().build()?;
|
||||
let mut scheduler = JobScheduler::new();
|
||||
for (cron_expr, exec) in async_jobs {
|
||||
scheduler.add(Job::new_async(cron_expr, exec));
|
||||
}
|
||||
|
||||
let runtime = Builder::new_multi_thread().enable_all().build()?;
|
||||
runtime.spawn(async move {
|
||||
loop {
|
||||
scheduler.tick_async().await;
|
||||
thread::sleep(scheduler.time_till_next_job());
|
||||
|
||||
// Cannot use `std::thread::sleep` because it blocks the Tokio runtime.
|
||||
tokio::time::sleep(scheduler.time_till_next_job()).await;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,21 @@
|
|||
//! A minimal web framework.
|
||||
//! [`zino`] is a full featured web application framework which focuses on productivity and performance.
|
||||
//!
|
||||
//! ## Highlights
|
||||
//!
|
||||
//! - 🚀 Out-of-the-box features for rapid application development.
|
||||
//! - ✨ Minimal design, modular architecture and high-level abstractions.
|
||||
//! - ⚡ Embrace practical conventions to get the best performance.
|
||||
//! - 🐘 Highly optimized ORM for PostgreSQL built with [`sqlx`].
|
||||
//! - ⏲ Lightweight scheduler for sync and async cron jobs.
|
||||
//! - 📊 Support for `tracing`, `logging` and `metrics`.
|
||||
//!
|
||||
//! ## Getting started
|
||||
//!
|
||||
//! You can start with the example [`axum-app`].
|
||||
//!
|
||||
//! [`zino`]: https://github.com/photino/zino
|
||||
//! [`sqlx`]: https://crates.io/crates/sqlx
|
||||
//! [`axum-app`]: https://github.com/photino/zino/tree/main/examples/axum-app
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![feature(once_cell)]
|
||||
|
|
Loading…
Reference in New Issue