feat: add analytics date dimension bindings
Some checks failed
CI / verify (push) Has been cancelled
Some checks failed
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
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user