From a7550a33e5f4460377a9a1f43117d620dea8482c Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Tue, 29 Jun 2021 18:38:20 +0800 Subject: [PATCH 01/23] Docs --- src/lib.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3214dc89..06cc6eb0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -141,6 +141,28 @@ //! # Ok(()) //! # } //! ``` +//! ## Save +//! ``` +//! # use sea_orm::{DbConn, entity::*, query::*, tests_cfg::*}; +//! # +//! # async fn function(db: &DbConn) -> Result<(), ExecErr> { +//! let banana = fruit::ActiveModel { +//! id: Unset(None), +//! name: Set("Banana".to_owned()), +//! ..Default::default() +//! }; +//! +//! // create, because primary key `id` is `Unset` +//! let mut banana = banana.save(db).await?; +//! +//! banana.name = Set("Banana Mongo".to_owned()); +//! +//! // update, because primary key `id` is `Set` +//! let banana = banana.save(db).await?; +//! +//! # Ok(()) +//! # } +//! ``` //! ## Delete //! ``` //! # use sea_orm::{DbConn, entity::*, query::*, tests_cfg::*}; From 3b88ed5a387bcc7bc188821803e01668898ffd86 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Tue, 29 Jun 2021 19:26:57 +0800 Subject: [PATCH 02/23] Logo --- src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 06cc6eb0..bb119ef7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -188,6 +188,10 @@ //! # Ok(()) //! # } //! ``` +#![doc( + html_logo_url = "https://raw.githubusercontent.com/SeaQL/sea-query/master/docs/SeaQL icon dark.png" +)] + mod database; mod driver; pub mod entity; From adaaf31dd9d2d56f81b594f99e27ac5e942efdb9 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Tue, 29 Jun 2021 23:32:05 +0800 Subject: [PATCH 03/23] Docs --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index bb119ef7..58276792 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -178,6 +178,9 @@ //! //! // delete one //! fruit::Entity::delete(orange).exec(db).await?; +//! // or simply +//! # let orange: fruit::ActiveModel = Fruit::find_by_id(1).one(db).await.unwrap().unwrap().into(); +//! orange.delete(db).await?; //! //! // delete many: DELETE FROM "fruit" WHERE "fruit"."name" LIKE 'Orange' //! fruit::Entity::delete_many() From f6ea8a7b3f02fc56004ba3ff49b86b3adf6c0981 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 30 Jun 2021 11:39:40 +0800 Subject: [PATCH 04/23] Docs --- README.md | 4 ++-- src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b02a2070..c314c05f 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,6 @@ Built upon SeaQuery, a dynamic query builder, SeaORM allows you to build complex Use mock connections to write unit tests for your logic. -4. API oriented +4. Service oriented -Quickly build search models that help you join, filter, sort and paginate data in APIs. +Quickly build services that join, filter, sort and paginate data in APIs. diff --git a/src/lib.rs b/src/lib.rs index 58276792..cc41fb8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,9 +35,9 @@ //! //! Use mock connections to write unit tests for your logic. //! -//! 4. API oriented +//! 4. Service oriented //! -//! Quickly build search models that help you join, filter, sort and paginate data in APIs. +//! Quickly build services that join, filter, sort and paginate data in APIs. //! //! # A quick taste of SeaORM //! From 2a1173c174d981caf54d6eb4b1bb29cdfc4e2088 Mon Sep 17 00:00:00 2001 From: Billy Chan <30400950+billy1624@users.noreply.github.com> Date: Wed, 30 Jun 2021 21:08:41 +0800 Subject: [PATCH 05/23] Add & use OrmError (#36) * Add & use OrmError * Rename to SeaErr --- examples/sqlx-mysql/src/operation.rs | 15 +++--- examples/sqlx-mysql/src/select.rs | 28 +++++------ sea-orm-macros/src/derives/active_model.rs | 4 +- .../src/derives/from_query_result.rs | 2 +- sea-orm-macros/src/derives/model.rs | 2 +- src/database/connection.rs | 20 ++------ src/database/mock.rs | 16 +++---- src/database/mod.rs | 6 ++- src/driver/mock.rs | 16 +++---- src/driver/mod.rs | 4 -- src/driver/sqlx_mysql.rs | 18 +++---- src/driver/sqlx_sqlite.rs | 18 +++---- src/driver/sqlx_types.rs | 13 ----- src/entity/active_model.rs | 18 +++---- src/entity/model.rs | 6 +-- src/entity/prelude.rs | 10 ++-- src/error.rs | 41 ++++++++++++++++ src/executor/delete.rs | 12 ++--- src/executor/execute.rs | 15 ------ src/executor/insert.rs | 8 ++-- src/executor/paginator.rs | 32 ++++++------- src/executor/query.rs | 47 ++++--------------- src/executor/select.rs | 28 +++++------ src/executor/update.rs | 17 ++++--- src/lib.rs | 28 ++++++----- src/query/json.rs | 4 +- src/query/mod.rs | 2 +- tests/basic.rs | 14 ++---- 28 files changed, 203 insertions(+), 241 deletions(-) delete mode 100644 src/driver/sqlx_types.rs create mode 100644 src/error.rs diff --git a/examples/sqlx-mysql/src/operation.rs b/examples/sqlx-mysql/src/operation.rs index d7a5ed78..733322ce 100644 --- a/examples/sqlx-mysql/src/operation.rs +++ b/examples/sqlx-mysql/src/operation.rs @@ -1,7 +1,7 @@ use super::*; -use sea_orm::{entity::*, query::*, DbConn}; +use sea_orm::{entity::*, error::*, query::*, DbConn}; -pub async fn all_about_operation(db: &DbConn) -> Result<(), ExecErr> { +pub async fn all_about_operation(db: &DbConn) -> Result<(), SeaErr> { insert_and_update(db).await?; println!("===== =====\n"); @@ -15,7 +15,7 @@ pub async fn all_about_operation(db: &DbConn) -> Result<(), ExecErr> { Ok(()) } -pub async fn insert_and_update(db: &DbConn) -> Result<(), ExecErr> { +pub async fn insert_and_update(db: &DbConn) -> Result<(), SeaErr> { let pear = fruit::ActiveModel { name: Set("pear".to_owned()), ..Default::default() @@ -25,10 +25,7 @@ pub async fn insert_and_update(db: &DbConn) -> Result<(), ExecErr> { println!(); println!("Inserted: last_insert_id = {}\n", res.last_insert_id); - let pear: Option = Fruit::find_by_id(res.last_insert_id) - .one(db) - .await - .map_err(|_| ExecErr)?; + let pear: Option = Fruit::find_by_id(res.last_insert_id).one(db).await?; println!(); println!("Pear: {:?}\n", pear); @@ -44,7 +41,7 @@ pub async fn insert_and_update(db: &DbConn) -> Result<(), ExecErr> { Ok(()) } -pub async fn save_active_model(db: &DbConn) -> Result<(), ExecErr> { +pub async fn save_active_model(db: &DbConn) -> Result<(), SeaErr> { let banana = fruit::ActiveModel { name: Set("Banana".to_owned()), ..Default::default() @@ -82,7 +79,7 @@ mod form { } } -async fn save_custom_active_model(db: &DbConn) -> Result<(), ExecErr> { +async fn save_custom_active_model(db: &DbConn) -> Result<(), SeaErr> { let pineapple = form::ActiveModel { id: Unset(None), name: Set("Pineapple".to_owned()), diff --git a/examples/sqlx-mysql/src/select.rs b/examples/sqlx-mysql/src/select.rs index c344bae6..7033b9f9 100644 --- a/examples/sqlx-mysql/src/select.rs +++ b/examples/sqlx-mysql/src/select.rs @@ -1,7 +1,7 @@ use super::*; -use sea_orm::{entity::*, query::*, DbConn, FromQueryResult}; +use sea_orm::{entity::*, error::*, query::*, DbConn, FromQueryResult}; -pub async fn all_about_select(db: &DbConn) -> Result<(), QueryErr> { +pub async fn all_about_select(db: &DbConn) -> Result<(), SeaErr> { find_all(db).await?; println!("===== =====\n"); @@ -41,7 +41,7 @@ pub async fn all_about_select(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn find_all(db: &DbConn) -> Result<(), QueryErr> { +async fn find_all(db: &DbConn) -> Result<(), SeaErr> { print!("find all cakes: "); let cakes: Vec = Cake::find().all(db).await?; @@ -63,7 +63,7 @@ async fn find_all(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn find_together(db: &DbConn) -> Result<(), QueryErr> { +async fn find_together(db: &DbConn) -> Result<(), SeaErr> { print!("find cakes and fruits: "); let both = Cake::find().find_also_related(Fruit).all(db).await?; @@ -82,7 +82,7 @@ impl Cake { } } -async fn find_one(db: &DbConn) -> Result<(), QueryErr> { +async fn find_one(db: &DbConn) -> Result<(), SeaErr> { print!("find one by primary key: "); let cheese: Option = Cake::find_by_id(1).one(db).await?; @@ -112,7 +112,7 @@ async fn find_one(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn count_fruits_by_cake(db: &DbConn) -> Result<(), QueryErr> { +async fn count_fruits_by_cake(db: &DbConn) -> Result<(), SeaErr> { #[derive(Debug, FromQueryResult)] struct SelectResult { name: String, @@ -138,7 +138,7 @@ async fn count_fruits_by_cake(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn find_many_to_many(db: &DbConn) -> Result<(), QueryErr> { +async fn find_many_to_many(db: &DbConn) -> Result<(), SeaErr> { print!("find cakes and fillings: "); let both: Vec<(cake::Model, Vec)> = @@ -178,7 +178,7 @@ async fn find_many_to_many(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn all_about_select_json(db: &DbConn) -> Result<(), QueryErr> { +async fn all_about_select_json(db: &DbConn) -> Result<(), SeaErr> { find_all_json(&db).await?; println!("===== =====\n"); @@ -192,7 +192,7 @@ async fn all_about_select_json(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn find_all_json(db: &DbConn) -> Result<(), QueryErr> { +async fn find_all_json(db: &DbConn) -> Result<(), SeaErr> { print!("find all cakes: "); let cakes = Cake::find().into_json().all(db).await?; @@ -208,7 +208,7 @@ async fn find_all_json(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn find_together_json(db: &DbConn) -> Result<(), QueryErr> { +async fn find_together_json(db: &DbConn) -> Result<(), SeaErr> { print!("find cakes and fruits: "); let cakes_fruits = Cake::find() @@ -225,7 +225,7 @@ async fn find_together_json(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn count_fruits_by_cake_json(db: &DbConn) -> Result<(), QueryErr> { +async fn count_fruits_by_cake_json(db: &DbConn) -> Result<(), SeaErr> { print!("count fruits by cake: "); let count = Cake::find() @@ -243,7 +243,7 @@ async fn count_fruits_by_cake_json(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn find_all_stream(db: &DbConn) -> Result<(), QueryErr> { +async fn find_all_stream(db: &DbConn) -> Result<(), SeaErr> { use async_std::task::sleep; use futures::TryStreamExt; use std::time::Duration; @@ -291,7 +291,7 @@ async fn find_all_stream(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn find_first_page(db: &DbConn) -> Result<(), QueryErr> { +async fn find_first_page(db: &DbConn) -> Result<(), SeaErr> { println!("fruits first page: "); let page = fruit::Entity::find().paginate(db, 2).fetch_page(0).await?; for fruit in page { @@ -301,7 +301,7 @@ async fn find_first_page(db: &DbConn) -> Result<(), QueryErr> { Ok(()) } -async fn find_num_pages(db: &DbConn) -> Result<(), QueryErr> { +async fn find_num_pages(db: &DbConn) -> Result<(), SeaErr> { println!("fruits number of page: "); let num_pages = fruit::Entity::find().paginate(db, 2).num_pages().await?; println!("{:?}", num_pages); diff --git a/sea-orm-macros/src/derives/active_model.rs b/sea-orm-macros/src/derives/active_model.rs index 701c0d71..ebf642e1 100644 --- a/sea-orm-macros/src/derives/active_model.rs +++ b/sea-orm-macros/src/derives/active_model.rs @@ -37,11 +37,11 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result Result { + pub async fn save(self, db: &sea_orm::DatabaseConnection) -> Result { sea_orm::save_active_model::(self, db).await } - pub async fn delete(self, db: &sea_orm::DatabaseConnection) -> Result { + pub async fn delete(self, db: &sea_orm::DatabaseConnection) -> Result { sea_orm::delete_active_model::(self, db).await } } diff --git a/sea-orm-macros/src/derives/from_query_result.rs b/sea-orm-macros/src/derives/from_query_result.rs index 65ef5a93..a87b4b63 100644 --- a/sea-orm-macros/src/derives/from_query_result.rs +++ b/sea-orm-macros/src/derives/from_query_result.rs @@ -30,7 +30,7 @@ pub fn expand_derive_from_query_result(ident: Ident, data: Data) -> syn::Result< Ok(quote!( impl sea_orm::FromQueryResult for #ident { - fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result { + fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result { Ok(Self { #(#field: row.try_get(pre, #name)?),* }) diff --git a/sea-orm-macros/src/derives/model.rs b/sea-orm-macros/src/derives/model.rs index c304e4c4..57db16ab 100644 --- a/sea-orm-macros/src/derives/model.rs +++ b/sea-orm-macros/src/derives/model.rs @@ -47,7 +47,7 @@ pub fn expand_derive_model(ident: Ident, data: Data) -> syn::Result } impl sea_orm::FromQueryResult for #ident { - fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result { + fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result { Ok(Self { #(#field: row.try_get(pre, <::Entity as EntityTrait>::Column::#name.as_str().into())?),* }) diff --git a/src/database/connection.rs b/src/database/connection.rs index 9727125b..0a138cc9 100644 --- a/src/database/connection.rs +++ b/src/database/connection.rs @@ -1,9 +1,8 @@ -use crate::{ExecErr, ExecResult, QueryErr, QueryResult, Statement, Transaction}; +use crate::{error::*, ExecResult, QueryResult, Statement, Transaction}; use sea_query::{ MysqlQueryBuilder, PostgresQueryBuilder, QueryStatementBuilder, SchemaStatementBuilder, SqliteQueryBuilder, }; -use std::{error::Error, fmt}; pub enum DatabaseConnection { #[cfg(feature = "sqlx-mysql")] @@ -29,17 +28,6 @@ pub enum SchemaBuilderBackend { Sqlite, } -#[derive(Debug)] -pub struct ConnectionErr; - -impl Error for ConnectionErr {} - -impl fmt::Display for ConnectionErr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} - impl Default for DatabaseConnection { fn default() -> Self { Self::Disconnected @@ -89,7 +77,7 @@ impl DatabaseConnection { } } - pub async fn execute(&self, stmt: Statement) -> Result { + pub async fn execute(&self, stmt: Statement) -> Result { match self { #[cfg(feature = "sqlx-mysql")] DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.execute(stmt).await, @@ -101,7 +89,7 @@ impl DatabaseConnection { } } - pub async fn query_one(&self, stmt: Statement) -> Result, QueryErr> { + pub async fn query_one(&self, stmt: Statement) -> Result, SeaErr> { match self { #[cfg(feature = "sqlx-mysql")] DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_one(stmt).await, @@ -113,7 +101,7 @@ impl DatabaseConnection { } } - pub async fn query_all(&self, stmt: Statement) -> Result, QueryErr> { + pub async fn query_all(&self, stmt: Statement) -> Result, SeaErr> { match self { #[cfg(feature = "sqlx-mysql")] DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_all(stmt).await, diff --git a/src/database/mock.rs b/src/database/mock.rs index 4088990a..e80ed4b5 100644 --- a/src/database/mock.rs +++ b/src/database/mock.rs @@ -1,7 +1,7 @@ use crate::{ - DatabaseConnection, EntityTrait, ExecErr, ExecResult, ExecResultHolder, Iden, Iterable, - MockDatabaseConnection, MockDatabaseTrait, ModelTrait, QueryErr, QueryResult, QueryResultRow, - Statement, Transaction, TypeErr, + error::*, DatabaseConnection, EntityTrait, ExecResult, ExecResultHolder, Iden, Iterable, + MockDatabaseConnection, MockDatabaseTrait, ModelTrait, QueryResult, QueryResultRow, Statement, + Transaction, }; use sea_query::{Value, ValueType}; use std::collections::BTreeMap; @@ -68,14 +68,14 @@ impl MockDatabase { } impl MockDatabaseTrait for MockDatabase { - fn execute(&mut self, counter: usize, statement: Statement) -> Result { + fn execute(&mut self, counter: usize, statement: Statement) -> Result { self.transaction_log.push(Transaction::one(statement)); if counter < self.exec_results.len() { Ok(ExecResult { result: ExecResultHolder::Mock(std::mem::take(&mut self.exec_results[counter])), }) } else { - Err(ExecErr) + Err(SeaErr::Execution) } } @@ -83,7 +83,7 @@ impl MockDatabaseTrait for MockDatabase { &mut self, counter: usize, statement: Statement, - ) -> Result, QueryErr> { + ) -> Result, SeaErr> { self.transaction_log.push(Transaction::one(statement)); if counter < self.query_results.len() { Ok(std::mem::take(&mut self.query_results[counter]) @@ -93,7 +93,7 @@ impl MockDatabaseTrait for MockDatabase { }) .collect()) } else { - Err(QueryErr) + Err(SeaErr::Query) } } @@ -103,7 +103,7 @@ impl MockDatabaseTrait for MockDatabase { } impl MockRow { - pub fn try_get(&self, col: &str) -> Result + pub fn try_get(&self, col: &str) -> Result where T: ValueType, { diff --git a/src/database/mod.rs b/src/database/mod.rs index ffcdb1c0..80f261b1 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -10,11 +10,13 @@ pub use mock::*; pub use statement::*; pub use transaction::*; +use crate::SeaErr; + #[derive(Debug, Default)] pub struct Database; impl Database { - pub async fn connect(string: &str) -> Result { + pub async fn connect(string: &str) -> Result { #[cfg(feature = "sqlx-mysql")] if crate::SqlxMySqlConnector::accepts(string) { return Ok(crate::SqlxMySqlConnector::connect(string).await?); @@ -27,6 +29,6 @@ impl Database { if crate::MockDatabaseConnector::accepts(string) { return Ok(crate::MockDatabaseConnector::connect(string).await?); } - Err(ConnectionErr) + Err(SeaErr::Connection) } } diff --git a/src/driver/mock.rs b/src/driver/mock.rs index 2622fdde..7ffffbdf 100644 --- a/src/driver/mock.rs +++ b/src/driver/mock.rs @@ -1,6 +1,6 @@ use crate::{ - debug_print, ConnectionErr, DatabaseConnection, ExecErr, ExecResult, MockDatabase, QueryErr, - QueryResult, Statement, Transaction, + debug_print, error::*, DatabaseConnection, ExecResult, MockDatabase, QueryResult, Statement, + Transaction, }; use std::sync::{ atomic::{AtomicUsize, Ordering}, @@ -15,9 +15,9 @@ pub struct MockDatabaseConnection { } pub trait MockDatabaseTrait: Send { - fn execute(&mut self, counter: usize, stmt: Statement) -> Result; + fn execute(&mut self, counter: usize, stmt: Statement) -> Result; - fn query(&mut self, counter: usize, stmt: Statement) -> Result, QueryErr>; + fn query(&mut self, counter: usize, stmt: Statement) -> Result, SeaErr>; fn drain_transaction_log(&mut self) -> Vec; } @@ -27,7 +27,7 @@ impl MockDatabaseConnector { string.starts_with("mock://") } - pub async fn connect(_string: &str) -> Result { + pub async fn connect(_string: &str) -> Result { Ok(DatabaseConnection::MockDatabaseConnection( MockDatabaseConnection::new(MockDatabase::new()), )) @@ -49,20 +49,20 @@ impl MockDatabaseConnection { &self.mocker } - pub async fn execute(&self, statement: Statement) -> Result { + pub async fn execute(&self, statement: Statement) -> Result { debug_print!("{}", statement); let counter = self.counter.fetch_add(1, Ordering::SeqCst); self.mocker.lock().unwrap().execute(counter, statement) } - pub async fn query_one(&self, statement: Statement) -> Result, QueryErr> { + pub async fn query_one(&self, statement: Statement) -> Result, SeaErr> { debug_print!("{}", statement); let counter = self.counter.fetch_add(1, Ordering::SeqCst); let result = self.mocker.lock().unwrap().query(counter, statement)?; Ok(result.into_iter().next()) } - pub async fn query_all(&self, statement: Statement) -> Result, QueryErr> { + pub async fn query_all(&self, statement: Statement) -> Result, SeaErr> { debug_print!("{}", statement); let counter = self.counter.fetch_add(1, Ordering::SeqCst); self.mocker.lock().unwrap().query(counter, statement) diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 2158f441..7cb183c3 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -4,8 +4,6 @@ mod mock; mod sqlx_mysql; #[cfg(feature = "sqlx-sqlite")] mod sqlx_sqlite; -#[cfg(feature = "sqlx-dep")] -mod sqlx_types; #[cfg(feature = "mock")] pub use mock::*; @@ -13,5 +11,3 @@ pub use mock::*; pub use sqlx_mysql::*; #[cfg(feature = "sqlx-sqlite")] pub use sqlx_sqlite::*; -#[cfg(feature = "sqlx-dep")] -pub use sqlx_types::*; diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs index 8b609d61..18e06154 100644 --- a/src/driver/sqlx_mysql.rs +++ b/src/driver/sqlx_mysql.rs @@ -6,7 +6,7 @@ use sqlx::{ sea_query::sea_query_driver_mysql!(); use sea_query_driver_mysql::bind_query; -use crate::{debug_print, executor::*, ConnectionErr, DatabaseConnection, Statement}; +use crate::{debug_print, error::*, executor::*, DatabaseConnection, Statement}; pub struct SqlxMySqlConnector; @@ -19,13 +19,13 @@ impl SqlxMySqlConnector { string.starts_with("mysql://") } - pub async fn connect(string: &str) -> Result { + pub async fn connect(string: &str) -> Result { if let Ok(pool) = MySqlPool::connect(string).await { Ok(DatabaseConnection::SqlxMySqlPoolConnection( SqlxMySqlPoolConnection { pool }, )) } else { - Err(ConnectionErr) + Err(SeaErr::Connection) } } } @@ -37,7 +37,7 @@ impl SqlxMySqlConnector { } impl SqlxMySqlPoolConnection { - pub async fn execute(&self, stmt: Statement) -> Result { + pub async fn execute(&self, stmt: Statement) -> Result { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -46,10 +46,10 @@ impl SqlxMySqlPoolConnection { return Ok(res.into()); } } - Err(ExecErr) + Err(SeaErr::Execution) } - pub async fn query_one(&self, stmt: Statement) -> Result, QueryErr> { + pub async fn query_one(&self, stmt: Statement) -> Result, SeaErr> { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -60,11 +60,11 @@ impl SqlxMySqlPoolConnection { Ok(None) } } else { - Err(QueryErr) + Err(SeaErr::Query) } } - pub async fn query_all(&self, stmt: Statement) -> Result, QueryErr> { + pub async fn query_all(&self, stmt: Statement) -> Result, SeaErr> { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -73,7 +73,7 @@ impl SqlxMySqlPoolConnection { return Ok(rows.into_iter().map(|r| r.into()).collect()); } } - Err(QueryErr) + Err(SeaErr::Query) } } diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs index 021cc919..e5290216 100644 --- a/src/driver/sqlx_sqlite.rs +++ b/src/driver/sqlx_sqlite.rs @@ -6,7 +6,7 @@ use sqlx::{ sea_query::sea_query_driver_sqlite!(); use sea_query_driver_sqlite::bind_query; -use crate::{debug_print, executor::*, ConnectionErr, DatabaseConnection, Statement}; +use crate::{debug_print, error::*, executor::*, DatabaseConnection, Statement}; pub struct SqlxSqliteConnector; @@ -19,13 +19,13 @@ impl SqlxSqliteConnector { string.starts_with("sqlite:") } - pub async fn connect(string: &str) -> Result { + pub async fn connect(string: &str) -> Result { if let Ok(pool) = SqlitePool::connect(string).await { Ok(DatabaseConnection::SqlxSqlitePoolConnection( SqlxSqlitePoolConnection { pool }, )) } else { - Err(ConnectionErr) + Err(SeaErr::Connection) } } } @@ -37,7 +37,7 @@ impl SqlxSqliteConnector { } impl SqlxSqlitePoolConnection { - pub async fn execute(&self, stmt: Statement) -> Result { + pub async fn execute(&self, stmt: Statement) -> Result { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -46,10 +46,10 @@ impl SqlxSqlitePoolConnection { return Ok(res.into()); } } - Err(ExecErr) + Err(SeaErr::Execution) } - pub async fn query_one(&self, stmt: Statement) -> Result, QueryErr> { + pub async fn query_one(&self, stmt: Statement) -> Result, SeaErr> { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -60,11 +60,11 @@ impl SqlxSqlitePoolConnection { Ok(None) } } else { - Err(QueryErr) + Err(SeaErr::Query) } } - pub async fn query_all(&self, stmt: Statement) -> Result, QueryErr> { + pub async fn query_all(&self, stmt: Statement) -> Result, SeaErr> { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -73,7 +73,7 @@ impl SqlxSqlitePoolConnection { return Ok(rows.into_iter().map(|r| r.into()).collect()); } } - Err(QueryErr) + Err(SeaErr::Query) } } diff --git a/src/driver/sqlx_types.rs b/src/driver/sqlx_types.rs deleted file mode 100644 index 5a52572e..00000000 --- a/src/driver/sqlx_types.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::{ExecErr, TypeErr}; - -impl From for TypeErr { - fn from(_: sqlx::Error) -> TypeErr { - TypeErr - } -} - -impl From for ExecErr { - fn from(_: sqlx::Error) -> ExecErr { - ExecErr - } -} diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs index dd35a423..6cbaf906 100644 --- a/src/entity/active_model.rs +++ b/src/entity/active_model.rs @@ -1,5 +1,5 @@ use crate::{ - DatabaseConnection, DeleteResult, EntityTrait, ExecErr, Iterable, PrimaryKeyToColumn, + error::*, DatabaseConnection, DeleteResult, EntityTrait, Iterable, PrimaryKeyToColumn, PrimaryKeyTrait, Value, }; use std::fmt::Debug; @@ -66,8 +66,8 @@ pub trait ActiveModelTrait: Clone + Debug { fn default() -> Self; // below is not yet possible. right now we define these methods in DeriveActiveModel - // fn save(self, db: &DatabaseConnection) -> impl Future>; - // fn delete(self, db: &DatabaseConnection) -> impl Future>; + // fn save(self, db: &DatabaseConnection) -> impl Future>; + // fn delete(self, db: &DatabaseConnection) -> impl Future>; } /// Behaviors for users to override @@ -188,7 +188,7 @@ where /// Insert the model if primary key is unset, update otherwise. /// Only works if the entity has auto increment primary key. -pub async fn save_active_model(mut am: A, db: &DatabaseConnection) -> Result +pub async fn save_active_model(mut am: A, db: &DatabaseConnection) -> Result where A: ActiveModelBehavior + ActiveModelTrait, E::Model: IntoActiveModel, @@ -212,7 +212,7 @@ where Ok(am) } -async fn insert_and_select_active_model(am: A, db: &DatabaseConnection) -> Result +async fn insert_and_select_active_model(am: A, db: &DatabaseConnection) -> Result where A: ActiveModelTrait, E::Model: IntoActiveModel, @@ -224,17 +224,17 @@ where if ::auto_increment() && res.last_insert_id != 0 { let find = E::find_by_id(res.last_insert_id).one(db); let res = find.await; - let model: Option = res.map_err(|_| ExecErr)?; + let model: Option = res?; match model { Some(model) => Ok(model.into_active_model()), - None => Err(ExecErr), + None => Err(SeaErr::Execution), } } else { Ok(A::default()) } } -async fn update_active_model(am: A, db: &DatabaseConnection) -> Result +async fn update_active_model(am: A, db: &DatabaseConnection) -> Result where A: ActiveModelTrait, E: EntityTrait, @@ -246,7 +246,7 @@ where pub async fn delete_active_model( mut am: A, db: &DatabaseConnection, -) -> Result +) -> Result where A: ActiveModelBehavior + ActiveModelTrait, E: EntityTrait, diff --git a/src/entity/model.rs b/src/entity/model.rs index 6161538b..4e4027d3 100644 --- a/src/entity/model.rs +++ b/src/entity/model.rs @@ -1,4 +1,4 @@ -use crate::{EntityTrait, QueryFilter, QueryResult, Related, Select, TypeErr}; +use crate::{EntityTrait, SeaErr, QueryFilter, QueryResult, Related, Select}; pub use sea_query::Value; use std::fmt::Debug; @@ -19,11 +19,11 @@ pub trait ModelTrait: Clone + Debug { } pub trait FromQueryResult { - fn from_query_result(res: &QueryResult, pre: &str) -> Result + fn from_query_result(res: &QueryResult, pre: &str) -> Result where Self: Sized; - fn from_query_result_optional(res: &QueryResult, pre: &str) -> Result, TypeErr> + fn from_query_result_optional(res: &QueryResult, pre: &str) -> Result, SeaErr> where Self: Sized, { diff --git a/src/entity/prelude.rs b/src/entity/prelude.rs index f7eb5cc1..77ef63f6 100644 --- a/src/entity/prelude.rs +++ b/src/entity/prelude.rs @@ -1,7 +1,7 @@ pub use crate::{ - ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType, DeriveActiveModel, - DeriveActiveModelBehavior, DeriveColumn, DeriveEntity, DeriveModel, DerivePrimaryKey, - EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait, PrimaryKeyToColumn, - PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, RelationTrait, Select, - TypeErr, Value, + error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType, + DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveEntity, DeriveModel, + DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait, + PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, + RelationTrait, Select, Value, }; diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 00000000..4b275416 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,41 @@ +use std::{error, fmt}; + +#[derive(Debug)] +pub enum SeaErr { + Connection, + Execution, + Query, + #[cfg(feature = "sqlx-dep")] + Sqlx(sqlx::Error), +} + +impl fmt::Display for SeaErr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Connection => write!(f, "{:?}", "Connection Error"), + Self::Execution => write!(f, "{:?}", "Execution Error"), + Self::Query => write!(f, "{:?}", "Query Error"), + #[cfg(feature = "sqlx-dep")] + Self::Sqlx(e) => write!(f, "{:?}", e), + } + } +} + +impl error::Error for SeaErr { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Connection => None, + Self::Execution => None, + Self::Query => None, + #[cfg(feature = "sqlx-dep")] + Self::Sqlx(e) => Some(e), + } + } +} + +#[cfg(feature = "sqlx-dep")] +impl From for SeaErr { + fn from(sqlx_err: sqlx::Error) -> Self { + Self::Sqlx(sqlx_err) + } +} diff --git a/src/executor/delete.rs b/src/executor/delete.rs index ac051ab5..4e0cb120 100644 --- a/src/executor/delete.rs +++ b/src/executor/delete.rs @@ -1,5 +1,5 @@ use crate::{ - ActiveModelTrait, DatabaseConnection, DeleteMany, DeleteOne, EntityTrait, ExecErr, Statement, + error::*, ActiveModelTrait, DatabaseConnection, DeleteMany, DeleteOne, EntityTrait, Statement, }; use sea_query::DeleteStatement; use std::future::Future; @@ -21,7 +21,7 @@ where pub fn exec( self, db: &'a DatabaseConnection, - ) -> impl Future> + 'a { + ) -> impl Future> + 'a { // so that self is dropped before entering await exec_delete_only(self.query, db) } @@ -34,7 +34,7 @@ where pub fn exec( self, db: &'a DatabaseConnection, - ) -> impl Future> + 'a { + ) -> impl Future> + 'a { // so that self is dropped before entering await exec_delete_only(self.query, db) } @@ -48,7 +48,7 @@ impl Deleter { pub fn exec( self, db: &DatabaseConnection, - ) -> impl Future> + '_ { + ) -> impl Future> + '_ { let builder = db.get_query_builder_backend(); exec_delete(builder.build(&self.query), db) } @@ -57,7 +57,7 @@ impl Deleter { async fn exec_delete_only( query: DeleteStatement, db: &DatabaseConnection, -) -> Result { +) -> Result { Deleter::new(query).exec(db).await } @@ -65,7 +65,7 @@ async fn exec_delete_only( async fn exec_delete( statement: Statement, db: &DatabaseConnection, -) -> Result { +) -> Result { let result = db.execute(statement).await?; Ok(DeleteResult { rows_affected: result.rows_affected(), diff --git a/src/executor/execute.rs b/src/executor/execute.rs index c1a7cd86..b795466a 100644 --- a/src/executor/execute.rs +++ b/src/executor/execute.rs @@ -1,5 +1,3 @@ -use std::{error::Error, fmt}; - #[derive(Debug)] pub struct ExecResult { pub(crate) result: ExecResultHolder, @@ -15,9 +13,6 @@ pub(crate) enum ExecResultHolder { Mock(crate::MockExecResult), } -#[derive(Debug)] -pub struct ExecErr; - // ExecResult // impl ExecResult { @@ -50,13 +45,3 @@ impl ExecResult { } } } - -// ExecErr // - -impl Error for ExecErr {} - -impl fmt::Display for ExecErr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} diff --git a/src/executor/insert.rs b/src/executor/insert.rs index 0c1132c3..ac8616f3 100644 --- a/src/executor/insert.rs +++ b/src/executor/insert.rs @@ -1,4 +1,4 @@ -use crate::{ActiveModelTrait, DatabaseConnection, ExecErr, Insert, QueryTrait, Statement}; +use crate::{error::*, ActiveModelTrait, DatabaseConnection, Insert, QueryTrait, Statement}; use sea_query::InsertStatement; use std::future::Future; @@ -19,7 +19,7 @@ where pub fn exec( self, db: &DatabaseConnection, - ) -> impl Future> + '_ { + ) -> impl Future> + '_ { // so that self is dropped before entering await Inserter::new(self.into_query()).exec(db) } @@ -33,7 +33,7 @@ impl Inserter { pub fn exec( self, db: &DatabaseConnection, - ) -> impl Future> + '_ { + ) -> impl Future> + '_ { let builder = db.get_query_builder_backend(); exec_insert(builder.build(&self.query), db) } @@ -43,7 +43,7 @@ impl Inserter { async fn exec_insert( statement: Statement, db: &DatabaseConnection, -) -> Result { +) -> Result { let result = db.execute(statement).await?; // TODO: Postgres instead use query_one + returning clause Ok(InsertResult { diff --git a/src/executor/paginator.rs b/src/executor/paginator.rs index ead5114b..4ab8cdb5 100644 --- a/src/executor/paginator.rs +++ b/src/executor/paginator.rs @@ -1,4 +1,4 @@ -use crate::{DatabaseConnection, QueryErr, SelectorTrait}; +use crate::{error::*, DatabaseConnection, SelectorTrait}; use async_stream::stream; use futures::Stream; use sea_query::{Alias, Expr, SelectStatement}; @@ -23,7 +23,7 @@ where S: SelectorTrait + 'db, { /// Fetch a specific page - pub async fn fetch_page(&self, page: usize) -> Result, QueryErr> { + pub async fn fetch_page(&self, page: usize) -> Result, SeaErr> { let query = self .query .clone() @@ -36,18 +36,18 @@ where let mut buffer = Vec::with_capacity(rows.len()); for row in rows.into_iter() { // TODO: Error handling - buffer.push(S::from_raw_query_result(row).map_err(|_e| QueryErr)?); + buffer.push(S::from_raw_query_result(row)?); } Ok(buffer) } /// Fetch the current page - pub async fn fetch(&self) -> Result, QueryErr> { + pub async fn fetch(&self) -> Result, SeaErr> { self.fetch_page(self.page).await } /// Get the total number of pages - pub async fn num_pages(&self) -> Result { + pub async fn num_pages(&self) -> Result { let builder = self.db.get_query_builder_backend(); let stmt = builder.build( SelectStatement::new() @@ -61,9 +61,7 @@ where Some(res) => res, None => return Ok(0), }; - let num_rows = result - .try_get::("", "num_rows") - .map_err(|_e| QueryErr)? as usize; + let num_rows = result.try_get::("", "num_rows")? as usize; let num_pages = (num_rows / self.page_size) + (num_rows % self.page_size > 0) as usize; Ok(num_pages) } @@ -79,7 +77,7 @@ where } /// Fetch one page and increment the page counter - pub async fn fetch_and_next(&mut self) -> Result>, QueryErr> { + pub async fn fetch_and_next(&mut self) -> Result>, SeaErr> { let vec = self.fetch().await?; self.next(); let opt = if !vec.is_empty() { Some(vec) } else { None }; @@ -87,7 +85,7 @@ where } /// Convert self into an async stream - pub fn into_stream(mut self) -> PinBoxStream<'db, Result, QueryErr>> { + pub fn into_stream(mut self) -> PinBoxStream<'db, Result, SeaErr>> { Box::pin(stream! { loop { if let Some(vec) = self.fetch_and_next().await? { @@ -105,7 +103,7 @@ where mod tests { use crate::entity::prelude::*; use crate::tests_cfg::*; - use crate::{DatabaseConnection, MockDatabase, QueryErr, Transaction}; + use crate::{DatabaseConnection, MockDatabase, Transaction}; use futures::TryStreamExt; use sea_query::{Alias, Expr, SelectStatement, Value}; @@ -150,7 +148,7 @@ mod tests { } #[async_std::test] - async fn fetch_page() -> Result<(), QueryErr> { + async fn fetch_page() -> Result<(), SeaErr> { let (db, pages) = setup(); let paginator = fruit::Entity::find().paginate(&db, 2); @@ -180,7 +178,7 @@ mod tests { } #[async_std::test] - async fn fetch() -> Result<(), QueryErr> { + async fn fetch() -> Result<(), SeaErr> { let (db, pages) = setup(); let mut paginator = fruit::Entity::find().paginate(&db, 2); @@ -214,7 +212,7 @@ mod tests { } #[async_std::test] - async fn num_pages() -> Result<(), QueryErr> { + async fn num_pages() -> Result<(), SeaErr> { let (db, num_rows) = setup_num_rows(); let num_rows = num_rows as usize; @@ -246,7 +244,7 @@ mod tests { } #[async_std::test] - async fn next_and_cur_page() -> Result<(), QueryErr> { + async fn next_and_cur_page() -> Result<(), SeaErr> { let (db, _) = setup(); let mut paginator = fruit::Entity::find().paginate(&db, 2); @@ -262,7 +260,7 @@ mod tests { } #[async_std::test] - async fn fetch_and_next() -> Result<(), QueryErr> { + async fn fetch_and_next() -> Result<(), SeaErr> { let (db, pages) = setup(); let mut paginator = fruit::Entity::find().paginate(&db, 2); @@ -297,7 +295,7 @@ mod tests { } #[async_std::test] - async fn into_stream() -> Result<(), QueryErr> { + async fn into_stream() -> Result<(), SeaErr> { let (db, pages) = setup(); let mut fruit_stream = fruit::Entity::find().paginate(&db, 2).into_stream(); diff --git a/src/executor/query.rs b/src/executor/query.rs index 330c8748..13582fe4 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -1,4 +1,5 @@ -use std::{error::Error, fmt}; +use crate::SeaErr; +use std::fmt; #[derive(Debug)] pub struct QueryResult { @@ -14,14 +15,8 @@ pub(crate) enum QueryResultRow { Mock(crate::MockRow), } -#[derive(Debug)] -pub struct QueryErr; - -#[derive(Debug)] -pub struct TypeErr; - pub trait TryGetable { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result where Self: Sized; } @@ -29,7 +24,7 @@ pub trait TryGetable { // QueryResult // impl QueryResult { - pub fn try_get(&self, pre: &str, col: &str) -> Result + pub fn try_get(&self, pre: &str, col: &str) -> Result where T: TryGetable, { @@ -50,38 +45,12 @@ impl fmt::Debug for QueryResultRow { } } -// QueryErr // - -impl Error for QueryErr {} - -impl fmt::Display for QueryErr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -impl From for QueryErr { - fn from(_: TypeErr) -> QueryErr { - QueryErr - } -} - -// TypeErr // - -impl Error for TypeErr {} - -impl fmt::Display for TypeErr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} - // TryGetable // macro_rules! try_getable_all { ( $type: ty ) => { impl TryGetable for $type { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { let column = format!("{}{}", pre, col); match &res.row { #[cfg(feature = "sqlx-mysql")] @@ -101,7 +70,7 @@ macro_rules! try_getable_all { } impl TryGetable for Option<$type> { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { let column = format!("{}{}", pre, col); match &res.row { #[cfg(feature = "sqlx-mysql")] @@ -134,7 +103,7 @@ macro_rules! try_getable_all { macro_rules! try_getable_mysql { ( $type: ty ) => { impl TryGetable for $type { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { let column = format!("{}{}", pre, col); match &res.row { #[cfg(feature = "sqlx-mysql")] @@ -153,7 +122,7 @@ macro_rules! try_getable_mysql { } impl TryGetable for Option<$type> { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { let column = format!("{}{}", pre, col); match &res.row { #[cfg(feature = "sqlx-mysql")] diff --git a/src/executor/select.rs b/src/executor/select.rs index 6c74c8cb..fa6e0868 100644 --- a/src/executor/select.rs +++ b/src/executor/select.rs @@ -1,7 +1,7 @@ use crate::{ - query::combine, DatabaseConnection, EntityTrait, FromQueryResult, Iterable, JsonValue, - ModelTrait, Paginator, PrimaryKeyToColumn, QueryErr, QueryResult, Select, SelectTwo, - SelectTwoMany, TypeErr, + error::*, query::combine, DatabaseConnection, EntityTrait, FromQueryResult, Iterable, + JsonValue, ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectTwo, + SelectTwoMany, }; use sea_query::SelectStatement; use std::marker::PhantomData; @@ -18,7 +18,7 @@ where pub trait SelectorTrait { type Item: Sized; - fn from_raw_query_result(res: QueryResult) -> Result; + fn from_raw_query_result(res: QueryResult) -> Result; } pub struct SelectModel @@ -43,7 +43,7 @@ where { type Item = M; - fn from_raw_query_result(res: QueryResult) -> Result { + fn from_raw_query_result(res: QueryResult) -> Result { M::from_query_result(&res, "") } } @@ -55,7 +55,7 @@ where { type Item = (M, Option); - fn from_raw_query_result(res: QueryResult) -> Result { + fn from_raw_query_result(res: QueryResult) -> Result { Ok(( M::from_query_result(&res, combine::SELECT_A)?, N::from_query_result_optional(&res, combine::SELECT_B)?, @@ -85,11 +85,11 @@ where } } - pub async fn one(self, db: &DatabaseConnection) -> Result, QueryErr> { + pub async fn one(self, db: &DatabaseConnection) -> Result, SeaErr> { self.into_model::().one(db).await } - pub async fn all(self, db: &DatabaseConnection) -> Result, QueryErr> { + pub async fn all(self, db: &DatabaseConnection) -> Result, SeaErr> { self.into_model::().all(db).await } @@ -129,14 +129,14 @@ where pub async fn one( self, db: &DatabaseConnection, - ) -> Result)>, QueryErr> { + ) -> Result)>, SeaErr> { self.into_model::().one(db).await } pub async fn all( self, db: &DatabaseConnection, - ) -> Result)>, QueryErr> { + ) -> Result)>, SeaErr> { self.into_model::().all(db).await } } @@ -168,14 +168,14 @@ where pub async fn one( self, db: &DatabaseConnection, - ) -> Result)>, QueryErr> { + ) -> Result)>, SeaErr> { self.into_model::().one(db).await } pub async fn all( self, db: &DatabaseConnection, - ) -> Result)>, QueryErr> { + ) -> Result)>, SeaErr> { let rows = self.into_model::().all(db).await?; Ok(consolidate_query_result::(rows)) } @@ -185,7 +185,7 @@ impl Selector where S: SelectorTrait, { - pub async fn one(mut self, db: &DatabaseConnection) -> Result, QueryErr> { + pub async fn one(mut self, db: &DatabaseConnection) -> Result, SeaErr> { let builder = db.get_query_builder_backend(); self.query.limit(1); let row = db.query_one(builder.build(&self.query)).await?; @@ -195,7 +195,7 @@ where } } - pub async fn all(self, db: &DatabaseConnection) -> Result, QueryErr> { + pub async fn all(self, db: &DatabaseConnection) -> Result, SeaErr> { let builder = db.get_query_builder_backend(); let rows = db.query_all(builder.build(&self.query)).await?; let mut models = Vec::new(); diff --git a/src/executor/update.rs b/src/executor/update.rs index df4fabd4..e2c0ae75 100644 --- a/src/executor/update.rs +++ b/src/executor/update.rs @@ -1,5 +1,5 @@ use crate::{ - ActiveModelTrait, DatabaseConnection, EntityTrait, ExecErr, Statement, UpdateMany, UpdateOne, + error::*, ActiveModelTrait, DatabaseConnection, EntityTrait, Statement, UpdateMany, UpdateOne, }; use sea_query::UpdateStatement; use std::future::Future; @@ -18,7 +18,10 @@ impl<'a, A: 'a> UpdateOne where A: ActiveModelTrait, { - pub fn exec(self, db: &'a DatabaseConnection) -> impl Future> + 'a { + pub fn exec( + self, + db: &'a DatabaseConnection, + ) -> impl Future> + 'a { // so that self is dropped before entering await exec_update_and_return_original(self.query, self.model, db) } @@ -31,7 +34,7 @@ where pub fn exec( self, db: &'a DatabaseConnection, - ) -> impl Future> + 'a { + ) -> impl Future> + 'a { // so that self is dropped before entering await exec_update_only(self.query, db) } @@ -45,7 +48,7 @@ impl Updater { pub fn exec( self, db: &DatabaseConnection, - ) -> impl Future> + '_ { + ) -> impl Future> + '_ { let builder = db.get_query_builder_backend(); exec_update(builder.build(&self.query), db) } @@ -54,7 +57,7 @@ impl Updater { async fn exec_update_only( query: UpdateStatement, db: &DatabaseConnection, -) -> Result { +) -> Result { Updater::new(query).exec(db).await } @@ -62,7 +65,7 @@ async fn exec_update_and_return_original( query: UpdateStatement, model: A, db: &DatabaseConnection, -) -> Result +) -> Result where A: ActiveModelTrait, { @@ -74,7 +77,7 @@ where async fn exec_update( statement: Statement, db: &DatabaseConnection, -) -> Result { +) -> Result { let result = db.execute(statement).await?; Ok(UpdateResult { rows_affected: result.rows_affected(), diff --git a/src/lib.rs b/src/lib.rs index cc41fb8c..c300c1fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,8 +43,8 @@ //! //! ## Select //! ``` -//! # use sea_orm::{DbConn, entity::*, query::*, tests_cfg::*}; -//! # async fn function(db: &DbConn) -> Result<(), QueryErr> { +//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; +//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { //! # //! // find all models //! let cakes: Vec = Cake::find().all(db).await?; @@ -73,8 +73,8 @@ //! ``` //! ## Insert //! ``` -//! # use sea_orm::{DbConn, entity::*, query::*, tests_cfg::*}; -//! # async fn function(db: &DbConn) -> Result<(), ExecErr> { +//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; +//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { //! # //! let apple = fruit::ActiveModel { //! name: Set("Apple".to_owned()), @@ -94,7 +94,7 @@ //! # Ok(()) //! # } //! # -//! # async fn function2(db: &DbConn) -> Result<(), ExecErr> { +//! # async fn function2(db: &DbConn) -> Result<(), SeaErr> { //! # let apple = fruit::ActiveModel { //! # name: Set("Apple".to_owned()), //! # ..Default::default() // no need to set primary key @@ -113,16 +113,16 @@ //! ``` //! ## Update //! ``` -//! # use sea_orm::{DbConn, entity::*, query::*, tests_cfg::*}; +//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # //! use sea_orm::sea_query::{Expr, Value}; //! -//! # async fn function(db: &DbConn) -> Result<(), QueryErr> { +//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { //! let pear: Option = Fruit::find_by_id(1).one(db).await?; //! # Ok(()) //! # } //! # -//! # async fn function2(db: &DbConn) -> Result<(), ExecErr> { +//! # async fn function2(db: &DbConn) -> Result<(), SeaErr> { //! # let pear: Option = Fruit::find_by_id(1).one(db).await.unwrap(); //! //! let mut pear: fruit::ActiveModel = pear.unwrap().into(); @@ -143,9 +143,9 @@ //! ``` //! ## Save //! ``` -//! # use sea_orm::{DbConn, entity::*, query::*, tests_cfg::*}; +//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # -//! # async fn function(db: &DbConn) -> Result<(), ExecErr> { +//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { //! let banana = fruit::ActiveModel { //! id: Unset(None), //! name: Set("Banana".to_owned()), @@ -165,14 +165,14 @@ //! ``` //! ## Delete //! ``` -//! # use sea_orm::{DbConn, entity::*, query::*, tests_cfg::*}; +//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # -//! # async fn function(db: &DbConn) -> Result<(), QueryErr> { +//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { //! let orange: Option = Fruit::find_by_id(1).one(db).await?; //! # Ok(()) //! # } //! # -//! # async fn function2(db: &DbConn) -> Result<(), ExecErr> { +//! # async fn function2(db: &DbConn) -> Result<(), SeaErr> { //! # let orange: Option = Fruit::find_by_id(1).one(db).await.unwrap(); //! let orange: fruit::ActiveModel = orange.unwrap().into(); //! @@ -198,6 +198,7 @@ mod database; mod driver; pub mod entity; +pub mod error; mod executor; pub mod query; #[doc(hidden)] @@ -207,6 +208,7 @@ mod util; pub use database::*; pub use driver::*; pub use entity::*; +pub use error::*; pub use executor::*; pub use query::*; diff --git a/src/query/json.rs b/src/query/json.rs index b41309d4..4c5cd65d 100644 --- a/src/query/json.rs +++ b/src/query/json.rs @@ -1,9 +1,9 @@ -use crate::{FromQueryResult, QueryResult, QueryResultRow, TypeErr}; +use crate::{FromQueryResult, SeaErr, QueryResult, QueryResultRow}; use serde_json::Map; pub use serde_json::Value as JsonValue; impl FromQueryResult for JsonValue { - fn from_query_result(res: &QueryResult, pre: &str) -> Result { + fn from_query_result(res: &QueryResult, pre: &str) -> Result { match &res.row { #[cfg(feature = "sqlx-mysql")] QueryResultRow::SqlxMySql(row) => { diff --git a/src/query/mod.rs b/src/query/mod.rs index 51060a1e..86668231 100644 --- a/src/query/mod.rs +++ b/src/query/mod.rs @@ -20,4 +20,4 @@ pub use select::*; pub use traits::*; pub use update::*; -pub use crate::executor::{ExecErr, InsertResult, QueryErr, UpdateResult}; +pub use crate::executor::{InsertResult, UpdateResult}; diff --git a/tests/basic.rs b/tests/basic.rs index f4c4ef74..dc048863 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -1,4 +1,4 @@ -use sea_orm::{entity::*, query::*, sea_query, tests_cfg::*, DbConn}; +use sea_orm::{entity::*, error::*, sea_query, tests_cfg::*, DbConn}; mod setup; @@ -31,7 +31,7 @@ async fn setup_schema(db: &DbConn) { println!("Create table cake: {:?}", result); } -async fn crud_cake(db: &DbConn) -> Result<(), ExecErr> { +async fn crud_cake(db: &DbConn) -> Result<(), SeaErr> { let apple = cake::ActiveModel { name: Set("Apple Pie".to_owned()), ..Default::default() @@ -57,10 +57,7 @@ async fn crud_cake(db: &DbConn) -> Result<(), ExecErr> { println!(); println!("Updated: {:?}", apple); - let apple = cake::Entity::find_by_id(1) - .one(db) - .await - .map_err(|_| ExecErr)?; + let apple = cake::Entity::find_by_id(1).one(db).await?; assert_eq!( Some(cake::Model { @@ -77,10 +74,7 @@ async fn crud_cake(db: &DbConn) -> Result<(), ExecErr> { println!(); println!("Deleted: {:?}", result); - let apple = cake::Entity::find_by_id(1) - .one(db) - .await - .map_err(|_| ExecErr)?; + let apple = cake::Entity::find_by_id(1).one(db).await?; assert_eq!(None, apple); From 0298cfb6af9e5177ddaaafe4d26ab762fc851b92 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 30 Jun 2021 21:17:23 +0800 Subject: [PATCH 06/23] Rename to DbErr --- examples/sqlx-mysql/src/operation.rs | 8 +++--- examples/sqlx-mysql/src/select.rs | 26 +++++++++---------- sea-orm-macros/src/derives/active_model.rs | 4 +-- .../src/derives/from_query_result.rs | 2 +- sea-orm-macros/src/derives/model.rs | 2 +- src/database/connection.rs | 6 ++--- src/database/mock.rs | 10 +++---- src/database/mod.rs | 6 ++--- src/driver/mock.rs | 12 ++++----- src/driver/sqlx_mysql.rs | 16 ++++++------ src/driver/sqlx_sqlite.rs | 16 ++++++------ src/entity/active_model.rs | 14 +++++----- src/entity/model.rs | 6 ++--- src/error.rs | 8 +++--- src/executor/delete.rs | 10 +++---- src/executor/insert.rs | 6 ++--- src/executor/paginator.rs | 22 ++++++++-------- src/executor/query.rs | 14 +++++----- src/executor/select.rs | 22 ++++++++-------- src/executor/update.rs | 12 ++++----- src/lib.rs | 16 ++++++------ src/query/json.rs | 4 +-- tests/basic.rs | 2 +- 23 files changed, 122 insertions(+), 122 deletions(-) diff --git a/examples/sqlx-mysql/src/operation.rs b/examples/sqlx-mysql/src/operation.rs index 733322ce..b1273e10 100644 --- a/examples/sqlx-mysql/src/operation.rs +++ b/examples/sqlx-mysql/src/operation.rs @@ -1,7 +1,7 @@ use super::*; use sea_orm::{entity::*, error::*, query::*, DbConn}; -pub async fn all_about_operation(db: &DbConn) -> Result<(), SeaErr> { +pub async fn all_about_operation(db: &DbConn) -> Result<(), DbErr> { insert_and_update(db).await?; println!("===== =====\n"); @@ -15,7 +15,7 @@ pub async fn all_about_operation(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -pub async fn insert_and_update(db: &DbConn) -> Result<(), SeaErr> { +pub async fn insert_and_update(db: &DbConn) -> Result<(), DbErr> { let pear = fruit::ActiveModel { name: Set("pear".to_owned()), ..Default::default() @@ -41,7 +41,7 @@ pub async fn insert_and_update(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -pub async fn save_active_model(db: &DbConn) -> Result<(), SeaErr> { +pub async fn save_active_model(db: &DbConn) -> Result<(), DbErr> { let banana = fruit::ActiveModel { name: Set("Banana".to_owned()), ..Default::default() @@ -79,7 +79,7 @@ mod form { } } -async fn save_custom_active_model(db: &DbConn) -> Result<(), SeaErr> { +async fn save_custom_active_model(db: &DbConn) -> Result<(), DbErr> { let pineapple = form::ActiveModel { id: Unset(None), name: Set("Pineapple".to_owned()), diff --git a/examples/sqlx-mysql/src/select.rs b/examples/sqlx-mysql/src/select.rs index 7033b9f9..9b2cf15c 100644 --- a/examples/sqlx-mysql/src/select.rs +++ b/examples/sqlx-mysql/src/select.rs @@ -1,7 +1,7 @@ use super::*; use sea_orm::{entity::*, error::*, query::*, DbConn, FromQueryResult}; -pub async fn all_about_select(db: &DbConn) -> Result<(), SeaErr> { +pub async fn all_about_select(db: &DbConn) -> Result<(), DbErr> { find_all(db).await?; println!("===== =====\n"); @@ -41,7 +41,7 @@ pub async fn all_about_select(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn find_all(db: &DbConn) -> Result<(), SeaErr> { +async fn find_all(db: &DbConn) -> Result<(), DbErr> { print!("find all cakes: "); let cakes: Vec = Cake::find().all(db).await?; @@ -63,7 +63,7 @@ async fn find_all(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn find_together(db: &DbConn) -> Result<(), SeaErr> { +async fn find_together(db: &DbConn) -> Result<(), DbErr> { print!("find cakes and fruits: "); let both = Cake::find().find_also_related(Fruit).all(db).await?; @@ -82,7 +82,7 @@ impl Cake { } } -async fn find_one(db: &DbConn) -> Result<(), SeaErr> { +async fn find_one(db: &DbConn) -> Result<(), DbErr> { print!("find one by primary key: "); let cheese: Option = Cake::find_by_id(1).one(db).await?; @@ -112,7 +112,7 @@ async fn find_one(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn count_fruits_by_cake(db: &DbConn) -> Result<(), SeaErr> { +async fn count_fruits_by_cake(db: &DbConn) -> Result<(), DbErr> { #[derive(Debug, FromQueryResult)] struct SelectResult { name: String, @@ -138,7 +138,7 @@ async fn count_fruits_by_cake(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn find_many_to_many(db: &DbConn) -> Result<(), SeaErr> { +async fn find_many_to_many(db: &DbConn) -> Result<(), DbErr> { print!("find cakes and fillings: "); let both: Vec<(cake::Model, Vec)> = @@ -178,7 +178,7 @@ async fn find_many_to_many(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn all_about_select_json(db: &DbConn) -> Result<(), SeaErr> { +async fn all_about_select_json(db: &DbConn) -> Result<(), DbErr> { find_all_json(&db).await?; println!("===== =====\n"); @@ -192,7 +192,7 @@ async fn all_about_select_json(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn find_all_json(db: &DbConn) -> Result<(), SeaErr> { +async fn find_all_json(db: &DbConn) -> Result<(), DbErr> { print!("find all cakes: "); let cakes = Cake::find().into_json().all(db).await?; @@ -208,7 +208,7 @@ async fn find_all_json(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn find_together_json(db: &DbConn) -> Result<(), SeaErr> { +async fn find_together_json(db: &DbConn) -> Result<(), DbErr> { print!("find cakes and fruits: "); let cakes_fruits = Cake::find() @@ -225,7 +225,7 @@ async fn find_together_json(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn count_fruits_by_cake_json(db: &DbConn) -> Result<(), SeaErr> { +async fn count_fruits_by_cake_json(db: &DbConn) -> Result<(), DbErr> { print!("count fruits by cake: "); let count = Cake::find() @@ -243,7 +243,7 @@ async fn count_fruits_by_cake_json(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn find_all_stream(db: &DbConn) -> Result<(), SeaErr> { +async fn find_all_stream(db: &DbConn) -> Result<(), DbErr> { use async_std::task::sleep; use futures::TryStreamExt; use std::time::Duration; @@ -291,7 +291,7 @@ async fn find_all_stream(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn find_first_page(db: &DbConn) -> Result<(), SeaErr> { +async fn find_first_page(db: &DbConn) -> Result<(), DbErr> { println!("fruits first page: "); let page = fruit::Entity::find().paginate(db, 2).fetch_page(0).await?; for fruit in page { @@ -301,7 +301,7 @@ async fn find_first_page(db: &DbConn) -> Result<(), SeaErr> { Ok(()) } -async fn find_num_pages(db: &DbConn) -> Result<(), SeaErr> { +async fn find_num_pages(db: &DbConn) -> Result<(), DbErr> { println!("fruits number of page: "); let num_pages = fruit::Entity::find().paginate(db, 2).num_pages().await?; println!("{:?}", num_pages); diff --git a/sea-orm-macros/src/derives/active_model.rs b/sea-orm-macros/src/derives/active_model.rs index ebf642e1..76e80a02 100644 --- a/sea-orm-macros/src/derives/active_model.rs +++ b/sea-orm-macros/src/derives/active_model.rs @@ -37,11 +37,11 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result Result { + pub async fn save(self, db: &sea_orm::DatabaseConnection) -> Result { sea_orm::save_active_model::(self, db).await } - pub async fn delete(self, db: &sea_orm::DatabaseConnection) -> Result { + pub async fn delete(self, db: &sea_orm::DatabaseConnection) -> Result { sea_orm::delete_active_model::(self, db).await } } diff --git a/sea-orm-macros/src/derives/from_query_result.rs b/sea-orm-macros/src/derives/from_query_result.rs index a87b4b63..ef24c18d 100644 --- a/sea-orm-macros/src/derives/from_query_result.rs +++ b/sea-orm-macros/src/derives/from_query_result.rs @@ -30,7 +30,7 @@ pub fn expand_derive_from_query_result(ident: Ident, data: Data) -> syn::Result< Ok(quote!( impl sea_orm::FromQueryResult for #ident { - fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result { + fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result { Ok(Self { #(#field: row.try_get(pre, #name)?),* }) diff --git a/sea-orm-macros/src/derives/model.rs b/sea-orm-macros/src/derives/model.rs index 57db16ab..1faf3642 100644 --- a/sea-orm-macros/src/derives/model.rs +++ b/sea-orm-macros/src/derives/model.rs @@ -47,7 +47,7 @@ pub fn expand_derive_model(ident: Ident, data: Data) -> syn::Result } impl sea_orm::FromQueryResult for #ident { - fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result { + fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result { Ok(Self { #(#field: row.try_get(pre, <::Entity as EntityTrait>::Column::#name.as_str().into())?),* }) diff --git a/src/database/connection.rs b/src/database/connection.rs index 0a138cc9..6336db48 100644 --- a/src/database/connection.rs +++ b/src/database/connection.rs @@ -77,7 +77,7 @@ impl DatabaseConnection { } } - pub async fn execute(&self, stmt: Statement) -> Result { + pub async fn execute(&self, stmt: Statement) -> Result { match self { #[cfg(feature = "sqlx-mysql")] DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.execute(stmt).await, @@ -89,7 +89,7 @@ impl DatabaseConnection { } } - pub async fn query_one(&self, stmt: Statement) -> Result, SeaErr> { + pub async fn query_one(&self, stmt: Statement) -> Result, DbErr> { match self { #[cfg(feature = "sqlx-mysql")] DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_one(stmt).await, @@ -101,7 +101,7 @@ impl DatabaseConnection { } } - pub async fn query_all(&self, stmt: Statement) -> Result, SeaErr> { + pub async fn query_all(&self, stmt: Statement) -> Result, DbErr> { match self { #[cfg(feature = "sqlx-mysql")] DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_all(stmt).await, diff --git a/src/database/mock.rs b/src/database/mock.rs index e80ed4b5..2f99b32c 100644 --- a/src/database/mock.rs +++ b/src/database/mock.rs @@ -68,14 +68,14 @@ impl MockDatabase { } impl MockDatabaseTrait for MockDatabase { - fn execute(&mut self, counter: usize, statement: Statement) -> Result { + fn execute(&mut self, counter: usize, statement: Statement) -> Result { self.transaction_log.push(Transaction::one(statement)); if counter < self.exec_results.len() { Ok(ExecResult { result: ExecResultHolder::Mock(std::mem::take(&mut self.exec_results[counter])), }) } else { - Err(SeaErr::Execution) + Err(DbErr::Execution) } } @@ -83,7 +83,7 @@ impl MockDatabaseTrait for MockDatabase { &mut self, counter: usize, statement: Statement, - ) -> Result, SeaErr> { + ) -> Result, DbErr> { self.transaction_log.push(Transaction::one(statement)); if counter < self.query_results.len() { Ok(std::mem::take(&mut self.query_results[counter]) @@ -93,7 +93,7 @@ impl MockDatabaseTrait for MockDatabase { }) .collect()) } else { - Err(SeaErr::Query) + Err(DbErr::Query) } } @@ -103,7 +103,7 @@ impl MockDatabaseTrait for MockDatabase { } impl MockRow { - pub fn try_get(&self, col: &str) -> Result + pub fn try_get(&self, col: &str) -> Result where T: ValueType, { diff --git a/src/database/mod.rs b/src/database/mod.rs index 80f261b1..5150e3d7 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -10,13 +10,13 @@ pub use mock::*; pub use statement::*; pub use transaction::*; -use crate::SeaErr; +use crate::DbErr; #[derive(Debug, Default)] pub struct Database; impl Database { - pub async fn connect(string: &str) -> Result { + pub async fn connect(string: &str) -> Result { #[cfg(feature = "sqlx-mysql")] if crate::SqlxMySqlConnector::accepts(string) { return Ok(crate::SqlxMySqlConnector::connect(string).await?); @@ -29,6 +29,6 @@ impl Database { if crate::MockDatabaseConnector::accepts(string) { return Ok(crate::MockDatabaseConnector::connect(string).await?); } - Err(SeaErr::Connection) + Err(DbErr::Connection) } } diff --git a/src/driver/mock.rs b/src/driver/mock.rs index 7ffffbdf..96224c38 100644 --- a/src/driver/mock.rs +++ b/src/driver/mock.rs @@ -15,9 +15,9 @@ pub struct MockDatabaseConnection { } pub trait MockDatabaseTrait: Send { - fn execute(&mut self, counter: usize, stmt: Statement) -> Result; + fn execute(&mut self, counter: usize, stmt: Statement) -> Result; - fn query(&mut self, counter: usize, stmt: Statement) -> Result, SeaErr>; + fn query(&mut self, counter: usize, stmt: Statement) -> Result, DbErr>; fn drain_transaction_log(&mut self) -> Vec; } @@ -27,7 +27,7 @@ impl MockDatabaseConnector { string.starts_with("mock://") } - pub async fn connect(_string: &str) -> Result { + pub async fn connect(_string: &str) -> Result { Ok(DatabaseConnection::MockDatabaseConnection( MockDatabaseConnection::new(MockDatabase::new()), )) @@ -49,20 +49,20 @@ impl MockDatabaseConnection { &self.mocker } - pub async fn execute(&self, statement: Statement) -> Result { + pub async fn execute(&self, statement: Statement) -> Result { debug_print!("{}", statement); let counter = self.counter.fetch_add(1, Ordering::SeqCst); self.mocker.lock().unwrap().execute(counter, statement) } - pub async fn query_one(&self, statement: Statement) -> Result, SeaErr> { + pub async fn query_one(&self, statement: Statement) -> Result, DbErr> { debug_print!("{}", statement); let counter = self.counter.fetch_add(1, Ordering::SeqCst); let result = self.mocker.lock().unwrap().query(counter, statement)?; Ok(result.into_iter().next()) } - pub async fn query_all(&self, statement: Statement) -> Result, SeaErr> { + pub async fn query_all(&self, statement: Statement) -> Result, DbErr> { debug_print!("{}", statement); let counter = self.counter.fetch_add(1, Ordering::SeqCst); self.mocker.lock().unwrap().query(counter, statement) diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs index 18e06154..9076c1ed 100644 --- a/src/driver/sqlx_mysql.rs +++ b/src/driver/sqlx_mysql.rs @@ -19,13 +19,13 @@ impl SqlxMySqlConnector { string.starts_with("mysql://") } - pub async fn connect(string: &str) -> Result { + pub async fn connect(string: &str) -> Result { if let Ok(pool) = MySqlPool::connect(string).await { Ok(DatabaseConnection::SqlxMySqlPoolConnection( SqlxMySqlPoolConnection { pool }, )) } else { - Err(SeaErr::Connection) + Err(DbErr::Connection) } } } @@ -37,7 +37,7 @@ impl SqlxMySqlConnector { } impl SqlxMySqlPoolConnection { - pub async fn execute(&self, stmt: Statement) -> Result { + pub async fn execute(&self, stmt: Statement) -> Result { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -46,10 +46,10 @@ impl SqlxMySqlPoolConnection { return Ok(res.into()); } } - Err(SeaErr::Execution) + Err(DbErr::Execution) } - pub async fn query_one(&self, stmt: Statement) -> Result, SeaErr> { + pub async fn query_one(&self, stmt: Statement) -> Result, DbErr> { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -60,11 +60,11 @@ impl SqlxMySqlPoolConnection { Ok(None) } } else { - Err(SeaErr::Query) + Err(DbErr::Query) } } - pub async fn query_all(&self, stmt: Statement) -> Result, SeaErr> { + pub async fn query_all(&self, stmt: Statement) -> Result, DbErr> { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -73,7 +73,7 @@ impl SqlxMySqlPoolConnection { return Ok(rows.into_iter().map(|r| r.into()).collect()); } } - Err(SeaErr::Query) + Err(DbErr::Query) } } diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs index e5290216..94425eb4 100644 --- a/src/driver/sqlx_sqlite.rs +++ b/src/driver/sqlx_sqlite.rs @@ -19,13 +19,13 @@ impl SqlxSqliteConnector { string.starts_with("sqlite:") } - pub async fn connect(string: &str) -> Result { + pub async fn connect(string: &str) -> Result { if let Ok(pool) = SqlitePool::connect(string).await { Ok(DatabaseConnection::SqlxSqlitePoolConnection( SqlxSqlitePoolConnection { pool }, )) } else { - Err(SeaErr::Connection) + Err(DbErr::Connection) } } } @@ -37,7 +37,7 @@ impl SqlxSqliteConnector { } impl SqlxSqlitePoolConnection { - pub async fn execute(&self, stmt: Statement) -> Result { + pub async fn execute(&self, stmt: Statement) -> Result { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -46,10 +46,10 @@ impl SqlxSqlitePoolConnection { return Ok(res.into()); } } - Err(SeaErr::Execution) + Err(DbErr::Execution) } - pub async fn query_one(&self, stmt: Statement) -> Result, SeaErr> { + pub async fn query_one(&self, stmt: Statement) -> Result, DbErr> { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -60,11 +60,11 @@ impl SqlxSqlitePoolConnection { Ok(None) } } else { - Err(SeaErr::Query) + Err(DbErr::Query) } } - pub async fn query_all(&self, stmt: Statement) -> Result, SeaErr> { + pub async fn query_all(&self, stmt: Statement) -> Result, DbErr> { debug_print!("{}", stmt); let query = sqlx_query(&stmt); @@ -73,7 +73,7 @@ impl SqlxSqlitePoolConnection { return Ok(rows.into_iter().map(|r| r.into()).collect()); } } - Err(SeaErr::Query) + Err(DbErr::Query) } } diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs index 6cbaf906..df1fc869 100644 --- a/src/entity/active_model.rs +++ b/src/entity/active_model.rs @@ -66,8 +66,8 @@ pub trait ActiveModelTrait: Clone + Debug { fn default() -> Self; // below is not yet possible. right now we define these methods in DeriveActiveModel - // fn save(self, db: &DatabaseConnection) -> impl Future>; - // fn delete(self, db: &DatabaseConnection) -> impl Future>; + // fn save(self, db: &DatabaseConnection) -> impl Future>; + // fn delete(self, db: &DatabaseConnection) -> impl Future>; } /// Behaviors for users to override @@ -188,7 +188,7 @@ where /// Insert the model if primary key is unset, update otherwise. /// Only works if the entity has auto increment primary key. -pub async fn save_active_model(mut am: A, db: &DatabaseConnection) -> Result +pub async fn save_active_model(mut am: A, db: &DatabaseConnection) -> Result where A: ActiveModelBehavior + ActiveModelTrait, E::Model: IntoActiveModel, @@ -212,7 +212,7 @@ where Ok(am) } -async fn insert_and_select_active_model(am: A, db: &DatabaseConnection) -> Result +async fn insert_and_select_active_model(am: A, db: &DatabaseConnection) -> Result where A: ActiveModelTrait, E::Model: IntoActiveModel, @@ -227,14 +227,14 @@ where let model: Option = res?; match model { Some(model) => Ok(model.into_active_model()), - None => Err(SeaErr::Execution), + None => Err(DbErr::Execution), } } else { Ok(A::default()) } } -async fn update_active_model(am: A, db: &DatabaseConnection) -> Result +async fn update_active_model(am: A, db: &DatabaseConnection) -> Result where A: ActiveModelTrait, E: EntityTrait, @@ -246,7 +246,7 @@ where pub async fn delete_active_model( mut am: A, db: &DatabaseConnection, -) -> Result +) -> Result where A: ActiveModelBehavior + ActiveModelTrait, E: EntityTrait, diff --git a/src/entity/model.rs b/src/entity/model.rs index 4e4027d3..73dd66ae 100644 --- a/src/entity/model.rs +++ b/src/entity/model.rs @@ -1,4 +1,4 @@ -use crate::{EntityTrait, SeaErr, QueryFilter, QueryResult, Related, Select}; +use crate::{EntityTrait, DbErr, QueryFilter, QueryResult, Related, Select}; pub use sea_query::Value; use std::fmt::Debug; @@ -19,11 +19,11 @@ pub trait ModelTrait: Clone + Debug { } pub trait FromQueryResult { - fn from_query_result(res: &QueryResult, pre: &str) -> Result + fn from_query_result(res: &QueryResult, pre: &str) -> Result where Self: Sized; - fn from_query_result_optional(res: &QueryResult, pre: &str) -> Result, SeaErr> + fn from_query_result_optional(res: &QueryResult, pre: &str) -> Result, DbErr> where Self: Sized, { diff --git a/src/error.rs b/src/error.rs index 4b275416..de649dcb 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,7 @@ use std::{error, fmt}; #[derive(Debug)] -pub enum SeaErr { +pub enum DbErr { Connection, Execution, Query, @@ -9,7 +9,7 @@ pub enum SeaErr { Sqlx(sqlx::Error), } -impl fmt::Display for SeaErr { +impl fmt::Display for DbErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Connection => write!(f, "{:?}", "Connection Error"), @@ -21,7 +21,7 @@ impl fmt::Display for SeaErr { } } -impl error::Error for SeaErr { +impl error::Error for DbErr { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { Self::Connection => None, @@ -34,7 +34,7 @@ impl error::Error for SeaErr { } #[cfg(feature = "sqlx-dep")] -impl From for SeaErr { +impl From for DbErr { fn from(sqlx_err: sqlx::Error) -> Self { Self::Sqlx(sqlx_err) } diff --git a/src/executor/delete.rs b/src/executor/delete.rs index 4e0cb120..eebd0fc9 100644 --- a/src/executor/delete.rs +++ b/src/executor/delete.rs @@ -21,7 +21,7 @@ where pub fn exec( self, db: &'a DatabaseConnection, - ) -> impl Future> + 'a { + ) -> impl Future> + 'a { // so that self is dropped before entering await exec_delete_only(self.query, db) } @@ -34,7 +34,7 @@ where pub fn exec( self, db: &'a DatabaseConnection, - ) -> impl Future> + 'a { + ) -> impl Future> + 'a { // so that self is dropped before entering await exec_delete_only(self.query, db) } @@ -48,7 +48,7 @@ impl Deleter { pub fn exec( self, db: &DatabaseConnection, - ) -> impl Future> + '_ { + ) -> impl Future> + '_ { let builder = db.get_query_builder_backend(); exec_delete(builder.build(&self.query), db) } @@ -57,7 +57,7 @@ impl Deleter { async fn exec_delete_only( query: DeleteStatement, db: &DatabaseConnection, -) -> Result { +) -> Result { Deleter::new(query).exec(db).await } @@ -65,7 +65,7 @@ async fn exec_delete_only( async fn exec_delete( statement: Statement, db: &DatabaseConnection, -) -> Result { +) -> Result { let result = db.execute(statement).await?; Ok(DeleteResult { rows_affected: result.rows_affected(), diff --git a/src/executor/insert.rs b/src/executor/insert.rs index ac8616f3..cf36d5ff 100644 --- a/src/executor/insert.rs +++ b/src/executor/insert.rs @@ -19,7 +19,7 @@ where pub fn exec( self, db: &DatabaseConnection, - ) -> impl Future> + '_ { + ) -> impl Future> + '_ { // so that self is dropped before entering await Inserter::new(self.into_query()).exec(db) } @@ -33,7 +33,7 @@ impl Inserter { pub fn exec( self, db: &DatabaseConnection, - ) -> impl Future> + '_ { + ) -> impl Future> + '_ { let builder = db.get_query_builder_backend(); exec_insert(builder.build(&self.query), db) } @@ -43,7 +43,7 @@ impl Inserter { async fn exec_insert( statement: Statement, db: &DatabaseConnection, -) -> Result { +) -> Result { let result = db.execute(statement).await?; // TODO: Postgres instead use query_one + returning clause Ok(InsertResult { diff --git a/src/executor/paginator.rs b/src/executor/paginator.rs index 4ab8cdb5..8ea2af9f 100644 --- a/src/executor/paginator.rs +++ b/src/executor/paginator.rs @@ -23,7 +23,7 @@ where S: SelectorTrait + 'db, { /// Fetch a specific page - pub async fn fetch_page(&self, page: usize) -> Result, SeaErr> { + pub async fn fetch_page(&self, page: usize) -> Result, DbErr> { let query = self .query .clone() @@ -42,12 +42,12 @@ where } /// Fetch the current page - pub async fn fetch(&self) -> Result, SeaErr> { + pub async fn fetch(&self) -> Result, DbErr> { self.fetch_page(self.page).await } /// Get the total number of pages - pub async fn num_pages(&self) -> Result { + pub async fn num_pages(&self) -> Result { let builder = self.db.get_query_builder_backend(); let stmt = builder.build( SelectStatement::new() @@ -77,7 +77,7 @@ where } /// Fetch one page and increment the page counter - pub async fn fetch_and_next(&mut self) -> Result>, SeaErr> { + pub async fn fetch_and_next(&mut self) -> Result>, DbErr> { let vec = self.fetch().await?; self.next(); let opt = if !vec.is_empty() { Some(vec) } else { None }; @@ -85,7 +85,7 @@ where } /// Convert self into an async stream - pub fn into_stream(mut self) -> PinBoxStream<'db, Result, SeaErr>> { + pub fn into_stream(mut self) -> PinBoxStream<'db, Result, DbErr>> { Box::pin(stream! { loop { if let Some(vec) = self.fetch_and_next().await? { @@ -148,7 +148,7 @@ mod tests { } #[async_std::test] - async fn fetch_page() -> Result<(), SeaErr> { + async fn fetch_page() -> Result<(), DbErr> { let (db, pages) = setup(); let paginator = fruit::Entity::find().paginate(&db, 2); @@ -178,7 +178,7 @@ mod tests { } #[async_std::test] - async fn fetch() -> Result<(), SeaErr> { + async fn fetch() -> Result<(), DbErr> { let (db, pages) = setup(); let mut paginator = fruit::Entity::find().paginate(&db, 2); @@ -212,7 +212,7 @@ mod tests { } #[async_std::test] - async fn num_pages() -> Result<(), SeaErr> { + async fn num_pages() -> Result<(), DbErr> { let (db, num_rows) = setup_num_rows(); let num_rows = num_rows as usize; @@ -244,7 +244,7 @@ mod tests { } #[async_std::test] - async fn next_and_cur_page() -> Result<(), SeaErr> { + async fn next_and_cur_page() -> Result<(), DbErr> { let (db, _) = setup(); let mut paginator = fruit::Entity::find().paginate(&db, 2); @@ -260,7 +260,7 @@ mod tests { } #[async_std::test] - async fn fetch_and_next() -> Result<(), SeaErr> { + async fn fetch_and_next() -> Result<(), DbErr> { let (db, pages) = setup(); let mut paginator = fruit::Entity::find().paginate(&db, 2); @@ -295,7 +295,7 @@ mod tests { } #[async_std::test] - async fn into_stream() -> Result<(), SeaErr> { + async fn into_stream() -> Result<(), DbErr> { let (db, pages) = setup(); let mut fruit_stream = fruit::Entity::find().paginate(&db, 2).into_stream(); diff --git a/src/executor/query.rs b/src/executor/query.rs index 13582fe4..1452a4d6 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -1,4 +1,4 @@ -use crate::SeaErr; +use crate::DbErr; use std::fmt; #[derive(Debug)] @@ -16,7 +16,7 @@ pub(crate) enum QueryResultRow { } pub trait TryGetable { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result where Self: Sized; } @@ -24,7 +24,7 @@ pub trait TryGetable { // QueryResult // impl QueryResult { - pub fn try_get(&self, pre: &str, col: &str) -> Result + pub fn try_get(&self, pre: &str, col: &str) -> Result where T: TryGetable, { @@ -50,7 +50,7 @@ impl fmt::Debug for QueryResultRow { macro_rules! try_getable_all { ( $type: ty ) => { impl TryGetable for $type { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { let column = format!("{}{}", pre, col); match &res.row { #[cfg(feature = "sqlx-mysql")] @@ -70,7 +70,7 @@ macro_rules! try_getable_all { } impl TryGetable for Option<$type> { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { let column = format!("{}{}", pre, col); match &res.row { #[cfg(feature = "sqlx-mysql")] @@ -103,7 +103,7 @@ macro_rules! try_getable_all { macro_rules! try_getable_mysql { ( $type: ty ) => { impl TryGetable for $type { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { let column = format!("{}{}", pre, col); match &res.row { #[cfg(feature = "sqlx-mysql")] @@ -122,7 +122,7 @@ macro_rules! try_getable_mysql { } impl TryGetable for Option<$type> { - fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { let column = format!("{}{}", pre, col); match &res.row { #[cfg(feature = "sqlx-mysql")] diff --git a/src/executor/select.rs b/src/executor/select.rs index fa6e0868..607e0de0 100644 --- a/src/executor/select.rs +++ b/src/executor/select.rs @@ -18,7 +18,7 @@ where pub trait SelectorTrait { type Item: Sized; - fn from_raw_query_result(res: QueryResult) -> Result; + fn from_raw_query_result(res: QueryResult) -> Result; } pub struct SelectModel @@ -43,7 +43,7 @@ where { type Item = M; - fn from_raw_query_result(res: QueryResult) -> Result { + fn from_raw_query_result(res: QueryResult) -> Result { M::from_query_result(&res, "") } } @@ -55,7 +55,7 @@ where { type Item = (M, Option); - fn from_raw_query_result(res: QueryResult) -> Result { + fn from_raw_query_result(res: QueryResult) -> Result { Ok(( M::from_query_result(&res, combine::SELECT_A)?, N::from_query_result_optional(&res, combine::SELECT_B)?, @@ -85,11 +85,11 @@ where } } - pub async fn one(self, db: &DatabaseConnection) -> Result, SeaErr> { + pub async fn one(self, db: &DatabaseConnection) -> Result, DbErr> { self.into_model::().one(db).await } - pub async fn all(self, db: &DatabaseConnection) -> Result, SeaErr> { + pub async fn all(self, db: &DatabaseConnection) -> Result, DbErr> { self.into_model::().all(db).await } @@ -129,14 +129,14 @@ where pub async fn one( self, db: &DatabaseConnection, - ) -> Result)>, SeaErr> { + ) -> Result)>, DbErr> { self.into_model::().one(db).await } pub async fn all( self, db: &DatabaseConnection, - ) -> Result)>, SeaErr> { + ) -> Result)>, DbErr> { self.into_model::().all(db).await } } @@ -168,14 +168,14 @@ where pub async fn one( self, db: &DatabaseConnection, - ) -> Result)>, SeaErr> { + ) -> Result)>, DbErr> { self.into_model::().one(db).await } pub async fn all( self, db: &DatabaseConnection, - ) -> Result)>, SeaErr> { + ) -> Result)>, DbErr> { let rows = self.into_model::().all(db).await?; Ok(consolidate_query_result::(rows)) } @@ -185,7 +185,7 @@ impl Selector where S: SelectorTrait, { - pub async fn one(mut self, db: &DatabaseConnection) -> Result, SeaErr> { + pub async fn one(mut self, db: &DatabaseConnection) -> Result, DbErr> { let builder = db.get_query_builder_backend(); self.query.limit(1); let row = db.query_one(builder.build(&self.query)).await?; @@ -195,7 +195,7 @@ where } } - pub async fn all(self, db: &DatabaseConnection) -> Result, SeaErr> { + pub async fn all(self, db: &DatabaseConnection) -> Result, DbErr> { let builder = db.get_query_builder_backend(); let rows = db.query_all(builder.build(&self.query)).await?; let mut models = Vec::new(); diff --git a/src/executor/update.rs b/src/executor/update.rs index e2c0ae75..0a486afc 100644 --- a/src/executor/update.rs +++ b/src/executor/update.rs @@ -21,7 +21,7 @@ where pub fn exec( self, db: &'a DatabaseConnection, - ) -> impl Future> + 'a { + ) -> impl Future> + 'a { // so that self is dropped before entering await exec_update_and_return_original(self.query, self.model, db) } @@ -34,7 +34,7 @@ where pub fn exec( self, db: &'a DatabaseConnection, - ) -> impl Future> + 'a { + ) -> impl Future> + 'a { // so that self is dropped before entering await exec_update_only(self.query, db) } @@ -48,7 +48,7 @@ impl Updater { pub fn exec( self, db: &DatabaseConnection, - ) -> impl Future> + '_ { + ) -> impl Future> + '_ { let builder = db.get_query_builder_backend(); exec_update(builder.build(&self.query), db) } @@ -57,7 +57,7 @@ impl Updater { async fn exec_update_only( query: UpdateStatement, db: &DatabaseConnection, -) -> Result { +) -> Result { Updater::new(query).exec(db).await } @@ -65,7 +65,7 @@ async fn exec_update_and_return_original( query: UpdateStatement, model: A, db: &DatabaseConnection, -) -> Result +) -> Result where A: ActiveModelTrait, { @@ -77,7 +77,7 @@ where async fn exec_update( statement: Statement, db: &DatabaseConnection, -) -> Result { +) -> Result { let result = db.execute(statement).await?; Ok(UpdateResult { rows_affected: result.rows_affected(), diff --git a/src/lib.rs b/src/lib.rs index c300c1fa..8ce34253 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,7 @@ //! ## Select //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; -//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { +//! # async fn function(db: &DbConn) -> Result<(), DbErr> { //! # //! // find all models //! let cakes: Vec = Cake::find().all(db).await?; @@ -74,7 +74,7 @@ //! ## Insert //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; -//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { +//! # async fn function(db: &DbConn) -> Result<(), DbErr> { //! # //! let apple = fruit::ActiveModel { //! name: Set("Apple".to_owned()), @@ -94,7 +94,7 @@ //! # Ok(()) //! # } //! # -//! # async fn function2(db: &DbConn) -> Result<(), SeaErr> { +//! # async fn function2(db: &DbConn) -> Result<(), DbErr> { //! # let apple = fruit::ActiveModel { //! # name: Set("Apple".to_owned()), //! # ..Default::default() // no need to set primary key @@ -117,12 +117,12 @@ //! # //! use sea_orm::sea_query::{Expr, Value}; //! -//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { +//! # async fn function(db: &DbConn) -> Result<(), DbErr> { //! let pear: Option = Fruit::find_by_id(1).one(db).await?; //! # Ok(()) //! # } //! # -//! # async fn function2(db: &DbConn) -> Result<(), SeaErr> { +//! # async fn function2(db: &DbConn) -> Result<(), DbErr> { //! # let pear: Option = Fruit::find_by_id(1).one(db).await.unwrap(); //! //! let mut pear: fruit::ActiveModel = pear.unwrap().into(); @@ -145,7 +145,7 @@ //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # -//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { +//! # async fn function(db: &DbConn) -> Result<(), DbErr> { //! let banana = fruit::ActiveModel { //! id: Unset(None), //! name: Set("Banana".to_owned()), @@ -167,12 +167,12 @@ //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # -//! # async fn function(db: &DbConn) -> Result<(), SeaErr> { +//! # async fn function(db: &DbConn) -> Result<(), DbErr> { //! let orange: Option = Fruit::find_by_id(1).one(db).await?; //! # Ok(()) //! # } //! # -//! # async fn function2(db: &DbConn) -> Result<(), SeaErr> { +//! # async fn function2(db: &DbConn) -> Result<(), DbErr> { //! # let orange: Option = Fruit::find_by_id(1).one(db).await.unwrap(); //! let orange: fruit::ActiveModel = orange.unwrap().into(); //! diff --git a/src/query/json.rs b/src/query/json.rs index 4c5cd65d..aa3d9c6c 100644 --- a/src/query/json.rs +++ b/src/query/json.rs @@ -1,9 +1,9 @@ -use crate::{FromQueryResult, SeaErr, QueryResult, QueryResultRow}; +use crate::{FromQueryResult, DbErr, QueryResult, QueryResultRow}; use serde_json::Map; pub use serde_json::Value as JsonValue; impl FromQueryResult for JsonValue { - fn from_query_result(res: &QueryResult, pre: &str) -> Result { + fn from_query_result(res: &QueryResult, pre: &str) -> Result { match &res.row { #[cfg(feature = "sqlx-mysql")] QueryResultRow::SqlxMySql(row) => { diff --git a/tests/basic.rs b/tests/basic.rs index dc048863..641fc1aa 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -31,7 +31,7 @@ async fn setup_schema(db: &DbConn) { println!("Create table cake: {:?}", result); } -async fn crud_cake(db: &DbConn) -> Result<(), SeaErr> { +async fn crud_cake(db: &DbConn) -> Result<(), DbErr> { let apple = cake::ActiveModel { name: Set("Apple Pie".to_owned()), ..Default::default() From 30ac326d5cc0d7dd85de55e0c6b078daefe97435 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 30 Jun 2021 21:21:06 +0800 Subject: [PATCH 07/23] Rename to DbErr::Exec and DbErr::Conn --- src/database/mock.rs | 2 +- src/database/mod.rs | 2 +- src/driver/sqlx_mysql.rs | 4 ++-- src/driver/sqlx_sqlite.rs | 4 ++-- src/entity/active_model.rs | 2 +- src/error.rs | 12 ++++++------ 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/database/mock.rs b/src/database/mock.rs index 2f99b32c..c57ef63e 100644 --- a/src/database/mock.rs +++ b/src/database/mock.rs @@ -75,7 +75,7 @@ impl MockDatabaseTrait for MockDatabase { result: ExecResultHolder::Mock(std::mem::take(&mut self.exec_results[counter])), }) } else { - Err(DbErr::Execution) + Err(DbErr::Exec) } } diff --git a/src/database/mod.rs b/src/database/mod.rs index 5150e3d7..f461df3d 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -29,6 +29,6 @@ impl Database { if crate::MockDatabaseConnector::accepts(string) { return Ok(crate::MockDatabaseConnector::connect(string).await?); } - Err(DbErr::Connection) + Err(DbErr::Conn) } } diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs index 9076c1ed..7ecbd5a2 100644 --- a/src/driver/sqlx_mysql.rs +++ b/src/driver/sqlx_mysql.rs @@ -25,7 +25,7 @@ impl SqlxMySqlConnector { SqlxMySqlPoolConnection { pool }, )) } else { - Err(DbErr::Connection) + Err(DbErr::Conn) } } } @@ -46,7 +46,7 @@ impl SqlxMySqlPoolConnection { return Ok(res.into()); } } - Err(DbErr::Execution) + Err(DbErr::Exec) } pub async fn query_one(&self, stmt: Statement) -> Result, DbErr> { diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs index 94425eb4..161e010e 100644 --- a/src/driver/sqlx_sqlite.rs +++ b/src/driver/sqlx_sqlite.rs @@ -25,7 +25,7 @@ impl SqlxSqliteConnector { SqlxSqlitePoolConnection { pool }, )) } else { - Err(DbErr::Connection) + Err(DbErr::Conn) } } } @@ -46,7 +46,7 @@ impl SqlxSqlitePoolConnection { return Ok(res.into()); } } - Err(DbErr::Execution) + Err(DbErr::Exec) } pub async fn query_one(&self, stmt: Statement) -> Result, DbErr> { diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs index df1fc869..31a1345d 100644 --- a/src/entity/active_model.rs +++ b/src/entity/active_model.rs @@ -227,7 +227,7 @@ where let model: Option = res?; match model { Some(model) => Ok(model.into_active_model()), - None => Err(DbErr::Execution), + None => Err(DbErr::Exec), } } else { Ok(A::default()) diff --git a/src/error.rs b/src/error.rs index de649dcb..712df544 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,8 +2,8 @@ use std::{error, fmt}; #[derive(Debug)] pub enum DbErr { - Connection, - Execution, + Conn, + Exec, Query, #[cfg(feature = "sqlx-dep")] Sqlx(sqlx::Error), @@ -12,8 +12,8 @@ pub enum DbErr { impl fmt::Display for DbErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Connection => write!(f, "{:?}", "Connection Error"), - Self::Execution => write!(f, "{:?}", "Execution Error"), + Self::Conn => write!(f, "{:?}", "Connection Error"), + Self::Exec => write!(f, "{:?}", "Execution Error"), Self::Query => write!(f, "{:?}", "Query Error"), #[cfg(feature = "sqlx-dep")] Self::Sqlx(e) => write!(f, "{:?}", e), @@ -24,8 +24,8 @@ impl fmt::Display for DbErr { impl error::Error for DbErr { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { - Self::Connection => None, - Self::Execution => None, + Self::Conn => None, + Self::Exec => None, Self::Query => None, #[cfg(feature = "sqlx-dep")] Self::Sqlx(e) => Some(e), From f8f3d128fd93e8bf8eff4c0609038088715ac6b5 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 30 Jun 2021 22:50:01 +0800 Subject: [PATCH 08/23] Fix clippy warming --- sea-orm-codegen/src/entity/column.rs | 20 ++++++++++---------- sea-orm-codegen/src/entity/transformer.rs | 2 +- src/database/connection.rs | 4 ++-- src/database/mod.rs | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sea-orm-codegen/src/entity/column.rs b/sea-orm-codegen/src/entity/column.rs index e8a0b543..e077c0a6 100644 --- a/sea-orm-codegen/src/entity/column.rs +++ b/sea-orm-codegen/src/entity/column.rs @@ -61,21 +61,21 @@ impl Column { None => quote! { ColumnType::String(None).def() }, }, ColumnType::Text => quote! { ColumnType::Text.def() }, - ColumnType::TinyInteger(s) => quote! { ColumnType::TinyInteger.def() }, - ColumnType::SmallInteger(s) => quote! { ColumnType::SmallInteger.def() }, - ColumnType::Integer(s) => quote! { ColumnType::Integer.def() }, - ColumnType::BigInteger(s) => quote! { ColumnType::BigInteger.def() }, - ColumnType::Float(s) => quote! { ColumnType::Float.def() }, - ColumnType::Double(s) => quote! { ColumnType::Double.def() }, + ColumnType::TinyInteger(_) => quote! { ColumnType::TinyInteger.def() }, + ColumnType::SmallInteger(_) => quote! { ColumnType::SmallInteger.def() }, + ColumnType::Integer(_) => quote! { ColumnType::Integer.def() }, + ColumnType::BigInteger(_) => quote! { ColumnType::BigInteger.def() }, + ColumnType::Float(_) => quote! { ColumnType::Float.def() }, + ColumnType::Double(_) => quote! { ColumnType::Double.def() }, ColumnType::Decimal(s) => match s { Some((s1, s2)) => quote! { ColumnType::Decimal(Some((#s1, #s2))).def() }, None => quote! { ColumnType::Decimal(None).def() }, }, - ColumnType::DateTime(s) => quote! { ColumnType::DateTime.def() }, - ColumnType::Timestamp(s) => quote! { ColumnType::Timestamp.def() }, - ColumnType::Time(s) => quote! { ColumnType::Time.def() }, + ColumnType::DateTime(_) => quote! { ColumnType::DateTime.def() }, + ColumnType::Timestamp(_) => quote! { ColumnType::Timestamp.def() }, + ColumnType::Time(_) => quote! { ColumnType::Time.def() }, ColumnType::Date => quote! { ColumnType::Date.def() }, - ColumnType::Binary(s) => quote! { ColumnType::Binary.def() }, + ColumnType::Binary(_) => quote! { ColumnType::Binary.def() }, ColumnType::Boolean => quote! { ColumnType::Boolean.def() }, ColumnType::Money(s) => match s { Some((s1, s2)) => quote! { ColumnType::Money(Some((#s1, #s2))).def() }, diff --git a/sea-orm-codegen/src/entity/transformer.rs b/sea-orm-codegen/src/entity/transformer.rs index 02c7fb82..c49a871e 100644 --- a/sea-orm-codegen/src/entity/transformer.rs +++ b/sea-orm-codegen/src/entity/transformer.rs @@ -1,7 +1,7 @@ use crate::{Column, Entity, EntityWriter, Error, PrimaryKey, Relation, RelationType}; use sea_query::TableStatement; use sea_schema::mysql::def::Schema; -use std::{collections::HashMap, mem::swap}; +use std::collections::HashMap; #[derive(Clone, Debug)] pub struct EntityTransformer { diff --git a/src/database/connection.rs b/src/database/connection.rs index 6336db48..58a5bba8 100644 --- a/src/database/connection.rs +++ b/src/database/connection.rs @@ -1,4 +1,4 @@ -use crate::{error::*, ExecResult, QueryResult, Statement, Transaction}; +use crate::{error::*, ExecResult, QueryResult, Statement}; use sea_query::{ MysqlQueryBuilder, PostgresQueryBuilder, QueryStatementBuilder, SchemaStatementBuilder, SqliteQueryBuilder, @@ -127,7 +127,7 @@ impl DatabaseConnection { } #[cfg(feature = "mock")] - pub fn into_transaction_log(self) -> Vec { + pub fn into_transaction_log(self) -> Vec { let mut mocker = self.as_mock_connection().get_mocker_mutex().lock().unwrap(); mocker.drain_transaction_log() } diff --git a/src/database/mod.rs b/src/database/mod.rs index f461df3d..dd5fc5ea 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -19,15 +19,15 @@ impl Database { pub async fn connect(string: &str) -> Result { #[cfg(feature = "sqlx-mysql")] if crate::SqlxMySqlConnector::accepts(string) { - return Ok(crate::SqlxMySqlConnector::connect(string).await?); + return crate::SqlxMySqlConnector::connect(string).await; } #[cfg(feature = "sqlx-sqlite")] if crate::SqlxSqliteConnector::accepts(string) { - return Ok(crate::SqlxSqliteConnector::connect(string).await?); + return crate::SqlxSqliteConnector::connect(string).await; } #[cfg(feature = "mock")] if crate::MockDatabaseConnector::accepts(string) { - return Ok(crate::MockDatabaseConnector::connect(string).await?); + return crate::MockDatabaseConnector::connect(string).await; } Err(DbErr::Conn) } From dd8d8c3431bc22cb417ae84eee0e32a0012abacf Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 30 Jun 2021 23:01:23 +0800 Subject: [PATCH 09/23] Codegen without find_* helper fn --- examples/cli/src/entity/cake.rs | 9 --------- examples/cli/src/entity/cake_filling.rs | 9 --------- examples/cli/src/entity/filling.rs | 6 ------ examples/cli/src/entity/fruit.rs | 8 +++++--- examples/cli/src/entity/mod.rs | 1 + examples/cli/src/entity/prelude.rs | 1 + examples/cli/src/entity/vendor.rs | 10 ++-------- examples/codegen/src/entity/cake.rs | 19 ++----------------- examples/codegen/src/entity/cake_filling.rs | 13 ++----------- examples/codegen/src/entity/filling.rs | 11 +---------- examples/codegen/src/entity/fruit.rs | 18 +++--------------- examples/codegen/src/entity/vendor.rs | 10 ++-------- sea-orm-codegen/src/entity/writer.rs | 13 ------------- 13 files changed, 19 insertions(+), 109 deletions(-) diff --git a/examples/cli/src/entity/cake.rs b/examples/cli/src/entity/cake.rs index 9b786a5f..12e7c4ab 100644 --- a/examples/cli/src/entity/cake.rs +++ b/examples/cli/src/entity/cake.rs @@ -71,13 +71,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_cake_filling(&self) -> Select { - Entity::find_related().belongs_to::(self) - } - pub fn find_fruit(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/cli/src/entity/cake_filling.rs b/examples/cli/src/entity/cake_filling.rs index d5b4b8b6..1ac64920 100644 --- a/examples/cli/src/entity/cake_filling.rs +++ b/examples/cli/src/entity/cake_filling.rs @@ -78,13 +78,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_cake(&self) -> Select { - Entity::find_related().belongs_to::(self) - } - pub fn find_filling(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/cli/src/entity/filling.rs b/examples/cli/src/entity/filling.rs index e4563e55..752317a4 100644 --- a/examples/cli/src/entity/filling.rs +++ b/examples/cli/src/entity/filling.rs @@ -63,10 +63,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_cake_filling(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/cli/src/entity/fruit.rs b/examples/cli/src/entity/fruit.rs index f65d5b38..7ff7d9b8 100644 --- a/examples/cli/src/entity/fruit.rs +++ b/examples/cli/src/entity/fruit.rs @@ -39,6 +39,7 @@ impl PrimaryKeyTrait for PrimaryKey { #[derive(Copy, Clone, Debug, EnumIter)] pub enum Relation { Cake, + Vendor, } impl ColumnTrait for Column { @@ -59,6 +60,7 @@ impl RelationTrait for Relation { .from(Column::CakeId) .to(super::cake::Column::Id) .into(), + Self::Vendor => Entity::has_many(super::vendor::Entity).into(), } } } @@ -69,9 +71,9 @@ impl Related for Entity { } } -impl Model { - pub fn find_cake(&self) -> Select { - Entity::find_related().belongs_to::(self) +impl Related for Entity { + fn to() -> RelationDef { + Relation::Vendor.def() } } diff --git a/examples/cli/src/entity/mod.rs b/examples/cli/src/entity/mod.rs index 006f7e80..395d29f9 100644 --- a/examples/cli/src/entity/mod.rs +++ b/examples/cli/src/entity/mod.rs @@ -4,3 +4,4 @@ pub mod cake; pub mod cake_filling; pub mod filling; pub mod fruit; +pub mod vendor; diff --git a/examples/cli/src/entity/prelude.rs b/examples/cli/src/entity/prelude.rs index b4c1c94f..b4e85c78 100644 --- a/examples/cli/src/entity/prelude.rs +++ b/examples/cli/src/entity/prelude.rs @@ -4,3 +4,4 @@ pub use super::cake::Entity as Cake; pub use super::cake_filling::Entity as CakeFilling; pub use super::filling::Entity as Filling; pub use super::fruit::Entity as Fruit; +pub use super::vendor::Entity as Vendor; diff --git a/examples/cli/src/entity/vendor.rs b/examples/cli/src/entity/vendor.rs index 9c4ca7dd..2262519f 100644 --- a/examples/cli/src/entity/vendor.rs +++ b/examples/cli/src/entity/vendor.rs @@ -47,7 +47,7 @@ impl ColumnTrait for Column { match self { Self::Id => ColumnType::Integer.def(), Self::Name => ColumnType::String(Some(255u32)).def(), - Self::FruitId => ColumnType::Integer.def(), + Self::FruitId => ColumnType::Integer.def().null(), } } } @@ -55,7 +55,7 @@ impl ColumnTrait for Column { impl RelationTrait for Relation { fn def(&self) -> RelationDef { match self { - Self::Fruit => Entity::has_one(super::fruit::Entity) + Self::Fruit => Entity::belongs_to(super::fruit::Entity) .from(Column::FruitId) .to(super::fruit::Column::Id) .into(), @@ -69,10 +69,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_fruit(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/codegen/src/entity/cake.rs b/examples/codegen/src/entity/cake.rs index 87ee5f1a..12e7c4ab 100644 --- a/examples/codegen/src/entity/cake.rs +++ b/examples/codegen/src/entity/cake.rs @@ -53,14 +53,8 @@ impl ColumnTrait for Column { impl RelationTrait for Relation { fn def(&self) -> RelationDef { match self { - Self::CakeFilling => Entity::has_many(super::cake_filling::Entity) - .from(Column::Id) - .to(super::cake_filling::Column::CakeId) - .into(), - Self::Fruit => Entity::has_many(super::fruit::Entity) - .from(Column::Id) - .to(super::fruit::Column::CakeId) - .into(), + Self::CakeFilling => Entity::has_many(super::cake_filling::Entity).into(), + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), } } } @@ -77,13 +71,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_cake_filling(&self) -> Select { - Entity::find_related().belongs_to::(self) - } - pub fn find_fruit(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/codegen/src/entity/cake_filling.rs b/examples/codegen/src/entity/cake_filling.rs index b35279d4..1ac64920 100644 --- a/examples/codegen/src/entity/cake_filling.rs +++ b/examples/codegen/src/entity/cake_filling.rs @@ -54,11 +54,11 @@ impl ColumnTrait for Column { impl RelationTrait for Relation { fn def(&self) -> RelationDef { match self { - Self::Cake => Entity::has_one(super::cake::Entity) + Self::Cake => Entity::belongs_to(super::cake::Entity) .from(Column::CakeId) .to(super::cake::Column::Id) .into(), - Self::Filling => Entity::has_one(super::filling::Entity) + Self::Filling => Entity::belongs_to(super::filling::Entity) .from(Column::FillingId) .to(super::filling::Column::Id) .into(), @@ -78,13 +78,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_cake(&self) -> Select { - Entity::find_related().belongs_to::(self) - } - pub fn find_filling(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/codegen/src/entity/filling.rs b/examples/codegen/src/entity/filling.rs index 4134652f..752317a4 100644 --- a/examples/codegen/src/entity/filling.rs +++ b/examples/codegen/src/entity/filling.rs @@ -52,10 +52,7 @@ impl ColumnTrait for Column { impl RelationTrait for Relation { fn def(&self) -> RelationDef { match self { - Self::CakeFilling => Entity::has_many(super::cake_filling::Entity) - .from(Column::Id) - .to(super::cake_filling::Column::FillingId) - .into(), + Self::CakeFilling => Entity::has_many(super::cake_filling::Entity).into(), } } } @@ -66,10 +63,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_cake_filling(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/codegen/src/entity/fruit.rs b/examples/codegen/src/entity/fruit.rs index d3f21bf9..7ff7d9b8 100644 --- a/examples/codegen/src/entity/fruit.rs +++ b/examples/codegen/src/entity/fruit.rs @@ -48,7 +48,7 @@ impl ColumnTrait for Column { match self { Self::Id => ColumnType::Integer.def(), Self::Name => ColumnType::String(Some(255u32)).def(), - Self::CakeId => ColumnType::Integer.def(), + Self::CakeId => ColumnType::Integer.def().null(), } } } @@ -56,14 +56,11 @@ impl ColumnTrait for Column { impl RelationTrait for Relation { fn def(&self) -> RelationDef { match self { - Self::Cake => Entity::has_one(super::cake::Entity) + Self::Cake => Entity::belongs_to(super::cake::Entity) .from(Column::CakeId) .to(super::cake::Column::Id) .into(), - Self::Vendor => Entity::has_many(super::vendor::Entity) - .from(Column::Id) - .to(super::vendor::Column::FruitId) - .into(), + Self::Vendor => Entity::has_many(super::vendor::Entity).into(), } } } @@ -80,13 +77,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_cake(&self) -> Select { - Entity::find_related().belongs_to::(self) - } - pub fn find_vendor(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/codegen/src/entity/vendor.rs b/examples/codegen/src/entity/vendor.rs index 9c4ca7dd..2262519f 100644 --- a/examples/codegen/src/entity/vendor.rs +++ b/examples/codegen/src/entity/vendor.rs @@ -47,7 +47,7 @@ impl ColumnTrait for Column { match self { Self::Id => ColumnType::Integer.def(), Self::Name => ColumnType::String(Some(255u32)).def(), - Self::FruitId => ColumnType::Integer.def(), + Self::FruitId => ColumnType::Integer.def().null(), } } } @@ -55,7 +55,7 @@ impl ColumnTrait for Column { impl RelationTrait for Relation { fn def(&self) -> RelationDef { match self { - Self::Fruit => Entity::has_one(super::fruit::Entity) + Self::Fruit => Entity::belongs_to(super::fruit::Entity) .from(Column::FruitId) .to(super::fruit::Column::Id) .into(), @@ -69,10 +69,4 @@ impl Related for Entity { } } -impl Model { - pub fn find_fruit(&self) -> Select { - Entity::find_related().belongs_to::(self) - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index 01dd4a4c..3bd8fb59 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -117,7 +117,6 @@ impl EntityWriter { ]; code_blocks.extend(Self::gen_impl_related(entity)); code_blocks.extend(vec![ - Self::gen_impl_model(entity), Self::gen_impl_active_model_behavior(), ]); code_blocks @@ -256,18 +255,6 @@ impl EntityWriter { .collect() } - pub fn gen_impl_model(entity: &Entity) -> TokenStream { - let relation_ref_tables_snake_case = entity.get_relation_ref_tables_snake_case(); - let relation_rel_find_helpers = entity.get_relation_rel_find_helpers(); - quote! { - impl Model { - #(pub fn #relation_rel_find_helpers(&self) -> Select { - Entity::find_related().belongs_to::(self) - })* - } - } - } - pub fn gen_impl_active_model_behavior() -> TokenStream { quote! { impl ActiveModelBehavior for ActiveModel {} From f5ac84f9156a369b5440370b869b90b2876e6446 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 30 Jun 2021 23:42:12 +0800 Subject: [PATCH 10/23] Rework DbErr --- src/database/mock.rs | 4 ++-- src/database/mod.rs | 2 +- src/driver/mod.rs | 4 ++++ src/driver/sqlx_common.rs | 9 +++++++++ src/driver/sqlx_mysql.rs | 32 ++++++++++++++++++----------- src/driver/sqlx_sqlite.rs | 32 ++++++++++++++++++----------- src/entity/active_model.rs | 6 +++--- src/error.rs | 41 ++++++++------------------------------ src/executor/query.rs | 6 +++--- 9 files changed, 70 insertions(+), 66 deletions(-) create mode 100644 src/driver/sqlx_common.rs diff --git a/src/database/mock.rs b/src/database/mock.rs index c57ef63e..7b208a72 100644 --- a/src/database/mock.rs +++ b/src/database/mock.rs @@ -75,7 +75,7 @@ impl MockDatabaseTrait for MockDatabase { result: ExecResultHolder::Mock(std::mem::take(&mut self.exec_results[counter])), }) } else { - Err(DbErr::Exec) + Err(DbErr::Exec("`exec_results` buffer is empty.".to_owned())) } } @@ -93,7 +93,7 @@ impl MockDatabaseTrait for MockDatabase { }) .collect()) } else { - Err(DbErr::Query) + Err(DbErr::Query("`query_results` buffer is empty.".to_owned())) } } diff --git a/src/database/mod.rs b/src/database/mod.rs index dd5fc5ea..4ad1b347 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -29,6 +29,6 @@ impl Database { if crate::MockDatabaseConnector::accepts(string) { return crate::MockDatabaseConnector::connect(string).await; } - Err(DbErr::Conn) + Err(DbErr::Conn(format!("The connection string '{}' has no supporting driver.", string))) } } diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 7cb183c3..904e06a9 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -1,5 +1,7 @@ #[cfg(feature = "mock")] mod mock; +#[cfg(feature = "sqlx-dep")] +mod sqlx_common; #[cfg(feature = "sqlx-mysql")] mod sqlx_mysql; #[cfg(feature = "sqlx-sqlite")] @@ -7,6 +9,8 @@ mod sqlx_sqlite; #[cfg(feature = "mock")] pub use mock::*; +#[cfg(feature = "sqlx-dep")] +pub use sqlx_common::*; #[cfg(feature = "sqlx-mysql")] pub use sqlx_mysql::*; #[cfg(feature = "sqlx-sqlite")] diff --git a/src/driver/sqlx_common.rs b/src/driver/sqlx_common.rs new file mode 100644 index 00000000..5b1f7b35 --- /dev/null +++ b/src/driver/sqlx_common.rs @@ -0,0 +1,9 @@ +use crate::DbErr; + +pub fn sqlx_error_to_exec_err(err: sqlx::Error) -> DbErr { + DbErr::Exec(err.to_string()) +} + +pub fn sqlx_error_to_query_err(err: sqlx::Error) -> DbErr { + DbErr::Query(err.to_string()) +} diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs index 7ecbd5a2..ebea0a32 100644 --- a/src/driver/sqlx_mysql.rs +++ b/src/driver/sqlx_mysql.rs @@ -8,6 +8,8 @@ use sea_query_driver_mysql::bind_query; use crate::{debug_print, error::*, executor::*, DatabaseConnection, Statement}; +use super::sqlx_common::*; + pub struct SqlxMySqlConnector; pub struct SqlxMySqlPoolConnection { @@ -25,7 +27,7 @@ impl SqlxMySqlConnector { SqlxMySqlPoolConnection { pool }, )) } else { - Err(DbErr::Conn) + Err(DbErr::Conn("Failed to connect.".to_owned())) } } } @@ -42,11 +44,13 @@ impl SqlxMySqlPoolConnection { let query = sqlx_query(&stmt); if let Ok(conn) = &mut self.pool.acquire().await { - if let Ok(res) = query.execute(conn).await { - return Ok(res.into()); + match query.execute(conn).await { + Ok(res) => Ok(res.into()), + Err(err) => Err(sqlx_error_to_exec_err(err)), } + } else { + Err(DbErr::Exec("Failed to acquire connection from pool.".to_owned())) } - Err(DbErr::Exec) } pub async fn query_one(&self, stmt: Statement) -> Result, DbErr> { @@ -54,13 +58,15 @@ impl SqlxMySqlPoolConnection { let query = sqlx_query(&stmt); if let Ok(conn) = &mut self.pool.acquire().await { - if let Ok(row) = query.fetch_one(conn).await { - Ok(Some(row.into())) - } else { - Ok(None) + match query.fetch_one(conn).await { + Ok(row) => Ok(Some(row.into())), + Err(err) => match err { + sqlx::Error::RowNotFound => Ok(None), + _ => Err(DbErr::Query(err.to_string())), + }, } } else { - Err(DbErr::Query) + Err(DbErr::Query("Failed to acquire connection from pool.".to_owned())) } } @@ -69,11 +75,13 @@ impl SqlxMySqlPoolConnection { let query = sqlx_query(&stmt); if let Ok(conn) = &mut self.pool.acquire().await { - if let Ok(rows) = query.fetch_all(conn).await { - return Ok(rows.into_iter().map(|r| r.into()).collect()); + match query.fetch_all(conn).await { + Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()), + Err(err) => Err(sqlx_error_to_query_err(err)), } + } else { + Err(DbErr::Query("Failed to acquire connection from pool.".to_owned())) } - Err(DbErr::Query) } } diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs index 161e010e..ecd0ba4f 100644 --- a/src/driver/sqlx_sqlite.rs +++ b/src/driver/sqlx_sqlite.rs @@ -8,6 +8,8 @@ use sea_query_driver_sqlite::bind_query; use crate::{debug_print, error::*, executor::*, DatabaseConnection, Statement}; +use super::sqlx_common::*; + pub struct SqlxSqliteConnector; pub struct SqlxSqlitePoolConnection { @@ -25,7 +27,7 @@ impl SqlxSqliteConnector { SqlxSqlitePoolConnection { pool }, )) } else { - Err(DbErr::Conn) + Err(DbErr::Conn("Failed to connect.".to_owned())) } } } @@ -42,11 +44,13 @@ impl SqlxSqlitePoolConnection { let query = sqlx_query(&stmt); if let Ok(conn) = &mut self.pool.acquire().await { - if let Ok(res) = query.execute(conn).await { - return Ok(res.into()); + match query.execute(conn).await { + Ok(res) => Ok(res.into()), + Err(err) => Err(sqlx_error_to_exec_err(err)), } + } else { + Err(DbErr::Exec("Failed to acquire connection from pool.".to_owned())) } - Err(DbErr::Exec) } pub async fn query_one(&self, stmt: Statement) -> Result, DbErr> { @@ -54,13 +58,15 @@ impl SqlxSqlitePoolConnection { let query = sqlx_query(&stmt); if let Ok(conn) = &mut self.pool.acquire().await { - if let Ok(row) = query.fetch_one(conn).await { - Ok(Some(row.into())) - } else { - Ok(None) + match query.fetch_one(conn).await { + Ok(row) => Ok(Some(row.into())), + Err(err) => match err { + sqlx::Error::RowNotFound => Ok(None), + _ => Err(DbErr::Query(err.to_string())), + }, } } else { - Err(DbErr::Query) + Err(DbErr::Query("Failed to acquire connection from pool.".to_owned())) } } @@ -69,11 +75,13 @@ impl SqlxSqlitePoolConnection { let query = sqlx_query(&stmt); if let Ok(conn) = &mut self.pool.acquire().await { - if let Ok(rows) = query.fetch_all(conn).await { - return Ok(rows.into_iter().map(|r| r.into()).collect()); + match query.fetch_all(conn).await { + Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()), + Err(err) => Err(sqlx_error_to_query_err(err)), } + } else { + Err(DbErr::Query("Failed to acquire connection from pool.".to_owned())) } - Err(DbErr::Query) } } diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs index 31a1345d..96486dda 100644 --- a/src/entity/active_model.rs +++ b/src/entity/active_model.rs @@ -223,11 +223,11 @@ where // TODO: if the entity does not have auto increment primary key, then last_insert_id is a wrong value if ::auto_increment() && res.last_insert_id != 0 { let find = E::find_by_id(res.last_insert_id).one(db); - let res = find.await; - let model: Option = res?; + let found = find.await; + let model: Option = found?; match model { Some(model) => Ok(model.into_active_model()), - None => Err(DbErr::Exec), + None => Err(DbErr::Exec(format!("Failed to find inserted item: {} {}", E::default().to_string(), res.last_insert_id))), } } else { Ok(A::default()) diff --git a/src/error.rs b/src/error.rs index 712df544..68f2313f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,41 +1,16 @@ -use std::{error, fmt}; - #[derive(Debug)] pub enum DbErr { - Conn, - Exec, - Query, - #[cfg(feature = "sqlx-dep")] - Sqlx(sqlx::Error), + Conn(String), + Exec(String), + Query(String), } -impl fmt::Display for DbErr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl std::fmt::Display for DbErr { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - Self::Conn => write!(f, "{:?}", "Connection Error"), - Self::Exec => write!(f, "{:?}", "Execution Error"), - Self::Query => write!(f, "{:?}", "Query Error"), - #[cfg(feature = "sqlx-dep")] - Self::Sqlx(e) => write!(f, "{:?}", e), + Self::Conn(s) => write!(f, "Connection Error: {}", s), + Self::Exec(s) => write!(f, "Execution Error: {}", s), + Self::Query(s) => write!(f, "Query Error: {}", s), } } } - -impl error::Error for DbErr { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match self { - Self::Conn => None, - Self::Exec => None, - Self::Query => None, - #[cfg(feature = "sqlx-dep")] - Self::Sqlx(e) => Some(e), - } - } -} - -#[cfg(feature = "sqlx-dep")] -impl From for DbErr { - fn from(sqlx_err: sqlx::Error) -> Self { - Self::Sqlx(sqlx_err) - } -} diff --git a/src/executor/query.rs b/src/executor/query.rs index 1452a4d6..1d23a013 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -56,12 +56,12 @@ macro_rules! try_getable_all { #[cfg(feature = "sqlx-mysql")] QueryResultRow::SqlxMySql(row) => { use sqlx::Row; - Ok(row.try_get(column.as_str())?) + row.try_get(column.as_str()).map_err(crate::sqlx_error_to_query_err) } #[cfg(feature = "sqlx-sqlite")] QueryResultRow::SqlxSqlite(row) => { use sqlx::Row; - Ok(row.try_get(column.as_str())?) + row.try_get(column.as_str()).map_err(crate::sqlx_error_to_query_err) } #[cfg(feature = "mock")] QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?), @@ -109,7 +109,7 @@ macro_rules! try_getable_mysql { #[cfg(feature = "sqlx-mysql")] QueryResultRow::SqlxMySql(row) => { use sqlx::Row; - Ok(row.try_get(column.as_str())?) + row.try_get(column.as_str()).map_err(crate::sqlx_error_to_query_err) } #[cfg(feature = "sqlx-sqlite")] QueryResultRow::SqlxSqlite(_) => { From 3a0ea8146fb07ec63922a7a8a2e930ba5f4e2be7 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 30 Jun 2021 23:55:32 +0800 Subject: [PATCH 11/23] Docs --- src/lib.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8ce34253..ea7dc797 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,6 +95,7 @@ //! # } //! # //! # async fn function2(db: &DbConn) -> Result<(), DbErr> { +//! # //! # let apple = fruit::ActiveModel { //! # name: Set("Apple".to_owned()), //! # ..Default::default() // no need to set primary key @@ -118,14 +119,10 @@ //! use sea_orm::sea_query::{Expr, Value}; //! //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! let pear: Option = Fruit::find_by_id(1).one(db).await?; -//! # Ok(()) -//! # } //! # -//! # async fn function2(db: &DbConn) -> Result<(), DbErr> { -//! # let pear: Option = Fruit::find_by_id(1).one(db).await.unwrap(); -//! +//! let pear: Option = Fruit::find_by_id(1).one(db).await?; //! let mut pear: fruit::ActiveModel = pear.unwrap().into(); +//! //! pear.name = Set("Sweet pear".to_owned()); //! //! // update one @@ -146,6 +143,7 @@ //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # //! # async fn function(db: &DbConn) -> Result<(), DbErr> { +//! # //! let banana = fruit::ActiveModel { //! id: Unset(None), //! name: Set("Banana".to_owned()), @@ -168,12 +166,8 @@ //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! let orange: Option = Fruit::find_by_id(1).one(db).await?; -//! # Ok(()) -//! # } //! # -//! # async fn function2(db: &DbConn) -> Result<(), DbErr> { -//! # let orange: Option = Fruit::find_by_id(1).one(db).await.unwrap(); +//! let orange: Option = Fruit::find_by_id(1).one(db).await?; //! let orange: fruit::ActiveModel = orange.unwrap().into(); //! //! // delete one From 1b43ffc987203f3fe9f10369427081ceb6d734df Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 1 Jul 2021 17:41:16 +0800 Subject: [PATCH 12/23] Readme --- README.md | 124 ++++++++++++++++++++++++++++++++- build-tools/generate-readme.sh | 3 + src/lib.rs | 43 ++++++------ 3 files changed, 148 insertions(+), 22 deletions(-) create mode 100644 build-tools/generate-readme.sh diff --git a/README.md b/README.md index c314c05f..ccc68b39 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,12 @@ # SeaORM -Inspired by ActiveRecord, Eloquent and TypeORM, SeaORM aims to provide you an intuitive and ergonomic +Inspired by ActiveRecord, Eloquent and TypeORM, SeaORM aims to provide you an intuitive and ergonomic API to make working with databases in Rust a first-class experience. -> This is an early WIP of SeaORM, and is not yet published. See [example](examples/sqlx-mysql/src) for demo usage. +```rust +This is an early WIP of SeaORM, and is not yet released. +``` ## Features @@ -36,3 +38,121 @@ Use mock connections to write unit tests for your logic. 4. Service oriented Quickly build services that join, filter, sort and paginate data in APIs. + +## A quick taste of SeaORM + +### Select +```rust +// find all models +let cakes: Vec = Cake::find().all(db).await?; + +// find and filter +let chocolate: Vec = Cake::find() + .filter(cake::Column::Name.contains("chocolate")) + .all(db) + .await?; + +// find one model +let cheese: Option = Cake::find_by_id(1).one(db).await?; +let cheese: cake::Model = cheese.unwrap(); + +// find related models (lazy) +let fruits: Vec = cheese.find_related(Fruit).all(db).await?; + +// find related models (eager) +let cake_with_fruits: Vec<(cake::Model, Vec)> = Cake::find() + .find_with_related(Fruit) + .all(db) + .await?; + +``` +### Insert +```rust +let apple = fruit::ActiveModel { + name: Set("Apple".to_owned()), + ..Default::default() // no need to set primary key +}; + +let pear = fruit::ActiveModel { + name: Set("Pear".to_owned()), + ..Default::default() +}; + +// insert one +let res: InsertResult = Fruit::insert(pear).exec(db).await?; + +println!("InsertResult: {}", res.last_insert_id); + +// insert many +Fruit::insert_many(vec![apple, pear]).exec(db).await?; +``` +### Update +```rust +use sea_orm::sea_query::{Expr, Value}; + +let pear: Option = Fruit::find_by_id(1).one(db).await?; +let mut pear: fruit::ActiveModel = pear.unwrap().into(); + +pear.name = Set("Sweet pear".to_owned()); + +// update one +let pear: fruit::ActiveModel = Fruit::update(pear).exec(db).await?; + +// update many: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%' +Fruit::update_many() + .col_expr(fruit::Column::CakeId, Expr::value(Value::Null)) + .filter(fruit::Column::Name.contains("Apple")) + .exec(db) + .await?; + +``` +### Save +```rust +let banana = fruit::ActiveModel { + id: Unset(None), + name: Set("Banana".to_owned()), + ..Default::default() +}; + +// create, because primary key `id` is `Unset` +let mut banana = banana.save(db).await?; + +banana.name = Set("Banana Mongo".to_owned()); + +// update, because primary key `id` is `Set` +let banana = banana.save(db).await?; + +``` +### Delete +```rust +let orange: Option = Fruit::find_by_id(1).one(db).await?; +let orange: fruit::ActiveModel = orange.unwrap().into(); + +// delete one +fruit::Entity::delete(orange).exec(db).await?; +// or simply +orange.delete(db).await?; + +// delete many: DELETE FROM "fruit" WHERE "fruit"."name" LIKE 'Orange' +fruit::Entity::delete_many() + .filter(fruit::Column::Name.contains("Orange")) + .exec(db) + .await?; + +``` +## License + +Licensed under either of + +- Apache License, Version 2.0 + ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license + ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/build-tools/generate-readme.sh b/build-tools/generate-readme.sh new file mode 100644 index 00000000..9b871ef4 --- /dev/null +++ b/build-tools/generate-readme.sh @@ -0,0 +1,3 @@ +# Run `sh develop/cargo-readme.sh` on project root to generate `README.md` from `src/lib.rs` +# cargo install cargo-readme +cargo readme --no-badges --no-indent-headings --no-license --no-template --no-title > README.md \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index ea7dc797..1678b171 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ //! API to make working with databases in Rust a first-class experience. //! //! ```ignore -//! This is an early WIP of SeaORM, and is not yet published. See [example](examples/sqlx-mysql/src) for demo usage. +//! This is an early WIP of SeaORM, and is not yet released. //! ``` //! //! ## Features @@ -39,13 +39,12 @@ //! //! Quickly build services that join, filter, sort and paginate data in APIs. //! -//! # A quick taste of SeaORM +//! ## A quick taste of SeaORM //! -//! ## Select +//! ### Select //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! // find all models //! let cakes: Vec = Cake::find().all(db).await?; //! @@ -71,11 +70,10 @@ //! # Ok(()) //! # } //! ``` -//! ## Insert +//! ### Insert //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! let apple = fruit::ActiveModel { //! name: Set("Apple".to_owned()), //! ..Default::default() // no need to set primary key @@ -90,17 +88,13 @@ //! let res: InsertResult = Fruit::insert(pear).exec(db).await?; //! //! println!("InsertResult: {}", res.last_insert_id); -//! # //! # Ok(()) //! # } -//! # //! # async fn function2(db: &DbConn) -> Result<(), DbErr> { -//! # //! # let apple = fruit::ActiveModel { //! # name: Set("Apple".to_owned()), //! # ..Default::default() // no need to set primary key //! # }; -//! # //! # let pear = fruit::ActiveModel { //! # name: Set("Pear".to_owned()), //! # ..Default::default() @@ -108,18 +102,15 @@ //! //! // insert many //! Fruit::insert_many(vec![apple, pear]).exec(db).await?; -//! # //! # Ok(()) //! # } //! ``` -//! ## Update +//! ### Update //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; -//! # //! use sea_orm::sea_query::{Expr, Value}; //! //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! let pear: Option = Fruit::find_by_id(1).one(db).await?; //! let mut pear: fruit::ActiveModel = pear.unwrap().into(); //! @@ -138,12 +129,10 @@ //! # Ok(()) //! # } //! ``` -//! ## Save +//! ### Save //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; -//! # //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! let banana = fruit::ActiveModel { //! id: Unset(None), //! name: Set("Banana".to_owned()), @@ -161,12 +150,10 @@ //! # Ok(()) //! # } //! ``` -//! ## Delete +//! ### Delete //! ``` //! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*}; -//! # //! # async fn function(db: &DbConn) -> Result<(), DbErr> { -//! # //! let orange: Option = Fruit::find_by_id(1).one(db).await?; //! let orange: fruit::ActiveModel = orange.unwrap().into(); //! @@ -185,6 +172,22 @@ //! # Ok(()) //! # } //! ``` +//! ## License +//! +//! Licensed under either of +//! +//! - Apache License, Version 2.0 +//! ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +//! - MIT license +//! ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +//! +//! at your option. +//! +//! ## Contribution +//! +//! Unless you explicitly state otherwise, any contribution intentionally submitted +//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +//! dual licensed as above, without any additional terms or conditions. #![doc( html_logo_url = "https://raw.githubusercontent.com/SeaQL/sea-query/master/docs/SeaQL icon dark.png" )] From 87c8d0dc8d8b0ec7f7ead053e73f9d4d3883c45d Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 1 Jul 2021 19:07:43 +0800 Subject: [PATCH 13/23] chrono support --- Cargo.toml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 02a11051..0268df58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ path = "src/lib.rs" [dependencies] async-stream = { version = "^0.3" } +chrono = { version = "^0", optional = true } futures = { version = "^0.3" } futures-util = { version = "^0.3" } sea-query = { version = "^0.12" } @@ -44,11 +45,14 @@ sea-orm = { path = ".", features = ["sqlx-sqlite", "runtime-async-std-native-tls [features] debug-print = [] -default = [ "macros", "with-json", "mock" ] +default = [ "macros", "with-json", "with-chrono", "mock" ] macros = [ "sea-orm-macros" ] mock = [] with-json = [ "serde_json", "sea-query/with-json" ] -sqlx-dep = [ "sqlx", "sqlx/json" ] +with-chrono = [ "chrono", "sea-query/with-chrono" ] +sqlx-dep = [ "sqlx" ] +sqlx-json = [ "sqlx/json", "with-json" ] +sqlx-chrono = [ "sqlx/chrono", "with-chrono" ] sqlx-mysql = [ "sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql" ] sqlx-postgres = [ "sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres" ] sqlx-sqlite = [ "sqlx-dep", "sea-query/sqlx-sqlite", "sqlx/sqlite" ] From 7bf79ae5bffb19be506e3a3ac15e7659fa3389af Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 30 Jun 2021 11:02:04 +0800 Subject: [PATCH 14/23] Re-export strum_macros --- Cargo.toml | 2 +- examples/sqlx-mysql/Cargo.toml | 1 - examples/sqlx-mysql/src/example_cake.rs | 3 +++ examples/sqlx-mysql/src/example_cake_filling.rs | 3 +++ examples/sqlx-mysql/src/example_filling.rs | 3 +++ examples/sqlx-mysql/src/example_fruit.rs | 3 +++ src/lib.rs | 1 + src/tests_cfg/cake.rs | 3 +++ src/tests_cfg/cake_filling.rs | 3 +++ src/tests_cfg/filling.rs | 3 +++ src/tests_cfg/fruit.rs | 3 +++ 11 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0268df58..1a488d85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ sea-query = { version = "^0.12" } sea-orm-macros = { path = "sea-orm-macros", optional = true } serde = { version = "^1.0", features = [ "derive" ] } sqlx = { version = "^0.5", optional = true } -strum = { version = "^0.20", features = [ "derive" ] } +strum = { path = "../strum/strum", version = "^0.21", features = [ "derive" ] } serde_json = { version = "^1", optional = true } [dev-dependencies] diff --git a/examples/sqlx-mysql/Cargo.toml b/examples/sqlx-mysql/Cargo.toml index a9e1d9ae..ae622523 100644 --- a/examples/sqlx-mysql/Cargo.toml +++ b/examples/sqlx-mysql/Cargo.toml @@ -7,7 +7,6 @@ publish = false [dependencies] async-std = { version = "^1.9", features = [ "attributes" ] } sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", "debug-print", "with-json", "macros" ], default-features = false } -strum = { version = "^0.20", features = [ "derive" ] } serde_json = { version = "^1" } futures = { version = "^0.3" } async-stream = { version = "^0.3" } diff --git a/examples/sqlx-mysql/src/example_cake.rs b/examples/sqlx-mysql/src/example_cake.rs index 475315e8..714bb19a 100644 --- a/examples/sqlx-mysql/src/example_cake.rs +++ b/examples/sqlx-mysql/src/example_cake.rs @@ -16,12 +16,14 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -33,6 +35,7 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] +#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Fruit, } diff --git a/examples/sqlx-mysql/src/example_cake_filling.rs b/examples/sqlx-mysql/src/example_cake_filling.rs index 19de83e4..f38555a1 100644 --- a/examples/sqlx-mysql/src/example_cake_filling.rs +++ b/examples/sqlx-mysql/src/example_cake_filling.rs @@ -16,12 +16,14 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +#[strum(crate_path = "sea_orm::strum")] pub enum Column { CakeId, FillingId, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { CakeId, FillingId, @@ -34,6 +36,7 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] +#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Cake, Filling, diff --git a/examples/sqlx-mysql/src/example_filling.rs b/examples/sqlx-mysql/src/example_filling.rs index 925b92fc..b8e40072 100644 --- a/examples/sqlx-mysql/src/example_filling.rs +++ b/examples/sqlx-mysql/src/example_filling.rs @@ -16,12 +16,14 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -33,6 +35,7 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] +#[strum(crate_path = "sea_orm::strum")] pub enum Relation {} impl ColumnTrait for Column { diff --git a/examples/sqlx-mysql/src/example_fruit.rs b/examples/sqlx-mysql/src/example_fruit.rs index b875da24..ced70c88 100644 --- a/examples/sqlx-mysql/src/example_fruit.rs +++ b/examples/sqlx-mysql/src/example_fruit.rs @@ -17,6 +17,7 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, @@ -24,6 +25,7 @@ pub enum Column { } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -35,6 +37,7 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] +#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Cake, } diff --git a/src/lib.rs b/src/lib.rs index 1678b171..45f27470 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -216,3 +216,4 @@ pub use sea_orm_macros::{ pub use sea_query; pub use sea_query::Iden; pub use strum::EnumIter; +pub use strum; diff --git a/src/tests_cfg/cake.rs b/src/tests_cfg/cake.rs index f8a35d6c..8332111b 100644 --- a/src/tests_cfg/cake.rs +++ b/src/tests_cfg/cake.rs @@ -17,12 +17,14 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -34,6 +36,7 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] +#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Fruit, } diff --git a/src/tests_cfg/cake_filling.rs b/src/tests_cfg/cake_filling.rs index 6b5c20aa..c3a66023 100644 --- a/src/tests_cfg/cake_filling.rs +++ b/src/tests_cfg/cake_filling.rs @@ -17,12 +17,14 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +#[strum(crate_path = "sea_orm::strum")] pub enum Column { CakeId, FillingId, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { CakeId, FillingId, @@ -35,6 +37,7 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] +#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Cake, Filling, diff --git a/src/tests_cfg/filling.rs b/src/tests_cfg/filling.rs index a246d146..8f572436 100644 --- a/src/tests_cfg/filling.rs +++ b/src/tests_cfg/filling.rs @@ -17,12 +17,14 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -34,6 +36,7 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] +#[strum(crate_path = "sea_orm::strum")] pub enum Relation {} impl ColumnTrait for Column { diff --git a/src/tests_cfg/fruit.rs b/src/tests_cfg/fruit.rs index 0511ae58..67d1d07e 100644 --- a/src/tests_cfg/fruit.rs +++ b/src/tests_cfg/fruit.rs @@ -18,6 +18,7 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, @@ -25,6 +26,7 @@ pub enum Column { } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -36,6 +38,7 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] +#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Cake, } From 059b732401d4122921c5eec67d7e4b8943411735 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 30 Jun 2021 11:13:16 +0800 Subject: [PATCH 15/23] Depends on forked strum --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1a488d85..5f993e68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,8 @@ sea-query = { version = "^0.12" } sea-orm-macros = { path = "sea-orm-macros", optional = true } serde = { version = "^1.0", features = [ "derive" ] } sqlx = { version = "^0.5", optional = true } -strum = { path = "../strum/strum", version = "^0.21", features = [ "derive" ] } +# strum = { path = "../strum/strum", version = "^0.21", features = [ "derive" ] } +strum = { git = "https://github.com/billy1624/strum.git", branch = "re-export-macros", version = "^0.21", features = [ "derive" ] } serde_json = { version = "^1", optional = true } [dev-dependencies] From 2f456d972f10784a865380793139286eec0ef141 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 1 Jul 2021 21:00:41 +0800 Subject: [PATCH 16/23] Fix test --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5f993e68..742fcce1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ serde_json = { version = "^1", optional = true } [dev-dependencies] async-std = { version = "^1.9", features = [ "attributes" ] } maplit = { version = "^1" } -sea-orm = { path = ".", features = ["sqlx-sqlite", "runtime-async-std-native-tls"] } +sea-orm = { path = ".", features = ["sqlx-sqlite", "sqlx-json", "sqlx-chrono", "runtime-async-std-native-tls"] } [features] debug-print = [] From e40455e7710ef5d9898c278aece494c6d69b8597 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 1 Jul 2021 21:07:23 +0800 Subject: [PATCH 17/23] Use SeaQL/strum --- Cargo.toml | 3 +-- examples/sqlx-mysql/Cargo.toml | 2 +- examples/sqlx-mysql/src/example_cake.rs | 3 --- examples/sqlx-mysql/src/example_cake_filling.rs | 3 --- examples/sqlx-mysql/src/example_filling.rs | 3 --- examples/sqlx-mysql/src/example_fruit.rs | 3 --- src/tests_cfg/cake.rs | 3 --- src/tests_cfg/cake_filling.rs | 3 --- src/tests_cfg/filling.rs | 3 --- src/tests_cfg/fruit.rs | 3 --- 10 files changed, 2 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 742fcce1..df9e2b79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,8 +35,7 @@ sea-query = { version = "^0.12" } sea-orm-macros = { path = "sea-orm-macros", optional = true } serde = { version = "^1.0", features = [ "derive" ] } sqlx = { version = "^0.5", optional = true } -# strum = { path = "../strum/strum", version = "^0.21", features = [ "derive" ] } -strum = { git = "https://github.com/billy1624/strum.git", branch = "re-export-macros", version = "^0.21", features = [ "derive" ] } +strum = { git = "https://github.com/SeaQL/strum.git", branch = "sea-orm", version = "^0.21", features = [ "derive", "sea-orm" ] } serde_json = { version = "^1", optional = true } [dev-dependencies] diff --git a/examples/sqlx-mysql/Cargo.toml b/examples/sqlx-mysql/Cargo.toml index ae622523..4b39809c 100644 --- a/examples/sqlx-mysql/Cargo.toml +++ b/examples/sqlx-mysql/Cargo.toml @@ -6,7 +6,7 @@ publish = false [dependencies] async-std = { version = "^1.9", features = [ "attributes" ] } -sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", "debug-print", "with-json", "macros" ], default-features = false } +sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", "debug-print", "sqlx-json", "macros" ], default-features = false } serde_json = { version = "^1" } futures = { version = "^0.3" } async-stream = { version = "^0.3" } diff --git a/examples/sqlx-mysql/src/example_cake.rs b/examples/sqlx-mysql/src/example_cake.rs index 714bb19a..475315e8 100644 --- a/examples/sqlx-mysql/src/example_cake.rs +++ b/examples/sqlx-mysql/src/example_cake.rs @@ -16,14 +16,12 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -35,7 +33,6 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] -#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Fruit, } diff --git a/examples/sqlx-mysql/src/example_cake_filling.rs b/examples/sqlx-mysql/src/example_cake_filling.rs index f38555a1..19de83e4 100644 --- a/examples/sqlx-mysql/src/example_cake_filling.rs +++ b/examples/sqlx-mysql/src/example_cake_filling.rs @@ -16,14 +16,12 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -#[strum(crate_path = "sea_orm::strum")] pub enum Column { CakeId, FillingId, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { CakeId, FillingId, @@ -36,7 +34,6 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] -#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Cake, Filling, diff --git a/examples/sqlx-mysql/src/example_filling.rs b/examples/sqlx-mysql/src/example_filling.rs index b8e40072..925b92fc 100644 --- a/examples/sqlx-mysql/src/example_filling.rs +++ b/examples/sqlx-mysql/src/example_filling.rs @@ -16,14 +16,12 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -35,7 +33,6 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] -#[strum(crate_path = "sea_orm::strum")] pub enum Relation {} impl ColumnTrait for Column { diff --git a/examples/sqlx-mysql/src/example_fruit.rs b/examples/sqlx-mysql/src/example_fruit.rs index ced70c88..b875da24 100644 --- a/examples/sqlx-mysql/src/example_fruit.rs +++ b/examples/sqlx-mysql/src/example_fruit.rs @@ -17,7 +17,6 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, @@ -25,7 +24,6 @@ pub enum Column { } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -37,7 +35,6 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] -#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Cake, } diff --git a/src/tests_cfg/cake.rs b/src/tests_cfg/cake.rs index 8332111b..f8a35d6c 100644 --- a/src/tests_cfg/cake.rs +++ b/src/tests_cfg/cake.rs @@ -17,14 +17,12 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -36,7 +34,6 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] -#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Fruit, } diff --git a/src/tests_cfg/cake_filling.rs b/src/tests_cfg/cake_filling.rs index c3a66023..6b5c20aa 100644 --- a/src/tests_cfg/cake_filling.rs +++ b/src/tests_cfg/cake_filling.rs @@ -17,14 +17,12 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -#[strum(crate_path = "sea_orm::strum")] pub enum Column { CakeId, FillingId, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { CakeId, FillingId, @@ -37,7 +35,6 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] -#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Cake, Filling, diff --git a/src/tests_cfg/filling.rs b/src/tests_cfg/filling.rs index 8f572436..a246d146 100644 --- a/src/tests_cfg/filling.rs +++ b/src/tests_cfg/filling.rs @@ -17,14 +17,12 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -36,7 +34,6 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] -#[strum(crate_path = "sea_orm::strum")] pub enum Relation {} impl ColumnTrait for Column { diff --git a/src/tests_cfg/fruit.rs b/src/tests_cfg/fruit.rs index 67d1d07e..0511ae58 100644 --- a/src/tests_cfg/fruit.rs +++ b/src/tests_cfg/fruit.rs @@ -18,7 +18,6 @@ pub struct Model { } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -#[strum(crate_path = "sea_orm::strum")] pub enum Column { Id, Name, @@ -26,7 +25,6 @@ pub enum Column { } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -#[strum(crate_path = "sea_orm::strum")] pub enum PrimaryKey { Id, } @@ -38,7 +36,6 @@ impl PrimaryKeyTrait for PrimaryKey { } #[derive(Copy, Clone, Debug, EnumIter)] -#[strum(crate_path = "sea_orm::strum")] pub enum Relation { Cake, } From fe4297d233f6afab33b8d650858d85365641e0a8 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 1 Jul 2021 21:19:42 +0800 Subject: [PATCH 18/23] Readme --- README.md | 4 ++-- src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ccc68b39..c10c87f8 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Inspired by ActiveRecord, Eloquent and TypeORM, SeaORM aims to provide you an in API to make working with databases in Rust a first-class experience. ```rust -This is an early WIP of SeaORM, and is not yet released. +This is a preview of SeaORM, and is not yet released. ``` ## Features @@ -29,7 +29,7 @@ Relying on SQLx, SeaORM is a new library with async support from day 1. 2. Dynamic -Built upon SeaQuery, a dynamic query builder, SeaORM allows you to build complex queries without 'fighting the ORM'. +Under the hood, SeaQuery allows you to build complex, dynamic queries without 'fighting the ORM'. 3. Testable diff --git a/src/lib.rs b/src/lib.rs index 45f27470..edb5ed6d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ //! API to make working with databases in Rust a first-class experience. //! //! ```ignore -//! This is an early WIP of SeaORM, and is not yet released. +//! This is a preview of SeaORM, and is not yet released. //! ``` //! //! ## Features @@ -29,7 +29,7 @@ //! //! 2. Dynamic //! -//! Built upon SeaQuery, a dynamic query builder, SeaORM allows you to build complex queries without 'fighting the ORM'. +//! Under the hood, SeaQuery allows you to build complex, dynamic queries without 'fighting the ORM'. //! //! 3. Testable //! From fb292e94b626ef8cc191e152c663c34e66aa086a Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 1 Jul 2021 21:29:36 +0800 Subject: [PATCH 19/23] Remove file --- Diesel.md | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 Diesel.md diff --git a/Diesel.md b/Diesel.md deleted file mode 100644 index 080c7154..00000000 --- a/Diesel.md +++ /dev/null @@ -1,39 +0,0 @@ -# Comparison with Diesel - -SeaORM and Diesel shares the same goal: to offer you a complete solution in interfacing with databases. - -Both SeaORM and Diesel works with MySQL, Postgres and SQLite, so you aren't constrained going with either. - -However, there are things we chose to do differently. - -## Architecture - -First off, perhaps the number one requested feature, async Rust support. While using async may not offer you better performance today, programming in async is an architectural decision you have to make early on. By choosing SeaORM, we together look forward to Rust's async ecosystem maturing. - -Under the hood, SeaORM together with SQLx offers you a pure Rust technology stack. While Diesel is tied to native drivers. Each side has their pros and cons, so it's up to your preference. - -SeaORM has a modular design. If you don't like the idea of ORM, you'll definitely still want to use SeaQuery, the underlying query builder. It is light weight and can be easily integrated into any project. The SeaQuery API is also available to you when using SeaORM, so you receive the benefits of high level abstraction while still having the power of a flexible query builder when you need it. - -SeaSchema is our schema discovery library, but it is not sealed inside SeaORM. So you can reuse our data structures for developing libraries inter-operating with SeaORM. - -## Programming paradigm - -In addition to the sync vs async foundation, the biggest distinction between Diesel and SeaORM is static vs dynamic. Diesel has an everything-compile-time design which has its pros and cons. SeaORM is dynamic, in which things are established runtime. It offers more flexibility. While you loses some compile-time guarantee, SeaORM helps you to prove correctness by unit testing instead. - -Both libraries make heavy use of traits and generics, but SeaORM generate less types (each column in Diesel is a struct, while each column in SeaORM is a enum variant) and less depthness (there won't be `A>>`). That probably means looser type/lifetime constraints and faster compilation. - -You don't have to use macros when using SeaORM. We provide some derive macros for convenience, but they are entirely optional. - -## Schema Builder - -While in the Diesel ecosystem there are awesome libraries like barrel, SeaQL maintain the tooling for schema building. That means a familiar API and a more unified experience. - -## Similarities - -Both Diesel and SeaORM are schema first, meaning it all starts from your existing database schema, instead of starting from your OOP classes. - -Both Diesel and SeaORM are relational, meaning you can do complex joins with defined relations. - -## Final words - -Diesel is a well established library in the Rust ecosystem. SeaORM is very new. Neither can replace the other. We hope that the Rust community will grow stronger together. \ No newline at end of file From de7524e50292fa61a7581ecc3ee02e91064151de Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 1 Jul 2021 21:55:00 +0800 Subject: [PATCH 20/23] Fix sea-orm-codegen --- sea-orm-codegen/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/sea-orm-codegen/Cargo.toml b/sea-orm-codegen/Cargo.toml index bfae08ed..a72a366a 100644 --- a/sea-orm-codegen/Cargo.toml +++ b/sea-orm-codegen/Cargo.toml @@ -16,7 +16,6 @@ name = "sea_orm_codegen" path = "src/lib.rs" [dependencies] -sea-orm = { path = "../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", "debug-print", "with-json", "macros" ], default-features = false } sea-schema = { version = "^0.2", default-features = false, features = [ "sqlx-mysql", "runtime-async-std-native-tls", "discovery", "writer" ] } sea-query = { version = "^0.12" } sqlx = { version = "^0.5", features = [ "mysql", "runtime-async-std-native-tls" ] } From 47bb5b3ad73824ce7a2f5e800773f97c74c4536d Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Fri, 2 Jul 2021 10:42:56 +0800 Subject: [PATCH 21/23] sea-orm-cli showing help message when no sub-command provided --- sea-orm-cli/src/cli.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/sea-orm-cli/src/cli.rs b/sea-orm-cli/src/cli.rs index 474dec5f..f66b2aa6 100644 --- a/sea-orm-cli/src/cli.rs +++ b/sea-orm-cli/src/cli.rs @@ -40,4 +40,5 @@ pub fn build_cli() -> App<'static, 'static> { .version(env!("CARGO_PKG_VERSION")) .setting(AppSettings::VersionlessSubcommands) .subcommand(entity_subcommand) + .setting(AppSettings::SubcommandRequiredElseHelp) } From 78eeda0c008d86fb1195a44f7275fecb932af404 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 1 Jul 2021 23:03:09 +0800 Subject: [PATCH 22/23] Update example --- examples/sqlx-mysql/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sqlx-mysql/Readme.md b/examples/sqlx-mysql/Readme.md index 77a90bd6..98a14ada 100644 --- a/examples/sqlx-mysql/Readme.md +++ b/examples/sqlx-mysql/Readme.md @@ -14,7 +14,7 @@ cargo run All about selects: ```sh -Database { connection: SqlxMySqlPoolConnection } +SqlxMySqlPoolConnection ===== ===== From 53311d883b47aeffbbfd6eff54e968cd46427a63 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 3 Jul 2021 15:23:42 +0800 Subject: [PATCH 23/23] Docs --- Cargo.toml | 6 +++++- README.md | 2 +- src/lib.rs | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index df9e2b79..2773730f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,13 @@ license = "MIT OR Apache-2.0" documentation = "https://docs.rs/sea-orm" repository = "https://github.com/SeaQL/sea-orm" categories = [ "database" ] -keywords = [ "orm", "database", "sql", "mysql", "postgres", "sqlite" ] +keywords = [ "orm", "database", "sql", "mysql", "postgres", "sqlite", "async" ] publish = false +[package.metadata.docs.rs] +features = ["default", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", "runtime-async-std-native-tls"] +rustdoc-args = ["--cfg", "docsrs"] + [lib] name = "sea_orm" path = "src/lib.rs" diff --git a/README.md b/README.md index c10c87f8..c5345d22 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Relying on SQLx, SeaORM is a new library with async support from day 1. 2. Dynamic -Under the hood, SeaQuery allows you to build complex, dynamic queries without 'fighting the ORM'. +Built upon SeaQuery, SeaORM allows you to build complex queries without 'fighting the ORM'. 3. Testable diff --git a/src/lib.rs b/src/lib.rs index edb5ed6d..ae71656e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ //! //! 2. Dynamic //! -//! Under the hood, SeaQuery allows you to build complex, dynamic queries without 'fighting the ORM'. +//! Built upon SeaQuery, SeaORM allows you to build complex queries without 'fighting the ORM'. //! //! 3. Testable //!