Merge pull request #117 from SeaQL/primary-key-type
`InsertResult` to return the primary key's type
This commit is contained in:
commit
76596da46a
@ -87,7 +87,7 @@ let pear = fruit::ActiveModel {
|
||||
};
|
||||
|
||||
// insert one
|
||||
let res: InsertResult = Fruit::insert(pear).exec(db).await?;
|
||||
let res = Fruit::insert(pear).exec(db).await?;
|
||||
|
||||
println!("InsertResult: {}", res.last_insert_id);
|
||||
|
||||
|
@ -27,6 +27,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = (i32, i32);
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
false
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ pub async fn insert_and_update(db: &DbConn) -> Result<(), DbErr> {
|
||||
name: Set("pear".to_owned()),
|
||||
..Default::default()
|
||||
};
|
||||
let res: InsertResult = Fruit::insert(pear).exec(db).await?;
|
||||
let res = Fruit::insert(pear).exec(db).await?;
|
||||
|
||||
println!();
|
||||
println!("Inserted: last_insert_id = {}\n", res.last_insert_id);
|
||||
|
@ -27,6 +27,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -117,6 +117,31 @@ impl Entity {
|
||||
format_ident!("{}", auto_increment)
|
||||
}
|
||||
|
||||
pub fn get_primary_key_rs_type(&self) -> TokenStream {
|
||||
let types = self
|
||||
.primary_keys
|
||||
.iter()
|
||||
.map(|primary_key| {
|
||||
self.columns
|
||||
.iter()
|
||||
.find(|col| col.name.eq(&primary_key.name))
|
||||
.unwrap()
|
||||
.get_rs_type()
|
||||
.to_string()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
if !types.is_empty() {
|
||||
let value_type = if types.len() > 1 {
|
||||
vec!["(".to_owned(), types.join(", "), ")".to_owned()]
|
||||
} else {
|
||||
types
|
||||
};
|
||||
value_type.join("").parse().unwrap()
|
||||
} else {
|
||||
TokenStream::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_conjunct_relations_via_snake_case(&self) -> Vec<Ident> {
|
||||
self.conjunct_relations
|
||||
.iter()
|
||||
@ -151,7 +176,7 @@ mod tests {
|
||||
columns: vec![
|
||||
Column {
|
||||
name: "id".to_owned(),
|
||||
col_type: ColumnType::String(None),
|
||||
col_type: ColumnType::Integer(None),
|
||||
auto_increment: false,
|
||||
not_null: false,
|
||||
unique: false,
|
||||
@ -373,6 +398,16 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_primary_key_rs_type() {
|
||||
let entity = setup();
|
||||
|
||||
assert_eq!(
|
||||
entity.get_primary_key_rs_type().to_string(),
|
||||
entity.columns[0].get_rs_type().to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_conjunct_relations_via_snake_case() {
|
||||
let entity = setup();
|
||||
|
@ -173,8 +173,11 @@ impl EntityWriter {
|
||||
|
||||
pub fn gen_impl_primary_key(entity: &Entity) -> TokenStream {
|
||||
let primary_key_auto_increment = entity.get_primary_key_auto_increment();
|
||||
let value_type = entity.get_primary_key_rs_type();
|
||||
quote! {
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = #value_type;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
#primary_key_auto_increment
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = (i32, i32);
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
false
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -102,24 +102,11 @@ impl From<PgRow> for QueryResult {
|
||||
impl From<PgQueryResult> for ExecResult {
|
||||
fn from(result: PgQueryResult) -> ExecResult {
|
||||
ExecResult {
|
||||
result: ExecResultHolder::SqlxPostgres {
|
||||
last_insert_id: 0,
|
||||
rows_affected: result.rows_affected(),
|
||||
},
|
||||
result: ExecResultHolder::SqlxPostgres(result),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn query_result_into_exec_result(res: QueryResult) -> Result<ExecResult, DbErr> {
|
||||
let last_insert_id: i32 = res.try_get("", "last_insert_id")?;
|
||||
Ok(ExecResult {
|
||||
result: ExecResultHolder::SqlxPostgres {
|
||||
last_insert_id: last_insert_id as u64,
|
||||
rows_affected: 0,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Postgres, PgArguments> {
|
||||
let mut query = sqlx::query(&stmt.sql);
|
||||
if let Some(values) = &stmt.values {
|
||||
|
@ -221,16 +221,18 @@ where
|
||||
let exec = E::insert(am).exec(db);
|
||||
let res = exec.await?;
|
||||
// TODO: if the entity does not have auto increment primary key, then last_insert_id is a wrong value
|
||||
if <E::PrimaryKey as PrimaryKeyTrait>::auto_increment() && res.last_insert_id != 0 {
|
||||
// FIXME: Assumed valid last_insert_id is not equals to Default::default()
|
||||
if <E::PrimaryKey as PrimaryKeyTrait>::auto_increment()
|
||||
&& res.last_insert_id != <E::PrimaryKey as PrimaryKeyTrait>::ValueType::default()
|
||||
{
|
||||
let find = E::find_by_id(res.last_insert_id).one(db);
|
||||
let found = find.await;
|
||||
let model: Option<E::Model> = found?;
|
||||
match model {
|
||||
Some(model) => Ok(model.into_active_model()),
|
||||
None => Err(DbErr::Exec(format!(
|
||||
"Failed to find inserted item: {} {}",
|
||||
"Failed to find inserted item: {}",
|
||||
E::default().to_string(),
|
||||
res.last_insert_id
|
||||
))),
|
||||
}
|
||||
} else {
|
||||
|
@ -1,7 +1,18 @@
|
||||
use super::{ColumnTrait, IdenStatic, Iterable};
|
||||
use crate::{TryFromU64, TryGetableMany};
|
||||
use sea_query::IntoValueTuple;
|
||||
use std::fmt::Debug;
|
||||
|
||||
//LINT: composite primary key cannot auto increment
|
||||
pub trait PrimaryKeyTrait: IdenStatic + Iterable {
|
||||
type ValueType: Sized
|
||||
+ Default
|
||||
+ Debug
|
||||
+ PartialEq
|
||||
+ IntoValueTuple
|
||||
+ TryGetableMany
|
||||
+ TryFromU64;
|
||||
|
||||
fn auto_increment() -> bool;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DbErr {
|
||||
Conn(String),
|
||||
Exec(String),
|
||||
|
@ -8,10 +8,7 @@ pub(crate) enum ExecResultHolder {
|
||||
#[cfg(feature = "sqlx-mysql")]
|
||||
SqlxMySql(sqlx::mysql::MySqlQueryResult),
|
||||
#[cfg(feature = "sqlx-postgres")]
|
||||
SqlxPostgres {
|
||||
last_insert_id: u64,
|
||||
rows_affected: u64,
|
||||
},
|
||||
SqlxPostgres(sqlx::postgres::PgQueryResult),
|
||||
#[cfg(feature = "sqlx-sqlite")]
|
||||
SqlxSqlite(sqlx::sqlite::SqliteQueryResult),
|
||||
#[cfg(feature = "mock")]
|
||||
@ -26,7 +23,9 @@ impl ExecResult {
|
||||
#[cfg(feature = "sqlx-mysql")]
|
||||
ExecResultHolder::SqlxMySql(result) => result.last_insert_id(),
|
||||
#[cfg(feature = "sqlx-postgres")]
|
||||
ExecResultHolder::SqlxPostgres { last_insert_id, .. } => last_insert_id.to_owned(),
|
||||
ExecResultHolder::SqlxPostgres(_) => {
|
||||
panic!("Should not retrieve last_insert_id this way")
|
||||
}
|
||||
#[cfg(feature = "sqlx-sqlite")]
|
||||
ExecResultHolder::SqlxSqlite(result) => {
|
||||
let last_insert_rowid = result.last_insert_rowid();
|
||||
@ -46,7 +45,7 @@ impl ExecResult {
|
||||
#[cfg(feature = "sqlx-mysql")]
|
||||
ExecResultHolder::SqlxMySql(result) => result.rows_affected(),
|
||||
#[cfg(feature = "sqlx-postgres")]
|
||||
ExecResultHolder::SqlxPostgres { rows_affected, .. } => rows_affected.to_owned(),
|
||||
ExecResultHolder::SqlxPostgres(result) => result.rows_affected(),
|
||||
#[cfg(feature = "sqlx-sqlite")]
|
||||
ExecResultHolder::SqlxSqlite(result) => result.rows_affected(),
|
||||
#[cfg(feature = "mock")]
|
||||
|
@ -1,15 +1,25 @@
|
||||
use crate::{error::*, ActiveModelTrait, DatabaseConnection, Insert, Statement};
|
||||
use crate::{
|
||||
error::*, ActiveModelTrait, DatabaseConnection, EntityTrait, Insert, PrimaryKeyTrait,
|
||||
Statement, TryFromU64,
|
||||
};
|
||||
use sea_query::InsertStatement;
|
||||
use std::future::Future;
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Inserter {
|
||||
pub struct Inserter<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
query: InsertStatement,
|
||||
model: PhantomData<A>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct InsertResult {
|
||||
pub last_insert_id: u64,
|
||||
#[derive(Debug)]
|
||||
pub struct InsertResult<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
pub last_insert_id: <<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType,
|
||||
}
|
||||
|
||||
impl<A> Insert<A>
|
||||
@ -17,54 +27,79 @@ where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
#[allow(unused_mut)]
|
||||
pub fn exec(
|
||||
pub fn exec<'a>(
|
||||
self,
|
||||
db: &DatabaseConnection,
|
||||
) -> impl Future<Output = Result<InsertResult, DbErr>> + '_ {
|
||||
db: &'a DatabaseConnection,
|
||||
) -> impl Future<Output = Result<InsertResult<A>, DbErr>> + 'a
|
||||
where
|
||||
A: 'a,
|
||||
{
|
||||
// so that self is dropped before entering await
|
||||
let mut query = self.query;
|
||||
#[cfg(feature = "sqlx-postgres")]
|
||||
if let DatabaseConnection::SqlxPostgresPoolConnection(_) = db {
|
||||
use crate::{EntityTrait, Iterable};
|
||||
use sea_query::{Alias, Expr, Query};
|
||||
for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {
|
||||
use crate::{sea_query::Query, Iterable};
|
||||
if <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
|
||||
query.returning(
|
||||
Query::select()
|
||||
.expr_as(Expr::col(key), Alias::new("last_insert_id"))
|
||||
.to_owned(),
|
||||
.columns(<A::Entity as EntityTrait>::PrimaryKey::iter())
|
||||
.take(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Inserter::new(query).exec(db)
|
||||
Inserter::<A>::new(query).exec(db)
|
||||
}
|
||||
}
|
||||
|
||||
impl Inserter {
|
||||
impl<A> Inserter<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
pub fn new(query: InsertStatement) -> Self {
|
||||
Self { query }
|
||||
Self {
|
||||
query,
|
||||
model: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exec(
|
||||
pub fn exec<'a>(
|
||||
self,
|
||||
db: &DatabaseConnection,
|
||||
) -> impl Future<Output = Result<InsertResult, DbErr>> + '_ {
|
||||
db: &'a DatabaseConnection,
|
||||
) -> impl Future<Output = Result<InsertResult<A>, DbErr>> + 'a
|
||||
where
|
||||
A: 'a,
|
||||
{
|
||||
let builder = db.get_database_backend();
|
||||
exec_insert(builder.build(&self.query), db)
|
||||
}
|
||||
}
|
||||
|
||||
// Only Statement impl Send
|
||||
async fn exec_insert(statement: Statement, db: &DatabaseConnection) -> Result<InsertResult, DbErr> {
|
||||
// TODO: Postgres instead use query_one + returning clause
|
||||
let result = match db {
|
||||
async fn exec_insert<A>(
|
||||
statement: Statement,
|
||||
db: &DatabaseConnection,
|
||||
) -> Result<InsertResult<A>, DbErr>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
type PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey;
|
||||
type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;
|
||||
let last_insert_id = match db {
|
||||
#[cfg(feature = "sqlx-postgres")]
|
||||
DatabaseConnection::SqlxPostgresPoolConnection(conn) => {
|
||||
use crate::{sea_query::Iden, Iterable};
|
||||
let cols = PrimaryKey::<A>::iter()
|
||||
.map(|col| col.to_string())
|
||||
.collect::<Vec<_>>();
|
||||
let res = conn.query_one(statement).await?.unwrap();
|
||||
crate::query_result_into_exec_result(res)?
|
||||
res.try_get_many("", cols.as_ref()).unwrap_or_default()
|
||||
}
|
||||
_ => {
|
||||
let last_insert_id = db.execute(statement).await?.last_insert_id();
|
||||
ValueTypeOf::<A>::try_from_u64(last_insert_id)
|
||||
.ok()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
_ => db.execute(statement).await?,
|
||||
};
|
||||
Ok(InsertResult {
|
||||
last_insert_id: result.last_insert_id(),
|
||||
})
|
||||
Ok(InsertResult { last_insert_id })
|
||||
}
|
||||
|
@ -17,6 +17,10 @@ pub(crate) enum QueryResultRow {
|
||||
Mock(crate::MockRow),
|
||||
}
|
||||
|
||||
pub trait TryGetable: Sized {
|
||||
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError>;
|
||||
}
|
||||
|
||||
pub enum TryGetError {
|
||||
DbErr(DbErr),
|
||||
Null,
|
||||
@ -31,12 +35,6 @@ impl From<TryGetError> for DbErr {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TryGetable {
|
||||
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
// QueryResult //
|
||||
|
||||
impl QueryResult {
|
||||
@ -46,6 +44,13 @@ impl QueryResult {
|
||||
{
|
||||
Ok(T::try_get(self, pre, col)?)
|
||||
}
|
||||
|
||||
pub fn try_get_many<T>(&self, pre: &str, cols: &[String]) -> Result<T, DbErr>
|
||||
where
|
||||
T: TryGetableMany,
|
||||
{
|
||||
Ok(T::try_get_many(self, pre, cols)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for QueryResultRow {
|
||||
@ -283,3 +288,135 @@ impl TryGetable for Decimal {
|
||||
|
||||
#[cfg(feature = "with-uuid")]
|
||||
try_getable_all!(uuid::Uuid);
|
||||
|
||||
// TryGetableMany //
|
||||
|
||||
pub trait TryGetableMany: Sized {
|
||||
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError>;
|
||||
}
|
||||
|
||||
impl<T> TryGetableMany for T
|
||||
where
|
||||
T: TryGetable,
|
||||
{
|
||||
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {
|
||||
try_get_many_with_slice_len_of(1, cols)?;
|
||||
T::try_get(res, pre, &cols[0])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TryGetableMany for (T, T)
|
||||
where
|
||||
T: TryGetable,
|
||||
{
|
||||
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {
|
||||
try_get_many_with_slice_len_of(2, cols)?;
|
||||
Ok((
|
||||
T::try_get(res, pre, &cols[0])?,
|
||||
T::try_get(res, pre, &cols[1])?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TryGetableMany for (T, T, T)
|
||||
where
|
||||
T: TryGetable,
|
||||
{
|
||||
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {
|
||||
try_get_many_with_slice_len_of(3, cols)?;
|
||||
Ok((
|
||||
T::try_get(res, pre, &cols[0])?,
|
||||
T::try_get(res, pre, &cols[1])?,
|
||||
T::try_get(res, pre, &cols[2])?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn try_get_many_with_slice_len_of(len: usize, cols: &[String]) -> Result<(), TryGetError> {
|
||||
if cols.len() < len {
|
||||
Err(TryGetError::DbErr(DbErr::Query(format!(
|
||||
"Expect {} column names supplied but got slice of length {}",
|
||||
len,
|
||||
cols.len()
|
||||
))))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// TryFromU64 //
|
||||
|
||||
pub trait TryFromU64: Sized {
|
||||
fn try_from_u64(n: u64) -> Result<Self, DbErr>;
|
||||
}
|
||||
|
||||
macro_rules! try_from_u64_err {
|
||||
( $type: ty ) => {
|
||||
impl TryFromU64 for $type {
|
||||
fn try_from_u64(_: u64) -> Result<Self, DbErr> {
|
||||
Err(DbErr::Exec(format!(
|
||||
"{} cannot be converted from u64",
|
||||
stringify!($type)
|
||||
)))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! try_from_u64_tuple {
|
||||
( $type: ty ) => {
|
||||
try_from_u64_err!(($type, $type));
|
||||
try_from_u64_err!(($type, $type, $type));
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! try_from_u64_numeric {
|
||||
( $type: ty ) => {
|
||||
impl TryFromU64 for $type {
|
||||
fn try_from_u64(n: u64) -> Result<Self, DbErr> {
|
||||
use std::convert::TryInto;
|
||||
n.try_into().map_err(|_| {
|
||||
DbErr::Exec(format!(
|
||||
"fail to convert '{}' into '{}'",
|
||||
n,
|
||||
stringify!($type)
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
try_from_u64_tuple!($type);
|
||||
};
|
||||
}
|
||||
|
||||
try_from_u64_numeric!(i8);
|
||||
try_from_u64_numeric!(i16);
|
||||
try_from_u64_numeric!(i32);
|
||||
try_from_u64_numeric!(i64);
|
||||
try_from_u64_numeric!(u8);
|
||||
try_from_u64_numeric!(u16);
|
||||
try_from_u64_numeric!(u32);
|
||||
try_from_u64_numeric!(u64);
|
||||
|
||||
macro_rules! try_from_u64_string {
|
||||
( $type: ty ) => {
|
||||
impl TryFromU64 for $type {
|
||||
fn try_from_u64(n: u64) -> Result<Self, DbErr> {
|
||||
Ok(n.to_string())
|
||||
}
|
||||
}
|
||||
try_from_u64_tuple!($type);
|
||||
};
|
||||
}
|
||||
|
||||
try_from_u64_string!(String);
|
||||
|
||||
macro_rules! try_from_u64_dummy {
|
||||
( $type: ty ) => {
|
||||
try_from_u64_err!($type);
|
||||
try_from_u64_err!(($type, $type));
|
||||
try_from_u64_err!(($type, $type, $type));
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-uuid")]
|
||||
try_from_u64_dummy!(uuid::Uuid);
|
||||
|
@ -93,7 +93,7 @@
|
||||
//! };
|
||||
//!
|
||||
//! // insert one
|
||||
//! let res: InsertResult = Fruit::insert(pear).exec(db).await?;
|
||||
//! let res = Fruit::insert(pear).exec(db).await?;
|
||||
//!
|
||||
//! println!("InsertResult: {}", res.last_insert_id);
|
||||
//! # Ok(())
|
||||
|
@ -28,6 +28,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = (i32, i32);
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
false
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = (i32, i32);
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
false
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = (i32, i32);
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
false
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
61
tests/common/bakery_chain/metadata.rs
Normal file
61
tests/common/bakery_chain/metadata.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use sea_orm::entity::prelude::*;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
|
||||
pub struct Entity;
|
||||
|
||||
impl EntityName for Entity {
|
||||
fn table_name(&self) -> &str {
|
||||
"metadata"
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
|
||||
pub struct Model {
|
||||
pub uuid: Uuid,
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||
pub enum Column {
|
||||
Uuid,
|
||||
Key,
|
||||
Value,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||
pub enum PrimaryKey {
|
||||
Uuid,
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = Uuid;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ColumnTrait for Column {
|
||||
type EntityName = Entity;
|
||||
|
||||
fn def(&self) -> ColumnDef {
|
||||
match self {
|
||||
Self::Uuid => ColumnType::Uuid.def(),
|
||||
Self::Key => ColumnType::String(None).def(),
|
||||
Self::Value => ColumnType::String(None).def(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -4,6 +4,7 @@ pub mod cake;
|
||||
pub mod cakes_bakers;
|
||||
pub mod customer;
|
||||
pub mod lineitem;
|
||||
pub mod metadata;
|
||||
pub mod order;
|
||||
|
||||
pub use super::baker::Entity as Baker;
|
||||
@ -12,4 +13,5 @@ pub use super::cake::Entity as Cake;
|
||||
pub use super::cakes_bakers::Entity as CakesBakers;
|
||||
pub use super::customer::Entity as Customer;
|
||||
pub use super::lineitem::Entity as Lineitem;
|
||||
pub use super::metadata::Entity as Metadata;
|
||||
pub use super::order::Entity as Order;
|
||||
|
@ -33,6 +33,8 @@ pub enum PrimaryKey {
|
||||
}
|
||||
|
||||
impl PrimaryKeyTrait for PrimaryKey {
|
||||
type ValueType = i32;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -45,13 +45,14 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {
|
||||
Database::connect(base_url).await.unwrap()
|
||||
};
|
||||
|
||||
assert!(schema::create_bakery_table(&db).await.is_ok());
|
||||
assert!(schema::create_baker_table(&db).await.is_ok());
|
||||
assert!(schema::create_customer_table(&db).await.is_ok());
|
||||
assert!(schema::create_order_table(&db).await.is_ok());
|
||||
assert!(schema::create_cake_table(&db).await.is_ok());
|
||||
assert!(schema::create_cakes_bakers_table(&db).await.is_ok());
|
||||
assert!(schema::create_lineitem_table(&db).await.is_ok());
|
||||
schema::create_bakery_table(&db).await.unwrap();
|
||||
schema::create_baker_table(&db).await.unwrap();
|
||||
schema::create_customer_table(&db).await.unwrap();
|
||||
schema::create_order_table(&db).await.unwrap();
|
||||
schema::create_cake_table(&db).await.unwrap();
|
||||
schema::create_cakes_bakers_table(&db).await.unwrap();
|
||||
schema::create_lineitem_table(&db).await.unwrap();
|
||||
schema::create_metadata_table(&db).await.unwrap();
|
||||
db
|
||||
}
|
||||
|
||||
|
@ -271,3 +271,20 @@ pub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
|
||||
create_table(db, &stmt, Cake).await
|
||||
}
|
||||
|
||||
pub async fn create_metadata_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||
let stmt = sea_query::Table::create()
|
||||
.table(metadata::Entity)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(metadata::Column::Uuid)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(metadata::Column::Key).string().not_null())
|
||||
.col(ColumnDef::new(metadata::Column::Value).string().not_null())
|
||||
.to_owned();
|
||||
|
||||
create_table(db, &stmt).await
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ pub async fn test_create_baker(db: &DbConn) {
|
||||
profit_margin: Set(10.4),
|
||||
..Default::default()
|
||||
};
|
||||
let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery)
|
||||
let bakery_insert_res = Bakery::insert(seaside_bakery)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert bakery");
|
||||
@ -30,7 +30,7 @@ pub async fn test_create_baker(db: &DbConn) {
|
||||
bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)),
|
||||
..Default::default()
|
||||
};
|
||||
let res: InsertResult = Baker::insert(baker_bob)
|
||||
let res = Baker::insert(baker_bob)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert baker");
|
||||
|
@ -8,7 +8,7 @@ pub async fn test_create_cake(db: &DbConn) {
|
||||
profit_margin: Set(10.4),
|
||||
..Default::default()
|
||||
};
|
||||
let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery)
|
||||
let bakery_insert_res = Bakery::insert(seaside_bakery)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert bakery");
|
||||
@ -23,7 +23,7 @@ pub async fn test_create_cake(db: &DbConn) {
|
||||
bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)),
|
||||
..Default::default()
|
||||
};
|
||||
let baker_insert_res: InsertResult = Baker::insert(baker_bob)
|
||||
let baker_insert_res = Baker::insert(baker_bob)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert baker");
|
||||
@ -38,7 +38,7 @@ pub async fn test_create_cake(db: &DbConn) {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let cake_insert_res: InsertResult = Cake::insert(mud_cake)
|
||||
let cake_insert_res = Cake::insert(mud_cake)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake");
|
||||
@ -53,10 +53,18 @@ pub async fn test_create_cake(db: &DbConn) {
|
||||
baker_id: Set(baker_insert_res.last_insert_id as i32),
|
||||
..Default::default()
|
||||
};
|
||||
let _cake_baker_res: InsertResult = CakesBakers::insert(cake_baker)
|
||||
let cake_baker_res = CakesBakers::insert(cake_baker.clone())
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake_baker");
|
||||
assert_eq!(
|
||||
cake_baker_res.last_insert_id,
|
||||
if cfg!(feature = "sqlx-postgres") {
|
||||
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
assert!(cake.is_some());
|
||||
let cake_model = cake.unwrap();
|
||||
|
@ -10,7 +10,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
|
||||
profit_margin: Set(10.4),
|
||||
..Default::default()
|
||||
};
|
||||
let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery)
|
||||
let bakery_insert_res = Bakery::insert(seaside_bakery)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert bakery");
|
||||
@ -26,7 +26,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
|
||||
bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)),
|
||||
..Default::default()
|
||||
};
|
||||
let baker_insert_res: InsertResult = Baker::insert(baker_bob)
|
||||
let baker_insert_res = Baker::insert(baker_bob)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert baker");
|
||||
@ -41,7 +41,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let cake_insert_res: InsertResult = Cake::insert(mud_cake)
|
||||
let cake_insert_res = Cake::insert(mud_cake)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake");
|
||||
@ -52,10 +52,18 @@ pub async fn test_create_lineitem(db: &DbConn) {
|
||||
baker_id: Set(baker_insert_res.last_insert_id as i32),
|
||||
..Default::default()
|
||||
};
|
||||
let _cake_baker_res: InsertResult = CakesBakers::insert(cake_baker)
|
||||
let cake_baker_res = CakesBakers::insert(cake_baker.clone())
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake_baker");
|
||||
assert_eq!(
|
||||
cake_baker_res.last_insert_id,
|
||||
if cfg!(feature = "sqlx-postgres") {
|
||||
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
// Customer
|
||||
let customer_kate = customer::ActiveModel {
|
||||
@ -63,7 +71,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
|
||||
notes: Set(Some("Loves cheese cake".to_owned())),
|
||||
..Default::default()
|
||||
};
|
||||
let customer_insert_res: InsertResult = Customer::insert(customer_kate)
|
||||
let customer_insert_res = Customer::insert(customer_kate)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert customer");
|
||||
@ -76,7 +84,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
|
||||
placed_at: Set(Utc::now().naive_utc()),
|
||||
..Default::default()
|
||||
};
|
||||
let order_insert_res: InsertResult = Order::insert(order_1)
|
||||
let order_insert_res = Order::insert(order_1)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert order");
|
||||
@ -89,7 +97,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
|
||||
quantity: Set(1),
|
||||
..Default::default()
|
||||
};
|
||||
let lineitem_insert_res: InsertResult = Lineitem::insert(lineitem_1)
|
||||
let lineitem_insert_res = Lineitem::insert(lineitem_1)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert lineitem");
|
||||
@ -105,7 +113,7 @@ pub async fn test_create_lineitem(db: &DbConn) {
|
||||
|
||||
assert_eq!(lineitem_model.price, dec!(7.55));
|
||||
|
||||
let cake: Option<cake::Model> = Cake::find_by_id(lineitem_model.cake_id as u64)
|
||||
let cake: Option<cake::Model> = Cake::find_by_id(lineitem_model.cake_id)
|
||||
.one(db)
|
||||
.await
|
||||
.expect("could not find cake");
|
||||
|
@ -10,7 +10,7 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
profit_margin: Set(10.4),
|
||||
..Default::default()
|
||||
};
|
||||
let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery)
|
||||
let bakery_insert_res = Bakery::insert(seaside_bakery)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert bakery");
|
||||
@ -26,7 +26,7 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)),
|
||||
..Default::default()
|
||||
};
|
||||
let baker_insert_res: InsertResult = Baker::insert(baker_bob)
|
||||
let baker_insert_res = Baker::insert(baker_bob)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert baker");
|
||||
@ -41,7 +41,7 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let cake_insert_res: InsertResult = Cake::insert(mud_cake)
|
||||
let cake_insert_res = Cake::insert(mud_cake)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake");
|
||||
@ -52,10 +52,18 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
baker_id: Set(baker_insert_res.last_insert_id as i32),
|
||||
..Default::default()
|
||||
};
|
||||
let _cake_baker_res: InsertResult = CakesBakers::insert(cake_baker)
|
||||
let cake_baker_res = CakesBakers::insert(cake_baker.clone())
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake_baker");
|
||||
assert_eq!(
|
||||
cake_baker_res.last_insert_id,
|
||||
if cfg!(feature = "sqlx-postgres") {
|
||||
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
// Customer
|
||||
let customer_kate = customer::ActiveModel {
|
||||
@ -63,7 +71,7 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
notes: Set(Some("Loves cheese cake".to_owned())),
|
||||
..Default::default()
|
||||
};
|
||||
let customer_insert_res: InsertResult = Customer::insert(customer_kate)
|
||||
let customer_insert_res = Customer::insert(customer_kate)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert customer");
|
||||
@ -76,7 +84,7 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
placed_at: Set(Utc::now().naive_utc()),
|
||||
..Default::default()
|
||||
};
|
||||
let order_insert_res: InsertResult = Order::insert(order_1)
|
||||
let order_insert_res = Order::insert(order_1)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert order");
|
||||
@ -89,7 +97,7 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
quantity: Set(2),
|
||||
..Default::default()
|
||||
};
|
||||
let _lineitem_insert_res: InsertResult = Lineitem::insert(lineitem_1)
|
||||
let _lineitem_insert_res = Lineitem::insert(lineitem_1)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert lineitem");
|
||||
@ -103,7 +111,7 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
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 as u64)
|
||||
let customer: Option<customer::Model> = Customer::find_by_id(order_model.customer_id)
|
||||
.one(db)
|
||||
.await
|
||||
.expect("could not find customer");
|
||||
@ -111,7 +119,7 @@ pub async fn test_create_order(db: &DbConn) {
|
||||
let customer_model = customer.unwrap();
|
||||
assert_eq!(customer_model.name, "Kate");
|
||||
|
||||
let bakery: Option<bakery::Model> = Bakery::find_by_id(order_model.bakery_id as i64)
|
||||
let bakery: Option<bakery::Model> = Bakery::find_by_id(order_model.bakery_id)
|
||||
.one(db)
|
||||
.await
|
||||
.expect("could not find bakery");
|
||||
|
@ -10,7 +10,7 @@ pub async fn test_delete_cake(db: &DbConn) {
|
||||
profit_margin: Set(10.4),
|
||||
..Default::default()
|
||||
};
|
||||
let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery)
|
||||
let bakery_insert_res = Bakery::insert(seaside_bakery)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert bakery");
|
||||
|
@ -1,4 +1,4 @@
|
||||
use sea_orm::{entity::*, DbConn, InsertResult};
|
||||
use sea_orm::{entity::*, DbConn};
|
||||
|
||||
pub use super::common::bakery_chain::*;
|
||||
|
||||
@ -15,7 +15,7 @@ pub async fn test_create_bakery(db: &DbConn) {
|
||||
profit_margin: Set(10.4),
|
||||
..Default::default()
|
||||
};
|
||||
let res: InsertResult = Bakery::insert(seaside_bakery)
|
||||
let res = Bakery::insert(seaside_bakery)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert bakery");
|
||||
@ -37,7 +37,7 @@ pub async fn test_create_customer(db: &DbConn) {
|
||||
notes: Set(Some("Loves cheese cake".to_owned())),
|
||||
..Default::default()
|
||||
};
|
||||
let res: InsertResult = Customer::insert(customer_kate)
|
||||
let res = Customer::insert(customer_kate)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert customer");
|
||||
|
@ -8,7 +8,7 @@ pub async fn test_update_cake(db: &DbConn) {
|
||||
profit_margin: Set(10.4),
|
||||
..Default::default()
|
||||
};
|
||||
let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery)
|
||||
let bakery_insert_res = Bakery::insert(seaside_bakery)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert bakery");
|
||||
@ -22,7 +22,7 @@ pub async fn test_update_cake(db: &DbConn) {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let cake_insert_res: InsertResult = Cake::insert(mud_cake)
|
||||
let cake_insert_res = Cake::insert(mud_cake)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake");
|
||||
@ -62,7 +62,7 @@ pub async fn test_update_bakery(db: &DbConn) {
|
||||
profit_margin: Set(10.4),
|
||||
..Default::default()
|
||||
};
|
||||
let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery)
|
||||
let bakery_insert_res = Bakery::insert(seaside_bakery)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert bakery");
|
||||
@ -130,11 +130,10 @@ pub async fn test_update_deleted_customer(db: &DbConn) {
|
||||
|
||||
assert_eq!(Customer::find().count(db).await.unwrap(), init_n_customers);
|
||||
|
||||
let customer: Option<customer::Model> =
|
||||
Customer::find_by_id(customer_id.clone().unwrap() as i64)
|
||||
.one(db)
|
||||
.await
|
||||
.expect("could not find customer");
|
||||
let customer: Option<customer::Model> = Customer::find_by_id(customer_id.clone().unwrap())
|
||||
.one(db)
|
||||
.await
|
||||
.expect("could not find customer");
|
||||
|
||||
assert_eq!(customer, None);
|
||||
}
|
||||
|
41
tests/primary_key_tests.rs
Normal file
41
tests/primary_key_tests.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use sea_orm::{entity::prelude::*, DatabaseConnection, Set};
|
||||
pub mod common;
|
||||
pub use common::{bakery_chain::*, setup::*, TestContext};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[sea_orm_macros::test]
|
||||
#[cfg(any(
|
||||
feature = "sqlx-mysql",
|
||||
feature = "sqlx-sqlite",
|
||||
feature = "sqlx-postgres"
|
||||
))]
|
||||
async fn main() -> Result<(), DbErr> {
|
||||
let ctx = TestContext::new("bakery_chain_schema_primary_key_tests").await;
|
||||
|
||||
create_metadata(&ctx.db).await?;
|
||||
|
||||
ctx.delete().await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn create_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {
|
||||
let metadata = metadata::ActiveModel {
|
||||
uuid: Set(Uuid::new_v4()),
|
||||
key: Set("markup".to_owned()),
|
||||
value: Set("1.18".to_owned()),
|
||||
};
|
||||
|
||||
let res = Metadata::insert(metadata.clone()).exec(db).await?;
|
||||
|
||||
assert_eq!(
|
||||
res.last_insert_id,
|
||||
if cfg!(feature = "sqlx-postgres") {
|
||||
metadata.uuid.unwrap()
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
@ -67,7 +67,7 @@ async fn init_setup(db: &DatabaseConnection) {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let cake_insert_res: InsertResult = Cake::insert(mud_cake)
|
||||
let cake_insert_res = Cake::insert(mud_cake)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake");
|
||||
@ -78,10 +78,18 @@ async fn init_setup(db: &DatabaseConnection) {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let _cake_baker_res: InsertResult = CakesBakers::insert(cake_baker)
|
||||
let cake_baker_res = CakesBakers::insert(cake_baker.clone())
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake_baker");
|
||||
assert_eq!(
|
||||
cake_baker_res.last_insert_id,
|
||||
if cfg!(feature = "sqlx-postgres") {
|
||||
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
let customer_kate = customer::ActiveModel {
|
||||
name: Set("Kate".to_owned()),
|
||||
@ -183,7 +191,7 @@ async fn find_baker_least_sales(db: &DatabaseConnection) -> Option<baker::Model>
|
||||
|
||||
results.sort_by(|a, b| b.cakes_sold.cmp(&a.cakes_sold));
|
||||
|
||||
Baker::find_by_id(results.last().unwrap().id as i64)
|
||||
Baker::find_by_id(results.last().unwrap().id)
|
||||
.one(db)
|
||||
.await
|
||||
.unwrap()
|
||||
@ -200,7 +208,7 @@ async fn create_cake(db: &DatabaseConnection, baker: baker::Model) -> Option<cak
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let cake_insert_res: InsertResult = Cake::insert(new_cake)
|
||||
let cake_insert_res = Cake::insert(new_cake)
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake");
|
||||
@ -211,10 +219,18 @@ async fn create_cake(db: &DatabaseConnection, baker: baker::Model) -> Option<cak
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let _cake_baker_res: InsertResult = CakesBakers::insert(cake_baker)
|
||||
let cake_baker_res = CakesBakers::insert(cake_baker.clone())
|
||||
.exec(db)
|
||||
.await
|
||||
.expect("could not insert cake_baker");
|
||||
assert_eq!(
|
||||
cake_baker_res.last_insert_id,
|
||||
if cfg!(feature = "sqlx-postgres") {
|
||||
(cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
Cake::find_by_id(cake_insert_res.last_insert_id)
|
||||
.one(db)
|
||||
|
Loading…
x
Reference in New Issue
Block a user