Merge branch 'master' into transaction-3

This commit is contained in:
Chris Tsang 2021-10-12 14:24:35 +08:00
commit 7bc6477091
33 changed files with 151 additions and 89 deletions

View File

@ -177,7 +177,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest] os: [ubuntu-latest]
path: [async-std, tokio, actix_example, actix4_example, rocket_example] path: [basic, actix_example, actix4_example, rocket_example]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -193,6 +193,28 @@ jobs:
args: > args: >
--manifest-path examples/${{ matrix.path }}/Cargo.toml --manifest-path examples/${{ matrix.path }}/Cargo.toml
issues:
name: Issues
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
path: [86]
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: build
args: >
--manifest-path issues/${{ matrix.path }}/Cargo.toml
sqlite: sqlite:
name: SQLite name: SQLite
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04

View File

@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## 0.2.6 - 2021-10-09
- [[#224]] [sea-orm-cli] Date & Time column type mapping
- Escape rust keywords with `r#` raw identifier
[#224]: https://github.com/SeaQL/sea-orm/pull/224
## 0.2.5 - 2021-10-06 ## 0.2.5 - 2021-10-06
- [[#227]] Resolve "Inserting actual none value of Option<Date> results in panic" - [[#227]] Resolve "Inserting actual none value of Option<Date> results in panic"

View File

@ -3,7 +3,7 @@ members = [".", "sea-orm-macros", "sea-orm-codegen"]
[package] [package]
name = "sea-orm" name = "sea-orm"
version = "0.2.5" version = "0.2.6"
authors = ["Chris Tsang <tyt2y7@gmail.com>"] authors = ["Chris Tsang <tyt2y7@gmail.com>"]
edition = "2018" edition = "2018"
description = "🐚 An async & dynamic ORM for Rust" description = "🐚 An async & dynamic ORM for Rust"
@ -29,8 +29,8 @@ futures = { version = "^0.3" }
futures-util = { version = "^0.3" } futures-util = { version = "^0.3" }
log = { version = "^0.4", optional = true } log = { version = "^0.4", optional = true }
rust_decimal = { version = "^1", optional = true } rust_decimal = { version = "^1", optional = true }
sea-orm-macros = { version = "^0.2.5", path = "sea-orm-macros", optional = true } sea-orm-macros = { version = "^0.2.6", path = "sea-orm-macros", optional = true }
sea-query = { version = "^0.17.0", features = ["thread-safe"] } sea-query = { version = "^0.17.1", features = ["thread-safe"] }
sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] } sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
serde = { version = "^1.0", features = ["derive"] } serde = { version = "^1.0", features = ["derive"] }
serde_json = { version = "^1", optional = true } serde_json = { version = "^1", optional = true }

View File

@ -21,7 +21,7 @@
SeaORM is a relational ORM to help you build light weight and concurrent web services in Rust. SeaORM is a relational ORM to help you build light weight and concurrent web services in Rust.
[![Getting Started](https://img.shields.io/badge/Getting%20Started-brightgreen)](https://www.sea-ql.org/SeaORM/docs/index) [![Getting Started](https://img.shields.io/badge/Getting%20Started-brightgreen)](https://www.sea-ql.org/SeaORM/docs/index)
[![Usage Example](https://img.shields.io/badge/Usage%20Example-yellow)](https://github.com/SeaQL/sea-orm/tree/master/examples/async-std) [![Usage Example](https://img.shields.io/badge/Usage%20Example-yellow)](https://github.com/SeaQL/sea-orm/tree/master/examples/basic)
[![Actix Example](https://img.shields.io/badge/Actix%20Example-blue)](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example) [![Actix Example](https://img.shields.io/badge/Actix%20Example-blue)](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)
[![Rocket Example](https://img.shields.io/badge/Rocket%20Example-orange)](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example) [![Rocket Example](https://img.shields.io/badge/Rocket%20Example-orange)](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example)
[![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv) [![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv)

View File

@ -3,7 +3,7 @@
[package] [package]
name = "sea-orm-cli" name = "sea-orm-cli"
version = "0.2.5" version = "0.2.6"
authors = [ "Billy Chan <ccw.billy.123@gmail.com>" ] authors = [ "Billy Chan <ccw.billy.123@gmail.com>" ]
edition = "2018" edition = "2018"
description = "Command line utility for SeaORM" description = "Command line utility for SeaORM"
@ -21,7 +21,7 @@ path = "src/main.rs"
clap = { version = "^2.33.3" } clap = { version = "^2.33.3" }
dotenv = { version = "^0.15" } dotenv = { version = "^0.15" }
async-std = { version = "^1.9", features = [ "attributes" ] } async-std = { version = "^1.9", features = [ "attributes" ] }
sea-orm-codegen = { version = "^0.2.5", path = "../sea-orm-codegen" } sea-orm-codegen = { version = "^0.2.6", path = "../sea-orm-codegen" }
sea-schema = { version = "^0.2.9", default-features = false, features = [ sea-schema = { version = "^0.2.9", default-features = false, features = [
"debug-print", "debug-print",
"sqlx-mysql", "sqlx-mysql",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "sea-orm-codegen" name = "sea-orm-codegen"
version = "0.2.5" version = "0.2.6"
authors = ["Billy Chan <ccw.billy.123@gmail.com>"] authors = ["Billy Chan <ccw.billy.123@gmail.com>"]
edition = "2018" edition = "2018"
description = "Code Generator for SeaORM" description = "Code Generator for SeaORM"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "sea-orm-macros" name = "sea-orm-macros"
version = "0.2.5" version = "0.2.6"
authors = [ "Billy Chan <ccw.billy.123@gmail.com>" ] authors = [ "Billy Chan <ccw.billy.123@gmail.com>" ]
edition = "2018" edition = "2018"
description = "Derive macros for SeaORM" description = "Derive macros for SeaORM"

View File

@ -1,7 +1,7 @@
use std::{future::Future, pin::Pin}; use std::{future::Future, pin::Pin};
use sqlx::{ use sqlx::{
sqlite::{SqliteArguments, SqliteQueryResult, SqliteRow}, sqlite::{SqliteArguments, SqlitePoolOptions, SqliteQueryResult, SqliteRow},
Sqlite, SqlitePool, Sqlite, SqlitePool,
}; };
@ -29,7 +29,11 @@ impl SqlxSqliteConnector {
} }
pub async fn connect(string: &str) -> Result<DatabaseConnection, DbErr> { pub async fn connect(string: &str) -> Result<DatabaseConnection, DbErr> {
if let Ok(pool) = SqlitePool::connect(string).await { if let Ok(pool) = SqlitePoolOptions::new()
.max_connections(1)
.connect(string)
.await
{
Ok(DatabaseConnection::SqlxSqlitePoolConnection( Ok(DatabaseConnection::SqlxSqlitePoolConnection(
SqlxSqlitePoolConnection { pool }, SqlxSqlitePoolConnection { pool },
)) ))

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
error::*, ConnectionTrait, DeleteResult, EntityTrait, Iterable, PrimaryKeyToColumn, error::*, ConnectionTrait, DeleteResult, EntityTrait, Iterable, PrimaryKeyToColumn, Value,
PrimaryKeyTrait, Value,
}; };
use async_trait::async_trait; use async_trait::async_trait;
use sea_query::ValueTuple;
use std::fmt::Debug; use std::fmt::Debug;
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
@ -10,7 +10,8 @@ pub struct ActiveValue<V>
where where
V: Into<Value>, V: Into<Value>,
{ {
value: Option<V>, // Don't want to call ActiveValue::unwrap() and cause panic
pub(self) value: Option<V>,
state: ActiveValueState, state: ActiveValueState,
} }
@ -67,6 +68,42 @@ pub trait ActiveModelTrait: Clone + Debug {
fn default() -> Self; fn default() -> Self;
#[allow(clippy::question_mark)]
fn get_primary_key_value(&self) -> Option<ValueTuple> {
let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();
macro_rules! next {
() => {
if let Some(col) = cols.next() {
if let Some(val) = self.get(col.into_column()).value {
val
} else {
return None;
}
} else {
return None;
}
};
}
match <Self::Entity as EntityTrait>::PrimaryKey::iter().count() {
1 => {
let s1 = next!();
Some(ValueTuple::One(s1))
}
2 => {
let s1 = next!();
let s2 = next!();
Some(ValueTuple::Two(s1, s2))
}
3 => {
let s1 = next!();
let s2 = next!();
let s3 = next!();
Some(ValueTuple::Three(s1, s2, s3))
}
_ => panic!("The arity cannot be larger than 3"),
}
}
async fn insert<'a, C>(self, db: &'a C) -> Result<Self, DbErr> async fn insert<'a, C>(self, db: &'a C) -> Result<Self, DbErr>
where where
<Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>, <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
@ -76,19 +113,12 @@ pub trait ActiveModelTrait: Clone + Debug {
let am = self; let am = self;
let exec = <Self::Entity as EntityTrait>::insert(am).exec(db); let exec = <Self::Entity as EntityTrait>::insert(am).exec(db);
let res = exec.await?; let res = exec.await?;
// Assume valid last_insert_id is not equals to Default::default() let found = <Self::Entity as EntityTrait>::find_by_id(res.last_insert_id)
if res.last_insert_id .one(db)
!= <<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType::default() .await?;
{ match found {
let found = <Self::Entity as EntityTrait>::find_by_id(res.last_insert_id) Some(model) => Ok(model.into_active_model()),
.one(db) None => Err(DbErr::Exec("Failed to find inserted item".to_owned())),
.await?;
match found {
Some(model) => Ok(model.into_active_model()),
None => Err(DbErr::Exec("Failed to find inserted item".to_owned())),
}
} else {
Ok(Self::default())
} }
} }
@ -217,23 +247,23 @@ where
matches!(self.state, ActiveValueState::Unset) matches!(self.state, ActiveValueState::Unset)
} }
pub fn take(&mut self) -> V { pub fn take(&mut self) -> Option<V> {
self.state = ActiveValueState::Unset; self.state = ActiveValueState::Unset;
self.value.take().unwrap() self.value.take()
} }
pub fn unwrap(self) -> V { pub fn unwrap(self) -> V {
self.value.unwrap() self.value.unwrap()
} }
pub fn into_value(self) -> Value { pub fn into_value(self) -> Option<Value> {
self.value.unwrap().into() self.value.map(Into::into)
} }
pub fn into_wrapped_value(self) -> ActiveValue<Value> { pub fn into_wrapped_value(self) -> ActiveValue<Value> {
match self.state { match self.state {
ActiveValueState::Set => ActiveValue::set(self.into_value()), ActiveValueState::Set => ActiveValue::set(self.into_value().unwrap()),
ActiveValueState::Unchanged => ActiveValue::unchanged(self.into_value()), ActiveValueState::Unchanged => ActiveValue::unchanged(self.into_value().unwrap()),
ActiveValueState::Unset => ActiveValue::unset(), ActiveValueState::Unset => ActiveValue::unset(),
} }
} }

View File

@ -1,16 +1,16 @@
use super::{ColumnTrait, IdenStatic, Iterable}; use super::{ColumnTrait, IdenStatic, Iterable};
use crate::{TryFromU64, TryGetableMany}; use crate::{TryFromU64, TryGetableMany};
use sea_query::IntoValueTuple; use sea_query::{FromValueTuple, IntoValueTuple};
use std::fmt::Debug; use std::fmt::Debug;
//LINT: composite primary key cannot auto increment //LINT: composite primary key cannot auto increment
pub trait PrimaryKeyTrait: IdenStatic + Iterable { pub trait PrimaryKeyTrait: IdenStatic + Iterable {
type ValueType: Sized type ValueType: Sized
+ Send + Send
+ Default
+ Debug + Debug
+ PartialEq + PartialEq
+ IntoValueTuple + IntoValueTuple
+ FromValueTuple
+ TryGetableMany + TryGetableMany
+ TryFromU64; + TryFromU64;

View File

@ -2,14 +2,15 @@ use crate::{
error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, PrimaryKeyTrait, error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, PrimaryKeyTrait,
Statement, TryFromU64, Statement, TryFromU64,
}; };
use sea_query::InsertStatement; use sea_query::{FromValueTuple, InsertStatement, ValueTuple};
use std::marker::PhantomData; use std::{future::Future, marker::PhantomData};
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct Inserter<A> pub struct Inserter<A>
where where
A: ActiveModelTrait, A: ActiveModelTrait,
{ {
primary_key: Option<ValueTuple>,
query: InsertStatement, query: InsertStatement,
model: PhantomData<A>, model: PhantomData<A>,
} }
@ -27,12 +28,14 @@ where
A: ActiveModelTrait, A: ActiveModelTrait,
{ {
#[allow(unused_mut)] #[allow(unused_mut)]
pub async fn exec<'a, C>(self, db: &'a C) -> Result<InsertResult<A>, DbErr> pub fn exec<'a, C>(
self,
db: &'a C,
) -> impl Future<Output = Result<InsertResult<A>, DbErr>> + 'a
where where
C: ConnectionTrait<'a>, C: ConnectionTrait<'a>,
A: 'a, A: 'a,
{ {
// TODO: extract primary key's value from query
// so that self is dropped before entering await // so that self is dropped before entering await
let mut query = self.query; let mut query = self.query;
if db.get_database_backend() == DbBackend::Postgres { if db.get_database_backend() == DbBackend::Postgres {
@ -45,8 +48,7 @@ where
); );
} }
} }
Inserter::<A>::new(query).exec(db).await Inserter::<A>::new(self.primary_key, query).exec(db)
// TODO: return primary key if extracted before, otherwise use InsertResult
} }
} }
@ -54,46 +56,59 @@ impl<A> Inserter<A>
where where
A: ActiveModelTrait, A: ActiveModelTrait,
{ {
pub fn new(query: InsertStatement) -> Self { pub fn new(primary_key: Option<ValueTuple>, query: InsertStatement) -> Self {
Self { Self {
primary_key,
query, query,
model: PhantomData, model: PhantomData,
} }
} }
pub async fn exec<'a, C>(self, db: &'a C) -> Result<InsertResult<A>, DbErr> pub fn exec<'a, C>(
self,
db: &'a C,
) -> impl Future<Output = Result<InsertResult<A>, DbErr>> + 'a
where where
C: ConnectionTrait<'a>, C: ConnectionTrait<'a>,
A: 'a, A: 'a,
{ {
let builder = db.get_database_backend(); let builder = db.get_database_backend();
exec_insert(builder.build(&self.query), db).await exec_insert(self.primary_key, builder.build(&self.query), db)
} }
} }
// Only Statement impl Send // Only Statement impl Send
async fn exec_insert<'a, A, C>(statement: Statement, db: &C) -> Result<InsertResult<A>, DbErr> async fn exec_insert<'a, A, C>(
primary_key: Option<ValueTuple>,
statement: Statement,
db: &'a C,
) -> Result<InsertResult<A>, DbErr>
where where
C: ConnectionTrait<'a>, C: ConnectionTrait<'a>,
A: ActiveModelTrait, A: ActiveModelTrait,
{ {
type PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey; type PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey;
type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType; type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;
let last_insert_id = match db.get_database_backend() { let last_insert_id_opt = match db.get_database_backend() {
DbBackend::Postgres => { DbBackend::Postgres => {
use crate::{sea_query::Iden, Iterable}; use crate::{sea_query::Iden, Iterable};
let cols = PrimaryKey::<A>::iter() let cols = PrimaryKey::<A>::iter()
.map(|col| col.to_string()) .map(|col| col.to_string())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let res = db.query_one(statement).await?.unwrap(); let res = db.query_one(statement).await?.unwrap();
res.try_get_many("", cols.as_ref()).unwrap_or_default() res.try_get_many("", cols.as_ref()).ok()
} }
_ => { _ => {
let last_insert_id = db.execute(statement).await?.last_insert_id(); let last_insert_id = db.execute(statement).await?.last_insert_id();
ValueTypeOf::<A>::try_from_u64(last_insert_id) ValueTypeOf::<A>::try_from_u64(last_insert_id).ok()
.ok()
.unwrap_or_default()
} }
}; };
let last_insert_id = match last_insert_id_opt {
Some(last_insert_id) => last_insert_id,
None => match primary_key {
Some(value_tuple) => FromValueTuple::from_value_tuple(value_tuple),
None => return Err(DbErr::Exec("Fail to unpack last_insert_id".to_owned())),
},
};
Ok(InsertResult { last_insert_id }) Ok(InsertResult { last_insert_id })
} }

View File

@ -28,7 +28,7 @@
//! SeaORM is a relational ORM to help you build light weight and concurrent web services in Rust. //! SeaORM is a relational ORM to help you build light weight and concurrent web services in Rust.
//! //!
//! [![Getting Started](https://img.shields.io/badge/Getting%20Started-brightgreen)](https://www.sea-ql.org/SeaORM/docs/index) //! [![Getting Started](https://img.shields.io/badge/Getting%20Started-brightgreen)](https://www.sea-ql.org/SeaORM/docs/index)
//! [![Usage Example](https://img.shields.io/badge/Usage%20Example-yellow)](https://github.com/SeaQL/sea-orm/tree/master/examples/async-std) //! [![Usage Example](https://img.shields.io/badge/Usage%20Example-yellow)](https://github.com/SeaQL/sea-orm/tree/master/examples/basic)
//! [![Actix Example](https://img.shields.io/badge/Actix%20Example-blue)](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example) //! [![Actix Example](https://img.shields.io/badge/Actix%20Example-blue)](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)
//! [![Rocket Example](https://img.shields.io/badge/Rocket%20Example-orange)](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example) //! [![Rocket Example](https://img.shields.io/badge/Rocket%20Example-orange)](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example)
//! [![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv) //! [![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv)

View File

@ -1,14 +1,18 @@
use crate::{ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, QueryTrait}; use crate::{
ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, PrimaryKeyTrait,
QueryTrait,
};
use core::marker::PhantomData; use core::marker::PhantomData;
use sea_query::InsertStatement; use sea_query::{InsertStatement, ValueTuple};
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct Insert<A> pub struct Insert<A>
where where
A: ActiveModelTrait, A: ActiveModelTrait,
{ {
pub(crate) query: InsertStatement, pub(crate) query: InsertStatement,
pub(crate) columns: Vec<bool>, pub(crate) columns: Vec<bool>,
pub(crate) primary_key: Option<ValueTuple>,
pub(crate) model: PhantomData<A>, pub(crate) model: PhantomData<A>,
} }
@ -31,6 +35,7 @@ where
.into_table(A::Entity::default().table_ref()) .into_table(A::Entity::default().table_ref())
.to_owned(), .to_owned(),
columns: Vec::new(), columns: Vec::new(),
primary_key: None,
model: PhantomData, model: PhantomData,
} }
} }
@ -107,6 +112,12 @@ where
M: IntoActiveModel<A>, M: IntoActiveModel<A>,
{ {
let mut am: A = m.into_active_model(); let mut am: A = m.into_active_model();
self.primary_key =
if !<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::auto_increment() {
am.get_primary_key_value()
} else {
None
};
let mut columns = Vec::new(); let mut columns = Vec::new();
let mut values = Vec::new(); let mut values = Vec::new();
let columns_empty = self.columns.is_empty(); let columns_empty = self.columns.is_empty();
@ -120,7 +131,7 @@ where
} }
if av_has_val { if av_has_val {
columns.push(col); columns.push(col);
values.push(av.into_value()); values.push(av.into_value().unwrap());
} }
} }
self.query.columns(columns); self.query.columns(columns);

View File

@ -58,11 +58,7 @@ pub async fn test_create_cake(db: &DbConn) {
.expect("could not insert cake_baker"); .expect("could not insert cake_baker");
assert_eq!( assert_eq!(
cake_baker_res.last_insert_id, cake_baker_res.last_insert_id,
if cfg!(feature = "sqlx-postgres") { (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
} else {
Default::default()
}
); );
assert!(cake.is_some()); assert!(cake.is_some());

View File

@ -57,11 +57,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
.expect("could not insert cake_baker"); .expect("could not insert cake_baker");
assert_eq!( assert_eq!(
cake_baker_res.last_insert_id, cake_baker_res.last_insert_id,
if cfg!(feature = "sqlx-postgres") { (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
} else {
Default::default()
}
); );
// Customer // Customer

View File

@ -57,11 +57,7 @@ pub async fn test_create_order(db: &DbConn) {
.expect("could not insert cake_baker"); .expect("could not insert cake_baker");
assert_eq!( assert_eq!(
cake_baker_res.last_insert_id, cake_baker_res.last_insert_id,
if cfg!(feature = "sqlx-postgres") { (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
} else {
Default::default()
}
); );
// Customer // Customer

View File

@ -84,11 +84,7 @@ async fn init_setup(db: &DatabaseConnection) {
.expect("could not insert cake_baker"); .expect("could not insert cake_baker");
assert_eq!( assert_eq!(
cake_baker_res.last_insert_id, cake_baker_res.last_insert_id,
if cfg!(feature = "sqlx-postgres") { (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
} else {
Default::default()
}
); );
let customer_kate = customer::ActiveModel { let customer_kate = customer::ActiveModel {
@ -225,11 +221,7 @@ async fn create_cake(db: &DatabaseConnection, baker: baker::Model) -> Option<cak
.expect("could not insert cake_baker"); .expect("could not insert cake_baker");
assert_eq!( assert_eq!(
cake_baker_res.last_insert_id, cake_baker_res.last_insert_id,
if cfg!(feature = "sqlx-postgres") { (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
} else {
Default::default()
}
); );
Cake::find_by_id(cake_insert_res.last_insert_id) Cake::find_by_id(cake_insert_res.last_insert_id)

View File

@ -34,14 +34,7 @@ pub async fn create_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {
assert_eq!(Metadata::find().one(db).await?, Some(metadata.clone())); assert_eq!(Metadata::find().one(db).await?, Some(metadata.clone()));
assert_eq!( assert_eq!(res.last_insert_id, metadata.uuid);
res.last_insert_id,
if cfg!(feature = "sqlx-postgres") {
metadata.uuid
} else {
Default::default()
}
);
let update_res = Metadata::update(metadata::ActiveModel { let update_res = Metadata::update(metadata::ActiveModel {
value: Set("0.22".to_owned()), value: Set("0.22".to_owned()),