Merge branch 'master' into ss/actix-example

This commit is contained in:
Sam Samai 2021-09-19 21:43:10 +10:00
commit 54edd87706
31 changed files with 280 additions and 184 deletions

View File

@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## 0.2.2 - 2021-09-18
- [[#105]] Compact entity format
- [[#132]] Add ActiveModel `insert` & `update`
- [[#129]] Add `set` method to `UpdateMany`
- [[#118]] Initial lock support
- [[#167]] Add `FromQueryResult::find_by_statement`
[#105]: https://github.com/SeaQL/sea-orm/issues/105
[#132]: https://github.com/SeaQL/sea-orm/issues/132
[#129]: https://github.com/SeaQL/sea-orm/issues/129
[#118]: https://github.com/SeaQL/sea-orm/issues/118
[#167]: https://github.com/SeaQL/sea-orm/issues/167
## 0.2.1 - 2021-09-04
- Update dependencies

View File

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

View File

@ -23,11 +23,6 @@ rocket_dyn_templates = { git = "https://github.com/SergioBenitez/Rocket.git", fe
sea-orm = { path = "../../", version = "^0.2", features = ["macros"], default-features = false }
serde_json = { version = "^1" }
[dependencies.sqlx]
version = "^0.5"
default-features = false
features = ["macros", "offline", "migrate"]
[features]
default = ["sqlx-postgres"]
sqlx-mysql = ["sea-orm/sqlx-mysql", "rocket_db_pools/sqlx_mysql"]

View File

@ -10,7 +10,7 @@ use rocket::{Build, Request, Rocket};
use rocket_db_pools::{sqlx, Connection, Database};
use rocket_dyn_templates::{context, Template};
use sea_orm::entity::*;
use sea_orm::{entity::*, query::*};
mod pool;
use pool::RocketDbPool;
@ -81,7 +81,9 @@ async fn list(
) -> Template {
let page = page.unwrap_or(0);
let posts_per_page = posts_per_page.unwrap_or(DEFAULT_POSTS_PER_PAGE);
let paginator = Post::find().paginate(&conn, posts_per_page);
let paginator = Post::find()
.order_by_asc(post::Column::Id)
.paginate(&conn, posts_per_page);
let num_pages = paginator.num_pages().await.ok().unwrap();
let posts = paginator

View File

@ -1,65 +1,17 @@
use rocket::serde::{Deserialize, Serialize};
use sea_orm::entity::prelude::*;
#[derive(Copy, Clone, Default, Debug, DeriveEntity, Deserialize, Serialize)]
#[serde(crate = "rocket::serde")]
pub struct Entity;
impl EntityName for Entity {
fn table_name(&self) -> &str {
"posts"
}
}
#[derive(
Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Deserialize, Serialize, FromForm,
)]
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize, FromForm)]
#[serde(crate = "rocket::serde")]
#[sea_orm(table_name = "posts")]
pub struct Model {
#[serde(skip_deserializing, skip_serializing_if = "Option::is_none")]
pub id: Option<i32>,
#[sea_orm(primary_key)]
pub id: i32,
pub title: String,
pub text: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
pub enum Column {
Id,
Title,
Text,
}
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
pub enum PrimaryKey {
Id,
}
impl PrimaryKeyTrait for PrimaryKey {
type ValueType = i32;
fn auto_increment() -> bool {
true
}
}
#[derive(Copy, Clone, Debug, EnumIter)]
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ColumnTrait for Column {
type EntityName = Entity;
fn def(&self) -> ColumnDef {
match self {
Self::Id => ColumnType::Integer.def(),
Self::Title => ColumnType::String(None).def(),
Self::Text => ColumnType::String(None).def(),
}
}
}
impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
panic!()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@ -5,6 +5,12 @@
<div class="ten columns">
<form action="/{{ post.id }}" method="post">
<div class="twelve columns">
<input
type="hidden"
name="id"
id="id"
value="0"
/>
<input
type="text"
placeholder="title"

View File

@ -3,6 +3,12 @@
<h4>New Post</h4>
<form action="/" method="post">
<div class="twelve columns">
<input
type="hidden"
name="id"
id="id"
value="0"
/>
<input
type="text"
placeholder="enter title"

View File

@ -8,7 +8,7 @@ edition = "2018"
publish = false
[dependencies]
sea-orm = { path = "../../", features = [ "sqlx-all", "runtime-tokio-native-tls" ] }
sea-orm = { path = "../../", features = [ "sqlx-all", "runtime-tokio-native-tls", "debug-print" ] }
tokio = { version = "1", features = ["full"] }
env_logger = { version = "^0.9" }
log = { version = "^0.4" }

View File

@ -1,57 +1,14 @@
use sea_orm::entity::prelude::*;
#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
pub struct Entity;
impl EntityName for Entity {
fn table_name(&self) -> &str {
"cake"
}
}
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "cake")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
pub enum Column {
Id,
Name,
}
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
pub enum PrimaryKey {
Id,
}
impl PrimaryKeyTrait for PrimaryKey {
type ValueType = i32;
fn auto_increment() -> bool {
true
}
}
#[derive(Copy, Clone, Debug, EnumIter)]
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ColumnTrait for Column {
type EntityName = Entity;
fn def(&self) -> ColumnDef {
match self {
Self::Id => ColumnType::Integer.def(),
Self::Name => ColumnType::String(None).def(),
}
}
}
impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
unreachable!()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

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

View File

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

View File

@ -38,6 +38,7 @@ impl Column {
ColumnType::Double(_) => "f64",
ColumnType::Json | ColumnType::JsonBinary => "Json",
ColumnType::DateTime(_) | ColumnType::Timestamp(_) => "DateTime",
ColumnType::TimestampWithTimeZone(_) => "DateTimeWithTimeZone",
ColumnType::Decimal(_) | ColumnType::Money(_) => "Decimal",
ColumnType::Uuid => "Uuid",
ColumnType::Binary(_) => "Vec<u8>",

View File

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

View File

@ -165,19 +165,22 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
"String" | "&str" => quote! { String(None) },
"u8" | "i8" => quote! { TinyInteger },
"u16" | "i16" => quote! { SmallInteger },
"u32" | "u64" | "i32" | "i64" => quote! { Integer },
"u128" | "i128" => quote! { BigInteger },
"u32" | "i32" => quote! { Integer },
"u64" | "i64" => quote! { BigInteger },
"f32" => quote! { Float },
"f64" => quote! { Double },
"bool" => quote! { Boolean },
"NaiveDate" => quote! { Date },
"NaiveTime" => quote! { Time },
"DateTime" | "NaiveDateTime" | "DateTimeWithTimeZone" => {
"DateTime" | "NaiveDateTime" => {
quote! { DateTime }
}
"DateTimeWithTimeZone" => {
quote! { TimestampWithTimeZone }
}
"Uuid" => quote! { Uuid },
"Json" => quote! { Json },
"Decimal" => quote! { Decimal },
"Decimal" => quote! { Decimal(None) },
"Vec<u8>" => quote! { Binary },
_ => {
return Err(Error::new(

View File

@ -1,6 +1,7 @@
use crate::{error::*, ExecResult, QueryResult, Statement, StatementBuilder};
use sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, QueryBuilder, SqliteQueryBuilder};
#[cfg_attr(not(feature = "mock"), derive(Clone))]
pub enum DatabaseConnection {
#[cfg(feature = "sqlx-mysql")]
SqlxMySqlPoolConnection(crate::SqlxMySqlPoolConnection),
@ -143,3 +144,15 @@ impl DbBackend {
}
}
}
#[cfg(test)]
mod tests {
use crate::DatabaseConnection;
#[test]
fn assert_database_connection_traits() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<DatabaseConnection>();
}
}

View File

@ -13,7 +13,7 @@ use super::sqlx_common::*;
#[derive(Debug)]
pub struct SqlxMySqlConnector;
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct SqlxMySqlPoolConnection {
pool: MySqlPool,
}

View File

@ -13,7 +13,7 @@ use super::sqlx_common::*;
#[derive(Debug)]
pub struct SqlxPostgresConnector;
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct SqlxPostgresPoolConnection {
pool: PgPool,
}

View File

@ -13,7 +13,7 @@ use super::sqlx_common::*;
#[derive(Debug)]
pub struct SqlxSqliteConnector;
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct SqlxSqlitePoolConnection {
pool: SqlitePool,
}

View File

@ -541,3 +541,58 @@ pub trait EntityTrait: EntityName {
Delete::many(Self::default())
}
}
#[cfg(test)]
mod tests {
#[test]
#[cfg(feature = "macros")]
fn entity_model_1() {
use crate::entity::*;
mod hello {
use crate as sea_orm;
use crate::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "hello")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
}
assert_eq!(hello::Entity.table_name(), "hello");
assert_eq!(hello::Entity.schema_name(), None);
}
#[test]
#[cfg(feature = "macros")]
fn entity_model_2() {
use crate::entity::*;
mod hello {
use crate as sea_orm;
use crate::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "hello", schema_name = "world")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
}
assert_eq!(hello::Entity.table_name(), "hello");
assert_eq!(hello::Entity.schema_name(), Some("world"));
}
}

View File

@ -24,6 +24,7 @@ pub enum ColumnType {
Decimal(Option<(u32, u32)>),
DateTime,
Timestamp,
TimestampWithTimeZone,
Time,
Date,
Binary,
@ -278,6 +279,7 @@ impl From<ColumnType> for sea_query::ColumnType {
ColumnType::Decimal(s) => sea_query::ColumnType::Decimal(s),
ColumnType::DateTime => sea_query::ColumnType::DateTime(None),
ColumnType::Timestamp => sea_query::ColumnType::Timestamp(None),
ColumnType::TimestampWithTimeZone => sea_query::ColumnType::TimestampWithTimeZone(None),
ColumnType::Time => sea_query::ColumnType::Time(None),
ColumnType::Date => sea_query::ColumnType::Date,
ColumnType::Binary => sea_query::ColumnType::Binary(None),
@ -309,6 +311,7 @@ impl From<sea_query::ColumnType> for ColumnType {
sea_query::ColumnType::Decimal(s) => Self::Decimal(s),
sea_query::ColumnType::DateTime(_) => Self::DateTime,
sea_query::ColumnType::Timestamp(_) => Self::Timestamp,
sea_query::ColumnType::TimestampWithTimeZone(_) => Self::TimestampWithTimeZone,
sea_query::ColumnType::Time(_) => Self::Time,
sea_query::ColumnType::Date => Self::Date,
sea_query::ColumnType::Binary(_) => Self::Binary,

View File

@ -314,29 +314,50 @@ where
}
}
impl<T> TryGetableMany for (T, T)
impl<A, B> TryGetableMany for (A, B)
where
T: TryGetable,
A: TryGetable,
B: 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])?,
A::try_get(res, pre, &cols[0])?,
B::try_get(res, pre, &cols[1])?,
))
}
}
impl<T> TryGetableMany for (T, T, T)
impl<A, B, C> TryGetableMany for (A, B, C)
where
T: TryGetable,
A: TryGetable,
B: TryGetable,
C: 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])?,
A::try_get(res, pre, &cols[0])?,
B::try_get(res, pre, &cols[1])?,
C::try_get(res, pre, &cols[2])?,
))
}
}
impl<A, B, C, D> TryGetableMany for (A, B, C, D)
where
A: TryGetable,
B: TryGetable,
C: TryGetable,
D: TryGetable,
{
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {
try_get_many_with_slice_len_of(4, cols)?;
Ok((
A::try_get(res, pre, &cols[0])?,
B::try_get(res, pre, &cols[1])?,
C::try_get(res, pre, &cols[2])?,
D::try_get(res, pre, &cols[3])?,
))
}
}
@ -370,15 +391,27 @@ macro_rules! try_from_u64_err {
}
}
};
}
macro_rules! try_from_u64_tuple {
( $type: ty ) => {
try_from_u64_err!(($type, $type));
try_from_u64_err!(($type, $type, $type));
( $($gen_type: ident),* ) => {
impl<$( $gen_type, )*> TryFromU64 for ($( $gen_type, )*)
where
$( $gen_type: TryFromU64, )*
{
fn try_from_u64(_: u64) -> Result<Self, DbErr> {
Err(DbErr::Exec(format!(
"{} cannot be converted from u64",
stringify!(($($gen_type,)*))
)))
}
}
};
}
// impl TryFromU64 for tuples with generic types
try_from_u64_err!(A, B);
try_from_u64_err!(A, B, C);
try_from_u64_err!(A, B, C, D);
macro_rules! try_from_u64_numeric {
( $type: ty ) => {
impl TryFromU64 for $type {
@ -393,7 +426,6 @@ macro_rules! try_from_u64_numeric {
})
}
}
try_from_u64_tuple!($type);
};
}
@ -413,19 +445,10 @@ macro_rules! try_from_u64_string {
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);
try_from_u64_err!(uuid::Uuid);

