This commit is contained in:
Chris Tsang 2023-07-26 21:09:25 +01:00
parent 530c612bc4
commit ec581abf56
4 changed files with 30 additions and 21 deletions

View File

@ -1,5 +1,5 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use sea_orm::{TryGetError, TryGetable}; use sea_orm::TryGetableFromJson;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: i32, pub id: i32,
pub str_vec: StringVec, pub str_vec: Option<StringVec>,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@ -18,26 +18,25 @@ impl ActiveModelBehavior for ActiveModel {}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct StringVec(pub Vec<String>); pub struct StringVec(pub Vec<String>);
impl TryGetableFromJson for StringVec {}
impl From<StringVec> for Value { impl From<StringVec> for Value {
fn from(source: StringVec) -> Self { fn from(source: StringVec) -> Self {
Value::String(serde_json::to_string(&source).ok().map(Box::new)) sea_orm::Value::Json(
} serde_json::to_value(&source)
} .ok()
.map(|s| std::boxed::Box::new(s)),
impl TryGetable for StringVec { )
fn try_get_by<I: sea_orm::ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {
let json_str: String = res.try_get_by(idx).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 { impl sea_query::ValueType for StringVec {
fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> { fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {
match v { match v {
Value::String(Some(x)) => Ok(StringVec( sea_orm::Value::Json(Some(json)) => {
serde_json::from_str(&x).map_err(|_| sea_query::ValueTypeErr)?, Ok(serde_json::from_value(*json).map_err(|_| sea_orm::sea_query::ValueTypeErr)?)
)), }
_ => Err(sea_query::ValueTypeErr), _ => Err(sea_orm::sea_query::ValueTypeErr),
} }
} }
@ -46,10 +45,16 @@ impl sea_query::ValueType for StringVec {
} }
fn array_type() -> sea_orm::sea_query::ArrayType { fn array_type() -> sea_orm::sea_query::ArrayType {
sea_orm::sea_query::ArrayType::String sea_orm::sea_query::ArrayType::Json
} }
fn column_type() -> sea_query::ColumnType { fn column_type() -> sea_query::ColumnType {
sea_query::ColumnType::String(None) sea_query::ColumnType::Json
}
}
impl sea_orm::sea_query::Nullable for StringVec {
fn null() -> sea_orm::Value {
sea_orm::Value::Json(None)
} }
} }

View File

@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: i32, pub id: i32,
pub str_vec: StringVec, pub str_vec: Option<StringVec>,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]

View File

@ -313,7 +313,7 @@ pub async fn create_json_vec_table(db: &DbConn) -> Result<ExecResult, DbErr> {
.auto_increment() .auto_increment()
.primary_key(), .primary_key(),
) )
.col(ColumnDef::new(json_vec::Column::StrVec).string().not_null()) .col(ColumnDef::new(json_vec::Column::StrVec).json())
.to_owned(); .to_owned();
create_table(db, &create_table_stmt, JsonVec).await create_table(db, &create_table_stmt, JsonVec).await

View File

@ -23,7 +23,11 @@ async fn main() -> Result<(), DbErr> {
pub async fn insert_json_vec(db: &DatabaseConnection) -> Result<(), DbErr> { pub async fn insert_json_vec(db: &DatabaseConnection) -> Result<(), DbErr> {
let json_vec = json_vec::Model { let json_vec = json_vec::Model {
id: 1, id: 1,
str_vec: json_vec::StringVec(vec!["1".to_string(), "2".to_string(), "3".to_string()]), str_vec: Some(json_vec::StringVec(vec![
"1".to_string(),
"2".to_string(),
"3".to_string(),
])),
}; };
let result = json_vec.clone().into_active_model().insert(db).await?; let result = json_vec.clone().into_active_model().insert(db).await?;
@ -43,11 +47,11 @@ pub async fn insert_json_vec(db: &DatabaseConnection) -> Result<(), DbErr> {
pub async fn insert_json_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> { pub async fn insert_json_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> {
let json_vec = json_vec_derive::Model { let json_vec = json_vec_derive::Model {
id: 2, id: 2,
str_vec: json_vec_derive::StringVec(vec![ str_vec: Some(json_vec_derive::StringVec(vec![
"4".to_string(), "4".to_string(),
"5".to_string(), "5".to_string(),
"6".to_string(), "6".to_string(),
]), ])),
}; };
let result = json_vec.clone().into_active_model().insert(db).await?; let result = json_vec.clone().into_active_model().insert(db).await?;