From 2a7a2ffc99a4b267a61f9e98ae5f744ec050fc41 Mon Sep 17 00:00:00 2001 From: soul-walker <31162815+soul-walker@users.noreply.github.com> Date: Thu, 19 Sep 2024 00:07:53 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8D=89=E7=A8=BF=E5=92=8C=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=B7=BB=E5=8A=A0options=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B9=20=E5=AE=9E=E7=8E=B0=E9=85=8D=E7=BD=AE=E9=A1=B9?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84CRUD=20=E8=B0=83=E6=95=B4=E8=8D=89?= =?UTF-8?q?=E7=A8=BF=E6=95=B0=E6=8D=AE=E7=AE=A1=E7=90=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 1 + Cargo.lock | 3 + Cargo.toml | 1 + crates/rtss_api/Cargo.toml | 4 +- crates/rtss_api/src/draft_data.rs | 183 +++++++++++++++++---- crates/rtss_db/Cargo.toml | 2 + crates/rtss_db/src/db_access/draft_data.rs | 76 +++++++-- crates/rtss_db/src/model.rs | 13 +- crates/rtss_dto/Cargo.toml | 1 + crates/rtss_dto/build.rs | 5 + crates/rtss_dto/src/pb/common.rs | 41 +++++ migrations/20240830095636_init.up.sql | 9 + rtss-proto-msg | 2 +- 13 files changed, 289 insertions(+), 52 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c28db26..21cd088 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,6 +11,7 @@ "Joylink", "jsonwebtoken", "mplj", + "Neng", "plpgsql", "prost", "proto", diff --git a/Cargo.lock b/Cargo.lock index bb09e65..105a870 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2199,6 +2199,8 @@ dependencies = [ "anyhow", "rtss_dto", "rtss_log", + "serde", + "serde_json", "sqlx", "thiserror", ] @@ -2210,6 +2212,7 @@ dependencies = [ "async-graphql", "prost", "prost-build", + "serde", "sqlx", ] diff --git a/Cargo.toml b/Cargo.toml index b64e63b..e09bfb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ sqlx = { version = "0.8", features = [ "chrono", ] } serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.125" anyhow = "1.0" [dependencies] diff --git a/crates/rtss_api/Cargo.toml b/crates/rtss_api/Cargo.toml index 2f05fc6..8cf242c 100644 --- a/crates/rtss_api/Cargo.toml +++ b/crates/rtss_api/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" [dependencies] anyhow = { workspace = true } tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } -serde = { version = "1.0.208", features = ["derive"] } -serde_json = "1.0.125" +serde = { workspace = true } +serde_json = { workspace = true } chrono = { version = "0.4.38", features = ["serde"] } axum = "0.7.5" axum-extra = { version = "0.9.3", features = ["typed-header"] } diff --git a/crates/rtss_api/src/draft_data.rs b/crates/rtss_api/src/draft_data.rs index 3c01cf1..ed51af4 100644 --- a/crates/rtss_api/src/draft_data.rs +++ b/crates/rtss_api/src/draft_data.rs @@ -1,8 +1,13 @@ use async_graphql::{Context, InputObject, Object, SimpleObject}; +use async_graphql::{InputType, OutputType}; use chrono::{DateTime, Local}; +use rtss_db::common::TableColumn; +use rtss_db::model::DraftDataColumn; use rtss_db::DraftDataAccessor; use rtss_db::RtssDbAccessor; -use rtss_dto::common::DataType; +use rtss_dto::common::{DataType, IscsStyle}; +use serde::de::DeserializeOwned; +use serde::{Deserialize, Serialize}; use crate::pagination::PageQueryDto; @@ -28,12 +33,12 @@ impl DraftDataQuery { Ok(paging_result.into()) } /// 分页查询用户的草稿数据 - async fn user_draft_data_paging<'ctx>( + async fn user_draft_iscs_data_paging<'ctx>( &self, ctx: &Context<'ctx>, paging: PageQueryDto, - query: UserDraftDataFilterDto, - ) -> async_graphql::Result { + query: UserDraftDataFilterDto, + ) -> async_graphql::Result { let db_accessor = ctx.data::()?; let paging_result = db_accessor .query_draft_data(query.into(), paging.into()) @@ -41,12 +46,12 @@ impl DraftDataQuery { Ok(paging_result.into()) } /// 分页查询共享的草稿数据 - async fn shared_draft_data_paging<'ctx>( + async fn shared_draft_iscs_data_paging<'ctx>( &self, ctx: &Context<'ctx>, paging: PageQueryDto, - query: SharedDraftDataFilterDto, - ) -> async_graphql::Result { + query: SharedDraftDataFilterDto, + ) -> async_graphql::Result { let db_accessor = ctx.data::()?; let paging_result = db_accessor .query_draft_data(query.into(), paging.into()) @@ -54,7 +59,11 @@ impl DraftDataQuery { Ok(paging_result.into()) } /// 根据id获取草稿数据 - async fn draft_data(&self, ctx: &Context<'_>, id: i32) -> async_graphql::Result { + async fn draft_data( + &self, + ctx: &Context<'_>, + id: i32, + ) -> async_graphql::Result { let db_accessor = ctx.data::()?; let draft_data = db_accessor.query_draft_data_by_id(id).await?; Ok(draft_data.into()) @@ -74,12 +83,12 @@ impl DraftDataQuery { #[Object] impl DraftDataMutation { - /// 创建草稿数据 - async fn create_draft_data( + /// 创建草稿ISCS数据 + async fn create_draft_iscs_data( &self, ctx: &Context<'_>, - input: CreateDraftDataDto, - ) -> async_graphql::Result { + input: CreateDraftDataDto, + ) -> async_graphql::Result> { let db_accessor = ctx.data::()?; let draft_data = db_accessor.create_draft_data(input.into()).await?; Ok(draft_data.into()) @@ -90,7 +99,7 @@ impl DraftDataMutation { ctx: &Context<'_>, id: i32, name: String, - ) -> async_graphql::Result { + ) -> async_graphql::Result { let db_accessor = ctx.data::()?; let draft_data = db_accessor.update_draft_data_name(id, &name).await?; Ok(draft_data.into()) @@ -101,7 +110,7 @@ impl DraftDataMutation { ctx: &Context<'_>, id: i32, data: Vec, - ) -> async_graphql::Result { + ) -> async_graphql::Result { let db_accessor = ctx.data::()?; let draft_data = db_accessor .update_draft_data_data(id, data.as_slice()) @@ -114,7 +123,7 @@ impl DraftDataMutation { ctx: &Context<'_>, id: i32, is_shared: bool, - ) -> async_graphql::Result { + ) -> async_graphql::Result { let db_accessor = ctx.data::()?; let draft_data = db_accessor.set_draft_data_shared(id, is_shared).await?; Ok(draft_data.into()) @@ -135,7 +144,7 @@ impl DraftDataMutation { ctx: &Context<'_>, id: i32, release_data_id: i32, - ) -> async_graphql::Result { + ) -> async_graphql::Result { let db_accessor = ctx.data::()?; let draft_data = db_accessor .set_default_release_data_id(id, release_data_id) @@ -149,7 +158,7 @@ impl DraftDataMutation { id: i32, name: String, user_id: i32, - ) -> async_graphql::Result { + ) -> async_graphql::Result { let db_accessor = ctx.data::()?; let draft_data = db_accessor.save_as_new_draft(id, &name, user_id).await?; Ok(draft_data.into()) @@ -157,54 +166,87 @@ impl DraftDataMutation { } #[derive(Debug, InputObject)] -pub struct CreateDraftDataDto { +#[graphql(concrete(name = "CreateDraftIscsDto", params(IscsDataOptions)))] +pub struct CreateDraftDataDto { pub name: String, - pub data_type: rtss_dto::common::DataType, - pub data: Vec, + pub options: Option, pub user_id: i32, } -impl From for rtss_db::CreateDraftData { - fn from(value: CreateDraftDataDto) -> Self { - Self::new(&value.name, value.data_type, value.user_id).with_data(value.data.as_slice()) +impl From> for rtss_db::CreateDraftData { + fn from(value: CreateDraftDataDto) -> Self { + let cdd = Self::new(&value.name, DataType::Iscs, value.user_id); + if value.options.is_some() { + cdd.with_options(serde_json::to_value(value.options).unwrap()) + } else { + cdd + } } } /// 用户的草稿数据查询条件 #[derive(Debug, InputObject)] -pub struct UserDraftDataFilterDto { +#[graphql(concrete(name = "UserDraftIscsDataFilterDto", params(IscsDataOptions)))] +pub struct UserDraftDataFilterDto { pub user_id: i32, pub name: Option, pub data_type: Option, + pub options: Option, pub is_shared: Option, } -impl From for rtss_db::DraftDataQuery { - fn from(value: UserDraftDataFilterDto) -> Self { +impl From> for rtss_db::DraftDataQuery { + fn from(value: UserDraftDataFilterDto) -> Self { Self { user_id: Some(value.user_id), name: value.name, data_type: value.data_type, + options_filter: value.options.map(|o| o.to_data_options_filter_clause()), is_shared: value.is_shared, } } } +pub trait DataOptions: InputType + OutputType + Serialize + DeserializeOwned { + fn to_data_options_filter_clause(&self) -> String; +} + +#[derive(Debug, InputObject, SimpleObject, Serialize, Deserialize)] +#[graphql(input_name = "IscsDataOptionsInput")] +pub struct IscsDataOptions { + pub style: IscsStyle, +} + +impl DataOptions for IscsDataOptions { + fn to_data_options_filter_clause(&self) -> String { + let options_column = DraftDataColumn::Options.name(); + // format!("{options_column}['style'] = '\"{}\"'", self.style.as_str_name()) + format!( + "{options_column} @> '{}'", + serde_json::to_string(self).unwrap() + ) + } +} + /// 共享的草稿数据查询条件 #[derive(Debug, InputObject)] -pub struct SharedDraftDataFilterDto { +#[graphql(concrete(name = "SharedDraftIscsDataFilterDto", params(IscsDataOptions)))] + +pub struct SharedDraftDataFilterDto { pub user_id: Option, pub name: Option, pub data_type: Option, + pub options: Option, } -impl From for rtss_db::DraftDataQuery { - fn from(value: SharedDraftDataFilterDto) -> Self { +impl From> for rtss_db::DraftDataQuery { + fn from(value: SharedDraftDataFilterDto) -> Self { Self { user_id: value.user_id, name: value.name, data_type: value.data_type, is_shared: Some(true), + options_filter: value.options.map(|o| o.to_data_options_filter_clause()), } } } @@ -225,15 +267,17 @@ impl From for rtss_db::DraftDataQuery { name: value.name, data_type: value.data_type, is_shared: value.is_shared, + options_filter: None, } } } #[derive(Debug, SimpleObject)] -pub struct DraftData { +pub struct DraftDataWithStringOptions { pub id: i32, pub name: String, pub data_type: rtss_dto::common::DataType, + pub options: Option, pub data: Option>, pub user_id: i32, pub is_shared: bool, @@ -241,12 +285,43 @@ pub struct DraftData { pub updated_at: DateTime, } -impl From for DraftData { +impl From for DraftDataWithStringOptions { fn from(value: rtss_db::model::DraftDataModel) -> Self { Self { id: value.id, name: value.name, data_type: DataType::try_from(value.data_type).unwrap(), + options: value.options.map(|o| serde_json::to_string(&o).unwrap()), + data: value.data, + user_id: value.user_id, + is_shared: value.is_shared, + created_at: value.created_at, + updated_at: value.updated_at, + } + } +} + +#[derive(Debug, SimpleObject)] +#[graphql(concrete(name = "DraftIscsData", params(IscsDataOptions)))] +pub struct DraftData { + pub id: i32, + pub name: String, + pub data_type: rtss_dto::common::DataType, + pub options: Option, + pub data: Option>, + pub user_id: i32, + pub is_shared: bool, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +impl From for DraftData { + fn from(value: rtss_db::model::DraftDataModel) -> Self { + Self { + id: value.id, + name: value.name, + data_type: DataType::try_from(value.data_type).unwrap(), + options: value.options.map(|o| serde_json::from_value(o).unwrap()), data: value.data, user_id: value.user_id, is_shared: value.is_shared, @@ -259,7 +334,7 @@ impl From for DraftData { #[derive(Debug, SimpleObject)] pub struct DraftDataPage { pub total: i64, - pub data: Vec, + pub data: Vec, } impl From> for DraftDataPage { @@ -270,3 +345,47 @@ impl From> for Draft } } } + +#[derive(Debug, SimpleObject)] +pub struct DraftIscsDataPage { + pub total: i64, + pub data: Vec>, +} + +impl From> for DraftIscsDataPage { + fn from(value: rtss_db::common::PageResult) -> Self { + Self { + total: value.total, + data: value.data.into_iter().map(|m| m.into()).collect(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_iscs_data_options_serialize() { + rtss_log::Logging::default().init(); + let options = IscsDataOptions { + style: IscsStyle::DaShiZhiNeng, + }; + let json = serde_json::to_string(&options).unwrap(); + println!("{}", json); + println!("{}", options.style.as_str_name()); + assert_eq!(json, r#"{"style":"DaShiZhiNeng"}"#); + let options: IscsDataOptions = serde_json::from_str(&json).unwrap(); + assert_eq!(options.style, IscsStyle::DaShiZhiNeng); + } + + #[test] + fn test_iscs_data_options_into_data_options_filter_clause() { + let options = IscsDataOptions { + style: IscsStyle::DaShiZhiNeng, + }; + let clause = options.to_data_options_filter_clause(); + println!("{clause}"); + assert_eq!(clause, r#"options @> '{"style":"DaShiZhiNeng"}'"#); + } +} diff --git a/crates/rtss_db/Cargo.toml b/crates/rtss_db/Cargo.toml index 946e724..8fc0590 100644 --- a/crates/rtss_db/Cargo.toml +++ b/crates/rtss_db/Cargo.toml @@ -5,6 +5,8 @@ edition = "2021" [dependencies] anyhow = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } sqlx = { workspace = true, features = [ "runtime-tokio", "macros", diff --git a/crates/rtss_db/src/db_access/draft_data.rs b/crates/rtss_db/src/db_access/draft_data.rs index e91eda2..dc7491c 100644 --- a/crates/rtss_db/src/db_access/draft_data.rs +++ b/crates/rtss_db/src/db_access/draft_data.rs @@ -2,6 +2,7 @@ use std::vec; use rtss_dto::common::DataType; use rtss_log::tracing::debug; +use serde_json::Value; use crate::{ common::{PageQuery, PageResult, Sort, SortOrder, TableColumn}, @@ -69,6 +70,8 @@ pub struct DraftDataQuery { pub user_id: Option, pub name: Option, pub data_type: Option, + /// 选项过滤条件,由业务层构建并确保合法性 + pub options_filter: Option, pub is_shared: Option, } @@ -97,6 +100,11 @@ impl DraftDataQuery { self } + pub fn with_options_filter(mut self, options_filter: &str) -> Self { + self.options_filter = Some(options_filter.to_string()); + self + } + fn build_filter(&self) -> String { let mut filters = vec![]; if let Some(user_id) = self.user_id { @@ -123,6 +131,9 @@ impl DraftDataQuery { is_shared )); } + if let Some(options_filter) = &self.options_filter { + filters.push(options_filter.clone()); + } if filters.is_empty() { "".to_string() } else { @@ -134,6 +145,7 @@ impl DraftDataQuery { pub struct CreateDraftData { name: String, data_type: DataType, + options: Option, data: Option>, default_release_data_id: Option, user_id: i32, @@ -144,12 +156,18 @@ impl CreateDraftData { CreateDraftData { name: name.to_string(), data_type, + options: None, data: None, default_release_data_id: None, user_id, } } + pub fn with_options(mut self, options: Value) -> Self { + self.options = Some(options); + self + } + pub fn with_data(mut self, data: &[u8]) -> Self { self.data = Some(data.to_vec()); self @@ -240,21 +258,23 @@ impl DraftDataAccessor for RtssDbAccessor { // 插入数据 let table = DraftDataColumn::Table.name(); let columns = format!( - "{}, {}, {}, {}, {}", + "{}, {}, {}, {}, {}, {}", DraftDataColumn::Name.name(), DraftDataColumn::DataType.name(), + DraftDataColumn::Options.name(), DraftDataColumn::UserId.name(), DraftDataColumn::Data.name(), DraftDataColumn::DefaultReleaseDataId.name(), ); let sql = - format!("INSERT INTO {table} ({columns}) VALUES ($1, $2, $3, $4, $5) RETURNING *",); + format!("INSERT INTO {table} ({columns}) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *",); // log sql debug!("create sql: {}", sql); // 插入数据 let draft_data: DraftDataModel = sqlx::query_as(&sql) .bind(create.name) .bind(create.data_type as i32) + .bind(create.options) .bind(create.user_id) .bind(create.data) .bind(create.default_release_data_id) @@ -380,9 +400,16 @@ impl DraftDataAccessor for RtssDbAccessor { #[cfg(test)] mod tests { use super::*; + use rtss_dto::common::IscsStyle; use rtss_log::tracing::Level; + use serde::{Deserialize, Serialize}; use sqlx::PgPool; + #[derive(Debug, Serialize, Deserialize)] + pub struct IscsDataOptions { + pub style: IscsStyle, + } + // You could also do `use foo_crate::MIGRATOR` and just refer to it as `MIGRATOR` here. #[sqlx::test(migrator = "crate::MIGRATOR")] async fn basic_use_test(pool: PgPool) -> Result<(), DbAccessError> { @@ -455,15 +482,7 @@ mod tests { // 查询确认当前数据已删除 let page = accessor - .query_draft_data( - DraftDataQuery { - user_id: None, - name: None, - data_type: None, - is_shared: None, - }, - PageQuery::new(1, 100), - ) + .query_draft_data(DraftDataQuery::new(), PageQuery::new(1, 100)) .await?; assert_eq!(page.total, 0); @@ -471,11 +490,28 @@ mod tests { // 分四个user_id各插入5条数据 for i in 1..5 { for j in 1..6 { - let draft = accessor - .create_draft_data(CreateDraftData::new(&format!("test{}", j), DataType::Em, i)) - .await?; if i == 1 { + let draft = accessor + .create_draft_data( + CreateDraftData::new(&format!("test{}", j), DataType::Iscs, i) + .with_options( + serde_json::to_value(IscsDataOptions { + style: IscsStyle::DaShiZhiNeng, + }) + .unwrap(), + ), + ) + .await?; + println!("{:?}", draft); accessor.set_draft_data_shared(draft.id, true).await?; + } else { + accessor + .create_draft_data(CreateDraftData::new( + &format!("test{}", j), + DataType::Em, + i, + )) + .await?; } } } @@ -483,7 +519,7 @@ mod tests { let page = accessor .query_draft_data( DraftDataQuery::new() - .with_user_id(1) + .with_user_id(2) .with_name("test".to_string()) .with_data_type(DataType::Em), PageQuery::new(1, 10), @@ -505,6 +541,16 @@ mod tests { .await?; assert_eq!(page.total, 5); + // 查询options + let page = accessor + .query_draft_data( + DraftDataQuery::new() + .with_options_filter(r#"options @> '{"style":"DaShiZhiNeng"}'"#), + PageQuery::new(1, 10), + ) + .await?; + assert_eq!(page.total, 5); + Ok(()) } } diff --git a/crates/rtss_db/src/model.rs b/crates/rtss_db/src/model.rs index 132f63a..d8c50fa 100644 --- a/crates/rtss_db/src/model.rs +++ b/crates/rtss_db/src/model.rs @@ -1,14 +1,16 @@ +use serde_json::Value; use sqlx::types::chrono::{DateTime, Local}; use crate::common::TableColumn; /// 数据库表 rtss.draft_data 列映射 #[derive(Debug)] -pub(crate) enum DraftDataColumn { +pub enum DraftDataColumn { Table, Id, Name, DataType, + Options, Data, DefaultReleaseDataId, UserId, @@ -23,6 +25,8 @@ pub struct DraftDataModel { pub name: String, pub data_type: i32, #[sqlx(default)] + pub options: Option, + #[sqlx(default)] pub data: Option>, #[sqlx(default)] pub default_release_data_id: Option, @@ -35,11 +39,12 @@ pub struct DraftDataModel { /// 数据库表 rtss.release_data 列映射 #[derive(Debug)] -pub(crate) enum ReleaseDataColumn { +pub enum ReleaseDataColumn { Table, Id, Name, DataType, + Options, UsedVersionId, UserId, IsPublished, @@ -53,6 +58,8 @@ pub struct ReleaseDataModel { pub id: i32, pub name: String, pub data_type: i32, + #[sqlx(default)] + pub options: Option, pub used_version_id: Option, pub user_id: i32, pub is_published: bool, @@ -201,6 +208,7 @@ impl TableColumn for DraftDataColumn { DraftDataColumn::Id => "id", DraftDataColumn::Name => "name", DraftDataColumn::DataType => "data_type", + DraftDataColumn::Options => "options", DraftDataColumn::Data => "data", DraftDataColumn::DefaultReleaseDataId => "default_release_data_id", DraftDataColumn::UserId => "user_id", @@ -218,6 +226,7 @@ impl TableColumn for ReleaseDataColumn { ReleaseDataColumn::Id => "id", ReleaseDataColumn::Name => "name", ReleaseDataColumn::DataType => "data_type", + ReleaseDataColumn::Options => "options", ReleaseDataColumn::UsedVersionId => "used_version_id", ReleaseDataColumn::UserId => "user_id", ReleaseDataColumn::IsPublished => "is_published", diff --git a/crates/rtss_dto/Cargo.toml b/crates/rtss_dto/Cargo.toml index 982a90c..63f5c80 100644 --- a/crates/rtss_dto/Cargo.toml +++ b/crates/rtss_dto/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" prost = "0.13" async-graphql = { version = "7.0.7", features = ["chrono"] } sqlx = { workspace = true } +serde = { workspace = true } [build-dependencies] prost-build = "0.13" diff --git a/crates/rtss_dto/build.rs b/crates/rtss_dto/build.rs index 637b086..037202c 100644 --- a/crates/rtss_dto/build.rs +++ b/crates/rtss_dto/build.rs @@ -23,6 +23,11 @@ fn main() { .out_dir("src/pb") .type_attribute("common.DataType", "#[derive(sqlx::Type)]") .type_attribute("common.DataType", "#[derive(async_graphql::Enum)]") + .type_attribute("common.IscsStyle", "#[derive(async_graphql::Enum)]") + .type_attribute( + "common.IscsStyle", + "#[derive(serde::Serialize, serde::Deserialize)]", + ) .type_attribute("common.FeatureType", "#[derive(sqlx::Type)]") .compile_protos( &[ diff --git a/crates/rtss_dto/src/pb/common.rs b/crates/rtss_dto/src/pb/common.rs index 801aad7..b1f72d6 100644 --- a/crates/rtss_dto/src/pb/common.rs +++ b/crates/rtss_dto/src/pb/common.rs @@ -141,6 +141,47 @@ impl DataType { } } } +#[derive( + async_graphql::Enum, + serde::Serialize, + serde::Deserialize, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration, +)] +#[repr(i32)] +pub enum IscsStyle { + /// 未知 + Unknown = 0, + /// 达实智能(福州一号线) + DaShiZhiNeng = 1, +} +impl IscsStyle { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + IscsStyle::Unknown => "IscsStyle_Unknown", + IscsStyle::DaShiZhiNeng => "DaShiZhiNeng", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "IscsStyle_Unknown" => Some(Self::Unknown), + "DaShiZhiNeng" => Some(Self::DaShiZhiNeng), + _ => None, + } + } +} /// 功能特性类型 #[derive( sqlx::Type, Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, diff --git a/migrations/20240830095636_init.up.sql b/migrations/20240830095636_init.up.sql index 8841666..67d0d60 100644 --- a/migrations/20240830095636_init.up.sql +++ b/migrations/20240830095636_init.up.sql @@ -7,6 +7,7 @@ CREATE TABLE id SERIAL PRIMARY KEY, -- id 自增主键 name VARCHAR(128) NOT NULL, -- 草稿名称 data_type INT NOT NULL, -- 数据类型 + options JSONB NULL, -- 数据相关的参数项或配置项 data BYTEA, -- 草稿数据 default_release_data_id INT NULL, -- 默认发布数据id user_id INT NOT NULL, -- 创建用户id @@ -22,6 +23,9 @@ CREATE INDEX ON rtss.draft_data (user_id); -- 创建草稿数据类型索引 CREATE INDEX ON rtss.draft_data (data_type); +-- 创建草稿数据配置项索引 +CREATE INDEX ON rtss.draft_data USING GIN (options); + -- 注释草稿数据表 COMMENT ON TABLE rtss.draft_data IS '草稿数据表'; @@ -32,6 +36,8 @@ COMMENT ON COLUMN rtss.draft_data.name IS '草稿名称'; COMMENT ON COLUMN rtss.draft_data.data_type IS '数据类型'; +COMMENT ON COLUMN rtss.draft_data.options IS '数据相关的参数项或配置项'; + COMMENT ON COLUMN rtss.draft_data.data IS '草稿数据'; COMMENT ON COLUMN rtss.draft_data.user_id IS '创建用户id'; @@ -48,6 +54,7 @@ CREATE TABLE id SERIAL PRIMARY KEY, -- id 自增主键 name VARCHAR(128) NOT NULL UNIQUE, -- 发布数据名称(数据唯一标识) data_type INT NOT NULL, -- 数据类型 + options JSONB NULL, -- 数据相关的参数项或配置项 used_version_id INT NULL, -- 使用的版本数据id user_id INT NOT NULL, -- 发布/更新用户id is_published BOOLEAN NOT NULL DEFAULT TRUE, -- 是否上架 @@ -65,6 +72,8 @@ COMMENT ON COLUMN rtss.release_data.name IS '发布数据名称(数据唯一标 COMMENT ON COLUMN rtss.release_data.data_type IS '数据类型'; +COMMENT ON COLUMN rtss.release_data.options IS '数据相关的参数项或配置项'; + COMMENT ON COLUMN rtss.release_data.used_version_id IS '使用的版本数据id'; COMMENT ON COLUMN rtss.release_data.user_id IS '发布/更新用户id'; diff --git a/rtss-proto-msg b/rtss-proto-msg index 4e447be..a162241 160000 --- a/rtss-proto-msg +++ b/rtss-proto-msg @@ -1 +1 @@ -Subproject commit 4e447beffa31c94b30bcee57a7cf229dcf01351f +Subproject commit a1622410919b58683bc0ec059b4f5de575583c13