View File

@ -116,7 +116,7 @@ where
);
}
stmt.table(entity).if_not_exists().take()
stmt.table(entity).take()
}
#[cfg(test)]
@ -130,7 +130,6 @@ mod tests {
Schema::create_table_from_entity(CakeFillingPrice).to_string(MysqlQueryBuilder),
Table::create()
.table(CakeFillingPrice)
.if_not_exists()
.col(
ColumnDef::new(cake_filling_price::Column::CakeId)
.integer()

View File

@ -2,22 +2,21 @@ pub mod common;
pub use sea_orm::{entity::*, error::*, sea_query, tests_cfg::*, Database, DbConn};
// DATABASE_URL="sqlite::memory:" cargo test --features sqlx-sqlite,runtime-async-std-native-tls --test basic
// cargo test --features sqlx-sqlite,runtime-async-std-native-tls --test basic
#[sea_orm_macros::test]
#[cfg(feature = "sqlx-sqlite")]
async fn main() {
use std::env;
let base_url = env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite::memory:".to_owned());
async fn main() -> Result<(), DbErr> {
let base_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite::memory:".to_owned());
let db: DbConn = Database::connect(&base_url).await.unwrap();
let db: DbConn = Database::connect(&base_url).await?;
setup_schema(&db).await?;
crud_cake(&db).await?;
setup_schema(&db).await;
crud_cake(&db).await.unwrap();
Ok(())
}
#[cfg(feature = "sqlx-sqlite")]
async fn setup_schema(db: &DbConn) {
async fn setup_schema(db: &DbConn) -> Result<(), DbErr> {
use sea_query::*;
let stmt = sea_query::Table::create()
@ -33,8 +32,10 @@ async fn setup_schema(db: &DbConn) {
.to_owned();
let builder = db.get_database_backend();
let result = db.execute(builder.build(&stmt)).await;
let result = db.execute(builder.build(&stmt)).await?;
println!("Create table cake: {:?}", result);
Ok(())
}
#[cfg(feature = "sqlx-sqlite")]

View File

@ -1,3 +1,5 @@
# Schema for SeaORM test suite
![Entity Relation Diagram](bakery_chain_erd.png)
ERD generated by DataGrip.

View File

@ -0,0 +1,15 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "applog")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub json: Json,
pub created_at: DateTimeWithTimeZone,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View File

@ -1,5 +1,4 @@
use sea_orm::entity::prelude::*;
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "metadata")]
@ -11,13 +10,7 @@ pub struct Model {
pub bytes: Vec<u8>,
}
#[derive(Copy, Clone, Debug, EnumIter)]
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
unreachable!()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@ -1,3 +1,4 @@
pub mod applog;
pub mod baker;
pub mod bakery;
pub mod cake;
@ -7,6 +8,7 @@ pub mod lineitem;
pub mod metadata;
pub mod order;
pub use super::applog::Entity as Applog;
pub use super::baker::Entity as Baker;
pub use super::bakery::Entity as Bakery;
pub use super::cake::Entity as Cake;

View File

@ -53,6 +53,7 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {
schema::create_cakes_bakers_table(&db).await.unwrap();
schema::create_lineitem_table(&db).await.unwrap();
schema::create_metadata_table(&db).await.unwrap();
schema::create_log_table(&db).await.unwrap();
db
}

View File

@ -1,18 +1,30 @@
pub use super::super::bakery_chain::*;
use pretty_assertions::assert_eq;
use sea_orm::{error::*, sea_query, DbConn, EntityTrait, ExecResult, Schema};
use sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Index, Table, TableCreateStatement};
use sea_orm::{error::*, sea_query, DbBackend, DbConn, EntityTrait, ExecResult, Schema};
use sea_query::{
Alias, ColumnDef, ForeignKey, ForeignKeyAction, Index, Table, TableCreateStatement,
};
async fn create_table<E>(
db: &DbConn,
stmt: &TableCreateStatement,
create: &TableCreateStatement,
entity: E,
) -> Result<ExecResult, DbErr>
where
E: EntityTrait,
{
let builder = db.get_database_backend();
let stmt = builder.build(stmt);
if builder != DbBackend::Sqlite {
let stmt = builder.build(
Table::drop()
.table(Alias::new(create.get_table_name().unwrap().as_ref()))
.if_exists()
.cascade(),
);
db.execute(stmt).await?;
}
let stmt = builder.build(create);
assert_eq!(
builder.build(&Schema::create_table_from_entity(entity)),
stmt
@ -23,7 +35,6 @@ where
pub async fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = Table::create()
.table(bakery::Entity)
.if_not_exists()
.col(
ColumnDef::new(bakery::Column::Id)
.integer()
@ -45,7 +56,6 @@ pub async fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {
pub async fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = Table::create()
.table(baker::Entity)
.if_not_exists()
.col(
ColumnDef::new(baker::Column::Id)
.integer()
@ -76,7 +86,6 @@ pub async fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {
pub async fn create_customer_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = Table::create()
.table(customer::Entity)
.if_not_exists()
.col(
ColumnDef::new(customer::Column::Id)
.integer()
@ -94,7 +103,6 @@ pub async fn create_customer_table(db: &DbConn) -> Result<ExecResult, DbErr> {
pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = Table::create()
.table(order::Entity)
.if_not_exists()
.col(
ColumnDef::new(order::Column::Id)
.integer()
@ -142,7 +150,6 @@ pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = Table::create()
.table(lineitem::Entity)
.if_not_exists()
.col(
ColumnDef::new(lineitem::Column::Id)
.integer()
@ -194,7 +201,6 @@ pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = Table::create()
.table(cakes_bakers::Entity)
.if_not_exists()
.col(
ColumnDef::new(cakes_bakers::Column::CakeId)
.integer()
@ -235,7 +241,6 @@ pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr>
pub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = Table::create()
.table(cake::Entity)
.if_not_exists()
.col(
ColumnDef::new(cake::Column::Id)
.integer()
@ -272,7 +277,6 @@ pub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {
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()
@ -286,3 +290,24 @@ pub async fn create_metadata_table(db: &DbConn) -> Result<ExecResult, DbErr> {
create_table(db, &stmt, Metadata).await
}
pub async fn create_log_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = sea_query::Table::create()
.table(applog::Entity)
.col(
ColumnDef::new(applog::Column::Id)
.integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(applog::Column::Json).json().not_null())
.col(
ColumnDef::new(applog::Column::CreatedAt)
.timestamp_with_time_zone()
.not_null(),
)
.to_owned();
create_table(db, &stmt, Applog).await
}

31
tests/timestamp_tests.rs Normal file
View File

@ -0,0 +1,31 @@
pub mod common;
pub use common::{bakery_chain::*, setup::*, TestContext};
use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel};
#[sea_orm_macros::test]
#[cfg(feature = "sqlx-postgres")]
async fn main() -> Result<(), DbErr> {
let ctx = TestContext::new("bakery_chain_schema_timestamp_tests").await;
create_applog(&ctx.db).await?;
ctx.delete().await;
Ok(())
}
pub async fn create_applog(db: &DatabaseConnection) -> Result<(), DbErr> {
let log = applog::Model {
id: 1,
json: Json::String("HI".to_owned()),
created_at: "2021-09-17T17:50:20+08:00".parse().unwrap(),
};
let res = Applog::insert(log.clone().into_active_model())
.exec(db)
.await?;
assert_eq!(log.id.clone(), res.last_insert_id);
assert_eq!(Applog::find().one(db).await?, Some(log.clone()));
Ok(())
}

View File

@ -2,7 +2,6 @@ pub mod common;
pub use common::{bakery_chain::*, setup::*, TestContext};
use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel};
use uuid::Uuid;
#[sea_orm_macros::test]
#[cfg(any(
@ -11,10 +10,8 @@ use uuid::Uuid;
feature = "sqlx-postgres"
))]
async fn main() -> Result<(), DbErr> {
let ctx = TestContext::new("bakery_chain_schema_primary_key_tests").await;
let ctx = TestContext::new("bakery_chain_schema_uuid_tests").await;
create_metadata(&ctx.db).await?;
ctx.delete().await;
Ok(())