Standardize query builder syntax across Rust, TypeScript, and C# #4261
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description of Changes
Standardizes the query builder API across all three language SDKs (Rust, TypeScript, C#) for consistency.
Rust:
Querystruct toRawQuery, makeQuerya trait withfn into_sql(self) -> StringTable,FromWhere,LeftSemiJoin,RightSemiJoin) implementQuery<T>trait-> impl Query<T>instead of specifying exact builder types#[view]macro auto-detectsimpl Query<T>and rewrites toRawQuery<T>Notvariant toBoolExprwith.not()methodTypeScript:
ne()toColumnExpressionBooleanExprtoBoolExprclass with chainable.and(),.or(),.not()methods.build()deprecated but still works)from()wrapper — usetables.person.where(...)directlyqueryexport intotablesso table refs are also query builderssubscribe(ctx => ctx.from.person.where(...))useTablewith query builder syntax; deprecatefilter.tsC#:
Not()method toBoolExpr<TRow>IQuery<TRow>interface implemented by all builder types (Table,FromWhere,LeftSemiJoin,RightSemiJoin,Query)ToSql()to all builder types so.Build()is no longer requiredAddQueryto acceptIQuery<TRow>instead ofQuery<TRow>API and ABI breaking changes
Query<T>is now a trait (was a struct). The struct is renamed toRawQuery<T>. This is a breaking change for any code that usedQuery<T>as a type directly.BooleanExpris now aBoolExprclass (was a discriminated union type). Thequeryexport is deprecated in favor oftables.AddQuerynow acceptsFunc<QueryBuilder, IQuery<TRow>>instead ofFunc<QueryBuilder, Query<TRow>>. Existing.Build()calls still work sinceQuery<TRow>implementsIQuery<TRow>.Expected complexity level and risk
3 — Changes touch multiple language SDKs and codegen, but each individual change is straightforward. The Rust macro rewrite for
impl Query<T>detection is the most complex piece. All existing.build()/.Build()calls continue to work.Testing
cargo test -p spacetimedb-query-builder— 16/16 tests passcargo check -p spacetimedb— clean, no warningscargo checkon views-query, views-sql, views-basic, views-trapped smoketest modules — all cleancargo test -p spacetimedb-codegen codegen_csharp— snapshot updated, passesnpm test(TypeScript) — 101/101 tests passNot(),IQuery<T>interface