diff --git a/backend/basic/src/spi/spi_initializer.rs b/backend/basic/src/spi/spi_initializer.rs index 0f996ee1b..2974c659e 100644 --- a/backend/basic/src/spi/spi_initializer.rs +++ b/backend/basic/src/spi/spi_initializer.rs @@ -436,43 +436,55 @@ EXECUTE PROCEDURE TARDIS_AUTO_UPDATE_TIME_{}();"###, Ok(()) } - /// Modify table column - /// 修改表字段 - pub async fn modify_table_column( + /// alter table column + /// 更改表字段 + pub async fn alter_table_column( conn: &TardisRelDBlConnection, tag: Option<&str>, table_flag: &str, - modify_column_kind: &ModifyColumnKind, + alter_column_kind: &AlterColumnKind, field_name: &str, - field_type: &str, + field_content: &str, add_index: Vec<(&str, &str)>, ctx: &TardisContext, ) -> TardisResult<()> { let tag = tag.map(|t| format!("_{t}")).unwrap_or_default(); let schema_name = get_schema_name_from_context(ctx); - do_modify_table_column(&schema_name, conn, &tag, table_flag, modify_column_kind, field_name, field_type, add_index).await + do_alter_table_column(&schema_name, conn, &tag, table_flag, alter_column_kind, field_name, field_content, add_index).await } - async fn do_modify_table_column( + async fn do_alter_table_column( schema_name: &str, conn: &TardisRelDBlConnection, tag: &str, table_flag: &str, - modify_column_kind: &ModifyColumnKind, + alter_column_kind: &AlterColumnKind, field_name: &str, - field_type: &str, + field_content: &str, add_index: Vec<(&str, &str)>, ) -> TardisResult<()> { - match modify_column_kind { - ModifyColumnKind::Add => { + match alter_column_kind { + AlterColumnKind::Add => { conn.execute_one( - &format!("ALTER TABLE {schema_name}.{GLOBAL_STORAGE_FLAG}_{table_flag}{tag} ADD COLUMN {field_name} {field_type}"), + &format!("ALTER TABLE {schema_name}.{GLOBAL_STORAGE_FLAG}_{table_flag}{tag} ADD COLUMN {field_content}"), vec![], ) .await?; - // Add index - for (field_name_or_fun, index_type) in add_index.into_iter() { - let index_name = format!("idx_{schema_name}{tag}_{table_flag}_{field_name_or_fun}",); + for (idx, (field_name_or_fun, index_type)) in add_index.into_iter().enumerate() { + // index name shouldn't be longer than 63 characters + // [4 ][ 18 ][ 12 ][ 26 ][ 3 ] + // idx_{schema_name}{tag}_{table_flag}_{idx} + #[inline] + fn truncate_str(s: &str, max_size: usize) -> &str { + &s[..max_size.min(s.len())] + } + let index_name = format!( + "idx_{schema_name}{tag}_{table_flag}_{field_name_or_fun}_{idx}", + schema_name = truncate_str(schema_name, 18), + tag = truncate_str(tag, 11), + table_flag = truncate_str(table_flag, 25), + idx = truncate_str(idx.to_string().as_str(), 3), + ); conn.execute_one( &format!("CREATE INDEX {index_name} ON {schema_name}.{GLOBAL_STORAGE_FLAG}_{table_flag}{tag} USING {index_type}({field_name_or_fun})"), vec![], @@ -480,7 +492,7 @@ EXECUTE PROCEDURE TARDIS_AUTO_UPDATE_TIME_{}();"###, .await?; } } - ModifyColumnKind::Delete => { + AlterColumnKind::Delete => { conn.execute_one( &format!("ALTER TABLE {schema_name}.{GLOBAL_STORAGE_FLAG}_{table_flag}{tag} DROP COLUMN {field_name}"), vec![], @@ -491,7 +503,7 @@ EXECUTE PROCEDURE TARDIS_AUTO_UPDATE_TIME_{}();"###, Ok(()) } - pub enum ModifyColumnKind { + pub enum AlterColumnKind { Add, Delete, } diff --git a/backend/spi/spi-stats/src/dto/stats_conf_dto.rs b/backend/spi/spi-stats/src/dto/stats_conf_dto.rs index 94b534fd8..3669475c8 100644 --- a/backend/spi/spi-stats/src/dto/stats_conf_dto.rs +++ b/backend/spi/spi-stats/src/dto/stats_conf_dto.rs @@ -527,7 +527,7 @@ pub struct StatsConfFactColInfoResp { /// 关联外部系统传入的主键或编码 /// 用于扩展ext字段的事实列 pub rel_external_id: Option, - pub dim_exclusive_rec: Option, + pub dim_exclusive_rec: Option, pub remark: Option, pub create_time: DateTime, pub update_time: DateTime, diff --git a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_dim_serv.rs b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_dim_serv.rs index e0ed7481a..e7f944178 100644 --- a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_dim_serv.rs +++ b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_dim_serv.rs @@ -41,7 +41,7 @@ pub(crate) async fn add(add_req: &StatsConfDimAddReq, funs: &TardisFunsInst, ctx Value::from(add_req.data_type.to_string()), Value::from(add_req.hierarchy.as_ref().unwrap_or(&vec![]).clone()), Value::from(add_req.remark.as_ref().unwrap_or(&"".to_string()).as_str()), - Value::from(add_req.dim_group_key.as_deref()), + Value::from(add_req.dim_group_key.as_ref().unwrap_or(&"".to_string()).as_str()), Value::from(add_req.dynamic_url.as_deref()), Value::from(add_req.is_tree.unwrap_or(false)), Value::from(add_req.tree_dynamic_url.as_deref()), diff --git a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_col_serv.rs b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_col_serv.rs index a4d4fac4a..ac090c3b1 100644 --- a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_col_serv.rs +++ b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_col_serv.rs @@ -2,11 +2,12 @@ use bios_basic::spi::{ spi_funs::SpiBsInst, spi_initializer::{ self, - common_pg::{self, package_table_name, ModifyColumnKind}, + common_pg::{self, package_table_name, AlterColumnKind}, }, }; use tardis::{ basic::{dto::TardisContext, result::TardisResult}, + chrono::{DateTime, Utc}, db::{ reldb_client::{TardisRelDBClient, TardisRelDBlConnection}, sea_orm::Value, @@ -36,14 +37,15 @@ pub(crate) async fn add(fact_conf_key: &str, add_req: &StatsConfFactColAddReq, f return Err(funs.err().conflict("fact_col_conf", "add", "The rel_sql is not a valid sql.", "409-spi-stats-fact-col-conf-rel-sql-not-valid")); } } - if add_req.rel_external_id.is_none() && stats_pg_conf_fact_serv::online(fact_conf_key, &conn, ctx).await? { - return Err(funs.err().conflict( - "fact_col_conf", - "add", - "The fact instance table already exists, please delete it and then modify it.", - "409-spi-stats-fact-inst-exist", - )); - } + // todo cancel check if fact_conf_table online + // if add_req.rel_external_id.is_none() && stats_pg_conf_fact_serv::online(fact_conf_key, &conn, ctx).await? { + // return Err(funs.err().conflict( + // "fact_col_conf", + // "add", + // "The fact instance table already exists, please delete it and then modify it.", + // "409-spi-stats-fact-inst-exist", + // )); + // } let conf_params = if let Some(rel_external_ids) = add_req.rel_external_id.clone() { vec![ Value::from(&add_req.key), @@ -77,44 +79,6 @@ pub(crate) async fn add(fact_conf_key: &str, add_req: &StatsConfFactColAddReq, f "409-spi-stats-fact-conf-col-exist", )); } - // check if conf_fact_table online - if stats_pg_conf_fact_serv::online(fact_conf_key, &conn, ctx).await? { - let mut filed_type = "VARCHAR".to_string(); - let mut index_type = "gin".to_string(); - if add_req.kind == StatsFactColKind::Dimension { - let Some(dim_conf_key) = &add_req.dim_rel_conf_dim_key else { - return Err(funs.err().bad_request("fact_inst", "create", "Fail to get dimension config", "400-spi-stats-fail-to-get-dim-config-key")); - }; - let Some(dim_conf) = stats_pg_conf_dim_serv::get(dim_conf_key, None, None, &conn, ctx, inst).await? else { - return Err(funs.err().conflict( - "fact_inst", - "create", - &format!("Fail to get dimension config by key [{dim_conf_key}]"), - "409-spi-stats-fail-to-get-dim-config", - )); - }; - if add_req.dim_multi_values.clone().unwrap_or(false) { - filed_type = format!("{}[]", dim_conf.data_type.to_pg_data_type()); - index_type = "gin".to_string(); - } else { - filed_type = dim_conf.data_type.to_pg_data_type().to_owned(); - index_type = "btree".to_string(); - } - } else if add_req.kind == StatsFactColKind::Measure { - filed_type = add_req.mes_data_type.as_ref().unwrap_or(&StatsDataTypeKind::String).to_pg_data_type().to_owned(); - } - spi_initializer::common_pg::modify_table_column( - &conn, - None, - "stats_conf_fact", - &ModifyColumnKind::Add, - &add_req.key, - &filed_type, - vec![(&add_req.key, &index_type)], - ctx, - ) - .await?; - } if let Some(dim_rel_conf_dim_key) = &add_req.dim_rel_conf_dim_key { if add_req.rel_external_id.is_none() && !stats_pg_conf_dim_serv::online(dim_rel_conf_dim_key, &conn, ctx).await? { return Err(funs.err().conflict("fact_col_conf", "add", "The dimension config not online.", "409-spi-stats-dim-conf-not-online")); @@ -202,6 +166,34 @@ VALUES params, ) .await?; + // alter inst table column + if add_req.rel_external_id.is_none() { + let fact_col_conf = StatsConfFactColInfoResp { + key: add_req.key.to_string(), + show_name: add_req.show_name.clone(), + kind: add_req.kind.clone(), + dim_rel_conf_dim_key: add_req.dim_rel_conf_dim_key.clone(), + dim_multi_values: add_req.dim_multi_values, + dim_data_type: add_req.dim_data_type.clone(), + dim_dynamic_url: add_req.dim_dynamic_url.clone(), + mes_data_distinct: add_req.mes_data_distinct, + mes_data_type: add_req.mes_data_type.clone(), + mes_frequency: add_req.mes_frequency.clone(), + mes_unit: add_req.mes_unit.clone(), + mes_act_by_dim_conf_keys: add_req.mes_act_by_dim_conf_keys.clone(), + rel_conf_fact_key: Some(fact_conf_key.to_owned()), + rel_conf_fact_and_col_key: add_req.rel_conf_fact_and_col_key.clone(), + rel_external_id: add_req.rel_external_id.clone(), + dim_exclusive_rec: add_req.dim_exclusive_rec, + remark: add_req.remark.clone(), + create_time: Utc::now(), + update_time: Utc::now(), + rel_field: add_req.rel_field.clone(), + rel_sql: add_req.rel_sql.clone(), + rel_cert_id: add_req.rel_field.clone(), + }; + alter_inst_table_column(fact_conf_key, fact_col_conf, &AlterColumnKind::Add, &conn, funs, ctx, inst).await?; + } conn.commit().await?; Ok(()) } @@ -217,14 +209,15 @@ pub(crate) async fn modify( let bs_inst = inst.inst::(); let (mut conn, table_name) = stats_pg_initializer::init_conf_fact_col_table_and_conn(bs_inst, ctx, true).await?; conn.begin().await?; - if stats_pg_conf_fact_serv::online(fact_conf_key, &conn, ctx).await? { - return Err(funs.err().conflict( - "fact_col_conf", - "modify", - "The fact instance table already exists, please delete it and then modify it.", - "409-spi-stats-fact-inst-exist", - )); - } + // todo cancel check if fact_conf_table online + // if stats_pg_conf_fact_serv::online(fact_conf_key, &conn, ctx).await? { + // return Err(funs.err().conflict( + // "fact_col_conf", + // "modify", + // "The fact instance table already exists, please delete it and then modify it.", + // "409-spi-stats-fact-inst-exist", + // )); + // } if let Some(rel_sql) = &modify_req.rel_sql { if !stats_pg_sync_serv::validate_fact_col_sql(rel_sql) { return Err(funs.err().conflict("fact_col_conf", "add", "The rel_sql is not a valid sql.", "409-spi-stats-fact-col-conf-rel-sql-not-valid")); @@ -332,7 +325,7 @@ pub(crate) async fn delete( let bs_inst = inst.inst::(); let (mut conn, table_name) = stats_pg_initializer::init_conf_fact_col_table_and_conn(bs_inst, ctx, true).await?; conn.begin().await?; - if rel_external_id.is_none() && stats_pg_conf_fact_serv::online(fact_conf_key, &conn, ctx).await? { + if rel_external_id.is_none() { let fact_col_confs: Vec = if let Some(fact_col_conf_key) = fact_col_conf_key { if let Some(fact_col_conf) = find_by_fact_key_and_col_conf_key(fact_conf_key, fact_col_conf_key, funs, ctx, inst).await? { vec![fact_col_conf] @@ -343,28 +336,7 @@ pub(crate) async fn delete( find_by_fact_conf_key(fact_conf_key, funs, ctx, inst).await? }; for fact_col_conf in fact_col_confs { - let mut filed_type = "VARCHAR".to_string(); - if fact_col_conf.kind == StatsFactColKind::Dimension { - let Some(dim_conf_key) = &fact_col_conf.dim_rel_conf_dim_key else { - return Err(funs.err().bad_request("fact_col_conf", "delete", "Fail to get dimension config", "400-spi-stats-fail-to-get-dim-config-key")); - }; - let Some(dim_conf) = stats_pg_conf_dim_serv::get(dim_conf_key, None, None, &conn, ctx, inst).await? else { - return Err(funs.err().conflict( - "fact_col_conf", - "delete", - &format!("Fail to get dimension config by key [{dim_conf_key}]"), - "409-spi-stats-fail-to-get-dim-config", - )); - }; - if fact_col_conf.dim_multi_values.clone().unwrap_or(false) { - filed_type = format!("{}[]", dim_conf.data_type.to_pg_data_type()); - } else { - filed_type = dim_conf.data_type.to_pg_data_type().to_owned(); - } - } else if fact_col_conf.kind == StatsFactColKind::Measure { - filed_type = fact_col_conf.mes_data_type.as_ref().unwrap_or(&StatsDataTypeKind::String).to_pg_data_type().to_owned(); - } - spi_initializer::common_pg::modify_table_column(&conn, None, "stats_conf_fact", &ModifyColumnKind::Delete, &fact_col_conf.key, &filed_type, vec![], ctx).await?; + alter_inst_table_column(fact_conf_key, fact_col_conf, &AlterColumnKind::Delete, &conn, funs, ctx, inst).await?; } } let mut where_clause = String::from("rel_conf_fact_key = $1"); @@ -613,3 +585,112 @@ WHERE records: result, }) } + +async fn alter_inst_table_column( + fact_conf_key: &str, + fact_col_conf: StatsConfFactColInfoResp, + alter_column_kind: &AlterColumnKind, + conn: &TardisRelDBlConnection, + funs: &TardisFunsInst, + ctx: &TardisContext, + inst: &SpiBsInst, +) -> TardisResult<()> { + if stats_pg_conf_fact_serv::online(fact_conf_key, &conn, ctx).await? { + let mut indix: Vec<(String, &str)> = vec![]; + let col_sql = fact_col_column_sql(fact_col_conf.clone(), &mut indix, false, conn, funs, ctx, inst).await?; + let mut swap_index = vec![]; + for i in &indix { + swap_index.push((&i.0[..], i.1)); + } + spi_initializer::common_pg::alter_table_column( + &conn, + Some(fact_conf_key), + "stats_inst_fact", + alter_column_kind, + fact_col_conf.key.as_str(), + &col_sql, + swap_index, + ctx, + ) + .await?; + } + Ok(()) +} + +pub async fn fact_col_column_sql( + fact_col_conf: StatsConfFactColInfoResp, + index: &mut Vec<(String, &str)>, + is_not_null: bool, + conn: &TardisRelDBlConnection, + funs: &TardisFunsInst, + ctx: &TardisContext, + inst: &SpiBsInst, +) -> TardisResult { + let sql; + if fact_col_conf.kind == StatsFactColKind::Dimension { + let Some(dim_conf_key) = &fact_col_conf.dim_rel_conf_dim_key else { + return Err(funs.err().bad_request("fact_inst", "create", "Fail to get dimension config", "400-spi-stats-fail-to-get-dim-config-key")); + }; + if !stats_pg_conf_dim_serv::online(dim_conf_key, conn, ctx).await? { + return Err(funs.err().conflict( + "fact_inst", + "create", + &format!("The dimension config [{dim_conf_key}] not online."), + "409-spi-stats-dim-conf-not-online", + )); + } + let Some(dim_conf) = stats_pg_conf_dim_serv::get(dim_conf_key, None, None, conn, ctx, inst).await? else { + return Err(funs.err().conflict( + "fact_inst", + "create", + &format!("Fail to get dimension config by key [{dim_conf_key}]"), + "409-spi-stats-fail-to-get-dim-config", + )); + }; + if fact_col_conf.dim_multi_values.unwrap_or(false) { + sql = format!( + "{} {}[] {}", + &fact_col_conf.key, + dim_conf.data_type.to_pg_data_type(), + if is_not_null { "NOT NULL" } else { "" } + ); + index.push((fact_col_conf.key.clone(), "gin")); + } else { + sql = format!( + "{} {} {}", + &fact_col_conf.key, + dim_conf.data_type.to_pg_data_type(), + if is_not_null { "NOT NULL" } else { "" } + ); + index.push((fact_col_conf.key.clone(), "btree")); + match dim_conf.data_type { + StatsDataTypeKind::DateTime => { + index.push((format!("date(timezone('UTC', {}))", fact_col_conf.key), "btree")); + index.push((format!("date_part('hour',timezone('UTC', {}))", fact_col_conf.key), "btree")); + index.push((format!("date_part('day',timezone('UTC', {}))", fact_col_conf.key), "btree")); + index.push((format!("date_part('month',timezone('UTC', {}))", fact_col_conf.key), "btree")); + index.push((format!("date_part('year',timezone('UTC', {}))", fact_col_conf.key), "btree")); + } + StatsDataTypeKind::Date => { + index.push((format!("date_part('day', {})", fact_col_conf.key), "btree")); + index.push((format!("date_part('month', {})", fact_col_conf.key), "btree")); + index.push((format!("date_part('year', {})", fact_col_conf.key), "btree")); + } + _ => {} + } + } + } else if fact_col_conf.kind == StatsFactColKind::Measure { + let Some(mes_data_type) = fact_col_conf.mes_data_type.as_ref() else { + return Err(funs.err().conflict( + "fact_inst", + "create", + "Config of kind StatsFactColKind::Measure should have a mes_data_type", + "409-spi-stats-miss-mes-data-type", + )); + }; + sql = format!("{} {} {}", &fact_col_conf.key, mes_data_type.to_pg_data_type(), if is_not_null { "NOT NULL" } else { "" }); + } else { + sql = format!("{} character varying", &fact_col_conf.key); + } + Ok(sql) +} diff --git a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_serv.rs b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_serv.rs index dbfe021c4..3c22f7a1e 100644 --- a/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_serv.rs +++ b/backend/spi/spi-stats/src/serv/pg/stats_pg_conf_fact_serv.rs @@ -96,49 +96,49 @@ pub(crate) async fn modify(fact_conf_key: &str, modify_req: &StatsConfFactModify conn.begin().await?; let mut sql_sets = vec![]; let mut params = vec![Value::from(fact_conf_key.to_string())]; - if online(fact_conf_key, &conn, ctx).await? { - if modify_req.is_online.is_none() { - return Err(funs.err().conflict( - "fact_conf", - "modify", - "The fact instance table already exists, please delete it and then modify it.", - "409-spi-stats-fact-inst-exist", - )); - } - } else { - if let Some(show_name) = &modify_req.show_name { - sql_sets.push(format!("show_name = ${}", params.len() + 1)); - params.push(Value::from(show_name.to_string())); - } - if let Some(query_limit) = modify_req.query_limit { - sql_sets.push(format!("query_limit = ${}", params.len() + 1)); - params.push(Value::from(query_limit)); - } - if let Some(remark) = &modify_req.remark { - sql_sets.push(format!("remark = ${}", params.len() + 1)); - params.push(Value::from(remark.to_string())); - } - if let Some(redirect_path) = &modify_req.redirect_path { - sql_sets.push(format!("redirect_path = ${}", params.len() + 1)); - params.push(Value::from(redirect_path)); - } - if let Some(rel_cert_id) = &modify_req.rel_cert_id { - sql_sets.push(format!("rel_cert_id = ${}", params.len() + 1)); - params.push(Value::from(rel_cert_id.to_string())); - } - if let Some(sync_sql) = &modify_req.sync_sql { - sql_sets.push(format!("sync_sql = ${}", params.len() + 1)); - params.push(Value::from(sync_sql.to_string())); - } - if let Some(sync_cron) = &modify_req.sync_cron { - sql_sets.push(format!("sync_cron = ${}", params.len() + 1)); - params.push(Value::from(sync_cron.to_string())); - } - if let Some(is_sync) = &modify_req.is_sync { - sql_sets.push(format!("is_sync = ${}", params.len() + 1)); - params.push(Value::from(*is_sync)); - } - }; + // todo cancel online check + // if online(fact_conf_key, &conn, ctx).await? { + // if modify_req.is_online.is_none() { + // return Err(funs.err().conflict( + // "fact_conf", + // "modify", + // "The fact instance table already exists, please delete it and then modify it.", + // "409-spi-stats-fact-inst-exist", + // )); + // } + // } + if let Some(show_name) = &modify_req.show_name { + sql_sets.push(format!("show_name = ${}", params.len() + 1)); + params.push(Value::from(show_name.to_string())); + } + if let Some(query_limit) = modify_req.query_limit { + sql_sets.push(format!("query_limit = ${}", params.len() + 1)); + params.push(Value::from(query_limit)); + } + if let Some(remark) = &modify_req.remark { + sql_sets.push(format!("remark = ${}", params.len() + 1)); + params.push(Value::from(remark.to_string())); + } + if let Some(redirect_path) = &modify_req.redirect_path { + sql_sets.push(format!("redirect_path = ${}", params.len() + 1)); + params.push(Value::from(redirect_path)); + } + if let Some(rel_cert_id) = &modify_req.rel_cert_id { + sql_sets.push(format!("rel_cert_id = ${}", params.len() + 1)); + params.push(Value::from(rel_cert_id.to_string())); + } + if let Some(sync_sql) = &modify_req.sync_sql { + sql_sets.push(format!("sync_sql = ${}", params.len() + 1)); + params.push(Value::from(sync_sql.to_string())); + } + if let Some(sync_cron) = &modify_req.sync_cron { + sql_sets.push(format!("sync_cron = ${}", params.len() + 1)); + params.push(Value::from(sync_cron.to_string())); + } + if let Some(is_sync) = &modify_req.is_sync { + sql_sets.push(format!("is_sync = ${}", params.len() + 1)); + params.push(Value::from(*is_sync)); + } if let Some(is_online) = &modify_req.is_online { sql_sets.push(format!("is_online = ${}", params.len() + 1)); @@ -174,7 +174,7 @@ WHERE key = $1 Ok(()) } -pub(crate) async fn delete(fact_conf_key: &str, _funs: &TardisFunsInst, ctx: &TardisContext, inst: &SpiBsInst) -> TardisResult<()> { +pub(crate) async fn delete(fact_conf_key: &str, funs: &TardisFunsInst, ctx: &TardisContext, inst: &SpiBsInst) -> TardisResult<()> { let bs_inst = inst.inst::(); let (mut conn, table_name) = stats_pg_initializer::init_conf_fact_table_and_conn(bs_inst, ctx, true).await?; let (_, fact_col_table_name) = stats_pg_initializer::init_conf_fact_col_table_and_conn(bs_inst, ctx, true).await?; @@ -194,6 +194,7 @@ pub(crate) async fn delete(fact_conf_key: &str, _funs: &TardisFunsInst, ctx: &Ta conn.execute_one(&format!("DROP TABLE {}{fact_conf_key}", package_table_name("stats_inst_fact_", ctx)), vec![]).await?; conn.execute_one(&format!("DROP TABLE {}{fact_conf_key}_del", package_table_name("stats_inst_fact_", ctx)), vec![]).await?; } + ScheduleClient::delete_sync_task(&format!("{}_{}", SYNC_FACT_TASK_CODE, fact_conf_key), funs, ctx).await?; conn.commit().await?; Ok(()) } @@ -423,61 +424,8 @@ async fn create_inst_table( sql.push("idempotent_id character varying NOT NULL".to_string()); index.push(("own_paths".to_string(), "btree")); for fact_col_conf in fact_col_conf_set { - if fact_col_conf.kind == StatsFactColKind::Dimension { - let Some(dim_conf_key) = &fact_col_conf.dim_rel_conf_dim_key else { - return Err(funs.err().bad_request("fact_inst", "create", "Fail to get dimension config", "400-spi-stats-fail-to-get-dim-config-key")); - }; - if !stats_pg_conf_dim_serv::online(dim_conf_key, conn, ctx).await? { - return Err(funs.err().conflict( - "fact_inst", - "create", - &format!("The dimension config [{dim_conf_key}] not online."), - "409-spi-stats-dim-conf-not-online", - )); - } - let Some(dim_conf) = stats_pg_conf_dim_serv::get(dim_conf_key, None, None, conn, ctx, inst).await? else { - return Err(funs.err().conflict( - "fact_inst", - "create", - &format!("Fail to get dimension config by key [{dim_conf_key}]"), - "409-spi-stats-fail-to-get-dim-config", - )); - }; - if fact_col_conf.dim_multi_values.unwrap_or(false) { - sql.push(format!("{} {}[] NOT NULL", &fact_col_conf.key, dim_conf.data_type.to_pg_data_type())); - index.push((fact_col_conf.key.clone(), "gin")); - } else { - sql.push(format!("{} {} NOT NULL", &fact_col_conf.key, dim_conf.data_type.to_pg_data_type())); - index.push((fact_col_conf.key.clone(), "btree")); - match dim_conf.data_type { - StatsDataTypeKind::DateTime => { - index.push((format!("date(timezone('UTC', {}))", fact_col_conf.key), "btree")); - index.push((format!("date_part('hour',timezone('UTC', {}))", fact_col_conf.key), "btree")); - index.push((format!("date_part('day',timezone('UTC', {}))", fact_col_conf.key), "btree")); - index.push((format!("date_part('month',timezone('UTC', {}))", fact_col_conf.key), "btree")); - index.push((format!("date_part('year',timezone('UTC', {}))", fact_col_conf.key), "btree")); - } - StatsDataTypeKind::Date => { - index.push((format!("date_part('day', {})", fact_col_conf.key), "btree")); - index.push((format!("date_part('month', {})", fact_col_conf.key), "btree")); - index.push((format!("date_part('year', {})", fact_col_conf.key), "btree")); - } - _ => {} - } - } - } else if fact_col_conf.kind == StatsFactColKind::Measure { - let Some(mes_data_type) = fact_col_conf.mes_data_type.as_ref() else { - return Err(funs.err().conflict( - "fact_inst", - "create", - "Config of kind StatsFactColKind::Measure should have a mes_data_type", - "409-spi-stats-miss-mes-data-type", - )); - }; - sql.push(format!("{} {} NOT NULL", &fact_col_conf.key, mes_data_type.to_pg_data_type())); - } else { - sql.push(format!("{} character varying", &fact_col_conf.key)); - } + let col_sql = stats_pg_conf_fact_col_serv::fact_col_column_sql(fact_col_conf.clone(), &mut index, true, conn, funs, ctx, inst).await?; + sql.push(col_sql) } sql.push("ct timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP".to_string()); index.push(("ct".to_string(), "btree")); diff --git a/frontend/sdks/invoke/src/clients/schedule_client.rs b/frontend/sdks/invoke/src/clients/schedule_client.rs index 6bb939bcf..fc2d8f7b4 100644 --- a/frontend/sdks/invoke/src/clients/schedule_client.rs +++ b/frontend/sdks/invoke/src/clients/schedule_client.rs @@ -55,8 +55,15 @@ impl ScheduleClient { ) .await?; } else { - funs.web_client().delete_to_void(&format!("{schedule_url}/ci/schedule/jobs/{}", req.code), headers.clone()).await?; + Self::delete_sync_task(&req.code, funs, ctx).await?; } Ok(()) } + + pub async fn delete_sync_task(code: &str, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { + let schedule_url: String = BaseSpiClient::module_url(InvokeModuleKind::Schedule, funs).await?; + let headers = BaseSpiClient::headers(None, funs, ctx).await?; + funs.web_client().delete_to_void(&format!("{schedule_url}/ci/schedule/jobs/{}", code), headers).await?; + Ok(()) + } }