WIP strange fail with postgres driver

This commit is contained in:
Sam Samai 2021-08-01 15:53:28 +10:00
parent 1c3e1b410b
commit abed934d3f
10 changed files with 165 additions and 99 deletions

View File

@ -39,7 +39,7 @@ impl std::fmt::Debug for DatabaseConnection {
#[cfg(feature = "sqlx-mysql")] #[cfg(feature = "sqlx-mysql")]
Self::SqlxMySqlPoolConnection(_) => "SqlxMySqlPoolConnection", Self::SqlxMySqlPoolConnection(_) => "SqlxMySqlPoolConnection",
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
Self::SqlxPostgresPoolConnection(_) => "SqlxMySqlPoolConnection", Self::SqlxPostgresPoolConnection(_) => "SqlxPostgresPoolConnection",
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
Self::SqlxSqlitePoolConnection(_) => "SqlxSqlitePoolConnection", Self::SqlxSqlitePoolConnection(_) => "SqlxSqlitePoolConnection",
#[cfg(feature = "mock")] #[cfg(feature = "mock")]

View File

@ -27,10 +27,10 @@ async fn create_entities(db: &DatabaseConnection) {
crud::create_lineitem::test_create_lineitem(db).await; crud::create_lineitem::test_create_lineitem(db).await;
crud::create_order::test_create_order(db).await; crud::create_order::test_create_order(db).await;
crud::updates::test_update_cake(db).await; // crud::updates::test_update_cake(db).await;
crud::updates::test_update_bakery(db).await; // crud::updates::test_update_bakery(db).await;
crud::updates::test_update_deleted_customer(db).await; // crud::updates::test_update_deleted_customer(db).await;
crud::deletes::test_delete_cake(db).await; // crud::deletes::test_delete_cake(db).await;
crud::deletes::test_delete_bakery(db).await; // crud::deletes::test_delete_bakery(db).await;
} }

View File

