diff --git a/Cargo.lock b/Cargo.lock index 09c23257480..8251a63b8d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3728,6 +3728,7 @@ version = "0.1.0" dependencies = [ "anyhow", "log", + "paste", "spacetimedb", ] diff --git a/modules/benchmarks/src/circles.rs b/modules/benchmarks/src/circles.rs index 97d951dc4fe..e700e5414a3 100644 --- a/modules/benchmarks/src/circles.rs +++ b/modules/benchmarks/src/circles.rs @@ -1,6 +1,6 @@ //! STDB module used for benchmarks based on "realistic" workloads we are focusing in improving. use crate::Load; -use spacetimedb::{log, SpacetimeType, Timestamp}; +use spacetimedb::{log, ReducerContext, SpacetimeType, Table, Timestamp}; use std::hint::black_box; #[derive(SpacetimeType, Debug, Clone, Copy)] @@ -79,25 +79,29 @@ fn is_overlapping(entity1: &Entity, entity2: &Entity) -> bool { // ---------- insert bulk ---------- #[spacetimedb::reducer] -pub fn insert_bulk_entity(count: u32) { +pub fn insert_bulk_entity(ctx: &ReducerContext, count: u32) { for id in 0..count { - Entity::insert(Entity::new(0, id as f32, (id + 5) as f32, id * 5)).unwrap(); + ctx.db + .entities() + .insert(Entity::new(0, id as f32, (id + 5) as f32, id * 5)); } log::info!("INSERT ENTITY: {count}"); } #[spacetimedb::reducer] -pub fn insert_bulk_circle(count: u32) { +pub fn insert_bulk_circle(ctx: &ReducerContext, count: u32) { for id in 0..count { - Circle::insert(Circle::new(id, id, id as f32, (id + 5) as f32, (id * 5) as f32)).unwrap(); + ctx.db + .circles() + .insert(Circle::new(id, id, id as f32, (id + 5) as f32, (id * 5) as f32)); } log::info!("INSERT CIRCLE: {count}"); } #[spacetimedb::reducer] -pub fn insert_bulk_food(count: u32) { +pub fn insert_bulk_food(ctx: &ReducerContext, count: u32) { for id in 1..=count { - Food::insert(Food::new(id)).unwrap(); + ctx.db.food().insert(Food::new(id)); } log::info!("INSERT FOOD: {count}"); } @@ -107,11 +111,11 @@ pub fn insert_bulk_food(count: u32) { // SELECT * FROM Circle, Entity, Food // ``` #[spacetimedb::reducer] -pub fn cross_join_all(expected: u32) { +pub fn cross_join_all(ctx: &ReducerContext, expected: u32) { let mut count = 0; - for _circle in Circle::iter() { - for _entity in Entity::iter() { - for _food in Food::iter() { + for _circle in ctx.db.circles().iter() { + for _entity in ctx.db.entities().iter() { + for _food in ctx.db.food().iter() { count += 1; } } @@ -125,16 +129,20 @@ pub fn cross_join_all(expected: u32) { // SELECT * FROM Circle JOIN ENTITY USING(entity_id), Food JOIN ENTITY USING(entity_id) // ``` #[spacetimedb::reducer] -pub fn cross_join_circle_food(expected: u32) { +pub fn cross_join_circle_food(ctx: &ReducerContext, expected: u32) { let mut count = 0; - for circle in Circle::iter() { - let Some(circle_entity) = Entity::filter_by_id(&circle.entity_id) else { + for circle in ctx.db.circles().iter() { + let Some(circle_entity) = ctx.db.entities().id().find(circle.entity_id) else { continue; }; - for food in Food::iter() { + for food in ctx.db.food().iter() { count += 1; - let food_entity = Entity::filter_by_id(&food.entity_id) + let food_entity = ctx + .db + .entities() + .id() + .find(food.entity_id) .unwrap_or_else(|| panic!("Entity not found: {})", food.entity_id)); black_box(is_overlapping(&circle_entity, &food_entity)); } @@ -144,18 +152,18 @@ pub fn cross_join_circle_food(expected: u32) { } #[spacetimedb::reducer] -pub fn init_game_circles(initial_load: u32) { +pub fn init_game_circles(ctx: &ReducerContext, initial_load: u32) { let load = Load::new(initial_load); - insert_bulk_food(load.initial_load); - insert_bulk_entity(load.initial_load); - insert_bulk_circle(load.small_table); + insert_bulk_food(ctx, load.initial_load); + insert_bulk_entity(ctx, load.initial_load); + insert_bulk_circle(ctx, load.small_table); } #[spacetimedb::reducer] -pub fn run_game_circles(initial_load: u32) { +pub fn run_game_circles(ctx: &ReducerContext, initial_load: u32) { let load = Load::new(initial_load); - cross_join_circle_food(initial_load * load.small_table); - cross_join_all(initial_load * initial_load * load.small_table); + cross_join_circle_food(ctx, initial_load * load.small_table); + cross_join_all(ctx, initial_load * initial_load * load.small_table); } diff --git a/modules/benchmarks/src/ia_loop.rs b/modules/benchmarks/src/ia_loop.rs index 69d206805ac..cfb7a5714fb 100644 --- a/modules/benchmarks/src/ia_loop.rs +++ b/modules/benchmarks/src/ia_loop.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments, unused_variables)] use crate::Load; -use spacetimedb::{log, SpacetimeType, Timestamp}; +use spacetimedb::{log, ReducerContext, SpacetimeType, Table, Timestamp}; use std::hash::{Hash, Hasher}; #[spacetimedb::table(name = velocity)] @@ -138,17 +138,21 @@ fn calculate_hash(t: &T) -> u64 { // ---------- insert bulk ---------- #[spacetimedb::reducer] -pub fn insert_bulk_position(count: u32) { +pub fn insert_bulk_position(ctx: &ReducerContext, count: u32) { for id in 0..count { - Position::insert(Position::new(id, id as f32, (id + 5) as f32, (id * 5) as f32)).unwrap(); + ctx.db + .position() + .insert(Position::new(id, id as f32, (id + 5) as f32, (id * 5) as f32)); } log::info!("INSERT POSITION: {count}"); } #[spacetimedb::reducer] -pub fn insert_bulk_velocity(count: u32) { +pub fn insert_bulk_velocity(ctx: &ReducerContext, count: u32) { for id in 0..count { - Velocity::insert(Velocity::new(id, id as f32, (id + 5) as f32, (id * 5) as f32)).unwrap(); + ctx.db + .velocity() + .insert(Velocity::new(id, id as f32, (id + 5) as f32, (id * 5) as f32)); } log::info!("INSERT VELOCITY: {count}"); } @@ -161,15 +165,15 @@ pub fn insert_bulk_velocity(count: u32) { // z = z + vz; // ``` #[spacetimedb::reducer] -pub fn update_position_all(expected: u32) { +pub fn update_position_all(ctx: &ReducerContext, expected: u32) { let mut count = 0; - for mut position in Position::iter() { + for mut position in ctx.db.position().iter() { position.x += position.vx; position.y += position.vy; position.z += position.vz; let id = position.entity_id; - Position::update_by_entity_id(&id, position); + ctx.db.position().entity_id().update(position); count += 1; } log::info!("UPDATE POSITION ALL: {expected}, processed: {count}"); @@ -186,10 +190,10 @@ pub fn update_position_all(expected: u32) { // WHERE Position.entity_id = Velocity.entity_id; // ``` #[spacetimedb::reducer] -pub fn update_position_with_velocity(expected: u32) { +pub fn update_position_with_velocity(ctx: &ReducerContext, expected: u32) { let mut count = 0; - for velocity in Velocity::iter() { - let Some(mut position) = Position::filter_by_entity_id(&velocity.entity_id) else { + for velocity in ctx.db.velocity().iter() { + let Some(mut position) = ctx.db.position().entity_id().find(&velocity.entity_id) else { continue; }; @@ -198,7 +202,7 @@ pub fn update_position_with_velocity(expected: u32) { position.z += velocity.z; let id = position.entity_id; - Position::update_by_entity_id(&id, position); + ctx.db.position().entity_id().update(position); count += 1; } log::info!("UPDATE POSITION BY VELOCITY: {expected}, processed: {count}"); @@ -207,7 +211,7 @@ pub fn update_position_with_velocity(expected: u32) { // Simulations for a game loop #[spacetimedb::reducer] -pub fn insert_world(players: u64) { +pub fn insert_world(ctx: &ReducerContext, players: u64) { for (i, id) in (0..players).enumerate() { let next_action_timestamp = if i & 2 == 2 { moment_milliseconds() + 2000 // Check every 2secs @@ -215,41 +219,36 @@ pub fn insert_world(players: u64) { moment_milliseconds() }; - GameEnemyAiAgentState::insert(GameEnemyAiAgentState { + ctx.db.game_enemy_ai_agent_state().insert(GameEnemyAiAgentState { entity_id: id, next_action_timestamp, last_move_timestamps: vec![id, 0, id * 2], action: AgentAction::Idle, - }) - .unwrap(); + }); - GameLiveTargetableState::insert(GameLiveTargetableState { + ctx.db.game_live_targetable_state().insert(GameLiveTargetableState { entity_id: id, quad: id as i64, - }) - .unwrap(); + }); - GameTargetableState::insert(GameTargetableState { + ctx.db.game_targetable_state().insert(GameTargetableState { entity_id: id, quad: id as i64, - }) - .unwrap(); + }); - GameMobileEntityState::insert(GameMobileEntityState { + ctx.db.game_mobile_entity_state().insert(GameMobileEntityState { entity_id: id, location_x: id as i32, location_y: id as i32, timestamp: next_action_timestamp, - }) - .unwrap(); + }); - GameEnemyState::insert(GameEnemyState { + ctx.db.game_enemy_state().insert(GameEnemyState { entity_id: id, herd_id: id as i32, - }) - .unwrap(); + }); - GameHerdCache::insert(GameHerdCache { + ctx.db.game_herd_cache().insert(GameHerdCache { id: id as i32, dimension_id: id as u32, current_population: id as i32 * 2, @@ -261,18 +260,23 @@ pub fn insert_world(players: u64) { z: id as i32, dimension: id as u32 * 2, }, - }) - .unwrap(); + }); } log::info!("INSERT WORLD PLAYERS: {players}"); } -fn get_targetables_near_quad(entity_id: u64, num_players: u64) -> Vec { +fn get_targetables_near_quad(ctx: &ReducerContext, entity_id: u64, num_players: u64) -> Vec { let mut result = Vec::with_capacity(4); for id in entity_id..num_players { - for t in GameLiveTargetableState::filter_by_quad(&(id as i64)) { - result.push(GameTargetableState::filter_by_entity_id(&t.entity_id).expect("Identity not found")) + for t in ctx.db.game_live_targetable_state().quad().filter(&(id as i64)) { + result.push( + ctx.db + .game_targetable_state() + .entity_id() + .find(&t.entity_id) + .expect("Identity not found"), + ) } } @@ -280,13 +284,22 @@ fn get_targetables_near_quad(entity_id: u64, num_players: u64) -> Vec current_time_ms { continue; } - let agent_targetable = GameTargetableState::filter_by_entity_id(&agent.entity_id) + let agent_targetable = ctx + .db + .game_targetable_state() + .entity_id() + .find(&agent.entity_id) .expect("No TargetableState for AgentState entity"); - let surrounding_agents = get_targetables_near_quad(agent_targetable.entity_id, players); + let surrounding_agents = get_targetables_near_quad(ctx, agent_targetable.entity_id, players); agent.action = AgentAction::Fighting; - agent_loop(agent, agent_targetable, &surrounding_agents, current_time_ms); + agent_loop(ctx, agent, agent_targetable, &surrounding_agents, current_time_ms); count += 1; } @@ -372,20 +418,20 @@ pub fn game_loop_enemy_ia(players: u64) { } #[spacetimedb::reducer] -pub fn init_game_ia_loop(initial_load: u32) { +pub fn init_game_ia_loop(ctx: &ReducerContext, initial_load: u32) { let load = Load::new(initial_load); - insert_bulk_position(load.biggest_table); - insert_bulk_velocity(load.big_table); - update_position_all(load.biggest_table); - update_position_with_velocity(load.big_table); + insert_bulk_position(ctx, load.biggest_table); + insert_bulk_velocity(ctx, load.big_table); + update_position_all(ctx, load.biggest_table); + update_position_with_velocity(ctx, load.big_table); - insert_world(load.num_players as u64); + insert_world(ctx, load.num_players as u64); } #[spacetimedb::reducer] -pub fn run_game_ia_loop(initial_load: u32) { +pub fn run_game_ia_loop(ctx: &ReducerContext, initial_load: u32) { let load = Load::new(initial_load); - game_loop_enemy_ia(load.num_players as u64); + game_loop_enemy_ia(ctx, load.num_players as u64); } diff --git a/modules/benchmarks/src/synthetic.rs b/modules/benchmarks/src/synthetic.rs index 05f930d2202..bc897a538af 100644 --- a/modules/benchmarks/src/synthetic.rs +++ b/modules/benchmarks/src/synthetic.rs @@ -23,13 +23,13 @@ //! Obviously more could be added... #![allow(non_camel_case_types)] #![allow(clippy::too_many_arguments)] -use spacetimedb::println; +use spacetimedb::{println, ReducerContext, Table}; use std::hint::black_box; // ---------- schemas ---------- #[spacetimedb::table(name = unique_0_u32_u64_str)] -pub struct unique_0_u32_u64_str { +pub struct unique_0_u32_u64_str_t { #[unique] id: u32, age: u64, @@ -37,14 +37,14 @@ pub struct unique_0_u32_u64_str { } #[spacetimedb::table(name = no_index_u32_u64_str)] -pub struct no_index_u32_u64_str { +pub struct no_index_u32_u64_str_t { id: u32, age: u64, name: String, } #[spacetimedb::table(name = btree_each_column_u32_u64_str)] -pub struct btree_each_column_u32_u64_str { +pub struct btree_each_column_u32_u64_str_t { #[index(btree)] id: u32, #[index(btree)] @@ -54,7 +54,7 @@ pub struct btree_each_column_u32_u64_str { } #[spacetimedb::table(name = unique_0_u32_u64_u64)] -pub struct unique_0_u32_u64_u64 { +pub struct unique_0_u32_u64_u64_t { #[unique] id: u32, x: u64, @@ -62,14 +62,14 @@ pub struct unique_0_u32_u64_u64 { } #[spacetimedb::table(name = no_index_u32_u64_u64)] -pub struct no_index_u32_u64_u64 { +pub struct no_index_u32_u64_u64_t { id: u32, x: u64, y: u64, } #[spacetimedb::table(name = btree_each_column_u32_u64_u64)] -pub struct btree_each_column_u32_u64_u64 { +pub struct btree_each_column_u32_u64_u64_t { #[index(btree)] id: u32, #[index(btree)] @@ -81,121 +81,121 @@ pub struct btree_each_column_u32_u64_u64 { // ---------- empty ---------- #[spacetimedb::reducer] -pub fn empty() {} +pub fn empty(_ctx: &ReducerContext) {} // ---------- insert ---------- #[spacetimedb::reducer] -pub fn insert_unique_0_u32_u64_str(id: u32, age: u64, name: String) { - unique_0_u32_u64_str::insert(unique_0_u32_u64_str { id, name, age }).unwrap(); +pub fn insert_unique_0_u32_u64_str(ctx: &ReducerContext, id: u32, age: u64, name: String) { + ctx.db + .unique_0_u32_u64_str() + .insert(unique_0_u32_u64_str_t { id, name, age }); } #[spacetimedb::reducer] -pub fn insert_no_index_u32_u64_str(id: u32, age: u64, name: String) { - no_index_u32_u64_str::insert(no_index_u32_u64_str { id, name, age }); +pub fn insert_no_index_u32_u64_str(ctx: &ReducerContext, id: u32, age: u64, name: String) { + ctx.db + .no_index_u32_u64_str() + .insert(no_index_u32_u64_str_t { id, name, age }); } #[spacetimedb::reducer] -pub fn insert_btree_each_column_u32_u64_str(id: u32, age: u64, name: String) { - btree_each_column_u32_u64_str::insert(btree_each_column_u32_u64_str { id, name, age }); +pub fn insert_btree_each_column_u32_u64_str(ctx: &ReducerContext, id: u32, age: u64, name: String) { + ctx.db + .btree_each_column_u32_u64_str() + .insert(btree_each_column_u32_u64_str_t { id, name, age }); } #[spacetimedb::reducer] -pub fn insert_unique_0_u32_u64_u64(id: u32, x: u64, y: u64) { - unique_0_u32_u64_u64::insert(unique_0_u32_u64_u64 { id, x, y }).unwrap(); +pub fn insert_unique_0_u32_u64_u64(ctx: &ReducerContext, id: u32, x: u64, y: u64) { + ctx.db + .unique_0_u32_u64_u64() + .insert(unique_0_u32_u64_u64_t { id, x, y }); } #[spacetimedb::reducer] -pub fn insert_no_index_u32_u64_u64(id: u32, x: u64, y: u64) { - no_index_u32_u64_u64::insert(no_index_u32_u64_u64 { id, x, y }); +pub fn insert_no_index_u32_u64_u64(ctx: &ReducerContext, id: u32, x: u64, y: u64) { + ctx.db + .no_index_u32_u64_u64() + .insert(no_index_u32_u64_u64_t { id, x, y }); } #[spacetimedb::reducer] -pub fn insert_btree_each_column_u32_u64_u64(id: u32, x: u64, y: u64) { - btree_each_column_u32_u64_u64::insert(btree_each_column_u32_u64_u64 { id, x, y }); +pub fn insert_btree_each_column_u32_u64_u64(ctx: &ReducerContext, id: u32, x: u64, y: u64) { + ctx.db + .btree_each_column_u32_u64_u64() + .insert(btree_each_column_u32_u64_u64_t { id, x, y }); } // ---------- insert bulk ---------- #[spacetimedb::reducer] -pub fn insert_bulk_unique_0_u32_u64_u64(locs: Vec) { +pub fn insert_bulk_unique_0_u32_u64_u64(ctx: &ReducerContext, locs: Vec) { for loc in locs { - unique_0_u32_u64_u64::insert(loc).unwrap(); + ctx.db.unique_0_u32_u64_u64().insert(loc); } } #[spacetimedb::reducer] -pub fn insert_bulk_no_index_u32_u64_u64(locs: Vec) { +pub fn insert_bulk_no_index_u32_u64_u64(ctx: &ReducerContext, locs: Vec) { for loc in locs { - no_index_u32_u64_u64::insert(loc); + ctx.db.no_index_u32_u64_u64().insert(loc); } } #[spacetimedb::reducer] -pub fn insert_bulk_btree_each_column_u32_u64_u64(locs: Vec) { +pub fn insert_bulk_btree_each_column_u32_u64_u64(ctx: &ReducerContext, locs: Vec) { for loc in locs { - btree_each_column_u32_u64_u64::insert(loc); + ctx.db.btree_each_column_u32_u64_u64().insert(loc); } } #[spacetimedb::reducer] -pub fn insert_bulk_unique_0_u32_u64_str(people: Vec) { +pub fn insert_bulk_unique_0_u32_u64_str(ctx: &ReducerContext, people: Vec) { for u32_u64_str in people { - unique_0_u32_u64_str::insert(u32_u64_str).unwrap(); + ctx.db.unique_0_u32_u64_str().insert(u32_u64_str); } } #[spacetimedb::reducer] -pub fn insert_bulk_no_index_u32_u64_str(people: Vec) { +pub fn insert_bulk_no_index_u32_u64_str(ctx: &ReducerContext, people: Vec) { for u32_u64_str in people { - no_index_u32_u64_str::insert(u32_u64_str); + ctx.db.no_index_u32_u64_str().insert(u32_u64_str); } } #[spacetimedb::reducer] -pub fn insert_bulk_btree_each_column_u32_u64_str(people: Vec) { +pub fn insert_bulk_btree_each_column_u32_u64_str(ctx: &ReducerContext, people: Vec) { for u32_u64_str in people { - btree_each_column_u32_u64_str::insert(u32_u64_str); + ctx.db.btree_each_column_u32_u64_str().insert(u32_u64_str); } } // ---------- update ---------- #[spacetimedb::reducer] -pub fn update_bulk_unique_0_u32_u64_u64(row_count: u32) { +pub fn update_bulk_unique_0_u32_u64_u64(ctx: &ReducerContext, row_count: u32) { let mut hit: u32 = 0; - for loc in unique_0_u32_u64_u64::iter().take(row_count as usize) { + for loc in ctx.db.unique_0_u32_u64_u64().iter().take(row_count as usize) { hit += 1; - assert!( - unique_0_u32_u64_u64::update_by_id( - &loc.id, - unique_0_u32_u64_u64 { - id: loc.id, - x: loc.x.wrapping_add(1), - y: loc.y, - }, - ), - "failed to update u32_u64_u64" - ); + ctx.db.unique_0_u32_u64_u64().id().update(unique_0_u32_u64_u64_t { + id: loc.id, + x: loc.x.wrapping_add(1), + y: loc.y, + }); } assert_eq!(hit, row_count, "not enough rows to perform requested amount of updates"); } #[spacetimedb::reducer] -pub fn update_bulk_unique_0_u32_u64_str(row_count: u32) { +pub fn update_bulk_unique_0_u32_u64_str(ctx: &ReducerContext, row_count: u32) { let mut hit: u32 = 0; - for u32_u64_str in unique_0_u32_u64_str::iter().take(row_count as usize) { + for u32_u64_str in ctx.db.unique_0_u32_u64_str().iter().take(row_count as usize) { hit += 1; - assert!( - unique_0_u32_u64_str::update_by_id( - &u32_u64_str.id, - unique_0_u32_u64_str { - id: u32_u64_str.id, - name: u32_u64_str.name, - age: u32_u64_str.age.wrapping_add(1), - }, - ), - "failed to update u32_u64_str" - ); + ctx.db.unique_0_u32_u64_str().id().update(unique_0_u32_u64_str_t { + id: u32_u64_str.id, + name: u32_u64_str.name, + age: u32_u64_str.age.wrapping_add(1), + }); } assert_eq!(hit, row_count, "not enough rows to perform requested amount of updates"); } @@ -203,14 +203,14 @@ pub fn update_bulk_unique_0_u32_u64_str(row_count: u32) { // ---------- iterate ---------- #[spacetimedb::reducer] -pub fn iterate_unique_0_u32_u64_str() { - for u32_u64_str in unique_0_u32_u64_str::iter() { +pub fn iterate_unique_0_u32_u64_str(ctx: &ReducerContext) { + for u32_u64_str in ctx.db.unique_0_u32_u64_str().iter() { black_box(u32_u64_str); } } #[spacetimedb::reducer] -pub fn iterate_unique_0_u32_u64_u64() { - for u32_u64_u64 in unique_0_u32_u64_u64::iter() { +pub fn iterate_unique_0_u32_u64_u64(ctx: &ReducerContext) { + for u32_u64_u64 in ctx.db.unique_0_u32_u64_u64().iter() { black_box(u32_u64_u64); } } @@ -218,106 +218,106 @@ pub fn iterate_unique_0_u32_u64_u64() { // ---------- filtering ---------- #[spacetimedb::reducer] -pub fn filter_unique_0_u32_u64_str_by_id(id: u32) { - if let Some(p) = unique_0_u32_u64_str::filter_by_id(&id) { +pub fn filter_unique_0_u32_u64_str_by_id(ctx: &ReducerContext, id: u32) { + if let Some(p) = ctx.db.unique_0_u32_u64_str().id().find(&id) { black_box(p); } } #[spacetimedb::reducer] -pub fn filter_no_index_u32_u64_str_by_id(id: u32) { - for p in no_index_u32_u64_str::filter_by_id(&id) { +pub fn filter_no_index_u32_u64_str_by_id(ctx: &ReducerContext, id: u32) { + for p in ctx.db.no_index_u32_u64_str().iter().filter(|p| p.id == id) { black_box(p); } } #[spacetimedb::reducer] -pub fn filter_btree_each_column_u32_u64_str_by_id(id: u32) { - for p in btree_each_column_u32_u64_str::filter_by_id(&id) { +pub fn filter_btree_each_column_u32_u64_str_by_id(ctx: &ReducerContext, id: u32) { + for p in ctx.db.btree_each_column_u32_u64_str().id().filter(&id) { black_box(p); } } #[spacetimedb::reducer] -pub fn filter_unique_0_u32_u64_str_by_name(name: String) { - for p in unique_0_u32_u64_str::filter_by_name(&name) { +pub fn filter_unique_0_u32_u64_str_by_name(ctx: &ReducerContext, name: String) { + for p in ctx.db.unique_0_u32_u64_str().iter().filter(|p| p.name == name) { black_box(p); } } #[spacetimedb::reducer] -pub fn filter_no_index_u32_u64_str_by_name(name: String) { - for p in no_index_u32_u64_str::filter_by_name(&name) { +pub fn filter_no_index_u32_u64_str_by_name(ctx: &ReducerContext, name: String) { + for p in ctx.db.no_index_u32_u64_str().iter().filter(|p| p.name == name) { black_box(p); } } #[spacetimedb::reducer] -pub fn filter_btree_each_column_u32_u64_str_by_name(name: String) { - for p in btree_each_column_u32_u64_str::filter_by_name(&name) { +pub fn filter_btree_each_column_u32_u64_str_by_name(ctx: &ReducerContext, name: String) { + for p in ctx.db.btree_each_column_u32_u64_str().name().filter(&name) { black_box(p); } } #[spacetimedb::reducer] -pub fn filter_unique_0_u32_u64_u64_by_id(id: u32) { - if let Some(loc) = unique_0_u32_u64_u64::filter_by_id(&id) { +pub fn filter_unique_0_u32_u64_u64_by_id(ctx: &ReducerContext, id: u32) { + if let Some(loc) = ctx.db.unique_0_u32_u64_u64().id().find(&id) { black_box(loc); } } #[spacetimedb::reducer] -pub fn filter_no_index_u32_u64_u64_by_id(id: u32) { - for loc in no_index_u32_u64_u64::filter_by_id(&id) { +pub fn filter_no_index_u32_u64_u64_by_id(ctx: &ReducerContext, id: u32) { + for loc in ctx.db.no_index_u32_u64_u64().iter().filter(|p| p.id == id) { black_box(loc); } } #[spacetimedb::reducer] -pub fn filter_btree_each_column_u32_u64_u64_by_id(id: u32) { - for loc in btree_each_column_u32_u64_u64::filter_by_id(&id) { +pub fn filter_btree_each_column_u32_u64_u64_by_id(ctx: &ReducerContext, id: u32) { + for loc in ctx.db.btree_each_column_u32_u64_u64().id().filter(&id) { black_box(loc); } } #[spacetimedb::reducer] -pub fn filter_unique_0_u32_u64_u64_by_x(x: u64) { - for loc in unique_0_u32_u64_u64::filter_by_x(&x) { +pub fn filter_unique_0_u32_u64_u64_by_x(ctx: &ReducerContext, x: u64) { + for loc in ctx.db.unique_0_u32_u64_u64().iter().filter(|p| p.x == x) { black_box(loc); } } #[spacetimedb::reducer] -pub fn filter_no_index_u32_u64_u64_by_x(x: u64) { - for loc in no_index_u32_u64_u64::filter_by_x(&x) { +pub fn filter_no_index_u32_u64_u64_by_x(ctx: &ReducerContext, x: u64) { + for loc in ctx.db.no_index_u32_u64_u64().iter().filter(|p| p.x == x) { black_box(loc); } } #[spacetimedb::reducer] -pub fn filter_btree_each_column_u32_u64_u64_by_x(x: u64) { - for loc in btree_each_column_u32_u64_u64::filter_by_x(&x) { +pub fn filter_btree_each_column_u32_u64_u64_by_x(ctx: &ReducerContext, x: u64) { + for loc in ctx.db.btree_each_column_u32_u64_u64().x().filter(&x) { black_box(loc); } } #[spacetimedb::reducer] -pub fn filter_unique_0_u32_u64_u64_by_y(x: u64) { - for loc in unique_0_u32_u64_u64::filter_by_y(&x) { +pub fn filter_unique_0_u32_u64_u64_by_y(ctx: &ReducerContext, x: u64) { + for loc in ctx.db.unique_0_u32_u64_u64().iter().filter(|p| p.y == x) { black_box(loc); } } #[spacetimedb::reducer] -pub fn filter_no_index_u32_u64_u64_by_y(x: u64) { - for loc in no_index_u32_u64_u64::filter_by_y(&x) { +pub fn filter_no_index_u32_u64_u64_by_y(ctx: &ReducerContext, x: u64) { + for loc in ctx.db.no_index_u32_u64_u64().iter().filter(|p| p.y == x) { black_box(loc); } } #[spacetimedb::reducer] -pub fn filter_btree_each_column_u32_u64_u64_by_y(x: u64) { - for loc in btree_each_column_u32_u64_u64::filter_by_y(&x) { +pub fn filter_btree_each_column_u32_u64_u64_by_y(ctx: &ReducerContext, x: u64) { + for loc in ctx.db.btree_each_column_u32_u64_u64().y().filter(&x) { black_box(loc); } } @@ -327,43 +327,43 @@ pub fn filter_btree_each_column_u32_u64_u64_by_y(x: u64) { // FIXME: current nonunique delete interface is UNUSABLE!!!! #[spacetimedb::reducer] -pub fn delete_unique_0_u32_u64_str_by_id(id: u32) { - unique_0_u32_u64_str::delete_by_id(&id); +pub fn delete_unique_0_u32_u64_str_by_id(ctx: &ReducerContext, id: u32) { + ctx.db.unique_0_u32_u64_str().id().delete(&id); } #[spacetimedb::reducer] -pub fn delete_unique_0_u32_u64_u64_by_id(id: u32) { - unique_0_u32_u64_u64::delete_by_id(&id); +pub fn delete_unique_0_u32_u64_u64_by_id(ctx: &ReducerContext, id: u32) { + ctx.db.unique_0_u32_u64_u64().id().delete(&id); } // ---------- clear table ---------- #[spacetimedb::reducer] -pub fn clear_table_unique_0_u32_u64_str() { +pub fn clear_table_unique_0_u32_u64_str(_ctx: &ReducerContext) { unimplemented!("Modules currently have no interface to clear a table"); } #[spacetimedb::reducer] -pub fn clear_table_no_index_u32_u64_str() { +pub fn clear_table_no_index_u32_u64_str(_ctx: &ReducerContext) { unimplemented!("Modules currently have no interface to clear a table"); } #[spacetimedb::reducer] -pub fn clear_table_btree_each_column_u32_u64_str() { +pub fn clear_table_btree_each_column_u32_u64_str(_ctx: &ReducerContext) { unimplemented!("Modules currently have no interface to clear a table"); } #[spacetimedb::reducer] -pub fn clear_table_unique_0_u32_u64_u64() { +pub fn clear_table_unique_0_u32_u64_u64(_ctx: &ReducerContext) { unimplemented!("Modules currently have no interface to clear a table"); } #[spacetimedb::reducer] -pub fn clear_table_no_index_u32_u64_u64() { +pub fn clear_table_no_index_u32_u64_u64(_ctx: &ReducerContext) { unimplemented!("Modules currently have no interface to clear a table"); } #[spacetimedb::reducer] -pub fn clear_table_btree_each_column_u32_u64_u64() { +pub fn clear_table_btree_each_column_u32_u64_u64(_ctx: &ReducerContext) { unimplemented!("Modules currently have no interface to clear a table"); } // ---------- count ---------- @@ -371,41 +371,42 @@ pub fn clear_table_btree_each_column_u32_u64_u64() { // You need to inspect the module outputs to actually read the result from these. #[spacetimedb::reducer] -pub fn count_unique_0_u32_u64_str() { - println!("COUNT: {}", unique_0_u32_u64_str::iter().count()); +pub fn count_unique_0_u32_u64_str(ctx: &ReducerContext) { + println!("COUNT: {}", ctx.db.unique_0_u32_u64_str().count()); } #[spacetimedb::reducer] -pub fn count_no_index_u32_u64_str() { - println!("COUNT: {}", no_index_u32_u64_str::iter().count()); +pub fn count_no_index_u32_u64_str(ctx: &ReducerContext) { + println!("COUNT: {}", ctx.db.no_index_u32_u64_str().count()); } #[spacetimedb::reducer] -pub fn count_btree_each_column_u32_u64_str() { - println!("COUNT: {}", btree_each_column_u32_u64_str::iter().count()); +pub fn count_btree_each_column_u32_u64_str(ctx: &ReducerContext) { + println!("COUNT: {}", ctx.db.btree_each_column_u32_u64_str().count()); } #[spacetimedb::reducer] -pub fn count_unique_0_u32_u64_u64() { - println!("COUNT: {}", unique_0_u32_u64_u64::iter().count()); +pub fn count_unique_0_u32_u64_u64(ctx: &ReducerContext) { + println!("COUNT: {}", ctx.db.unique_0_u32_u64_u64().count()); } #[spacetimedb::reducer] -pub fn count_no_index_u32_u64_u64() { - println!("COUNT: {}", no_index_u32_u64_u64::iter().count()); +pub fn count_no_index_u32_u64_u64(ctx: &ReducerContext) { + println!("COUNT: {}", ctx.db.no_index_u32_u64_u64().count()); } #[spacetimedb::reducer] -pub fn count_btree_each_column_u32_u64_u64() { - println!("COUNT: {}", btree_each_column_u32_u64_u64::iter().count()); +pub fn count_btree_each_column_u32_u64_u64(ctx: &ReducerContext) { + println!("COUNT: {}", ctx.db.btree_each_column_u32_u64_u64().count()); } // ---------- module-specific stuff ---------- #[spacetimedb::reducer] -pub fn fn_with_1_args(_arg: String) {} +pub fn fn_with_1_args(_ctx: &ReducerContext, _arg: String) {} #[spacetimedb::reducer] pub fn fn_with_32_args( + _ctx: &ReducerContext, _arg1: String, _arg2: String, _arg3: String, @@ -442,7 +443,7 @@ pub fn fn_with_32_args( } #[spacetimedb::reducer] -pub fn print_many_things(n: u32) { +pub fn print_many_things(_ctx: &ReducerContext, n: u32) { for _ in 0..n { println!("hello again!"); } diff --git a/modules/perf-test/src/lib.rs b/modules/perf-test/src/lib.rs index a24aca82643..fbc4b1cd8aa 100644 --- a/modules/perf-test/src/lib.rs +++ b/modules/perf-test/src/lib.rs @@ -1,4 +1,5 @@ -use spacetimedb::{query, time_span::Span}; +use spacetimedb::time_span::Span; +use spacetimedb::{ReducerContext, Table}; #[spacetimedb::table(name = locations, index(name = coordinates, btree(columns = [x, z, dimension])))] #[derive(Debug, PartialEq, Eq)] @@ -18,14 +19,14 @@ const NUM_CHUNKS: u64 = 1000; const ROWS_PER_CHUNK: u64 = 1200; #[spacetimedb::reducer] -pub fn load_location_table() { +pub fn load_location_table(ctx: &ReducerContext) { for chunk in 0u64..NUM_CHUNKS { for i in 0u64..ROWS_PER_CHUNK { let id = chunk * 1200 + i; let x = 0i32; let z = chunk as i32; let dimension = id as u32; - let _ = Location::insert(Location { + ctx.db.locations().insert(Location { id, chunk, x, @@ -41,39 +42,49 @@ const CHUNK: u64 = ID / ROWS_PER_CHUNK; #[spacetimedb::reducer] /// Probing a single column index for a single row should be fast! -pub fn test_index_scan_on_id() { +pub fn test_index_scan_on_id(ctx: &ReducerContext) { let span = Span::start("Index scan on {id}"); - let location = Location::filter_by_id(&ID).unwrap(); + let location = ctx.db.locations().id().find(&ID).unwrap(); span.end(); assert_eq!(ID, location.id); } #[spacetimedb::reducer] /// Scanning a single column index for `ROWS_PER_CHUNK` rows should also be fast! -pub fn test_index_scan_on_chunk() { +pub fn test_index_scan_on_chunk(ctx: &ReducerContext) { let span = Span::start("Index scan on {chunk}"); - let n = Location::filter_by_chunk(&CHUNK).count(); + let n = ctx.db.locations().chunk().filter(&CHUNK).count(); span.end(); assert_eq!(n as u64, ROWS_PER_CHUNK); } #[spacetimedb::reducer] /// Probing a multi-column index for a single row should be fast! -pub fn test_index_scan_on_x_z_dimension() { +pub fn test_index_scan_on_x_z_dimension(ctx: &ReducerContext) { let z = CHUNK as i32; let dimension = ID as u32; let span = Span::start("Index scan on {x, z, dimension}"); - let n = query!(|r: Location| r.x == 0 && r.z == z && r.dimension == dimension).count(); + let n = ctx + .db + .locations() + .iter() + .filter(|r| r.x == 0 && r.z == z && r.dimension == dimension) + .count(); span.end(); assert_eq!(n, 1); } #[spacetimedb::reducer] /// Probing a multi-column index for `ROWS_PER_CHUNK` rows should also be fast! -pub fn test_index_scan_on_x_z() { +pub fn test_index_scan_on_x_z(ctx: &ReducerContext) { let z = CHUNK as i32; let span = Span::start("Index scan on {x, z}"); - let n = query!(|r: Location| r.x == 0 && r.z == z).count(); + let n = ctx + .db + .locations() + .iter() + .filter(|r| r.x == 0 && r.z == z) + .count(); span.end(); assert_eq!(n as u64, ROWS_PER_CHUNK); } diff --git a/modules/quickstart-chat/src/lib.rs b/modules/quickstart-chat/src/lib.rs index ac64186d1a1..3719c9f8d4a 100644 --- a/modules/quickstart-chat/src/lib.rs +++ b/modules/quickstart-chat/src/lib.rs @@ -1,4 +1,4 @@ -use spacetimedb::{Identity, ReducerContext, Timestamp}; +use spacetimedb::{Identity, ReducerContext, Table, Timestamp}; #[spacetimedb::table(name = users, public)] pub struct User { @@ -24,16 +24,13 @@ fn validate_name(name: String) -> Result { } #[spacetimedb::reducer] -pub fn set_name(ctx: ReducerContext, name: String) -> Result<(), String> { +pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { let name = validate_name(name)?; - if let Some(user) = User::filter_by_identity(&ctx.sender) { - User::update_by_identity( - &ctx.sender, - User { - name: Some(name), - ..user - }, - ); + if let Some(user) = ctx.db.users().identity().find(&ctx.sender) { + ctx.db.users().identity().update(User { + name: Some(name), + ..user + }); Ok(()) } else { Err("Cannot set name for unknown user".to_string()) @@ -49,12 +46,12 @@ fn validate_message(text: String) -> Result { } #[spacetimedb::reducer] -pub fn send_message(ctx: ReducerContext, text: String) -> Result<(), String> { +pub fn send_message(ctx: &ReducerContext, text: String) -> Result<(), String> { // Things to consider: // - Rate-limit messages per-user. // - Reject messages from unnamed users. let text = validate_message(text)?; - Message::insert(Message { + ctx.db.messages().insert(Message { sender: ctx.sender, text, sent: ctx.timestamp, @@ -64,30 +61,29 @@ pub fn send_message(ctx: ReducerContext, text: String) -> Result<(), String> { #[spacetimedb::reducer(init)] // Called when the module is initially published -pub fn init() {} +pub fn init(_ctx: &ReducerContext) {} #[spacetimedb::reducer(client_connected)] -pub fn identity_connected(ctx: ReducerContext) { - if let Some(user) = User::filter_by_identity(&ctx.sender) { +pub fn identity_connected(ctx: &ReducerContext) { + if let Some(user) = ctx.db.users().identity().find(&ctx.sender) { // If this is a returning user, i.e. we already have a `User` with this `Identity`, // set `online: true`, but leave `name` and `identity` unchanged. - User::update_by_identity(&ctx.sender, User { online: true, ..user }); + ctx.db.users().identity().update(User { online: true, ..user }); } else { // If this is a new user, create a `User` row for the `Identity`, // which is online, but hasn't set a name. - User::insert(User { + ctx.db.users().insert(User { name: None, identity: ctx.sender, online: true, - }) - .unwrap(); + }); } } #[spacetimedb::reducer(client_disconnected)] -pub fn identity_disconnected(ctx: ReducerContext) { - if let Some(user) = User::filter_by_identity(&ctx.sender) { - User::update_by_identity(&ctx.sender, User { online: false, ..user }); +pub fn identity_disconnected(ctx: &ReducerContext) { + if let Some(user) = ctx.db.users().identity().find(&ctx.sender) { + ctx.db.users().identity().update(User { online: false, ..user }); } else { // This branch should be unreachable, // as it doesn't make sense for a client to disconnect without connecting first. diff --git a/modules/sdk-test-connect-disconnect/src/lib.rs b/modules/sdk-test-connect-disconnect/src/lib.rs index 5cb6a6fdd07..c89b7af1f3c 100644 --- a/modules/sdk-test-connect-disconnect/src/lib.rs +++ b/modules/sdk-test-connect-disconnect/src/lib.rs @@ -8,24 +8,24 @@ //! - Disconnect, then reconnect again. //! - Subscribe to `Disconnected`. //! - Observe the presence of one row with the client's `Identity`. -use spacetimedb::{Identity, ReducerContext}; +use spacetimedb::{Identity, ReducerContext, Table}; -#[spacetimedb::table(name = Connected, public)] +#[spacetimedb::table(name = connected, public)] pub struct Connected { identity: Identity, } -#[spacetimedb::table(name = Disconnected, public)] +#[spacetimedb::table(name = disconnected, public)] pub struct Disconnected { identity: Identity, } #[spacetimedb::reducer(client_connected)] -pub fn identity_connected(ctx: ReducerContext) { - Connected::insert(Connected { identity: ctx.sender }); +pub fn identity_connected(ctx: &ReducerContext) { + ctx.db.connected().insert(Connected { identity: ctx.sender }); } #[spacetimedb::reducer(client_disconnected)] -pub fn identity_disconnected(ctx: ReducerContext) { - Disconnected::insert(Disconnected { identity: ctx.sender }); +pub fn identity_disconnected(ctx: &ReducerContext) { + ctx.db.disconnected().insert(Disconnected { identity: ctx.sender }); } diff --git a/modules/sdk-test/Cargo.toml b/modules/sdk-test/Cargo.toml index fbd8a926f3b..1bc7e8695ce 100644 --- a/modules/sdk-test/Cargo.toml +++ b/modules/sdk-test/Cargo.toml @@ -12,3 +12,4 @@ crate-type = ["cdylib"] spacetimedb.workspace = true log.workspace = true anyhow.workspace = true +paste.workspace = true diff --git a/modules/sdk-test/src/lib.rs b/modules/sdk-test/src/lib.rs index c540d70c121..252ae7592d2 100644 --- a/modules/sdk-test/src/lib.rs +++ b/modules/sdk-test/src/lib.rs @@ -9,7 +9,7 @@ use anyhow::{Context, Result}; use spacetimedb::{ sats::{i256, u256}, - Address, Identity, ReducerContext, SpacetimeType, + Address, Identity, ReducerContext, SpacetimeType, Table, }; #[derive(SpacetimeType)] @@ -152,9 +152,11 @@ macro_rules! define_tables { { insert $insert:ident $(, $($ops:tt)* )? } $($field_name:ident $ty:ty),* $(,)*) => { - #[spacetimedb::reducer] - pub fn $insert ($($field_name : $ty,)*) { - $name::insert($name { $($field_name,)* }); + paste::paste! { + #[spacetimedb::reducer] + pub fn $insert (ctx: &ReducerContext, $($field_name : $ty,)*) { + ctx.db.[<$name:snake>]().insert($name { $($field_name,)* }); + } } define_tables!(@impl_ops $name { $($($ops)*)? } $($field_name $ty,)*); @@ -166,9 +168,11 @@ macro_rules! define_tables { { insert_or_panic $insert:ident $(, $($ops:tt)* )? } $($field_name:ident $ty:ty),* $(,)*) => { - #[spacetimedb::reducer] - pub fn $insert ($($field_name : $ty,)*) { - $name::insert($name { $($field_name,)* }).expect(concat!("Failed to insert row for table: ", stringify!($name))); + paste::paste! { + #[spacetimedb::reducer] + pub fn $insert (ctx: &ReducerContext, $($field_name : $ty,)*) { + ctx.db.[<$name:snake>]().insert($name { $($field_name,)* }); + } } define_tables!(@impl_ops $name { $($($ops)*)? } $($field_name $ty,)*); @@ -180,10 +184,11 @@ macro_rules! define_tables { { update_by $update:ident = $update_method:ident($unique_field:ident) $(, $($ops:tt)* )? } $($field_name:ident $ty:ty),* $(,)*) => { - #[spacetimedb::reducer] - pub fn $update ($($field_name : $ty,)*) { - let key = $unique_field.clone(); - $name::$update_method(&key, $name { $($field_name,)* }); + paste::paste! { + #[spacetimedb::reducer] + pub fn $update (ctx: &ReducerContext, $($field_name : $ty,)*) { + ctx.db.[<$name:snake>]().$unique_field().update($name { $($field_name,)* }); + } } define_tables!(@impl_ops $name { $($($ops)*)? } $($field_name $ty,)*); @@ -195,9 +200,11 @@ macro_rules! define_tables { { delete_by $delete:ident = $delete_method:ident($unique_field:ident : $unique_ty:ty) $(, $($ops:tt)*)? } $($other_fields:tt)* ) => { - #[spacetimedb::reducer] - pub fn $delete ($unique_field : $unique_ty) { - $name::$delete_method(&$unique_field); + paste::paste! { + #[spacetimedb::reducer] + pub fn $delete (ctx: &ReducerContext, $unique_field : $unique_ty) { + ctx.db.[<$name:snake>]().$unique_field().delete(&$unique_field); + } } define_tables!(@impl_ops $name { $($($ops)*)? } $($other_fields)*); @@ -205,9 +212,11 @@ macro_rules! define_tables { // Define a table. (@one $name:ident { $($ops:tt)* } $($(#[$attr:meta])* $field_name:ident $ty:ty),* $(,)*) => { - #[spacetimedb::table(name = $name, public)] - pub struct $name { - $($(#[$attr])* pub $field_name : $ty,)* + paste::paste! { + #[spacetimedb::table(name = [<$name:snake>], public)] + pub struct $name { + $($(#[$attr])* pub $field_name : $ty,)* + } } // Recursively implement reducers based on the `ops`. @@ -505,66 +514,66 @@ define_tables! { } #[spacetimedb::reducer] -fn insert_caller_one_identity(ctx: ReducerContext) -> anyhow::Result<()> { - OneIdentity::insert(OneIdentity { i: ctx.sender }); +fn insert_caller_one_identity(ctx: &ReducerContext) -> anyhow::Result<()> { + ctx.db.one_identity().insert(OneIdentity { i: ctx.sender }); Ok(()) } #[spacetimedb::reducer] -fn insert_caller_vec_identity(ctx: ReducerContext) -> anyhow::Result<()> { - VecIdentity::insert(VecIdentity { i: vec![ctx.sender] }); +fn insert_caller_vec_identity(ctx: &ReducerContext) -> anyhow::Result<()> { + ctx.db.vec_identity().insert(VecIdentity { i: vec![ctx.sender] }); Ok(()) } #[spacetimedb::reducer] -fn insert_caller_unique_identity(ctx: ReducerContext, data: i32) -> anyhow::Result<()> { - UniqueIdentity::insert(UniqueIdentity { i: ctx.sender, data })?; +fn insert_caller_unique_identity(ctx: &ReducerContext, data: i32) -> anyhow::Result<()> { + ctx.db.unique_identity().insert(UniqueIdentity { i: ctx.sender, data }); Ok(()) } #[spacetimedb::reducer] -fn insert_caller_pk_identity(ctx: ReducerContext, data: i32) -> anyhow::Result<()> { - PkIdentity::insert(PkIdentity { i: ctx.sender, data })?; +fn insert_caller_pk_identity(ctx: &ReducerContext, data: i32) -> anyhow::Result<()> { + ctx.db.pk_identity().insert(PkIdentity { i: ctx.sender, data }); Ok(()) } #[spacetimedb::reducer] -fn insert_caller_one_address(ctx: ReducerContext) -> anyhow::Result<()> { - OneAddress::insert(OneAddress { +fn insert_caller_one_address(ctx: &ReducerContext) -> anyhow::Result<()> { + ctx.db.one_address().insert(OneAddress { a: ctx.address.context("No address in reducer context")?, }); Ok(()) } #[spacetimedb::reducer] -fn insert_caller_vec_address(ctx: ReducerContext) -> anyhow::Result<()> { - VecAddress::insert(VecAddress { +fn insert_caller_vec_address(ctx: &ReducerContext) -> anyhow::Result<()> { + ctx.db.vec_address().insert(VecAddress { a: vec![ctx.address.context("No address in reducer context")?], }); Ok(()) } #[spacetimedb::reducer] -fn insert_caller_unique_address(ctx: ReducerContext, data: i32) -> anyhow::Result<()> { - UniqueAddress::insert(UniqueAddress { +fn insert_caller_unique_address(ctx: &ReducerContext, data: i32) -> anyhow::Result<()> { + ctx.db.unique_address().insert(UniqueAddress { a: ctx.address.context("No address in reducer context")?, data, - })?; + }); Ok(()) } #[spacetimedb::reducer] -fn insert_caller_pk_address(ctx: ReducerContext, data: i32) -> anyhow::Result<()> { - PkAddress::insert(PkAddress { +fn insert_caller_pk_address(ctx: &ReducerContext, data: i32) -> anyhow::Result<()> { + ctx.db.pk_address().insert(PkAddress { a: ctx.address.context("No address in reducer context")?, data, - })?; + }); Ok(()) } #[spacetimedb::reducer] -fn insert_primitives_as_strings(s: EveryPrimitiveStruct) { - VecString::insert(VecString { +fn insert_primitives_as_strings(ctx: &ReducerContext, s: EveryPrimitiveStruct) { + ctx.db.vec_string().insert(VecString { s: vec![ s.a.to_string(), s.b.to_string(), @@ -629,4 +638,4 @@ define_tables! { } #[spacetimedb::reducer] -fn no_op_succeeds() {} +fn no_op_succeeds(_ctx: &ReducerContext) {} diff --git a/modules/spacetimedb-quickstart/src/lib.rs b/modules/spacetimedb-quickstart/src/lib.rs index 4541c08d1e5..323c53dd119 100644 --- a/modules/spacetimedb-quickstart/src/lib.rs +++ b/modules/spacetimedb-quickstart/src/lib.rs @@ -1,4 +1,4 @@ -use spacetimedb::{println, query}; +use spacetimedb::{println, ReducerContext, Table}; #[spacetimedb::table(name = people, public)] pub struct Person { @@ -10,21 +10,21 @@ pub struct Person { } #[spacetimedb::reducer] -pub fn add(name: String, age: u8) { - Person::insert(Person { id: 0, name, age }).unwrap(); +pub fn add(ctx: &ReducerContext, name: String, age: u8) { + ctx.db.people().insert(Person { id: 0, name, age }); } #[spacetimedb::reducer] -pub fn say_hello() { - for person in Person::iter() { +pub fn say_hello(ctx: &ReducerContext) { + for person in ctx.db.people().iter() { println!("Hello, {}!", person.name); } println!("Hello, World!"); } #[spacetimedb::reducer] -pub fn list_over_age(age: u8) { - for person in query!(|person: Person| person.age >= age) { +pub fn list_over_age(ctx: &ReducerContext, age: u8) { + for person in ctx.db.people().iter().filter(|person| person.age >= age) { println!("{} has age {} >= {}", person.name, person.age, age); } }