Use DatabaseConnection in place of Database
This commit is contained in:
parent
5d84c88ccd
commit
5002c62b40
@ -18,9 +18,7 @@ use select::*;
|
|||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let mut db = Database::default();
|
let db = Database::connect("mysql://sea:sea@localhost/bakery")
|
||||||
|
|
||||||
db.connect("mysql://sea:sea@localhost/bakery")
|
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use sea_orm::{entity::*, query::*, Database};
|
use sea_orm::{entity::*, query::*, DatabaseConnection};
|
||||||
|
|
||||||
pub async fn all_about_operation(db: &Database) -> Result<(), ExecErr> {
|
pub async fn all_about_operation(db: &DatabaseConnection) -> Result<(), ExecErr> {
|
||||||
insert_and_update(db).await?;
|
insert_and_update(db).await?;
|
||||||
|
|
||||||
println!("===== =====\n");
|
println!("===== =====\n");
|
||||||
@ -15,7 +15,7 @@ pub async fn all_about_operation(db: &Database) -> Result<(), ExecErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn insert_and_update(db: &Database) -> Result<(), ExecErr> {
|
pub async fn insert_and_update(db: &DatabaseConnection) -> Result<(), ExecErr> {
|
||||||
let pear = fruit::ActiveModel {
|
let pear = fruit::ActiveModel {
|
||||||
name: Set("pear".to_owned()),
|
name: Set("pear".to_owned()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -44,7 +44,7 @@ pub async fn insert_and_update(db: &Database) -> Result<(), ExecErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn save_active_model(db: &Database) -> Result<(), ExecErr> {
|
pub async fn save_active_model(db: &DatabaseConnection) -> Result<(), ExecErr> {
|
||||||
let banana = fruit::ActiveModel {
|
let banana = fruit::ActiveModel {
|
||||||
name: Set("Banana".to_owned()),
|
name: Set("Banana".to_owned()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -82,7 +82,7 @@ mod form {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn save_custom_active_model(db: &Database) -> Result<(), ExecErr> {
|
async fn save_custom_active_model(db: &DatabaseConnection) -> Result<(), ExecErr> {
|
||||||
let pineapple = form::ActiveModel {
|
let pineapple = form::ActiveModel {
|
||||||
id: Unset(None),
|
id: Unset(None),
|
||||||
name: Set("Pineapple".to_owned()),
|
name: Set("Pineapple".to_owned()),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use sea_orm::{entity::*, query::*, Database, FromQueryResult};
|
use sea_orm::{entity::*, query::*, DatabaseConnection, FromQueryResult};
|
||||||
|
|
||||||
pub async fn all_about_select(db: &Database) -> Result<(), QueryErr> {
|
pub async fn all_about_select(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
find_all(db).await?;
|
find_all(db).await?;
|
||||||
|
|
||||||
println!("===== =====\n");
|
println!("===== =====\n");
|
||||||
@ -41,7 +41,7 @@ pub async fn all_about_select(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_all(db: &Database) -> Result<(), QueryErr> {
|
async fn find_all(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
print!("find all cakes: ");
|
print!("find all cakes: ");
|
||||||
|
|
||||||
let cakes = Cake::find().all(db).await?;
|
let cakes = Cake::find().all(db).await?;
|
||||||
@ -63,7 +63,7 @@ async fn find_all(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_together(db: &Database) -> Result<(), QueryErr> {
|
async fn find_together(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
print!("find cakes and fruits: ");
|
print!("find cakes and fruits: ");
|
||||||
|
|
||||||
let both = Cake::find().left_join_and_select(Fruit).all(db).await?;
|
let both = Cake::find().left_join_and_select(Fruit).all(db).await?;
|
||||||
@ -82,7 +82,7 @@ impl Cake {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_one(db: &Database) -> Result<(), QueryErr> {
|
async fn find_one(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
print!("find one by primary key: ");
|
print!("find one by primary key: ");
|
||||||
|
|
||||||
let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;
|
let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;
|
||||||
@ -112,7 +112,7 @@ async fn find_one(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn count_fruits_by_cake(db: &Database) -> Result<(), QueryErr> {
|
async fn count_fruits_by_cake(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
#[derive(Debug, FromQueryResult)]
|
#[derive(Debug, FromQueryResult)]
|
||||||
struct SelectResult {
|
struct SelectResult {
|
||||||
name: String,
|
name: String,
|
||||||
@ -138,7 +138,7 @@ async fn count_fruits_by_cake(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_many_to_many(db: &Database) -> Result<(), QueryErr> {
|
async fn find_many_to_many(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
print!("find cakes and fillings: ");
|
print!("find cakes and fillings: ");
|
||||||
|
|
||||||
let both = Cake::find().left_join_and_select(Filling).all(db).await?;
|
let both = Cake::find().left_join_and_select(Filling).all(db).await?;
|
||||||
@ -177,7 +177,7 @@ async fn find_many_to_many(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn all_about_select_json(db: &Database) -> Result<(), QueryErr> {
|
async fn all_about_select_json(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
find_all_json(&db).await?;
|
find_all_json(&db).await?;
|
||||||
|
|
||||||
println!("===== =====\n");
|
println!("===== =====\n");
|
||||||
@ -191,7 +191,7 @@ async fn all_about_select_json(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_all_json(db: &Database) -> Result<(), QueryErr> {
|
async fn find_all_json(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
print!("find all cakes: ");
|
print!("find all cakes: ");
|
||||||
|
|
||||||
let cakes = Cake::find().into_json().all(db).await?;
|
let cakes = Cake::find().into_json().all(db).await?;
|
||||||
@ -207,7 +207,7 @@ async fn find_all_json(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_together_json(db: &Database) -> Result<(), QueryErr> {
|
async fn find_together_json(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
print!("find cakes and fruits: ");
|
print!("find cakes and fruits: ");
|
||||||
|
|
||||||
let cakes_fruits = Cake::find()
|
let cakes_fruits = Cake::find()
|
||||||
@ -224,7 +224,7 @@ async fn find_together_json(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn count_fruits_by_cake_json(db: &Database) -> Result<(), QueryErr> {
|
async fn count_fruits_by_cake_json(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
print!("count fruits by cake: ");
|
print!("count fruits by cake: ");
|
||||||
|
|
||||||
let count = Cake::find()
|
let count = Cake::find()
|
||||||
@ -242,7 +242,7 @@ async fn count_fruits_by_cake_json(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_all_stream(db: &Database) -> Result<(), QueryErr> {
|
async fn find_all_stream(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
use async_std::task::sleep;
|
use async_std::task::sleep;
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -290,7 +290,7 @@ async fn find_all_stream(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_first_page(db: &Database) -> Result<(), QueryErr> {
|
async fn find_first_page(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
println!("fruits first page: ");
|
println!("fruits first page: ");
|
||||||
let page = fruit::Entity::find().paginate(db, 2).fetch_page(0).await?;
|
let page = fruit::Entity::find().paginate(db, 2).fetch_page(0).await?;
|
||||||
for fruit in page {
|
for fruit in page {
|
||||||
@ -300,7 +300,7 @@ async fn find_first_page(db: &Database) -> Result<(), QueryErr> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_num_pages(db: &Database) -> Result<(), QueryErr> {
|
async fn find_num_pages(db: &DatabaseConnection) -> Result<(), QueryErr> {
|
||||||
println!("fruits number of page: ");
|
println!("fruits number of page: ");
|
||||||
let num_pages = fruit::Entity::find().paginate(db, 2).num_pages().await?;
|
let num_pages = fruit::Entity::find().paginate(db, 2).num_pages().await?;
|
||||||
println!("{:?}", num_pages);
|
println!("{:?}", num_pages);
|
||||||
|
@ -37,11 +37,11 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveModel {
|
impl ActiveModel {
|
||||||
pub async fn save(self, db: &sea_orm::Database) -> Result<Self, sea_orm::ExecErr> {
|
pub async fn save(self, db: &sea_orm::DatabaseConnection) -> Result<Self, sea_orm::ExecErr> {
|
||||||
sea_orm::save_active_model::<Self, Entity>(self, db).await
|
sea_orm::save_active_model::<Self, Entity>(self, db).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(self, db: &sea_orm::Database) -> Result<sea_orm::DeleteResult, sea_orm::ExecErr> {
|
pub async fn delete(self, db: &sea_orm::DatabaseConnection) -> Result<sea_orm::DeleteResult, sea_orm::ExecErr> {
|
||||||
sea_orm::delete_active_model::<Self, Entity>(self, db).await
|
sea_orm::delete_active_model::<Self, Entity>(self, db).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use crate::{ExecErr, ExecResult, QueryErr, QueryResult, Statement};
|
use crate::{ExecErr, ExecResult, QueryErr, QueryResult, Statement};
|
||||||
use sea_query::{
|
use sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, QueryStatementBuilder};
|
||||||
DeleteStatement, InsertStatement, MysqlQueryBuilder, PostgresQueryBuilder,
|
|
||||||
QueryStatementBuilder, SelectStatement, UpdateStatement,
|
|
||||||
};
|
|
||||||
use std::{error::Error, fmt};
|
use std::{error::Error, fmt};
|
||||||
|
|
||||||
pub enum DatabaseConnection {
|
pub enum DatabaseConnection {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Database, DatabaseConnection, EntityTrait, ExecErr, ExecResult, ExecResultHolder, Iden,
|
DatabaseConnection, EntityTrait, ExecErr, ExecResult, ExecResultHolder, Iden, Iterable,
|
||||||
Iterable, MockDatabaseConnection, MockDatabaseTrait, ModelTrait, QueryErr, QueryResult,
|
MockDatabaseConnection, MockDatabaseTrait, ModelTrait, QueryErr, QueryResult, QueryResultRow,
|
||||||
QueryResultRow, Statement, Transaction, TypeErr,
|
Statement, Transaction, TypeErr,
|
||||||
};
|
};
|
||||||
use sea_query::{Value, ValueType};
|
use sea_query::{Value, ValueType};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
@ -46,12 +46,8 @@ impl MockDatabase {
|
|||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_database(self) -> Database {
|
pub fn into_connection(self) -> DatabaseConnection {
|
||||||
Database {
|
DatabaseConnection::MockDatabaseConnection(MockDatabaseConnection::new(self))
|
||||||
connection: DatabaseConnection::MockDatabaseConnection(MockDatabaseConnection::new(
|
|
||||||
self,
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_exec_results(mut self, mut vec: Vec<MockExecResult>) -> Self {
|
pub fn append_exec_results(mut self, mut vec: Vec<MockExecResult>) -> Self {
|
||||||
|
@ -11,30 +11,18 @@ pub use statement::*;
|
|||||||
pub use transaction::*;
|
pub use transaction::*;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Database {
|
pub struct Database;
|
||||||
connection: DatabaseConnection,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
pub async fn connect(&mut self, string: &str) -> Result<(), ConnectionErr> {
|
pub async fn connect(string: &str) -> Result<DatabaseConnection, ConnectionErr> {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
if crate::SqlxMySqlConnector::accepts(string) {
|
if crate::SqlxMySqlConnector::accepts(string) {
|
||||||
self.connection = crate::SqlxMySqlConnector::connect(string).await?;
|
return Ok(crate::SqlxMySqlConnector::connect(string).await?);
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
if crate::MockDatabaseConnector::accepts(string) {
|
if crate::MockDatabaseConnector::accepts(string) {
|
||||||
self.connection = crate::MockDatabaseConnector::connect(string).await?;
|
return Ok(crate::MockDatabaseConnector::connect(string).await?);
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
Err(ConnectionErr)
|
Err(ConnectionErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_connection(&self) -> &DatabaseConnection {
|
|
||||||
&self.connection
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_query_builder_backend(&self) -> QueryBuilderBackend {
|
|
||||||
self.connection.get_query_builder_backend()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Database, DeleteResult, EntityTrait, ExecErr, Iterable, PrimaryKeyToColumn, PrimaryKeyTrait,
|
DatabaseConnection, DeleteResult, EntityTrait, ExecErr, Iterable, PrimaryKeyToColumn,
|
||||||
Value,
|
PrimaryKeyTrait, Value,
|
||||||
};
|
};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ pub trait ActiveModelTrait: Clone + Debug {
|
|||||||
fn default() -> Self;
|
fn default() -> Self;
|
||||||
|
|
||||||
// below is not yet possible. right now we define these methods in DeriveActiveModel
|
// below is not yet possible. right now we define these methods in DeriveActiveModel
|
||||||
// fn save(self, db: &Database) -> impl Future<Output = Result<Self, ExecErr>>;
|
// fn save(self, db: &DatabaseConnection) -> impl Future<Output = Result<Self, ExecErr>>;
|
||||||
// fn delete(self, db: &Database) -> impl Future<Output = Result<DeleteResult, ExecErr>>;
|
// fn delete(self, db: &DatabaseConnection) -> impl Future<Output = Result<DeleteResult, ExecErr>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Behaviors for users to override
|
/// Behaviors for users to override
|
||||||
@ -228,7 +228,7 @@ where
|
|||||||
|
|
||||||
/// Insert the model if primary key is unset, update otherwise.
|
/// Insert the model if primary key is unset, update otherwise.
|
||||||
/// Only works if the entity has auto increment primary key.
|
/// Only works if the entity has auto increment primary key.
|
||||||
pub async fn save_active_model<A, E>(mut am: A, db: &Database) -> Result<A, ExecErr>
|
pub async fn save_active_model<A, E>(mut am: A, db: &DatabaseConnection) -> Result<A, ExecErr>
|
||||||
where
|
where
|
||||||
A: ActiveModelBehavior + ActiveModelTrait<Entity = E>,
|
A: ActiveModelBehavior + ActiveModelTrait<Entity = E>,
|
||||||
E::Model: IntoActiveModel<A>,
|
E::Model: IntoActiveModel<A>,
|
||||||
@ -252,7 +252,7 @@ where
|
|||||||
Ok(am)
|
Ok(am)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn insert_and_select_active_model<A, E>(am: A, db: &Database) -> Result<A, ExecErr>
|
async fn insert_and_select_active_model<A, E>(am: A, db: &DatabaseConnection) -> Result<A, ExecErr>
|
||||||
where
|
where
|
||||||
A: ActiveModelTrait<Entity = E>,
|
A: ActiveModelTrait<Entity = E>,
|
||||||
E::Model: IntoActiveModel<A>,
|
E::Model: IntoActiveModel<A>,
|
||||||
@ -274,7 +274,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_active_model<A, E>(am: A, db: &Database) -> Result<A, ExecErr>
|
async fn update_active_model<A, E>(am: A, db: &DatabaseConnection) -> Result<A, ExecErr>
|
||||||
where
|
where
|
||||||
A: ActiveModelTrait<Entity = E>,
|
A: ActiveModelTrait<Entity = E>,
|
||||||
E: EntityTrait,
|
E: EntityTrait,
|
||||||
@ -283,7 +283,10 @@ where
|
|||||||
exec.await
|
exec.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_active_model<A, E>(mut am: A, db: &Database) -> Result<DeleteResult, ExecErr>
|
pub async fn delete_active_model<A, E>(
|
||||||
|
mut am: A,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<DeleteResult, ExecErr>
|
||||||
where
|
where
|
||||||
A: ActiveModelBehavior + ActiveModelTrait<Entity = E>,
|
A: ActiveModelBehavior + ActiveModelTrait<Entity = E>,
|
||||||
E: EntityTrait,
|
E: EntityTrait,
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use crate::{ActiveModelTrait, Database, DeleteMany, DeleteOne, EntityTrait, ExecErr, Statement};
|
use crate::{
|
||||||
|
ActiveModelTrait, DatabaseConnection, DeleteMany, DeleteOne, EntityTrait, ExecErr, Statement,
|
||||||
|
};
|
||||||
use sea_query::DeleteStatement;
|
use sea_query::DeleteStatement;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ where
|
|||||||
{
|
{
|
||||||
pub fn exec(
|
pub fn exec(
|
||||||
self,
|
self,
|
||||||
db: &'a Database,
|
db: &'a DatabaseConnection,
|
||||||
) -> impl Future<Output = Result<DeleteResult, ExecErr>> + 'a {
|
) -> impl Future<Output = Result<DeleteResult, ExecErr>> + 'a {
|
||||||
// so that self is dropped before entering await
|
// so that self is dropped before entering await
|
||||||
exec_delete_only(self.query, db)
|
exec_delete_only(self.query, db)
|
||||||
@ -31,7 +33,7 @@ where
|
|||||||
{
|
{
|
||||||
pub fn exec(
|
pub fn exec(
|
||||||
self,
|
self,
|
||||||
db: &'a Database,
|
db: &'a DatabaseConnection,
|
||||||
) -> impl Future<Output = Result<DeleteResult, ExecErr>> + 'a {
|
) -> impl Future<Output = Result<DeleteResult, ExecErr>> + 'a {
|
||||||
// so that self is dropped before entering await
|
// so that self is dropped before entering await
|
||||||
exec_delete_only(self.query, db)
|
exec_delete_only(self.query, db)
|
||||||
@ -43,19 +45,28 @@ impl Deleter {
|
|||||||
Self { query }
|
Self { query }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(self, db: &Database) -> impl Future<Output = Result<DeleteResult, ExecErr>> + '_ {
|
pub fn exec(
|
||||||
|
self,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> impl Future<Output = Result<DeleteResult, ExecErr>> + '_ {
|
||||||
let builder = db.get_query_builder_backend();
|
let builder = db.get_query_builder_backend();
|
||||||
exec_delete(builder.build(&self.query), db)
|
exec_delete(builder.build(&self.query), db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn exec_delete_only(query: DeleteStatement, db: &Database) -> Result<DeleteResult, ExecErr> {
|
async fn exec_delete_only(
|
||||||
|
query: DeleteStatement,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<DeleteResult, ExecErr> {
|
||||||
Deleter::new(query).exec(db).await
|
Deleter::new(query).exec(db).await
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only Statement impl Send
|
// Only Statement impl Send
|
||||||
async fn exec_delete(statement: Statement, db: &Database) -> Result<DeleteResult, ExecErr> {
|
async fn exec_delete(
|
||||||
let result = db.get_connection().execute(statement).await?;
|
statement: Statement,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<DeleteResult, ExecErr> {
|
||||||
|
let result = db.execute(statement).await?;
|
||||||
Ok(DeleteResult {
|
Ok(DeleteResult {
|
||||||
rows_affected: result.rows_affected(),
|
rows_affected: result.rows_affected(),
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{ActiveModelTrait, Database, ExecErr, Insert, QueryTrait, Statement};
|
use crate::{ActiveModelTrait, DatabaseConnection, ExecErr, Insert, QueryTrait, Statement};
|
||||||
use sea_query::InsertStatement;
|
use sea_query::InsertStatement;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
@ -16,7 +16,10 @@ impl<A> Insert<A>
|
|||||||
where
|
where
|
||||||
A: ActiveModelTrait,
|
A: ActiveModelTrait,
|
||||||
{
|
{
|
||||||
pub fn exec(self, db: &Database) -> impl Future<Output = Result<InsertResult, ExecErr>> + '_ {
|
pub fn exec(
|
||||||
|
self,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> impl Future<Output = Result<InsertResult, ExecErr>> + '_ {
|
||||||
// so that self is dropped before entering await
|
// so that self is dropped before entering await
|
||||||
Inserter::new(self.into_query()).exec(db)
|
Inserter::new(self.into_query()).exec(db)
|
||||||
}
|
}
|
||||||
@ -27,15 +30,21 @@ impl Inserter {
|
|||||||
Self { query }
|
Self { query }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(self, db: &Database) -> impl Future<Output = Result<InsertResult, ExecErr>> + '_ {
|
pub fn exec(
|
||||||
|
self,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> impl Future<Output = Result<InsertResult, ExecErr>> + '_ {
|
||||||
let builder = db.get_query_builder_backend();
|
let builder = db.get_query_builder_backend();
|
||||||
exec_insert(builder.build(&self.query), db)
|
exec_insert(builder.build(&self.query), db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only Statement impl Send
|
// Only Statement impl Send
|
||||||
async fn exec_insert(statement: Statement, db: &Database) -> Result<InsertResult, ExecErr> {
|
async fn exec_insert(
|
||||||
let result = db.get_connection().execute(statement).await?;
|
statement: Statement,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<InsertResult, ExecErr> {
|
||||||
|
let result = db.execute(statement).await?;
|
||||||
// TODO: Postgres instead use query_one + returning clause
|
// TODO: Postgres instead use query_one + returning clause
|
||||||
Ok(InsertResult {
|
Ok(InsertResult {
|
||||||
last_insert_id: result.last_insert_id(),
|
last_insert_id: result.last_insert_id(),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{Database, QueryErr, SelectorTrait};
|
use crate::{DatabaseConnection, QueryErr, SelectorTrait};
|
||||||
use async_stream::stream;
|
use async_stream::stream;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use sea_query::{Alias, Expr, SelectStatement};
|
use sea_query::{Alias, Expr, SelectStatement};
|
||||||
@ -14,7 +14,7 @@ where
|
|||||||
pub(crate) query: SelectStatement,
|
pub(crate) query: SelectStatement,
|
||||||
pub(crate) page: usize,
|
pub(crate) page: usize,
|
||||||
pub(crate) page_size: usize,
|
pub(crate) page_size: usize,
|
||||||
pub(crate) db: &'db Database,
|
pub(crate) db: &'db DatabaseConnection,
|
||||||
pub(crate) selector: PhantomData<S>,
|
pub(crate) selector: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ where
|
|||||||
.to_owned();
|
.to_owned();
|
||||||
let builder = self.db.get_query_builder_backend();
|
let builder = self.db.get_query_builder_backend();
|
||||||
let stmt = builder.build(&query);
|
let stmt = builder.build(&query);
|
||||||
let rows = self.db.get_connection().query_all(stmt).await?;
|
let rows = self.db.query_all(stmt).await?;
|
||||||
let mut buffer = Vec::with_capacity(rows.len());
|
let mut buffer = Vec::with_capacity(rows.len());
|
||||||
for row in rows.into_iter() {
|
for row in rows.into_iter() {
|
||||||
// TODO: Error handling
|
// TODO: Error handling
|
||||||
@ -57,7 +57,7 @@ where
|
|||||||
Alias::new("sub_query"),
|
Alias::new("sub_query"),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
let result = match self.db.get_connection().query_one(stmt).await? {
|
let result = match self.db.query_one(stmt).await? {
|
||||||
Some(res) => res,
|
Some(res) => res,
|
||||||
None => return Ok(0),
|
None => return Ok(0),
|
||||||
};
|
};
|
||||||
@ -105,11 +105,11 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use crate::entity::prelude::*;
|
use crate::entity::prelude::*;
|
||||||
use crate::tests_cfg::*;
|
use crate::tests_cfg::*;
|
||||||
use crate::{Database, MockDatabase, QueryErr, Transaction};
|
use crate::{DatabaseConnection, MockDatabase, QueryErr, Transaction};
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use sea_query::{Alias, Expr, SelectStatement, Value};
|
use sea_query::{Alias, Expr, SelectStatement, Value};
|
||||||
|
|
||||||
fn setup() -> (Database, Vec<Vec<fruit::Model>>) {
|
fn setup() -> (DatabaseConnection, Vec<Vec<fruit::Model>>) {
|
||||||
let page1 = vec![
|
let page1 = vec![
|
||||||
fruit::Model {
|
fruit::Model {
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -133,18 +133,18 @@ mod tests {
|
|||||||
|
|
||||||
let db = MockDatabase::new()
|
let db = MockDatabase::new()
|
||||||
.append_query_results(vec![page1.clone(), page2.clone(), page3.clone()])
|
.append_query_results(vec![page1.clone(), page2.clone(), page3.clone()])
|
||||||
.into_database();
|
.into_connection();
|
||||||
|
|
||||||
(db, vec![page1, page2, page3])
|
(db, vec![page1, page2, page3])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_num_rows() -> (Database, i32) {
|
fn setup_num_rows() -> (DatabaseConnection, i32) {
|
||||||
let num_rows = 3;
|
let num_rows = 3;
|
||||||
let db = MockDatabase::new()
|
let db = MockDatabase::new()
|
||||||
.append_query_results(vec![vec![maplit::btreemap! {
|
.append_query_results(vec![vec![maplit::btreemap! {
|
||||||
"num_rows" => Into::<Value>::into(num_rows),
|
"num_rows" => Into::<Value>::into(num_rows),
|
||||||
}]])
|
}]])
|
||||||
.into_database();
|
.into_connection();
|
||||||
|
|
||||||
(db, num_rows)
|
(db, num_rows)
|
||||||
}
|
}
|
||||||
@ -175,12 +175,7 @@ mod tests {
|
|||||||
query_builder.build(select.offset(4).limit(2)),
|
query_builder.build(select.offset(4).limit(2)),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut mocker = db
|
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
|
||||||
.get_connection()
|
|
||||||
.as_mock_connection()
|
|
||||||
.get_mocker_mutex()
|
|
||||||
.lock()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -216,12 +211,7 @@ mod tests {
|
|||||||
query_builder.build(select.offset(4).limit(2)),
|
query_builder.build(select.offset(4).limit(2)),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut mocker = db
|
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
|
||||||
.get_connection()
|
|
||||||
.as_mock_connection()
|
|
||||||
.get_mocker_mutex()
|
|
||||||
.lock()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -254,12 +244,7 @@ mod tests {
|
|||||||
|
|
||||||
let query_builder = db.get_query_builder_backend();
|
let query_builder = db.get_query_builder_backend();
|
||||||
let stmts = vec![query_builder.build(&select)];
|
let stmts = vec![query_builder.build(&select)];
|
||||||
let mut mocker = db
|
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
|
||||||
.get_connection()
|
|
||||||
.as_mock_connection()
|
|
||||||
.get_mocker_mutex()
|
|
||||||
.lock()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -312,12 +297,7 @@ mod tests {
|
|||||||
query_builder.build(select.offset(4).limit(2)),
|
query_builder.build(select.offset(4).limit(2)),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut mocker = db
|
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
|
||||||
.get_connection()
|
|
||||||
.as_mock_connection()
|
|
||||||
.get_mocker_mutex()
|
|
||||||
.lock()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -351,12 +331,7 @@ mod tests {
|
|||||||
query_builder.build(select.offset(4).limit(2)),
|
query_builder.build(select.offset(4).limit(2)),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut mocker = db
|
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
|
||||||
.get_connection()
|
|
||||||
.as_mock_connection()
|
|
||||||
.get_mocker_mutex()
|
|
||||||
.lock()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
query::combine, Database, EntityTrait, FromQueryResult, JsonValue, Paginator, QueryErr,
|
query::combine, DatabaseConnection, EntityTrait, FromQueryResult, JsonValue, Paginator,
|
||||||
QueryResult, Select, SelectTwo, TypeErr,
|
QueryErr, QueryResult, Select, SelectTwo, TypeErr,
|
||||||
};
|
};
|
||||||
use sea_query::SelectStatement;
|
use sea_query::SelectStatement;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@ -84,15 +84,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn one(self, db: &Database) -> Result<Option<E::Model>, QueryErr> {
|
pub async fn one(self, db: &DatabaseConnection) -> Result<Option<E::Model>, QueryErr> {
|
||||||
self.into_model::<E::Model>().one(db).await
|
self.into_model::<E::Model>().one(db).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn all(self, db: &Database) -> Result<Vec<E::Model>, QueryErr> {
|
pub async fn all(self, db: &DatabaseConnection) -> Result<Vec<E::Model>, QueryErr> {
|
||||||
self.into_model::<E::Model>().all(db).await
|
self.into_model::<E::Model>().all(db).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paginate(self, db: &Database, page_size: usize) -> Paginator<'_, SelectModel<E::Model>> {
|
pub fn paginate(
|
||||||
|
self,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
page_size: usize,
|
||||||
|
) -> Paginator<'_, SelectModel<E::Model>> {
|
||||||
self.into_model::<E::Model>().paginate(db, page_size)
|
self.into_model::<E::Model>().paginate(db, page_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,11 +125,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn one(self, db: &Database) -> Result<Option<(E::Model, F::Model)>, QueryErr> {
|
pub async fn one(
|
||||||
|
self,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<Option<(E::Model, F::Model)>, QueryErr> {
|
||||||
self.into_model::<E::Model, F::Model>().one(db).await
|
self.into_model::<E::Model, F::Model>().one(db).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn all(self, db: &Database) -> Result<Vec<(E::Model, F::Model)>, QueryErr> {
|
pub async fn all(self, db: &DatabaseConnection) -> Result<Vec<(E::Model, F::Model)>, QueryErr> {
|
||||||
self.into_model::<E::Model, F::Model>().all(db).await
|
self.into_model::<E::Model, F::Model>().all(db).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,25 +141,19 @@ impl<S> Selector<S>
|
|||||||
where
|
where
|
||||||
S: SelectorTrait,
|
S: SelectorTrait,
|
||||||
{
|
{
|
||||||
pub async fn one(mut self, db: &Database) -> Result<Option<S::Item>, QueryErr> {
|
pub async fn one(mut self, db: &DatabaseConnection) -> Result<Option<S::Item>, QueryErr> {
|
||||||
let builder = db.get_query_builder_backend();
|
let builder = db.get_query_builder_backend();
|
||||||
self.query.limit(1);
|
self.query.limit(1);
|
||||||
let row = db
|
let row = db.query_one(builder.build(&self.query)).await?;
|
||||||
.get_connection()
|
|
||||||
.query_one(builder.build(&self.query))
|
|
||||||
.await?;
|
|
||||||
match row {
|
match row {
|
||||||
Some(row) => Ok(Some(S::from_raw_query_result(row)?)),
|
Some(row) => Ok(Some(S::from_raw_query_result(row)?)),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn all(self, db: &Database) -> Result<Vec<S::Item>, QueryErr> {
|
pub async fn all(self, db: &DatabaseConnection) -> Result<Vec<S::Item>, QueryErr> {
|
||||||
let builder = db.get_query_builder_backend();
|
let builder = db.get_query_builder_backend();
|
||||||
let rows = db
|
let rows = db.query_all(builder.build(&self.query)).await?;
|
||||||
.get_connection()
|
|
||||||
.query_all(builder.build(&self.query))
|
|
||||||
.await?;
|
|
||||||
let mut models = Vec::new();
|
let mut models = Vec::new();
|
||||||
for row in rows.into_iter() {
|
for row in rows.into_iter() {
|
||||||
models.push(S::from_raw_query_result(row)?);
|
models.push(S::from_raw_query_result(row)?);
|
||||||
@ -160,7 +161,7 @@ where
|
|||||||
Ok(models)
|
Ok(models)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paginate(self, db: &Database, page_size: usize) -> Paginator<'_, S> {
|
pub fn paginate(self, db: &DatabaseConnection, page_size: usize) -> Paginator<'_, S> {
|
||||||
Paginator {
|
Paginator {
|
||||||
query: self.query,
|
query: self.query,
|
||||||
page: 0,
|
page: 0,
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use crate::{ActiveModelTrait, Database, EntityTrait, ExecErr, Statement, UpdateMany, UpdateOne};
|
use crate::{
|
||||||
|
ActiveModelTrait, DatabaseConnection, EntityTrait, ExecErr, Statement, UpdateMany, UpdateOne,
|
||||||
|
};
|
||||||
use sea_query::UpdateStatement;
|
use sea_query::UpdateStatement;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ impl<'a, A: 'a> UpdateOne<A>
|
|||||||
where
|
where
|
||||||
A: ActiveModelTrait,
|
A: ActiveModelTrait,
|
||||||
{
|
{
|
||||||
pub fn exec(self, db: &'a Database) -> impl Future<Output = Result<A, ExecErr>> + 'a {
|
pub fn exec(self, db: &'a DatabaseConnection) -> impl Future<Output = Result<A, ExecErr>> + 'a {
|
||||||
// so that self is dropped before entering await
|
// so that self is dropped before entering await
|
||||||
exec_update_and_return_original(self.query, self.model, db)
|
exec_update_and_return_original(self.query, self.model, db)
|
||||||
}
|
}
|
||||||
@ -28,7 +30,7 @@ where
|
|||||||
{
|
{
|
||||||
pub fn exec(
|
pub fn exec(
|
||||||
self,
|
self,
|
||||||
db: &'a Database,
|
db: &'a DatabaseConnection,
|
||||||
) -> impl Future<Output = Result<UpdateResult, ExecErr>> + 'a {
|
) -> impl Future<Output = Result<UpdateResult, ExecErr>> + 'a {
|
||||||
// so that self is dropped before entering await
|
// so that self is dropped before entering await
|
||||||
exec_update_only(self.query, db)
|
exec_update_only(self.query, db)
|
||||||
@ -40,20 +42,26 @@ impl Updater {
|
|||||||
Self { query }
|
Self { query }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(self, db: &Database) -> impl Future<Output = Result<UpdateResult, ExecErr>> + '_ {
|
pub fn exec(
|
||||||
|
self,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> impl Future<Output = Result<UpdateResult, ExecErr>> + '_ {
|
||||||
let builder = db.get_query_builder_backend();
|
let builder = db.get_query_builder_backend();
|
||||||
exec_update(builder.build(&self.query), db)
|
exec_update(builder.build(&self.query), db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn exec_update_only(query: UpdateStatement, db: &Database) -> Result<UpdateResult, ExecErr> {
|
async fn exec_update_only(
|
||||||
|
query: UpdateStatement,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<UpdateResult, ExecErr> {
|
||||||
Updater::new(query).exec(db).await
|
Updater::new(query).exec(db).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn exec_update_and_return_original<A>(
|
async fn exec_update_and_return_original<A>(
|
||||||
query: UpdateStatement,
|
query: UpdateStatement,
|
||||||
model: A,
|
model: A,
|
||||||
db: &Database,
|
db: &DatabaseConnection,
|
||||||
) -> Result<A, ExecErr>
|
) -> Result<A, ExecErr>
|
||||||
where
|
where
|
||||||
A: ActiveModelTrait,
|
A: ActiveModelTrait,
|
||||||
@ -63,8 +71,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only Statement impl Send
|
// Only Statement impl Send
|
||||||
async fn exec_update(statement: Statement, db: &Database) -> Result<UpdateResult, ExecErr> {
|
async fn exec_update(
|
||||||
let result = db.get_connection().execute(statement).await?;
|
statement: Statement,
|
||||||
|
db: &DatabaseConnection,
|
||||||
|
) -> Result<UpdateResult, ExecErr> {
|
||||||
|
let result = db.execute(statement).await?;
|
||||||
Ok(UpdateResult {
|
Ok(UpdateResult {
|
||||||
rows_affected: result.rows_affected(),
|
rows_affected: result.rows_affected(),
|
||||||
})
|
})
|
||||||
|
@ -73,7 +73,7 @@ mod tests {
|
|||||||
.append_query_results(vec![vec![maplit::btreemap! {
|
.append_query_results(vec![vec![maplit::btreemap! {
|
||||||
"id" => Into::<Value>::into(128), "name" => Into::<Value>::into("apple")
|
"id" => Into::<Value>::into(128), "name" => Into::<Value>::into("apple")
|
||||||
}]])
|
}]])
|
||||||
.into_database();
|
.into_connection();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cake::Entity::find().into_json().one(&db).await.unwrap(),
|
cake::Entity::find().into_json().one(&db).await.unwrap(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user