Skip to content

Commit

Permalink
Vector of string save as serialized format in db
Browse files Browse the repository at this point in the history
  • Loading branch information
billy1624 committed Jun 2, 2022
1 parent a0925cc commit 85b64ff
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
51 changes: 51 additions & 0 deletions tests/common/features/json_vec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use sea_orm::entity::prelude::*;
use sea_orm::{TryGetError, TryGetable};
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "json_vec")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub str_vec: StringVec,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct StringVec(pub Vec<String>);

impl From<StringVec> for Value {
fn from(source: StringVec) -> Self {
Value::String(serde_json::to_string(&source).ok().map(|s| Box::new(s)))
}
}

impl TryGetable for StringVec {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let json_str: String = res.try_get(pre, col).map_err(TryGetError::DbErr)?;
serde_json::from_str(&json_str).map_err(|e| TryGetError::DbErr(DbErr::Json(e.to_string())))
}
}

impl sea_query::ValueType for StringVec {
fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {
match v {
Value::String(Some(x)) => Ok(StringVec(
serde_json::from_str(&x).map_err(|_| sea_query::ValueTypeErr)?,
)),
_ => Err(sea_query::ValueTypeErr),
}
}

fn type_name() -> String {
stringify!(StringVec).to_owned()
}

fn column_type() -> sea_query::ColumnType {
sea_query::ColumnType::String(None)
}
}
2 changes: 2 additions & 0 deletions tests/common/features/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod active_enum_child;
pub mod applog;
pub mod byte_primary_key;
pub mod insert_default;
pub mod json_vec;
pub mod metadata;
pub mod repository;
pub mod satellite;
Expand All @@ -16,6 +17,7 @@ pub use active_enum_child::Entity as ActiveEnumChild;
pub use applog::Entity as Applog;
pub use byte_primary_key::Entity as BytePrimaryKey;
pub use insert_default::Entity as InsertDefault;
pub use json_vec::Entity as JsonVec;
pub use metadata::Entity as Metadata;
pub use repository::Entity as Repository;
pub use satellite::Entity as Satellite;
Expand Down
21 changes: 21 additions & 0 deletions tests/common/features/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> {
create_byte_primary_key_table(db).await?;
create_satellites_table(db).await?;
create_transaction_log_table(db).await?;
create_json_vec_table(db).await?;

let create_enum_stmts = match db_backend {
DbBackend::MySql | DbBackend::Sqlite => Vec::new(),
Expand Down Expand Up @@ -286,3 +287,23 @@ pub async fn create_insert_default_table(db: &DbConn) -> Result<ExecResult, DbEr

create_table(db, &create_table_stmt, InsertDefault).await
}

pub async fn create_json_vec_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let create_table_stmt = sea_query::Table::create()
.table(json_vec::Entity.table_ref())
.col(
ColumnDef::new(json_vec::Column::Id)
.integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(
ColumnDef::new(json_vec::Column::StrVec)
.string()
.not_null(),
)
.to_owned();

create_table(db, &create_table_stmt, JsonVec).await
}
49 changes: 49 additions & 0 deletions tests/json_vec_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
pub mod common;

pub use common::{features::*, setup::*, TestContext};
use pretty_assertions::assert_eq;
use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection};

#[sea_orm_macros::test]
#[cfg(any(
feature = "sqlx-mysql",
feature = "sqlx-sqlite",
feature = "sqlx-postgres"
))]
async fn main() -> Result<(), DbErr> {
let ctx = TestContext::new("json_vec_tests").await;
create_tables(&ctx.db).await?;
insert_json_vec(&ctx.db).await?;
ctx.delete().await;

Ok(())
}

pub async fn insert_json_vec(db: &DatabaseConnection) -> Result<(), DbErr> {
let json_vec = json_vec::Model {
id: 1,
str_vec: json_vec::StringVec(vec![
"1".to_string(),
"2".to_string(),
"3".to_string(),
])
};

let result = json_vec.clone().into_active_model().insert(db).await?;

assert_eq!(result, json_vec);

let model = json_vec::Entity::find()
.filter(json_vec::Column::Id.eq(json_vec.id))
.one(db)
.await?;

assert_eq!(
model,
Some(json_vec)
);

assert!(false);

Ok(())
}

0 comments on commit 85b64ff

Please sign in to comment.