5c7c039e52
CI / verify (push) Has been cancelled
- lock profile task tracking scope to user - add analytics date dimension module support and tests - regenerate SpacetimeDB Rust bindings with private APIs
127 lines
4.4 KiB
Rust
127 lines
4.4 KiB
Rust
use crate::*;
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
|
pub struct AnalyticsDateDimensionEnsureInput {
|
|
pub date_key: i64,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
|
pub struct AnalyticsDateDimensionSeedInput {
|
|
pub start_date: String,
|
|
pub end_date: String,
|
|
}
|
|
|
|
#[spacetimedb::table(
|
|
accessor = analytics_date_dimension,
|
|
index(accessor = by_analytics_date_dimension_iso_week, btree(columns = [iso_week_key])),
|
|
index(accessor = by_analytics_date_dimension_month, btree(columns = [month_key])),
|
|
index(accessor = by_analytics_date_dimension_quarter, btree(columns = [quarter_key])),
|
|
index(accessor = by_analytics_date_dimension_year, btree(columns = [year_key]))
|
|
)]
|
|
pub struct AnalyticsDateDimension {
|
|
#[primary_key]
|
|
pub(crate) date_key: i64,
|
|
// 中文注释:北京时间业务日对应的公历日期,格式 YYYY-MM-DD。
|
|
pub(crate) calendar_date: String,
|
|
// 中文注释:ISO weekday,周一=1,周日=7,方便统计层不重复计算。
|
|
pub(crate) weekday: u8,
|
|
// 中文注释:ISO week 编码为 YYYYWW,跨年周按 ISO 年归属。
|
|
pub(crate) iso_week_key: i32,
|
|
pub(crate) week_start_date_key: i64,
|
|
pub(crate) week_end_date_key: i64,
|
|
pub(crate) month_key: i32,
|
|
pub(crate) month_start_date_key: i64,
|
|
pub(crate) month_end_date_key: i64,
|
|
pub(crate) quarter_key: i32,
|
|
pub(crate) quarter_start_date_key: i64,
|
|
pub(crate) quarter_end_date_key: i64,
|
|
pub(crate) year_key: i32,
|
|
pub(crate) year_start_date_key: i64,
|
|
pub(crate) year_end_date_key: i64,
|
|
pub(crate) created_at: Timestamp,
|
|
pub(crate) updated_at: Timestamp,
|
|
}
|
|
|
|
#[spacetimedb::reducer]
|
|
pub fn ensure_analytics_date_dimension_for_date(
|
|
ctx: &ReducerContext,
|
|
input: AnalyticsDateDimensionEnsureInput,
|
|
) -> Result<(), String> {
|
|
ensure_analytics_date_dimension_row(ctx, input.date_key)?;
|
|
Ok(())
|
|
}
|
|
|
|
#[spacetimedb::reducer]
|
|
pub fn seed_analytics_date_dimensions(
|
|
ctx: &ReducerContext,
|
|
input: AnalyticsDateDimensionSeedInput,
|
|
) -> Result<(), String> {
|
|
let start_date_key = parse_analytics_calendar_date_key(&input.start_date)
|
|
.map_err(|error| format!("invalid start_date: {error}"))?;
|
|
let end_date_key = parse_analytics_calendar_date_key(&input.end_date)
|
|
.map_err(|error| format!("invalid end_date: {error}"))?;
|
|
if start_date_key > end_date_key {
|
|
return Err("start_date must be <= end_date".to_string());
|
|
}
|
|
let seed_days = end_date_key - start_date_key + 1;
|
|
if seed_days > ANALYTICS_DATE_DIMENSION_MAX_SEED_DAYS {
|
|
return Err(format!(
|
|
"date range too large: max {} days",
|
|
ANALYTICS_DATE_DIMENSION_MAX_SEED_DAYS
|
|
));
|
|
}
|
|
|
|
for date_key in start_date_key..=end_date_key {
|
|
ensure_analytics_date_dimension_row(ctx, date_key)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) fn ensure_analytics_date_dimension_row(
|
|
ctx: &ReducerContext,
|
|
date_key: i64,
|
|
) -> Result<(), String> {
|
|
validate_analytics_date_dimension_date_key(date_key)
|
|
.map_err(|error| format!("invalid date_key: {error}"))?;
|
|
if ctx
|
|
.db
|
|
.analytics_date_dimension()
|
|
.date_key()
|
|
.find(&date_key)
|
|
.is_some()
|
|
{
|
|
return Ok(());
|
|
}
|
|
|
|
let snapshot = build_analytics_date_dimension_from_date_key(date_key);
|
|
ctx.db
|
|
.analytics_date_dimension()
|
|
.insert(build_analytics_date_dimension_row(snapshot, ctx.timestamp));
|
|
Ok(())
|
|
}
|
|
|
|
fn build_analytics_date_dimension_row(
|
|
snapshot: AnalyticsDateDimensionSnapshot,
|
|
now: Timestamp,
|
|
) -> AnalyticsDateDimension {
|
|
AnalyticsDateDimension {
|
|
date_key: snapshot.date_key,
|
|
calendar_date: snapshot.calendar_date,
|
|
weekday: snapshot.weekday,
|
|
iso_week_key: snapshot.iso_week_key,
|
|
week_start_date_key: snapshot.week_start_date_key,
|
|
week_end_date_key: snapshot.week_end_date_key,
|
|
month_key: snapshot.month_key,
|
|
month_start_date_key: snapshot.month_start_date_key,
|
|
month_end_date_key: snapshot.month_end_date_key,
|
|
quarter_key: snapshot.quarter_key,
|
|
quarter_start_date_key: snapshot.quarter_start_date_key,
|
|
quarter_end_date_key: snapshot.quarter_end_date_key,
|
|
year_key: snapshot.year_key,
|
|
year_start_date_key: snapshot.year_start_date_key,
|
|
year_end_date_key: snapshot.year_end_date_key,
|
|
created_at: now,
|
|
updated_at: now,
|
|
}
|
|
}
|