This commit is contained in:
141
server-rs/crates/spacetime-module/src/runtime/settings.rs
Normal file
141
server-rs/crates/spacetime-module/src/runtime/settings.rs
Normal file
@@ -0,0 +1,141 @@
|
||||
use crate::*;
|
||||
|
||||
#[spacetimedb::table(accessor = runtime_setting)]
|
||||
pub struct RuntimeSetting {
|
||||
#[primary_key]
|
||||
pub(crate) user_id: String,
|
||||
pub(crate) music_volume: f32,
|
||||
pub(crate) platform_theme: RuntimePlatformTheme,
|
||||
pub(crate) created_at: Timestamp,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
}
|
||||
|
||||
// procedure 面向 Axum 同步读取设置;若没有持久化记录则返回默认值快照,但不产生额外写入。
|
||||
#[spacetimedb::procedure]
|
||||
pub fn get_runtime_setting_or_default(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: RuntimeSettingGetInput,
|
||||
) -> RuntimeSettingProcedureResult {
|
||||
match ctx.try_with_tx(|tx| get_runtime_setting_snapshot(tx, input.clone())) {
|
||||
Ok(record) => RuntimeSettingProcedureResult {
|
||||
ok: true,
|
||||
record: Some(record),
|
||||
error_message: None,
|
||||
},
|
||||
Err(message) => RuntimeSettingProcedureResult {
|
||||
ok: false,
|
||||
record: None,
|
||||
error_message: Some(message),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// procedure 面向 Axum 同步写入设置,并返回最终归一化后的持久化结果。
|
||||
#[spacetimedb::procedure]
|
||||
pub fn upsert_runtime_setting_and_return(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: RuntimeSettingUpsertInput,
|
||||
) -> RuntimeSettingProcedureResult {
|
||||
match ctx.try_with_tx(|tx| upsert_runtime_setting(tx, input.clone())) {
|
||||
Ok(record) => RuntimeSettingProcedureResult {
|
||||
ok: true,
|
||||
record: Some(record),
|
||||
error_message: None,
|
||||
},
|
||||
Err(message) => RuntimeSettingProcedureResult {
|
||||
ok: false,
|
||||
record: None,
|
||||
error_message: Some(message),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn get_runtime_setting_snapshot(
|
||||
ctx: &ReducerContext,
|
||||
input: RuntimeSettingGetInput,
|
||||
) -> Result<RuntimeSettingSnapshot, String> {
|
||||
let validated_input =
|
||||
build_runtime_setting_get_input(input.user_id).map_err(|error| error.to_string())?;
|
||||
|
||||
if let Some(existing) = ctx
|
||||
.db
|
||||
.runtime_setting()
|
||||
.user_id()
|
||||
.find(&validated_input.user_id)
|
||||
{
|
||||
return Ok(RuntimeSettingSnapshot {
|
||||
user_id: existing.user_id,
|
||||
music_volume: existing.music_volume,
|
||||
platform_theme: existing.platform_theme,
|
||||
created_at_micros: existing.created_at.to_micros_since_unix_epoch(),
|
||||
updated_at_micros: existing.updated_at.to_micros_since_unix_epoch(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(RuntimeSettingSnapshot {
|
||||
user_id: validated_input.user_id,
|
||||
music_volume: DEFAULT_MUSIC_VOLUME,
|
||||
platform_theme: DEFAULT_PLATFORM_THEME,
|
||||
created_at_micros: 0,
|
||||
updated_at_micros: 0,
|
||||
})
|
||||
}
|
||||
|
||||
fn upsert_runtime_setting(
|
||||
ctx: &ReducerContext,
|
||||
input: RuntimeSettingUpsertInput,
|
||||
) -> Result<RuntimeSettingSnapshot, String> {
|
||||
let validated_input = build_runtime_setting_upsert_input(
|
||||
input.user_id,
|
||||
input.music_volume,
|
||||
input.platform_theme,
|
||||
input.updated_at_micros,
|
||||
)
|
||||
.map_err(|error| error.to_string())?;
|
||||
let updated_at = Timestamp::from_micros_since_unix_epoch(validated_input.updated_at_micros);
|
||||
|
||||
let snapshot = match ctx
|
||||
.db
|
||||
.runtime_setting()
|
||||
.user_id()
|
||||
.find(&validated_input.user_id)
|
||||
{
|
||||
Some(existing) => {
|
||||
ctx.db.runtime_setting().user_id().delete(&existing.user_id);
|
||||
ctx.db.runtime_setting().insert(RuntimeSetting {
|
||||
user_id: existing.user_id.clone(),
|
||||
music_volume: validated_input.music_volume,
|
||||
platform_theme: validated_input.platform_theme,
|
||||
created_at: existing.created_at,
|
||||
updated_at,
|
||||
});
|
||||
|
||||
RuntimeSettingSnapshot {
|
||||
user_id: existing.user_id,
|
||||
music_volume: validated_input.music_volume,
|
||||
platform_theme: validated_input.platform_theme,
|
||||
created_at_micros: existing.created_at.to_micros_since_unix_epoch(),
|
||||
updated_at_micros: validated_input.updated_at_micros,
|
||||
}
|
||||
}
|
||||
None => {
|
||||
ctx.db.runtime_setting().insert(RuntimeSetting {
|
||||
user_id: validated_input.user_id.clone(),
|
||||
music_volume: validated_input.music_volume,
|
||||
platform_theme: validated_input.platform_theme,
|
||||
created_at: updated_at,
|
||||
updated_at,
|
||||
});
|
||||
|
||||
RuntimeSettingSnapshot {
|
||||
user_id: validated_input.user_id,
|
||||
music_volume: validated_input.music_volume,
|
||||
platform_theme: validated_input.platform_theme,
|
||||
created_at_micros: validated_input.updated_at_micros,
|
||||
updated_at_micros: validated_input.updated_at_micros,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(snapshot)
|
||||
}
|
||||
Reference in New Issue
Block a user