From a2d7330312c69e9dd68c350d292d06a43b0a6bab Mon Sep 17 00:00:00 2001 From: photino Date: Sat, 8 Jul 2023 00:16:04 +0800 Subject: [PATCH] Change the limit value for the default query --- README.md | 4 ++++ zino-core/Cargo.toml | 5 +++-- zino-core/src/database/mod.rs | 2 +- zino-core/src/database/mysql.rs | 25 ++++++++++--------------- zino-core/src/database/postgres.rs | 27 +++++++++++---------------- zino-core/src/database/query.rs | 28 ++++++++++++++++++++++++---- zino-core/src/database/schema.rs | 1 + zino-core/src/model/query.rs | 2 +- zino-core/src/openapi/mod.rs | 16 ++++++++++++++-- zino-core/src/response/mod.rs | 6 +++--- zino-model/Cargo.toml | 2 +- zino-model/src/user.rs | 2 +- 12 files changed, 74 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 9ce25b05..1a8bb259 100644 --- a/README.md +++ b/README.md @@ -61,3 +61,7 @@ This project is licensed under the [MIT license][license]. [`actix-app`]: https://github.com/photino/zino/tree/main/examples/actix-app [`axum-app`]: https://github.com/photino/zino/tree/main/examples/axum-app [license]: https://github.com/photino/zino/blob/main/LICENSE + +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=photino/zino&type=Date)](https://star-history.com/#photino/zino&Date) diff --git a/zino-core/Cargo.toml b/zino-core/Cargo.toml index 1a64056e..8d3a39dd 100644 --- a/zino-core/Cargo.toml +++ b/zino-core/Cargo.toml @@ -66,6 +66,8 @@ orm-mysql = ["orm", "sqlx/mysql"] orm-postgres = ["orm", "sqlx/postgres"] runtime-async-std = ["sqlx/runtime-async-std"] runtime-tokio = ["sqlx/runtime-tokio"] +tls-native = ["sqlx/tls-native-tls"] +tls-rustls = ["sqlx/tls-rustls"] view = ["dep:minijinja"] view-tera = ["view", "dep:tera"] view-minijinja = ["view", "dep:minijinja"] @@ -94,7 +96,7 @@ metrics-exporter-prometheus = "0.12.1" multer = "2.1.0" parking_lot = "0.12.1" rand = "0.8.5" -regex = "1.8.4" +regex = "1.9.0" reqwest-middleware = "0.2.2" reqwest-retry = "0.2.2" reqwest-tracing = "0.4.5" @@ -165,7 +167,6 @@ features = [ "bigdecimal", "chrono", "rust_decimal", - "tls-rustls", "uuid", ] diff --git a/zino-core/src/database/mod.rs b/zino-core/src/database/mod.rs index 60907611..7862bdff 100644 --- a/zino-core/src/database/mod.rs +++ b/zino-core/src/database/mod.rs @@ -129,7 +129,7 @@ impl ConnectionPool { if let Some(host) = config.get_str("host") { connect_options = connect_options.host(host); } - if let Some(port) = config.get_u16("hport") { + if let Some(port) = config.get_u16("port") { connect_options = connect_options.port(port); } if let Some(statement_cache_capacity) = config.get_usize("statement-cache-capacity") { diff --git a/zino-core/src/database/mysql.rs b/zino-core/src/database/mysql.rs index 05b9ca9d..c8327d90 100644 --- a/zino-core/src/database/mysql.rs +++ b/zino-core/src/database/mysql.rs @@ -488,6 +488,16 @@ impl QueryExt for Query { self.sort_order() } + #[inline] + fn query_offset(&self) -> usize { + self.offset() + } + + #[inline] + fn query_limit(&self) -> usize { + self.limit() + } + #[inline] fn placeholder(_n: usize) -> SharedString { "?".into() @@ -501,21 +511,6 @@ impl QueryExt for Query { crate::format::query::prepare_sql_query(query, params, '?') } - fn format_pagination(&self) -> String { - let limit = self.limit(); - if limit == usize::MAX { - return String::new(); - } - - let (sort_by, _) = self.sort_order(); - if self.filters().contains_key(sort_by) { - format!("LIMIT {limit}") - } else { - let offset = self.offset(); - format!("LIMIT {offset}, {limit}") - } - } - fn format_field(field: &str) -> Cow<'_, str> { if field.contains('.') { field diff --git a/zino-core/src/database/postgres.rs b/zino-core/src/database/postgres.rs index df614e73..c1fdd1f3 100644 --- a/zino-core/src/database/postgres.rs +++ b/zino-core/src/database/postgres.rs @@ -199,7 +199,7 @@ impl<'c> EncodeColumn for Column<'c> { let condition = format!(r#"array_length({field}, 1) = {value}"#); conditions.push(condition); } else if operator == "IN" || operator == "NOT IN" { - if let Some(values) = value.as_array() && !values.is_empty() { + if let Some(values) = value.as_array() { let field = Query::format_field(field); let value = values .iter() @@ -494,6 +494,16 @@ impl QueryExt for Query { self.sort_order() } + #[inline] + fn query_offset(&self) -> usize { + self.offset() + } + + #[inline] + fn query_limit(&self) -> usize { + self.limit() + } + #[inline] fn placeholder(n: usize) -> SharedString { if n == 1 { @@ -511,21 +521,6 @@ impl QueryExt for Query { crate::format::query::prepare_sql_query(query, params, '$') } - fn format_pagination(&self) -> String { - let limit = self.limit(); - if limit == usize::MAX { - return String::new(); - } - - let (sort_by, _) = self.sort_order(); - if self.filters().contains_key(sort_by) { - format!("LIMIT {limit}") - } else { - let offset = self.offset(); - format!("OFFSET {offset} LIMIT {limit} ") - } - } - fn format_field(field: &str) -> Cow<'_, str> { if field.contains('.') { field diff --git a/zino-core/src/database/query.rs b/zino-core/src/database/query.rs index 97c8fe07..519e1395 100644 --- a/zino-core/src/database/query.rs +++ b/zino-core/src/database/query.rs @@ -17,6 +17,12 @@ pub(super) trait QueryExt { /// Returns the sort order. fn query_order(&self) -> (&str, bool); + /// Returns the query offset. + fn query_offset(&self) -> usize; + + /// Returns the query limit. + fn query_limit(&self) -> usize; + /// Returns a placeholder for the n-th parameter. fn placeholder(n: usize) -> SharedString; @@ -26,9 +32,6 @@ pub(super) trait QueryExt { params: Option<&'a Map>, ) -> (Cow<'a, str>, Vec<&'a JsonValue>); - /// Formats the query pagination to generate SQL `LIMIT` expression. - fn format_pagination(&self) -> String; - /// Formats a field for the query. fn format_field(field: &str) -> Cow<'_, str>; @@ -71,6 +74,7 @@ pub(super) trait QueryExt { } let (sort_by, ascending) = self.query_order(); + let offset = self.query_offset(); let mut expression = String::new(); let mut conditions = Vec::with_capacity(filters.len()); for (key, value) in filters { @@ -114,7 +118,7 @@ pub(super) trait QueryExt { } _ => { if let Some(col) = M::get_column(key) { - let condition = if key == sort_by { + let condition = if key == sort_by && offset > 0 { // Use the filter condition to optimize pagination offset. let key = Self::format_field(key); let operator = if ascending { ">" } else { "<" }; @@ -160,6 +164,22 @@ pub(super) trait QueryExt { } } + /// Formats the query pagination to generate SQL `LIMIT` expression. + fn format_pagination(&self) -> String { + let limit = self.query_limit(); + if limit == usize::MAX { + return String::new(); + } + + let (sort_by, _) = self.query_order(); + if self.query_filters().contains_key(sort_by) { + format!("LIMIT {limit}") + } else { + let offset = self.query_offset(); + format!("LIMIT {limit} OFFSET {offset}") + } + } + // Formats the selection with a logic operator. fn format_selection(selection: &Map, operator: &str) -> String { let mut conditions = Vec::with_capacity(selection.len()); diff --git a/zino-core/src/database/schema.rs b/zino-core/src/database/schema.rs index 8bcfbd17..a6f04e69 100644 --- a/zino-core/src/database/schema.rs +++ b/zino-core/src/database/schema.rs @@ -76,6 +76,7 @@ pub trait Schema: 'static + Send + Sync + ModelHooks { let mut query = Query::default(); query.allow_fields(Self::fields()); query.deny_fields(Self::writeonly_fields()); + query.set_limit(super::MAX_ROWS.load(Relaxed)); query } diff --git a/zino-core/src/model/query.rs b/zino-core/src/model/query.rs index 56a77240..f0a53839 100644 --- a/zino-core/src/model/query.rs +++ b/zino-core/src/model/query.rs @@ -28,7 +28,7 @@ impl Query { filters, sort_order: (None, false), offset: 0, - limit: usize::MAX, + limit: 10, } } diff --git a/zino-core/src/openapi/mod.rs b/zino-core/src/openapi/mod.rs index 1aee54df..fe687818 100644 --- a/zino-core/src/openapi/mod.rs +++ b/zino-core/src/openapi/mod.rs @@ -35,6 +35,8 @@ pub(crate) fn default_paths() -> Paths { /// Returns the default OpenAPI components. pub(crate) fn default_components() -> Components { let mut components = OPENAPI_COMPONENTS.get_or_init(Components::new).clone(); + + // Default response let status_schema = ObjectBuilder::new() .schema_type(SchemaType::Integer) .example(Some(200.into())) @@ -47,8 +49,6 @@ pub(crate) fn default_components() -> Components { .schema_type(SchemaType::String) .format(Some(SchemaFormat::KnownFormat(KnownFormat::Uuid))) .build(); - - // Default response let message_schema = ObjectBuilder::new() .schema_type(SchemaType::String) .example(Some("OK".into())) @@ -90,6 +90,18 @@ pub(crate) fn default_components() -> Components { let model_id_example = Uuid::new_v4(); let detail_example = format!("404 Not Found: cannot find the model `{model_id_example}`"); let instance_example = format!("/model/{model_id_example}/view"); + let status_schema = ObjectBuilder::new() + .schema_type(SchemaType::Integer) + .example(Some(404.into())) + .build(); + let success_schema = ObjectBuilder::new() + .schema_type(SchemaType::Boolean) + .example(Some(false.into())) + .build(); + let request_id_schema = ObjectBuilder::new() + .schema_type(SchemaType::String) + .format(Some(SchemaFormat::KnownFormat(KnownFormat::Uuid))) + .build(); let title_schema = ObjectBuilder::new() .schema_type(SchemaType::String) .example(Some("NotFound".into())) diff --git a/zino-core/src/response/mod.rs b/zino-core/src/response/mod.rs index e507cdae..4079e798 100644 --- a/zino-core/src/response/mod.rs +++ b/zino-core/src/response/mod.rs @@ -30,7 +30,7 @@ pub type StatusCode = http::StatusCode; pub type FullResponse = http::Response>; /// A function pointer of transforming the response data. -pub type ResponseDataTransformer = fn(data: JsonValue) -> Result, Error>; +pub type DataTransformer = fn(data: JsonValue) -> Result, Error>; /// An HTTP response. #[derive(Debug, Serialize)] @@ -72,7 +72,7 @@ pub struct Response { data: Option>, /// Transformer of the response data. #[serde(skip)] - data_transformer: Option, + data_transformer: Option, /// Content type. #[serde(skip)] content_type: Option, @@ -268,7 +268,7 @@ impl Response { /// Sets a transformer for the response data. #[inline] - pub fn set_data_transformer(&mut self, transformer: ResponseDataTransformer) { + pub fn set_data_transformer(&mut self, transformer: DataTransformer) { self.data_transformer = Some(transformer); } diff --git a/zino-model/Cargo.toml b/zino-model/Cargo.toml index 6bc37d0e..e3b5310c 100644 --- a/zino-model/Cargo.toml +++ b/zino-model/Cargo.toml @@ -29,7 +29,7 @@ maintainer-id = [] edition = [] [dependencies] -regex = "1.8.4" +regex = "1.9.0" [dependencies.serde] version = "1.0.164" diff --git a/zino-model/src/user.rs b/zino-model/src/user.rs index 1efc53a6..f5549cf2 100644 --- a/zino-model/src/user.rs +++ b/zino-model/src/user.rs @@ -31,7 +31,7 @@ pub struct User { #[cfg(feature = "visibility")] #[schema(default_value = "Internal")] visibility: String, - #[schema(default_value = "Active", index_type = "hash")] + #[schema(default_value = "Inactive", index_type = "hash")] status: String, #[schema(index_type = "text")] description: String,