@ -15,8 +15,8 @@ pub struct Model {
pub id: i32, pub id: i32,
pub price: Decimal, pub price: Decimal,
pub quantity: i32, pub quantity: i32,
pub order_id: Option<i32>, pub order_id: i32,
pub cake_id: Option<i32>, pub cake_id: i32,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
@ -51,7 +51,7 @@ impl ColumnTrait for Column {
fn def(&self) -> ColumnDef { fn def(&self) -> ColumnDef {
match self { match self {
Self::Id => ColumnType::Integer.def(), Self::Id => ColumnType::Integer.def(),
Self::Price => ColumnType::Money(Some((19, 4))).def(), Self::Price => ColumnType::Decimal(Some((19, 4))).def(),
Self::Quantity => ColumnType::Integer.def(), Self::Quantity => ColumnType::Integer.def(),
Self::OrderId => ColumnType::Integer.def(), Self::OrderId => ColumnType::Integer.def(),
Self::CakeId => ColumnType::Integer.def(), Self::CakeId => ColumnType::Integer.def(),

View File

@ -15,8 +15,8 @@ impl EntityName for Entity {
pub struct Model { pub struct Model {
pub id: i32, pub id: i32,
pub total: Decimal, pub total: Decimal,
pub bakery_id: Option<i32>, pub bakery_id: i32,
pub customer_id: Option<i32>, pub customer_id: i32,
pub placed_at: NaiveDateTime, pub placed_at: NaiveDateTime,
} }

View File

@ -3,6 +3,9 @@ pub mod schema;
pub use schema::*; pub use schema::*;
pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection { pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {
let db = if cfg!(feature = "sqlx-mysql") {
println!("sqlx-mysql");
let url = format!("{}/mysql", base_url); let url = format!("{}/mysql", base_url);
let db = Database::connect(&url).await.unwrap(); let db = Database::connect(&url).await.unwrap();
let _drop_db_result = db let _drop_db_result = db
@ -20,7 +23,37 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {
.await; .await;
let url = format!("{}/{}", base_url, db_name); let url = format!("{}/{}", base_url, db_name);
Database::connect(&url).await.unwrap()
} else if cfg!(feature = "sqlx-postgres") {
println!("sqlx-postgres");
let url = format!("{}/postgres", base_url);
println!("url: {:#?}", url);
let db = Database::connect(&url).await.unwrap(); let db = Database::connect(&url).await.unwrap();
println!("db: {:#?}", db);
let _drop_db_result = db
.execute(Statement::from_string(
DatabaseBackend::Postgres,
format!("DROP DATABASE IF EXISTS \"{}\";", db_name),
))
.await;
let _create_db_result = db
.execute(Statement::from_string(
DatabaseBackend::Postgres,
format!("CREATE DATABASE \"{}\";", db_name),
))
.await;
let url = format!("{}/{}", base_url, db_name);
println!("url: {:#?}", url);
Database::connect(&url).await.unwrap()
} else {
println!("sqlx-sqlite");
Database::connect("sqlite::memory:").await.unwrap()
};
assert!(schema::create_bakery_table(&db).await.is_ok()); assert!(schema::create_bakery_table(&db).await.is_ok());
assert!(schema::create_baker_table(&db).await.is_ok()); assert!(schema::create_baker_table(&db).await.is_ok());
@ -33,12 +66,30 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {
} }
pub async fn tear_down(base_url: &str, db_name: &str) { pub async fn tear_down(base_url: &str, db_name: &str) {
if cfg!(feature = "sqlx-mysql") {
println!("sqlx-mysql");
let url = format!("{}/mysql", base_url); let url = format!("{}/mysql", base_url);
let db = Database::connect(&url).await.unwrap(); let db = Database::connect(&url).await.unwrap();
let _drop_db_result = db let _ = db
.execute(Statement::from_string( .execute(Statement::from_string(
DatabaseBackend::MySql, DatabaseBackend::MySql,
format!("DROP DATABASE IF EXISTS `{}`;", db_name), format!("DROP DATABASE IF EXISTS \"{}\";", db_name),
)) ))
.await; .await;
} else if cfg!(feature = "sqlx-postgres") {
println!("sqlx-postgres");
let url = format!("{}/postgres", base_url);
println!("url: {:#?}", url);
let db = Database::connect(&url).await.unwrap();
let _ = db
.execute(Statement::from_string(
DatabaseBackend::Postgres,
format!("DROP DATABASE IF EXISTS \"{}\";", db_name),
))
.await;
} else {
println!("sqlx-sqlite");
};
} }

View File

@ -70,8 +70,8 @@ pub async fn test_create_lineitem(db: &DbConn) {
// Order // Order
let order_1 = order::ActiveModel { let order_1 = order::ActiveModel {
bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)), bakery_id: Set(bakery_insert_res.last_insert_id as i32),
customer_id: Set(Some(customer_insert_res.last_insert_id as i32)), customer_id: Set(customer_insert_res.last_insert_id as i32),
total: Set(dec!(7.55)), total: Set(dec!(7.55)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
..Default::default() ..Default::default()
@ -83,8 +83,8 @@ pub async fn test_create_lineitem(db: &DbConn) {
// Lineitem // Lineitem
let lineitem_1 = lineitem::ActiveModel { let lineitem_1 = lineitem::ActiveModel {
cake_id: Set(Some(cake_insert_res.last_insert_id as i32)), cake_id: Set(cake_insert_res.last_insert_id as i32),
order_id: Set(Some(order_insert_res.last_insert_id as i32)), order_id: Set(order_insert_res.last_insert_id as i32),
price: Set(dec!(7.55)), price: Set(dec!(7.55)),
quantity: Set(1), quantity: Set(1),
..Default::default() ..Default::default()
@ -102,9 +102,10 @@ pub async fn test_create_lineitem(db: &DbConn) {
assert!(lineitem.is_some()); assert!(lineitem.is_some());
let lineitem_model = lineitem.unwrap(); let lineitem_model = lineitem.unwrap();
assert_eq!(lineitem_model.price, dec!(7.55)); assert_eq!(lineitem_model.price, dec!(7.55));
let cake: Option<cake::Model> = Cake::find_by_id(lineitem_model.cake_id) let cake: Option<cake::Model> = Cake::find_by_id(lineitem_model.cake_id as u64)
.one(db) .one(db)
.await .await
.expect("could not find cake"); .expect("could not find cake");
@ -119,7 +120,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
let order_model = order.unwrap(); let order_model = order.unwrap();
assert_eq!( assert_eq!(
order_model.customer_id.unwrap(), order_model.customer_id,
customer_insert_res.last_insert_id as i32 customer_insert_res.last_insert_id as i32
); );
} }

View File

@ -70,8 +70,8 @@ pub async fn test_create_order(db: &DbConn) {
// Order // Order
let order_1 = order::ActiveModel { let order_1 = order::ActiveModel {
bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)), bakery_id: Set(bakery_insert_res.last_insert_id as i32),
customer_id: Set(Some(customer_insert_res.last_insert_id as i32)), customer_id: Set(customer_insert_res.last_insert_id as i32),
total: Set(dec!(15.10)), total: Set(dec!(15.10)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
..Default::default() ..Default::default()
@ -81,10 +81,12 @@ pub async fn test_create_order(db: &DbConn) {
.await .await
.expect("could not insert order"); .expect("could not insert order");
println!("order_insert_res: {:#?}", order_insert_res);
// Lineitem // Lineitem
let lineitem_1 = lineitem::ActiveModel { let lineitem_1 = lineitem::ActiveModel {
cake_id: Set(Some(cake_insert_res.last_insert_id as i32)), cake_id: Set(cake_insert_res.last_insert_id as i32),
order_id: Set(Some(order_insert_res.last_insert_id as i32)), order_id: Set(order_insert_res.last_insert_id as i32),
price: Set(dec!(7.55)), price: Set(dec!(7.55)),
quantity: Set(2), quantity: Set(2),
..Default::default() ..Default::default()
@ -94,37 +96,48 @@ pub async fn test_create_order(db: &DbConn) {
.await .await
.expect("could not insert lineitem"); .expect("could not insert lineitem");
// This fails with "error returned from database: incorrect binary data format in bind parameter 1"
let order: Option<order::Model> = Order::find_by_id(order_insert_res.last_insert_id) let order: Option<order::Model> = Order::find_by_id(order_insert_res.last_insert_id)
.one(db) .one(db)
.await .await
.expect("could not find order"); .expect("could not find order");
assert!(order.is_some()); // this is ok
let order_model = order.unwrap(); let orders: Vec<order::Model> = Order::find_by_id(order_insert_res.last_insert_id)
assert_eq!(order_model.total, dec!(15.10));
let customer: Option<customer::Model> = Customer::find_by_id(order_model.customer_id)
.one(db)
.await
.expect("could not find customer");
let customer_model = customer.unwrap();
assert_eq!(customer_model.name, "Kate");
let bakery: Option<bakery::Model> = Bakery::find_by_id(order_model.bakery_id)
.one(db)
.await
.expect("could not find bakery");
let bakery_model = bakery.unwrap();
assert_eq!(bakery_model.name, "SeaSide Bakery");
let related_lineitems: Vec<lineitem::Model> = order_model
.find_related(Lineitem)
.all(db) .all(db)
.await .await
.expect("could not find related lineitems"); .unwrap();
assert_eq!(related_lineitems.len(), 1); println!("order: {:#?}", orders);
assert_eq!(related_lineitems[0].price, dec!(7.55)); let order: order::Model = orders[0].clone();
assert_eq!(related_lineitems[0].quantity, 2); println!("order: {:#?}", order);
assert_eq!(1, 2);
// assert!(order.is_some());
// let order_model = order.unwrap();
// assert_eq!(order_model.total, dec!(15.10));
// let customer: Option<customer::Model> = Customer::find_by_id(order_model.customer_id)
// .one(db)
// .await
// .expect("could not find customer");
// let customer_model = customer.unwrap();
// assert_eq!(customer_model.name, "Kate");
// let bakery: Option<bakery::Model> = Bakery::find_by_id(order_model.bakery_id)
// .one(db)
// .await
// .expect("could not find bakery");
// let bakery_model = bakery.unwrap();
// assert_eq!(bakery_model.name, "SeaSide Bakery");
// let related_lineitems: Vec<lineitem::Model> = order_model
// .find_related(Lineitem)
// .all(db)
// .await
// .expect("could not find related lineitems");
// assert_eq!(related_lineitems.len(), 1);
// assert_eq!(related_lineitems[0].price, dec!(7.55));
// assert_eq!(related_lineitems[0].quantity, 2);
} }

View File

@ -12,6 +12,7 @@ use sea_query::{ColumnDef, TableCreateStatement};
#[cfg_attr(feature = "runtime-async-std", async_std::test)] #[cfg_attr(feature = "runtime-async-std", async_std::test)]
#[cfg_attr(feature = "runtime-actix", actix_rt::test)] #[cfg_attr(feature = "runtime-actix", actix_rt::test)]
#[cfg_attr(feature = "runtime-tokio", tokio::test)] #[cfg_attr(feature = "runtime-tokio", tokio::test)]
#[async_std::test]
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
async fn main() { async fn main() {
let base_url = "postgres://root:root@localhost"; let base_url = "postgres://root:root@localhost";

View File

@ -124,8 +124,8 @@ pub async fn right_join() {
.expect("could not insert customer"); .expect("could not insert customer");
let _order = order::ActiveModel { let _order = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_kate.id.clone().unwrap())), customer_id: Set(customer_kate.id.clone().unwrap()),
total: Set(dec!(15.10)), total: Set(dec!(15.10)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -209,8 +209,8 @@ pub async fn inner_join() {
.expect("could not insert customer"); .expect("could not insert customer");
let kate_order_1 = order::ActiveModel { let kate_order_1 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_kate.id.clone().unwrap())), customer_id: Set(customer_kate.id.clone().unwrap()),
total: Set(dec!(15.10)), total: Set(dec!(15.10)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -221,8 +221,8 @@ pub async fn inner_join() {
.expect("could not insert order"); .expect("could not insert order");
let kate_order_2 = order::ActiveModel { let kate_order_2 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_kate.id.clone().unwrap())), customer_id: Set(customer_kate.id.clone().unwrap()),
total: Set(dec!(100.00)), total: Set(dec!(100.00)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -290,8 +290,8 @@ pub async fn group_by() {
.expect("could not insert customer"); .expect("could not insert customer");
let kate_order_1 = order::ActiveModel { let kate_order_1 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_kate.id.clone().unwrap())), customer_id: Set(customer_kate.id.clone().unwrap()),
total: Set(dec!(99.95)), total: Set(dec!(99.95)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -302,8 +302,8 @@ pub async fn group_by() {
.expect("could not insert order"); .expect("could not insert order");
let kate_order_2 = order::ActiveModel { let kate_order_2 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_kate.id.clone().unwrap())), customer_id: Set(customer_kate.id.clone().unwrap()),
total: Set(dec!(200.00)), total: Set(dec!(200.00)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -395,8 +395,8 @@ pub async fn having() {
.expect("could not insert customer"); .expect("could not insert customer");
let kate_order_1 = order::ActiveModel { let kate_order_1 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_kate.id.clone().unwrap())), customer_id: Set(customer_kate.id.clone().unwrap()),
total: Set(dec!(100.00)), total: Set(dec!(100.00)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -407,8 +407,8 @@ pub async fn having() {
.expect("could not insert order"); .expect("could not insert order");
let _kate_order_2 = order::ActiveModel { let _kate_order_2 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_kate.id.clone().unwrap())), customer_id: Set(customer_kate.id.clone().unwrap()),
total: Set(dec!(12.00)), total: Set(dec!(12.00)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -427,8 +427,8 @@ pub async fn having() {
.expect("could not insert customer"); .expect("could not insert customer");
let _bob_order_1 = order::ActiveModel { let _bob_order_1 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_bob.id.clone().unwrap())), customer_id: Set(customer_bob.id.clone().unwrap()),
total: Set(dec!(50.0)), total: Set(dec!(50.0)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -439,8 +439,8 @@ pub async fn having() {
.expect("could not insert order"); .expect("could not insert order");
let _bob_order_2 = order::ActiveModel { let _bob_order_2 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_bob.id.clone().unwrap())), customer_id: Set(customer_bob.id.clone().unwrap()),
total: Set(dec!(50.0)), total: Set(dec!(50.0)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),

View File

@ -95,8 +95,8 @@ async fn init_setup(db: &DatabaseConnection) {
.expect("could not insert customer"); .expect("could not insert customer");
let kate_order_1 = order::ActiveModel { let kate_order_1 = order::ActiveModel {
bakery_id: Set(Some(bakery.id.clone().unwrap())), bakery_id: Set(bakery.id.clone().unwrap()),
customer_id: Set(Some(customer_kate.id.clone().unwrap())), customer_id: Set(customer_kate.id.clone().unwrap()),
total: Set(dec!(99.95)), total: Set(dec!(99.95)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -107,10 +107,10 @@ async fn init_setup(db: &DatabaseConnection) {
.expect("could not insert order"); .expect("could not insert order");
let _lineitem = lineitem::ActiveModel { let _lineitem = lineitem::ActiveModel {
cake_id: Set(Some(cake_insert_res.last_insert_id as i32)), cake_id: Set(cake_insert_res.last_insert_id as i32),
price: Set(dec!(10.00)), price: Set(dec!(10.00)),
quantity: Set(12), quantity: Set(12),
order_id: Set(Some(kate_order_1.id.clone().unwrap())), order_id: Set(kate_order_1.id.clone().unwrap()),
..Default::default() ..Default::default()
} }
.save(db) .save(db)
@ -118,10 +118,10 @@ async fn init_setup(db: &DatabaseConnection) {
.expect("could not insert order"); .expect("could not insert order");
let _lineitem2 = lineitem::ActiveModel { let _lineitem2 = lineitem::ActiveModel {
cake_id: Set(Some(cake_insert_res.last_insert_id as i32)), cake_id: Set(cake_insert_res.last_insert_id as i32),
price: Set(dec!(50.00)), price: Set(dec!(50.00)),
quantity: Set(2), quantity: Set(2),
order_id: Set(Some(kate_order_1.id.clone().unwrap())), order_id: Set(kate_order_1.id.clone().unwrap()),
..Default::default() ..Default::default()
} }
.save(db) .save(db)
@ -228,8 +228,8 @@ async fn create_order(db: &DatabaseConnection, cake: cake::Model) {
.expect("could not insert customer"); .expect("could not insert customer");
let order = order::ActiveModel { let order = order::ActiveModel {
bakery_id: Set(Some(cake.bakery_id.unwrap())), bakery_id: Set(cake.bakery_id.unwrap()),
customer_id: Set(Some(another_customer.id.clone().unwrap())), customer_id: Set(another_customer.id.clone().unwrap()),
total: Set(dec!(200.00)), total: Set(dec!(200.00)),
placed_at: Set(Utc::now().naive_utc()), placed_at: Set(Utc::now().naive_utc()),
@ -240,10 +240,10 @@ async fn create_order(db: &DatabaseConnection, cake: cake::Model) {
.expect("could not insert order"); .expect("could not insert order");
let _lineitem = lineitem::ActiveModel { let _lineitem = lineitem::ActiveModel {
cake_id: Set(Some(cake.id)), cake_id: Set(cake.id),
price: Set(dec!(10.00)), price: Set(dec!(10.00)),
quantity: Set(300), quantity: Set(300),
order_id: Set(Some(order.id.clone().unwrap())), order_id: Set(order.id.clone().unwrap()),
..Default::default() ..Default::default()
} }
.save(db) .save(db)