Use DatabaseConnection in place of Database

This commit is contained in:
Chris Tsang 2021-06-19 17:25:51 +08:00
parent 5d84c88ccd
commit 5002c62b40
14 changed files with 128 additions and 139 deletions

View File

@ -18,9 +18,7 @@ use select::*;
#[async_std::main]
async fn main() {
let mut db = Database::default();
db.connect("mysql://sea:sea@localhost/bakery")
let db = Database::connect("mysql://sea:sea@localhost/bakery")
.await
.unwrap();

View File

@ -1,7 +1,7 @@
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?;
println!("===== =====\n");
@ -15,7 +15,7 @@ pub async fn all_about_operation(db: &Database) -> Result<(), ExecErr> {
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 {
name: Set("pear".to_owned()),
..Default::default()
@ -44,7 +44,7 @@ pub async fn insert_and_update(db: &Database) -> Result<(), ExecErr> {
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 {
name: Set("Banana".to_owned()),
..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 {
id: Unset(None),
name: Set("Pineapple".to_owned()),

View File

@ -1,7 +1,7 @@
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?;
println!("===== =====\n");
@ -41,7 +41,7 @@ pub async fn all_about_select(db: &Database) -> Result<(), QueryErr> {
Ok(())
}
async fn find_all(db: &Database) -> Result<(), QueryErr> {
async fn find_all(db: &DatabaseConnection) -> Result<(), QueryErr> {
print!("find all cakes: ");
let cakes = Cake::find().all(db).await?;
@ -63,7 +63,7 @@ async fn find_all(db: &Database) -> Result<(), QueryErr> {
Ok(())
}
async fn find_together(db: &Database) -> Result<(), QueryErr> {
async fn find_together(db: &DatabaseConnection) -> Result<(), QueryErr> {
print!("find cakes and fruits: ");
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: ");
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(())
}
async fn count_fruits_by_cake(db: &Database) -> Result<(), QueryErr> {
async fn count_fruits_by_cake(db: &DatabaseConnection) -> Result<(), QueryErr> {
#[derive(Debug, FromQueryResult)]
struct SelectResult {
name: String,
@ -138,7 +138,7 @@ async fn count_fruits_by_cake(db: &Database) -> Result<(), QueryErr> {
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: ");
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(())
}
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?;
println!("===== =====\n");
@ -191,7 +191,7 @@ async fn all_about_select_json(db: &Database) -> Result<(), QueryErr> {
Ok(())
}
async fn find_all_json(db: &Database) -> Result<(), QueryErr> {
async fn find_all_json(db: &DatabaseConnection) -> Result<(), QueryErr> {
print!("find all cakes: ");
let cakes = Cake::find().into_json().all(db).await?;
@ -207,7 +207,7 @@ async fn find_all_json(db: &Database) -> Result<(), QueryErr> {
Ok(())
}
async fn find_together_json(db: &Database) -> Result<(), QueryErr> {
async fn find_together_json(db: &DatabaseConnection) -> Result<(), QueryErr> {
print!("find cakes and fruits: ");
let cakes_fruits = Cake::find()
@ -224,7 +224,7 @@ async fn find_together_json(db: &Database) -> Result<(), QueryErr> {
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: ");
let count = Cake::find()
@ -242,7 +242,7 @@ async fn count_fruits_by_cake_json(db: &Database) -> Result<(), QueryErr> {
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 futures::TryStreamExt;
use std::time::Duration;
@ -290,7 +290,7 @@ async fn find_all_stream(db: &Database) -> Result<(), QueryErr> {
Ok(())
}
async fn find_first_page(db: &Database) -> Result<(), QueryErr> {
async fn find_first_page(db: &DatabaseConnection) -> Result<(), QueryErr> {
println!("fruits first page: ");
let page = fruit::Entity::find().paginate(db, 2).fetch_page(0).await?;
for fruit in page {
@ -300,7 +300,7 @@ async fn find_first_page(db: &Database) -> Result<(), QueryErr> {
Ok(())
}
async fn find_num_pages(db: &Database) -> Result<(), QueryErr> {
async fn find_num_pages(db: &DatabaseConnection) -> Result<(), QueryErr> {
println!("fruits number of page: ");
let num_pages = fruit::Entity::find().paginate(db, 2).num_pages().await?;
println!("{:?}", num_pages);

View File

@ -37,11 +37,11 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
}
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
}
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
}
}

View File

@ -1,8 +1,5 @@
use crate::{ExecErr, ExecResult, QueryErr, QueryResult, Statement};
use sea_query::{
DeleteStatement, InsertStatement, MysqlQueryBuilder, PostgresQueryBuilder,
QueryStatementBuilder, SelectStatement, UpdateStatement,
};
use sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, QueryStatementBuilder};
use std::{error::Error, fmt};
pub enum DatabaseConnection {

View File

@ -1,7 +1,7 @@
use crate::{
Database, DatabaseConnection, EntityTrait, ExecErr, ExecResult, ExecResultHolder, Iden,
Iterable, MockDatabaseConnection, MockDatabaseTrait, ModelTrait, QueryErr, QueryResult,
QueryResultRow, Statement, Transaction, TypeErr,
DatabaseConnection, EntityTrait, ExecErr, ExecResult, ExecResultHolder, Iden, Iterable,
MockDatabaseConnection, MockDatabaseTrait, ModelTrait, QueryErr, QueryResult, QueryResultRow,
Statement, Transaction, TypeErr,
};
use sea_query::{Value, ValueType};
use std::collections::BTreeMap;
@ -46,12 +46,8 @@ impl MockDatabase {
Default::default()
}
pub fn into_database(self) -> Database {
Database {
connection: DatabaseConnection::MockDatabaseConnection(MockDatabaseConnection::new(
self,
)),
}
pub fn into_connection(self) -> DatabaseConnection {
DatabaseConnection::MockDatabaseConnection(MockDatabaseConnection::new(self))
}
pub fn append_exec_results(mut self, mut vec: Vec<MockExecResult>) -> Self {

View File

@ -11,30 +11,18 @@ pub use statement::*;
pub use transaction::*;
#[derive(Debug, Default)]
pub struct Database {
connection: DatabaseConnection,
}
pub struct 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")]
if crate::SqlxMySqlConnector::accepts(string) {
self.connection = crate::SqlxMySqlConnector::connect(string).await?;
return Ok(());
return Ok(crate::SqlxMySqlConnector::connect(string).await?);
}
#[cfg(feature = "mock")]
if crate::MockDatabaseConnector::accepts(string) {
self.connection = crate::MockDatabaseConnector::connect(string).await?;
return Ok(());
return Ok(crate::MockDatabaseConnector::connect(string).await?);
}
Err(ConnectionErr)
}
pub fn get_connection(&self) -> &DatabaseConnection {
&self.connection
}
pub fn get_query_builder_backend(&self) -> QueryBuilderBackend {
self.connection.get_query_builder_backend()
}
}

View File

@ -1,6 +1,6 @@
use crate::{
Database, DeleteResult, EntityTrait, ExecErr, Iterable, PrimaryKeyToColumn, PrimaryKeyTrait,
Value,
DatabaseConnection, DeleteResult, EntityTrait, ExecErr, Iterable, PrimaryKeyToColumn,
PrimaryKeyTrait, Value,
};
use std::fmt::Debug;
@ -77,8 +77,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: &Database) -> impl Future<Output = Result<Self, ExecErr>>;
// fn delete(self, db: &Database) -> impl Future<Output = Result<DeleteResult, ExecErr>>;
// fn save(self, db: &DatabaseConnection) -> impl Future<Output = Result<Self, ExecErr>>;
// fn delete(self, db: &DatabaseConnection) -> impl Future<Output = Result<DeleteResult, ExecErr>>;
}
/// Behaviors for users to override
@ -228,7 +228,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<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
A: ActiveModelBehavior + ActiveModelTrait<Entity = E>,
E::Model: IntoActiveModel<A>,
@ -252,7 +252,7 @@ where
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
A: ActiveModelTrait<Entity = E>,
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
A: ActiveModelTrait<Entity = E>,
E: EntityTrait,
@ -283,7 +283,10 @@ where
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
A: ActiveModelBehavior + ActiveModelTrait<Entity = E>,
E: EntityTrait,

View File

@ -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 std::future::Future;
@ -18,7 +20,7 @@ where
{
pub fn exec(
self,
db: &'a Database,
db: &'a DatabaseConnection,
) -> impl Future<Output = Result<DeleteResult, ExecErr>> + 'a {
// so that self is dropped before entering await
exec_delete_only(self.query, db)
@ -31,7 +33,7 @@ where
{
pub fn exec(
self,
db: &'a Database,
db: &'a DatabaseConnection,
) -> impl Future<Output = Result<DeleteResult, ExecErr>> + 'a {
// so that self is dropped before entering await
exec_delete_only(self.query, db)
@ -43,19 +45,28 @@ impl Deleter {
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();
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
}
// Only Statement impl Send
async fn exec_delete(statement: Statement, db: &Database) -> Result<DeleteResult, ExecErr> {
let result = db.get_connection().execute(statement).await?;
async fn exec_delete(
statement: Statement,
db: &DatabaseConnection,
) -> Result<DeleteResult, ExecErr> {
let result = db.execute(statement).await?;
Ok(DeleteResult {
rows_affected: result.rows_affected(),
})

View File

@ -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 std::future::Future;
@ -16,7 +16,10 @@ impl<A> Insert<A>
where
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
Inserter::new(self.into_query()).exec(db)
}
@ -27,15 +30,21 @@ impl Inserter {
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();
exec_insert(builder.build(&self.query), db)
}
}
// Only Statement impl Send
async fn exec_insert(statement: Statement, db: &Database) -> Result<InsertResult, ExecErr> {
let result = db.get_connection().execute(statement).await?;
async fn exec_insert(
statement: Statement,
db: &DatabaseConnection,
) -> Result<InsertResult, ExecErr> {
let result = db.execute(statement).await?;
// TODO: Postgres instead use query_one + returning clause
Ok(InsertResult {
last_insert_id: result.last_insert_id(),

View File

@ -1,4 +1,4 @@
use crate::{Database, QueryErr, SelectorTrait};
use crate::{DatabaseConnection, QueryErr, SelectorTrait};
use async_stream::stream;
use futures::Stream;
use sea_query::{Alias, Expr, SelectStatement};
@ -14,7 +14,7 @@ where
pub(crate) query: SelectStatement,
pub(crate) page: usize,
pub(crate) page_size: usize,
pub(crate) db: &'db Database,
pub(crate) db: &'db DatabaseConnection,
pub(crate) selector: PhantomData<S>,
}
@ -32,7 +32,7 @@ where
.to_owned();
let builder = self.db.get_query_builder_backend();
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());
for row in rows.into_iter() {
// TODO: Error handling
@ -57,7 +57,7 @@ where
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,
None => return Ok(0),
};
@ -105,11 +105,11 @@ where
mod tests {
use crate::entity::prelude::*;
use crate::tests_cfg::*;
use crate::{Database, MockDatabase, QueryErr, Transaction};
use crate::{DatabaseConnection, MockDatabase, QueryErr, Transaction};
use futures::TryStreamExt;
use sea_query::{Alias, Expr, SelectStatement, Value};
fn setup() -> (Database, Vec<Vec<fruit::Model>>) {
fn setup() -> (DatabaseConnection, Vec<Vec<fruit::Model>>) {
let page1 = vec![
fruit::Model {
id: 1,
@ -133,18 +133,18 @@ mod tests {
let db = MockDatabase::new()
.append_query_results(vec![page1.clone(), page2.clone(), page3.clone()])
.into_database();
.into_connection();
(db, vec![page1, page2, page3])
}
fn setup_num_rows() -> (Database, i32) {
fn setup_num_rows() -> (DatabaseConnection, i32) {
let num_rows = 3;
let db = MockDatabase::new()
.append_query_results(vec![vec![maplit::btreemap! {
"num_rows" => Into::<Value>::into(num_rows),
}]])
.into_database();
.into_connection();
(db, num_rows)
}
@ -175,12 +175,7 @@ mod tests {
query_builder.build(select.offset(4).limit(2)),
];
let mut mocker = db
.get_connection()
.as_mock_connection()
.get_mocker_mutex()
.lock()
.unwrap();
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
Ok(())
@ -216,12 +211,7 @@ mod tests {
query_builder.build(select.offset(4).limit(2)),
];
let mut mocker = db
.get_connection()
.as_mock_connection()
.get_mocker_mutex()
.lock()
.unwrap();
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
Ok(())
@ -254,12 +244,7 @@ mod tests {
let query_builder = db.get_query_builder_backend();
let stmts = vec![query_builder.build(&select)];
let mut mocker = db
.get_connection()
.as_mock_connection()
.get_mocker_mutex()
.lock()
.unwrap();
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
Ok(())
@ -312,12 +297,7 @@ mod tests {
query_builder.build(select.offset(4).limit(2)),
];
let mut mocker = db
.get_connection()
.as_mock_connection()
.get_mocker_mutex()
.lock()
.unwrap();
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
Ok(())
@ -351,12 +331,7 @@ mod tests {
query_builder.build(select.offset(4).limit(2)),
];
let mut mocker = db
.get_connection()
.as_mock_connection()
.get_mocker_mutex()
.lock()
.unwrap();
let mut mocker = db.as_mock_connection().get_mocker_mutex().lock().unwrap();
assert_eq!(mocker.drain_transaction_log(), Transaction::wrap(stmts));
Ok(())

View File

@ -1,6 +1,6 @@
use crate::{
query::combine, Database, EntityTrait, FromQueryResult, JsonValue, Paginator, QueryErr,
QueryResult, Select, SelectTwo, TypeErr,
query::combine, DatabaseConnection, EntityTrait, FromQueryResult, JsonValue, Paginator,
QueryErr, QueryResult, Select, SelectTwo, TypeErr,
};
use sea_query::SelectStatement;
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
}
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
}
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)
}
}
@ -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
}
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
}
}
@ -134,25 +141,19 @@ impl<S> Selector<S>
where
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();
self.query.limit(1);
let row = db
.get_connection()
.query_one(builder.build(&self.query))
.await?;
let row = db.query_one(builder.build(&self.query)).await?;
match row {
Some(row) => Ok(Some(S::from_raw_query_result(row)?)),
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 rows = db
.get_connection()
.query_all(builder.build(&self.query))
.await?;
let rows = db.query_all(builder.build(&self.query)).await?;
let mut models = Vec::new();
for row in rows.into_iter() {
models.push(S::from_raw_query_result(row)?);
@ -160,7 +161,7 @@ where
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 {
query: self.query,
page: 0,

View File

@ -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 std::future::Future;
@ -16,7 +18,7 @@ impl<'a, A: 'a> UpdateOne<A>
where
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
exec_update_and_return_original(self.query, self.model, db)
}
@ -28,7 +30,7 @@ where
{
pub fn exec(
self,
db: &'a Database,
db: &'a DatabaseConnection,
) -> impl Future<Output = Result<UpdateResult, ExecErr>> + 'a {
// so that self is dropped before entering await
exec_update_only(self.query, db)
@ -40,20 +42,26 @@ impl Updater {
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();
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
}
async fn exec_update_and_return_original<A>(
query: UpdateStatement,
model: A,
db: &Database,
db: &DatabaseConnection,
) -> Result<A, ExecErr>
where
A: ActiveModelTrait,
@ -63,8 +71,11 @@ where
}
// Only Statement impl Send
async fn exec_update(statement: Statement, db: &Database) -> Result<UpdateResult, ExecErr> {
let result = db.get_connection().execute(statement).await?;
async fn exec_update(
statement: Statement,
db: &DatabaseConnection,
) -> Result<UpdateResult, ExecErr> {
let result = db.execute(statement).await?;
Ok(UpdateResult {
rows_affected: result.rows_affected(),
})

View File

@ -73,7 +73,7 @@ mod tests {
.append_query_results(vec![vec![maplit::btreemap! {
"id" => Into::<Value>::into(128), "name" => Into::<Value>::into("apple")
}]])
.into_database();
.into_connection();
assert_eq!(
cake::Entity::find().into_json().one(&db).await.unwrap(),