Today we've released query builders for Rust and TypeScript modules. The purpose of the query builder API is so that you can write views that will take advantage of the unique performance guarantees of SpacetimeDB's query engine, particularly for realtime subscription updates.
The query builder also now allows you to iterate or scan a table in a view, something that previously wasn't possible using only the index accessors exposed by ViewContext and AnonymousViewContext.
The query builder exposes the following query operators:
.where()Used for filtering. Equivalent to aWHEREcondition in SQL..leftSemijoin()Equivalent to an inner join in sql where a row is return from thelhsonly if it matches with a row on therhs..rightSemijoin()Equivalent to an inner join in sql where a row is return from therhsonly if it matches with a row on thelhs.
Examples (Rust)
use spacetimedb::{Identity, Query, Table, ViewContext, AnonymousViewContext};
#[spacetimedb::table(name = player_state)]
pub struct PlayerState {
#[unique]
player_id: u64,
online: bool,
}
#[spacetimedb::table(name = player_internal)]
pub struct Player {
#[auto_inc]
#[primary_key]
id: u64,
#[unique]
identity: Identity,
name: String,
#[index(btree)]
age: u8,
}
#[spacetimedb::table(name = moderator_internal)]
pub struct Moderator {
#[unique]
player_id: u64,
}
/// Returns all players.
/// Equivalent to `SELECT * FROM player_internal`.
#[spacetimedb::view(name = player, public)]
fn player(ctx: &AnonymousViewContext) -> Query<Player> {
ctx.from.player_internal().build()
}
/// Returns the caller's player.
/// Equivalent to `SELECT * FROM player_internal WHERE "identity" = :sender`.
#[spacetimedb::view(name = my_player, public)]
fn my_player(ctx: &ViewContext) -> Query<Player> {
ctx.from.player_internal().r#where(|p| p.identity.eq(ctx.sender)).build()
}
/// Returns only online players.
/// Equivalent to:
/// ```sql
/// SELECT q.*
/// FROM player_state p JOIN player_internal q ON p.player_id = q.id
/// WHERE p.online
/// ```
#[spacetimedb::view(name = online_player, public)]
fn online_player(ctx: &AnonymousViewContext) -> Query<Player> {
ctx.from
.player_state()
.r#where(|p| p.online.eq(true))
.right_semijoin(ctx.from.player_internal(), |(p, q)| p.player_id.eq(q.id))
.build()
}
/// Returns only the caller's player if online.
/// Equivalent to:
/// ```sql
/// SELECT q.*
/// FROM player_state p JOIN player_internal q ON p.player_id = q.id
/// WHERE p.online AND q.identity = :sender
/// ```
#[spacetimedb::view(name = my_online_player, public)]
fn my_online_player(ctx: &ViewContext) -> Query<Player> {
ctx.from
.player_state()
.r#where(|p| p.online.eq(true))
.right_semijoin(ctx.from.player_internal(), |(p, q)| p.player_id.eq(q.id))
.r#where(|p| p.identity.eq(ctx.sender))
.build()
}
/// Returns the moderators.
/// Equivalent to:
/// ```sql
/// SELECT p.* FROM player_internal p JOIN moderator_internal m ON p.id = m.player_id
/// ```
#[spacetimedb::view(name = moderator, public)]
fn moderator(ctx: &AnonymousViewContext) -> Query<Player> {
ctx.from
.player_internal()
.left_semijoin(ctx.from.moderator_internal(), |(p, m)| p.id.eq(m.player_id))
.build()
} Examples (TypeScript)
import { schema, table, t, type RowObj } from 'spacetimedb/server';
const playerState = table('playerState', {
playerId: t.u64().unique(),
online: t.bool(),
});
const playerInternal = table('playerInternal', {
id: t.u64().primaryKey().autoInc(),
identity: t.identity().unique(),
name: t.string(),
age: t.u8().index('btree'),
});
const spacetimedb = schema(playerState, playerInternal);
spacetimedb.view(
{ name: 'my_online_player', public: true },
t.array(playerInternal.row()),
ctx => {
return ctx.from.playerState
.where(p => p.online.eq(true))
.rightSemijoin(ctx.from.playerInternal, (p, q) => p.playerId.eq(q.id))
.where(p => p.identity.eq(ctx.sender))
.build();
}
); Bug Fixes
- Fixes an issue with the
--delete-data=on-conflictflag ofspacetimedb publish - Fixes an issue where databases were returning 400/500 errors after publishing with
-c - Fixes an issue where
on_insertandon_deletewere not firing correctly for per-client (ViewContext) views
What's Changed
- Delete duplicated docs folders by @gefjon in https://github.com/clockworklabs/SpacetimeDB/pull/3780
- Fixes reported issues with the TypeScript SDK by @cloutiertyler in https://github.com/clockworklabs/SpacetimeDB/pull/3737
- Fix some typescript issues by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3775
- Split Unity and C# tests into separate jobs by @jdetter in https://github.com/clockworklabs/SpacetimeDB/pull/3779
- Update typescript package size limits by @jdetter in https://github.com/clockworklabs/SpacetimeDB/pull/3786
- Add docs for procedures by @gefjon in https://github.com/clockworklabs/SpacetimeDB/pull/3766
- Actually report reducer fuel used by @drogus in https://github.com/clockworklabs/SpacetimeDB/pull/3799
- Fix view rewrite for delta tables by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3801
- Remove race condition from sdk test by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3804
- Implement DbContext for AnonymousViewContext and ViewContext by @tamaro-skaljic in https://github.com/clockworklabs/SpacetimeDB/pull/3787
- Fixes docs links by @cloutiertyler in https://github.com/clockworklabs/SpacetimeDB/pull/3803
- C# Views - Use Name from ViewAttribute instead of Method Name by @chutch1122 in https://github.com/clockworklabs/SpacetimeDB/pull/3792
- Remove duplicate assertSql in smoke test by @mamcx in https://github.com/clockworklabs/SpacetimeDB/pull/3588
- Docs: Update docs nav height to 56px by @clockwork-tien in https://github.com/clockworklabs/SpacetimeDB/pull/3788
- [TS] Fix
developmentexports breaking NextJS by @kistz in https://github.com/clockworklabs/SpacetimeDB/pull/3796 - [TS] Call registerType for procedure params by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3806
- CI - Skip the Unity testsuite on external PRs by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3805
- Bump versions to 1.11.0 by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3808
- Added and tested procedure docs for Unreal C++ & Unreal Blueprint by @JasonAtClockwork in https://github.com/clockworklabs/SpacetimeDB/pull/3810
- Update view ABI to support returning queries by @jsdt in https://github.com/clockworklabs/SpacetimeDB/pull/3685
- [Rust] Module-side query builder types by @Shubham8287 in https://github.com/clockworklabs/SpacetimeDB/pull/3797
- [Rust] update module bindings to use new view abi by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3819
- Update wasmtime to v39 by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3818
- [Rust] Query builder Integration. by @Shubham8287 in https://github.com/clockworklabs/SpacetimeDB/pull/3823
- Store
SubscriptionMetricsforUpdate,Subscribe,UnsubscribeinModuleSubscriptionsby @Centril in https://github.com/clockworklabs/SpacetimeDB/pull/3821 - smoketests: Adjust test_enable_disable_replication test by @kim in https://github.com/clockworklabs/SpacetimeDB/pull/3822
- [TS] Implement TextEncoder/TextDecoder with native code by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3800
- Debug "stuck module" issue by @kim in https://github.com/clockworklabs/SpacetimeDB/pull/3813
- Fixes issues with
--delete-data=on-conflictby @cloutiertyler in https://github.com/clockworklabs/SpacetimeDB/pull/3730 - Add a typescript query builder for views by @jsdt in https://github.com/clockworklabs/SpacetimeDB/pull/3812
New Contributors
- @tamaro-skaljic made their first contribution in https://github.com/clockworklabs/SpacetimeDB/pull/3787
- @chutch1122 made their first contribution in https://github.com/clockworklabs/SpacetimeDB/pull/3792
- @kistz made their first contribution in https://github.com/clockworklabs/SpacetimeDB/pull/3796
Full Changelog: https://github.com/clockworklabs/SpacetimeDB/compare/v1.10.0...v1.11.0
