You've already forked seamantic
Add tests around the new entity format
This commit is contained in:
Generated
+26
-16
@@ -115,9 +115,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.43"
|
version = "1.2.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2"
|
checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"shlex",
|
"shlex",
|
||||||
@@ -669,6 +669,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inventory"
|
||||||
|
version = "0.3.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e"
|
||||||
|
dependencies = [
|
||||||
|
"rustversion",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
@@ -1046,14 +1055,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sea-orm"
|
name = "sea-orm"
|
||||||
version = "2.0.0-rc.16"
|
version = "2.0.0-rc.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6265b8190c0898db442eeb8333f277de801742f0072f984601a10bb3145237d3"
|
checksum = "296a092e16fbbcc3a9969eae3915ef11024b98a43f3b77ff5199bc626c462d7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-stream",
|
"async-stream",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"inventory",
|
||||||
"itertools",
|
"itertools",
|
||||||
"log",
|
"log",
|
||||||
"ouroboros",
|
"ouroboros",
|
||||||
@@ -1071,9 +1081,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sea-orm-cli"
|
name = "sea-orm-cli"
|
||||||
version = "2.0.0-rc.16"
|
version = "2.0.0-rc.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52d9971a23ea89ab63b48d19923871415358f07a1db72b4dd9a40b6cae625c32"
|
checksum = "301f7ace977d940474b47a154a5fc453714d13e5d53bdb077330c6fc6212a31b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"glob",
|
"glob",
|
||||||
@@ -1089,9 +1099,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sea-orm-macros"
|
name = "sea-orm-macros"
|
||||||
version = "2.0.0-rc.16"
|
version = "2.0.0-rc.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c54373b4c855be7a5b0691e1fcbdd1d5bd25a9a54efdcf922f281356a7129808"
|
checksum = "e56ee8be52d15a801dc62a5a30d83dc718762401f7c7945b7f2730ef385b8b3d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -1103,9 +1113,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sea-orm-migration"
|
name = "sea-orm-migration"
|
||||||
version = "2.0.0-rc.16"
|
version = "2.0.0-rc.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82dbb9a68e0d64b5f5493f2924958e2149f1d4827bb381100d75886d1b1df281"
|
checksum = "b7444940e5b7db32f55dea6d04cfb312480e45ae07753b1391311eccd5753475"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
@@ -1177,7 +1187,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "seamantic"
|
name = "seamantic"
|
||||||
version = "0.0.9"
|
version = "0.0.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
"sea-orm-migration",
|
"sea-orm-migration",
|
||||||
@@ -1590,9 +1600,9 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.20"
|
version = "1.0.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06"
|
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
@@ -1693,14 +1703,14 @@ version = "0.26.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
|
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"webpki-roots 1.0.3",
|
"webpki-roots 1.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "1.0.3"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8"
|
checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|||||||
+2
-2
@@ -35,8 +35,8 @@ overflow-checks = true
|
|||||||
strip = "debuginfo"
|
strip = "debuginfo"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
sea-orm = { version = "2.0.0-rc.16", default-features = false }
|
sea-orm = { version = "2.0.0-rc.17", default-features = false }
|
||||||
sea-orm-migration = { version = "2.0.0-rc.16", default-features = false }
|
sea-orm-migration = { version = "2.0.0-rc.17", default-features = false }
|
||||||
|
|
||||||
serde = { version = "^1", default-features = false }
|
serde = { version = "^1", default-features = false }
|
||||||
serde_test = { version = "^1", default-features = false }
|
serde_test = { version = "^1", default-features = false }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "seamantic"
|
name = "seamantic"
|
||||||
version = "0.0.9"
|
version = "0.0.10"
|
||||||
|
|
||||||
categories = []
|
categories = []
|
||||||
description = "A library to enhance SeaORM"
|
description = "A library to enhance SeaORM"
|
||||||
@@ -35,6 +35,7 @@ sea-orm-migration = { workspace = true }
|
|||||||
serde = { workspace = true, features = ["derive", "std"], optional = true }
|
serde = { workspace = true, features = ["derive", "std"], optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
sea-orm = { workspace = true, features = ["entity-registry", "schema-sync"] }
|
||||||
sea-orm-migration = { workspace = true, features = ["runtime-tokio-rustls"] }
|
sea-orm-migration = { workspace = true, features = ["runtime-tokio-rustls"] }
|
||||||
serde_test = { workspace = true }
|
serde_test = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["rt", "macros"] }
|
tokio = { workspace = true, features = ["rt", "macros"] }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ type DurationRepr = u64;
|
|||||||
///
|
///
|
||||||
/// ### Warning:
|
/// ### Warning:
|
||||||
/// Sub-second precision will be lost
|
/// Sub-second precision will be lost
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
|||||||
+199
-12
@@ -11,34 +11,221 @@ use sea_orm_migration::sea_query::{ColumnDef, IntoIden};
|
|||||||
/// and should be tagged with:
|
/// and should be tagged with:
|
||||||
///
|
///
|
||||||
/// `#[sea_orm(primary_key, auto_increment = false)]`
|
/// `#[sea_orm(primary_key, auto_increment = false)]`
|
||||||
|
///
|
||||||
|
/// When using the new entity format:
|
||||||
|
///
|
||||||
|
/// use sea_orm::entity::prelude::*;
|
||||||
|
/// use seamantic::model::id::Id;
|
||||||
|
///
|
||||||
|
/// #[sea_orm::model]
|
||||||
|
/// #[derive(Debug, Clone, DeriveEntityModel)]
|
||||||
|
/// #[sea_orm(table_name = "rowid_test")]
|
||||||
|
/// pub struct Model {
|
||||||
|
/// #[sea_orm(column_type = "Integer", primary_key, nullable, auto_increment = false)]
|
||||||
|
/// id: Id<Model>,
|
||||||
|
/// }
|
||||||
|
/// impl ActiveModelBehavior for ActiveModel {}
|
||||||
pub fn sqlite_rowid_alias<T: IntoIden>(name: T) -> ColumnDef {
|
pub fn sqlite_rowid_alias<T: IntoIden>(name: T) -> ColumnDef {
|
||||||
integer_null(name).primary_key().take()
|
integer_null(name).primary_key().take()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the column to be a case insensitive string
|
/// Set the column to be a case insensitive string
|
||||||
|
///
|
||||||
|
/// When using the new entity format:
|
||||||
|
///
|
||||||
|
/// use sea_orm::entity::prelude::*;
|
||||||
|
/// use seamantic::model::id::Id;
|
||||||
|
///
|
||||||
|
/// #[sea_orm::model]
|
||||||
|
/// #[derive(Debug, Clone, DeriveEntityModel)]
|
||||||
|
/// #[sea_orm(table_name = "nocase_test")]
|
||||||
|
/// pub struct Model {
|
||||||
|
/// #[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
/// id: i64,
|
||||||
|
/// #[sea_orm(extra = "COLLATE NOCASE")]
|
||||||
|
/// nocase: String,
|
||||||
|
/// }
|
||||||
|
/// impl ActiveModelBehavior for ActiveModel {}
|
||||||
pub fn sqlite_case_insensitive_string<T: IntoIden>(name: T) -> ColumnDef {
|
pub fn sqlite_case_insensitive_string<T: IntoIden>(name: T) -> ColumnDef {
|
||||||
string(name).extra("COLLATE NOCASE").take()
|
string(name).extra("COLLATE NOCASE").take()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod entity_tests {
|
||||||
use sea_orm_migration::async_trait::async_trait;
|
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
|
||||||
use sea_orm_migration::sea_orm::QueryFilter;
|
|
||||||
use sea_orm_migration::sea_orm::{
|
pub async fn new_initialized_memory_db() -> DatabaseConnection {
|
||||||
ActiveModelBehavior, ActiveModelTrait, ActiveValue::NotSet, ActiveValue::Set, ColumnTrait,
|
let options = ConnectOptions::new("sqlite::memory:");
|
||||||
ConnectOptions, Database, DatabaseConnection, DbErr, DeriveEntityModel,
|
|
||||||
DeriveMigrationName, DerivePrimaryKey, EntityTrait, EnumIter, PrimaryKeyTrait, RelationDef,
|
let db = Database::connect(options)
|
||||||
RelationTrait,
|
.await
|
||||||
|
.expect("Database::connect()");
|
||||||
|
db.get_schema_registry("seamantic::schema::sqlite::*")
|
||||||
|
.sync(&db)
|
||||||
|
.await
|
||||||
|
.expect("db.get_schema_registry().sync()");
|
||||||
|
db
|
||||||
|
}
|
||||||
|
|
||||||
|
mod rowid_test {
|
||||||
|
use sea_orm::ActiveValue::{NotSet, Set};
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
use crate::model::id::{Id, SeaOrmRepr};
|
||||||
|
|
||||||
|
#[sea_orm::model]
|
||||||
|
#[derive(Debug, Clone, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "rowid_test")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(column_type = "Integer", primary_key, nullable, auto_increment = false)]
|
||||||
|
id: Id<Model>,
|
||||||
|
}
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_sqlite_rowid_alias() {
|
||||||
|
let db = super::new_initialized_memory_db().await;
|
||||||
|
|
||||||
|
// Starts at 1 and increments
|
||||||
|
for i in 1..=3 {
|
||||||
|
let model = ActiveModel { id: NotSet };
|
||||||
|
let model = model.insert(&db).await.expect("insert");
|
||||||
|
assert_eq!(model.id.into_raw(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the top number and re-add
|
||||||
|
for i in 3..=3 {
|
||||||
|
let model = ActiveModel {
|
||||||
|
id: Set(Id::from_raw(i)),
|
||||||
};
|
};
|
||||||
use sea_orm_migration::sea_query::{self, Iden, Table};
|
model.delete(&db).await.expect("delete");
|
||||||
use sea_orm_migration::{MigrationTrait, MigratorTrait, SchemaManager};
|
let model = ActiveModel { id: NotSet };
|
||||||
|
let model = model.insert(&db).await.expect("insert");
|
||||||
|
assert_eq!(model.id.into_raw(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jump to 100 and increment
|
||||||
|
for i in 100..=103 {
|
||||||
|
let model = ActiveModel {
|
||||||
|
id: Set(Id::from_raw(i)),
|
||||||
|
};
|
||||||
|
let model = model.insert(&db).await.expect("insert");
|
||||||
|
assert_eq!(model.id.into_raw(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue to increment
|
||||||
|
for i in 104..=104 {
|
||||||
|
let model = ActiveModel { id: NotSet };
|
||||||
|
let model = model.insert(&db).await.expect("insert");
|
||||||
|
assert_eq!(model.id.into_raw(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jump to SeaOrmRepr::MAX and increment
|
||||||
|
for i in SeaOrmRepr::MAX..=SeaOrmRepr::MAX {
|
||||||
|
let model = ActiveModel {
|
||||||
|
id: Set(Id::from_raw(i)),
|
||||||
|
};
|
||||||
|
let model = model.insert(&db).await.expect("insert");
|
||||||
|
assert_eq!(model.id.into_raw(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next ones are random around the center
|
||||||
|
for _ in 0..3 {
|
||||||
|
let model = ActiveModel { id: NotSet };
|
||||||
|
let model = model.insert(&db).await.expect("insert");
|
||||||
|
assert!(model.id.into_raw() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero ID is valid
|
||||||
|
for i in 0..=0 {
|
||||||
|
let model = ActiveModel {
|
||||||
|
id: Set(Id::from_raw(i)),
|
||||||
|
};
|
||||||
|
let model = model.insert(&db).await.expect("insert");
|
||||||
|
assert_eq!(model.id.into_raw(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negative ID is valid
|
||||||
|
for i in SeaOrmRepr::MIN..=(SeaOrmRepr::MIN + 3) {
|
||||||
|
let model = ActiveModel {
|
||||||
|
id: Set(Id::from_raw(i)),
|
||||||
|
};
|
||||||
|
let model = model.insert(&db).await.expect("insert");
|
||||||
|
assert_eq!(model.id.into_raw(), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod nocase_test {
|
||||||
|
use sea_orm::ActiveValue::Set;
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
#[sea_orm::model]
|
||||||
|
#[derive(Debug, Clone, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "nocase_test")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
id: i64,
|
||||||
|
case: String,
|
||||||
|
#[sea_orm(extra = "COLLATE NOCASE")]
|
||||||
|
nocase: String,
|
||||||
|
}
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_sqlite_case_insensitive_string() {
|
||||||
|
let db = super::new_initialized_memory_db().await;
|
||||||
|
|
||||||
|
let i = 50;
|
||||||
|
|
||||||
|
// Insert a lowercase string
|
||||||
|
{
|
||||||
|
let model = ActiveModel {
|
||||||
|
id: Set(i),
|
||||||
|
case: Set("abcd".to_owned()),
|
||||||
|
nocase: Set("abcd".to_owned()),
|
||||||
|
};
|
||||||
|
model.insert(&db).await.expect("insert");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query by uppercase string
|
||||||
|
{
|
||||||
|
Entity::find()
|
||||||
|
.filter(Column::Case.eq("ABCD"))
|
||||||
|
.one(&db)
|
||||||
|
.await
|
||||||
|
.expect("find by case insensitive string")
|
||||||
|
.ok_or(())
|
||||||
|
.expect_err("find by case insensitive string");
|
||||||
|
|
||||||
|
let model = Entity::find()
|
||||||
|
.filter(Column::Nocase.eq("ABCD"))
|
||||||
|
.one(&db)
|
||||||
|
.await
|
||||||
|
.expect("find by case insensitive string")
|
||||||
|
.expect("find by case insensitive string");
|
||||||
|
assert_eq!(model.id, i);
|
||||||
|
// The string should be read back as-is
|
||||||
|
assert_eq!(model.nocase, "abcd");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use sea_orm::ActiveValue::{NotSet, Set};
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
|
||||||
|
use sea_orm_migration::async_trait::async_trait;
|
||||||
|
use sea_orm_migration::prelude::*;
|
||||||
|
|
||||||
use crate::model::id::{Id, SeaOrmRepr};
|
use crate::model::id::{Id, SeaOrmRepr};
|
||||||
|
|
||||||
use super::{sqlite_case_insensitive_string, sqlite_rowid_alias};
|
use super::{sqlite_case_insensitive_string, sqlite_rowid_alias};
|
||||||
|
|
||||||
async fn new_memory_db() -> DatabaseConnection {
|
async fn new_memory_db() -> DatabaseConnection {
|
||||||
let options = ConnectOptions::new("sqlite:/tmp/db?mode=memory");
|
let options = ConnectOptions::new("sqlite::memory:");
|
||||||
Database::connect(options).await.expect("Database::connect")
|
Database::connect(options).await.expect("Database::connect")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +415,7 @@ mod tests {
|
|||||||
// Query by uppercase string
|
// Query by uppercase string
|
||||||
{
|
{
|
||||||
let model = Entity::find()
|
let model = Entity::find()
|
||||||
.filter(Column::CiStr.contains("ABCD"))
|
.filter(Column::CiStr.eq("ABCD"))
|
||||||
.one(&db)
|
.one(&db)
|
||||||
.await
|
.await
|
||||||
.expect("find by case insensitive string")
|
.expect("find by case insensitive string")
|
||||||
|
|||||||
Reference in New Issue
Block a user