Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
12e95c8
Update C# bindings to use new View ABI
rekhoff Jan 27, 2026
d6ae551
Adding `Codegen.Test` snapshot updates
rekhoff Jan 28, 2026
0c02dbe
Merge branch 'master' into rekhoff/add-views-returning-queries
rekhoff Jan 28, 2026
dec5af0
Merge branch 'master' into rekhoff/add-views-returning-queries
rekhoff Jan 28, 2026
301b109
Initial add of C# module Typed Query Builder
rekhoff Jan 29, 2026
14f1ad1
Merge branch 'master' into rekhoff/add-views-returning-queries
rekhoff Jan 29, 2026
2aae402
Merge branch 'rekhoff/add-views-returning-queries' into rekhoff/cshar…
rekhoff Jan 29, 2026
7e5385b
Merge branch 'master' into rekhoff/add-views-returning-queries
rekhoff Jan 29, 2026
db3435b
Merge branch 'master' into rekhoff/add-views-returning-queries
rekhoff Jan 30, 2026
804cef2
Merge branch 'rekhoff/add-views-returning-queries' into rekhoff/cshar…
rekhoff Jan 30, 2026
0d3441f
Moved QueryBuilder to BSATN.Runtime to remove duplicate code
rekhoff Jan 31, 2026
0c196ed
Removed QueryBuilder meta file and updated SQL validation tests
rekhoff Feb 1, 2026
e55ba7d
Another formatting fix in QueryBuilderTests test
rekhoff Feb 1, 2026
0cb858c
Created specific Python test that invokes PublicTableQuery view
rekhoff Feb 3, 2026
84e7206
Use the literal overload in equality test
rekhoff Feb 3, 2026
40dfe17
Updated lints
rekhoff Feb 3, 2026
02ac28f
Moved end-to-end QueryBuilder test to csharp_module.py
rekhoff Feb 3, 2026
ac429f3
Removed new testing from python test entirely
rekhoff Feb 3, 2026
04c5794
Removed unneeded testing framework from server fixture
rekhoff Feb 4, 2026
d250f89
Readding a test that invokes Codegen.Tests views
rekhoff Feb 4, 2026
cecd264
Trigger Build
rekhoff Feb 5, 2026
a6d7ba9
Remove accidental add
rekhoff Feb 5, 2026
78c2b7c
Merge branch 'master' into rekhoff/csharp-module-query-builder
rekhoff Feb 7, 2026
bf96a67
Corrected a test in Codegen.Test and added module testing to regressi…
rekhoff Feb 10, 2026
d8f9d32
Added regression test for on view update received
rekhoff Feb 10, 2026
4b388e4
Merge branch 'master' into rekhoff/csharp-module-query-builder
rekhoff Feb 10, 2026
5f27d29
Updated all Regression Tests Views to go through `ctx`
rekhoff Feb 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,216 changes: 1,216 additions & 0 deletions crates/bindings-csharp/BSATN.Runtime/QueryBuilder.cs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions crates/bindings-csharp/Codegen.Tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public static async Task<Fixture> Compile(string name)
return new(projectDir, (CSharpCompilation)compilation!);
}

public Task Verify(string fileName, object target) =>
Verifier.Verify(target).UseDirectory($"{projectDir}/snapshots").UseFileName(fileName);

private static CSharpGeneratorDriver CreateDriver(
IIncrementalGenerator generator,
LanguageVersion languageVersion
Expand All @@ -42,9 +45,6 @@ LanguageVersion languageVersion
);
}

public Task Verify(string fileName, object target) =>
Verifier.Verify(target).UseDirectory($"{projectDir}/snapshots").UseFileName(fileName);

private async Task<IEnumerable<SyntaxTree>> RunAndCheckGenerator(
IIncrementalGenerator generator
)
Expand Down
102 changes: 101 additions & 1 deletion crates/bindings-csharp/Codegen.Tests/fixtures/client/Lib.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using SpacetimeDB;

Expand Down Expand Up @@ -39,6 +40,9 @@ public enum CustomEnum
namespace System.Runtime.CompilerServices
{
internal static class IsExternalInit { } // https://stackoverflow.com/a/64749403/1484415

[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
internal sealed class ModuleInitializerAttribute : Attribute { }
}

[SpacetimeDB.Type]
Expand All @@ -48,6 +52,7 @@ public partial record CustomTaggedEnum
[SpacetimeDB.Type]
public partial struct PublicTable
{
public int Id;
public byte ByteField;
public ushort UshortField;
public uint UintField;
Expand All @@ -74,3 +79,98 @@ public partial struct PublicTable
public int? NullableValueField;
public string? NullableReferenceField;
}

internal static class PublicTableViewRegressions
{
[global::System.Runtime.CompilerServices.ModuleInitializer]
internal static void Initialize()
{
ValidatePublicTableQuerySql();
ValidatePublicTableViewSql();
ValidateFindPublicTableByIdentitySql();
}

private sealed class PublicTableCols
{
public Col<PublicTable, int> Id { get; }

public PublicTableCols(string tableName)
{
Id = new Col<PublicTable, int>(tableName, "Id");
}
}

private sealed class PublicTableIxCols
{
public IxCol<PublicTable, int> Id { get; }

public PublicTableIxCols(string tableName)
{
Id = new IxCol<PublicTable, int>(tableName, "Id");
}
}

private static Table<PublicTable, PublicTableCols, PublicTableIxCols> MakeTable()
{
const string tableName = "PublicTable";
return new Table<PublicTable, PublicTableCols, PublicTableIxCols>(
tableName,
new PublicTableCols(tableName),
new PublicTableIxCols(tableName)
);
}

private static string BuildPublicTableQuerySql() =>
MakeTable().Where(cols => cols.Id.Eq(0)).Build().Sql;

private static string BuildPublicTableViewSql()
{
var cols = new PublicTableCols("PublicTable");
return MakeTable().Where(_ => cols.Id.Eq(0)).Build().Sql;
}

private static string BuildFindPublicTableByIdentitySql()
{
var table = MakeTable();
return table.Where(cols => cols.Id.Eq(0)).Build().Sql;
}

/// <summary>
/// Mirrors Module.PublicTableQuery server view to ensure the generated SQL stays in sync.
/// </summary>
[Conditional("DEBUG")]
public static void ValidatePublicTableQuerySql()
{
var sql = BuildPublicTableQuerySql();
Debug.Assert(
sql == "SELECT * FROM \"PublicTable\" WHERE (\"PublicTable\".\"Id\" = 0)",
$"Unexpected SQL produced for public_table_query: {sql}"
);
}

/// <summary>
/// Mirrors Module.PublicTableByIdentity (public_table_view) returning Option<PublicTable>.
/// </summary>
[Conditional("DEBUG")]
public static void ValidatePublicTableViewSql()
{
var sql = BuildPublicTableViewSql();
Debug.Assert(
sql == "SELECT * FROM \"PublicTable\" WHERE (\"PublicTable\".\"Id\" = 0)",
$"Unexpected SQL produced for public_table_view: {sql}"
);
}

/// <summary>
/// Mirrors Module.FindPublicTableByIdentity anonymous view.
/// </summary>
[Conditional("DEBUG")]
public static void ValidateFindPublicTableByIdentitySql()
{
var sql = BuildFindPublicTableByIdentitySql();
Debug.Assert(
sql == "SELECT * FROM \"PublicTable\" WHERE (\"PublicTable\".\"Id\" = 0)",
$"Unexpected SQL produced for find_public_table__by_identity: {sql}"
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ partial struct PublicTable : System.IEquatable<PublicTable>, SpacetimeDB.BSATN.I
{
public void ReadFields(System.IO.BinaryReader reader)
{
Id = BSATN.IdRW.Read(reader);
ByteField = BSATN.ByteFieldRW.Read(reader);
UshortField = BSATN.UshortFieldRW.Read(reader);
UintField = BSATN.UintFieldRW.Read(reader);
Expand Down Expand Up @@ -35,6 +36,7 @@ public void ReadFields(System.IO.BinaryReader reader)

public void WriteFields(System.IO.BinaryWriter writer)
{
BSATN.IdRW.Write(writer, Id);
BSATN.ByteFieldRW.Write(writer, ByteField);
BSATN.UshortFieldRW.Write(writer, UshortField);
BSATN.UintFieldRW.Write(writer, UintField);
Expand Down Expand Up @@ -68,10 +70,11 @@ object SpacetimeDB.BSATN.IStructuralReadWrite.GetSerializer()
}

public override string ToString() =>
$"PublicTable {{ ByteField = {SpacetimeDB.BSATN.StringUtil.GenericToString(ByteField)}, UshortField = {SpacetimeDB.BSATN.StringUtil.GenericToString(UshortField)}, UintField = {SpacetimeDB.BSATN.StringUtil.GenericToString(UintField)}, UlongField = {SpacetimeDB.BSATN.StringUtil.GenericToString(UlongField)}, U128Field = {SpacetimeDB.BSATN.StringUtil.GenericToString(U128Field)}, U256Field = {SpacetimeDB.BSATN.StringUtil.GenericToString(U256Field)}, SbyteField = {SpacetimeDB.BSATN.StringUtil.GenericToString(SbyteField)}, ShortField = {SpacetimeDB.BSATN.StringUtil.GenericToString(ShortField)}, IntField = {SpacetimeDB.BSATN.StringUtil.GenericToString(IntField)}, LongField = {SpacetimeDB.BSATN.StringUtil.GenericToString(LongField)}, I128Field = {SpacetimeDB.BSATN.StringUtil.GenericToString(I128Field)}, I256Field = {SpacetimeDB.BSATN.StringUtil.GenericToString(I256Field)}, BoolField = {SpacetimeDB.BSATN.StringUtil.GenericToString(BoolField)}, FloatField = {SpacetimeDB.BSATN.StringUtil.GenericToString(FloatField)}, DoubleField = {SpacetimeDB.BSATN.StringUtil.GenericToString(DoubleField)}, StringField = {SpacetimeDB.BSATN.StringUtil.GenericToString(StringField)}, IdentityField = {SpacetimeDB.BSATN.StringUtil.GenericToString(IdentityField)}, ConnectionIdField = {SpacetimeDB.BSATN.StringUtil.GenericToString(ConnectionIdField)}, CustomStructField = {SpacetimeDB.BSATN.StringUtil.GenericToString(CustomStructField)}, CustomClassField = {SpacetimeDB.BSATN.StringUtil.GenericToString(CustomClassField)}, CustomEnumField = {SpacetimeDB.BSATN.StringUtil.GenericToString(CustomEnumField)}, CustomTaggedEnumField = {SpacetimeDB.BSATN.StringUtil.GenericToString(CustomTaggedEnumField)}, ListField = {SpacetimeDB.BSATN.StringUtil.GenericToString(ListField)}, NullableValueField = {SpacetimeDB.BSATN.StringUtil.GenericToString(NullableValueField)}, NullableReferenceField = {SpacetimeDB.BSATN.StringUtil.GenericToString(NullableReferenceField)} }}";
$"PublicTable {{ Id = {SpacetimeDB.BSATN.StringUtil.GenericToString(Id)}, ByteField = {SpacetimeDB.BSATN.StringUtil.GenericToString(ByteField)}, UshortField = {SpacetimeDB.BSATN.StringUtil.GenericToString(UshortField)}, UintField = {SpacetimeDB.BSATN.StringUtil.GenericToString(UintField)}, UlongField = {SpacetimeDB.BSATN.StringUtil.GenericToString(UlongField)}, U128Field = {SpacetimeDB.BSATN.StringUtil.GenericToString(U128Field)}, U256Field = {SpacetimeDB.BSATN.StringUtil.GenericToString(U256Field)}, SbyteField = {SpacetimeDB.BSATN.StringUtil.GenericToString(SbyteField)}, ShortField = {SpacetimeDB.BSATN.StringUtil.GenericToString(ShortField)}, IntField = {SpacetimeDB.BSATN.StringUtil.GenericToString(IntField)}, LongField = {SpacetimeDB.BSATN.StringUtil.GenericToString(LongField)}, I128Field = {SpacetimeDB.BSATN.StringUtil.GenericToString(I128Field)}, I256Field = {SpacetimeDB.BSATN.StringUtil.GenericToString(I256Field)}, BoolField = {SpacetimeDB.BSATN.StringUtil.GenericToString(BoolField)}, FloatField = {SpacetimeDB.BSATN.StringUtil.GenericToString(FloatField)}, DoubleField = {SpacetimeDB.BSATN.StringUtil.GenericToString(DoubleField)}, StringField = {SpacetimeDB.BSATN.StringUtil.GenericToString(StringField)}, IdentityField = {SpacetimeDB.BSATN.StringUtil.GenericToString(IdentityField)}, ConnectionIdField = {SpacetimeDB.BSATN.StringUtil.GenericToString(ConnectionIdField)}, CustomStructField = {SpacetimeDB.BSATN.StringUtil.GenericToString(CustomStructField)}, CustomClassField = {SpacetimeDB.BSATN.StringUtil.GenericToString(CustomClassField)}, CustomEnumField = {SpacetimeDB.BSATN.StringUtil.GenericToString(CustomEnumField)}, CustomTaggedEnumField = {SpacetimeDB.BSATN.StringUtil.GenericToString(CustomTaggedEnumField)}, ListField = {SpacetimeDB.BSATN.StringUtil.GenericToString(ListField)}, NullableValueField = {SpacetimeDB.BSATN.StringUtil.GenericToString(NullableValueField)}, NullableReferenceField = {SpacetimeDB.BSATN.StringUtil.GenericToString(NullableReferenceField)} }}";

public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite<PublicTable>
{
internal static readonly SpacetimeDB.BSATN.I32 IdRW = new();
internal static readonly SpacetimeDB.BSATN.U8 ByteFieldRW = new();
internal static readonly SpacetimeDB.BSATN.U16 UshortFieldRW = new();
internal static readonly SpacetimeDB.BSATN.U32 UintFieldRW = new();
Expand Down Expand Up @@ -123,6 +126,7 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar
registrar.RegisterType<PublicTable>(_ => new SpacetimeDB.BSATN.AlgebraicType.Product(
new SpacetimeDB.BSATN.AggregateElement[]
{
new("Id", IdRW.GetAlgebraicType(registrar)),
new("ByteField", ByteFieldRW.GetAlgebraicType(registrar)),
new("UshortField", UshortFieldRW.GetAlgebraicType(registrar)),
new("UintField", UintFieldRW.GetAlgebraicType(registrar)),
Expand Down Expand Up @@ -164,6 +168,7 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar

public override int GetHashCode()
{
var ___hashId = Id.GetHashCode();
var ___hashByteField = ByteField.GetHashCode();
var ___hashUshortField = UshortField.GetHashCode();
var ___hashUintField = UintField.GetHashCode();
Expand Down Expand Up @@ -202,7 +207,8 @@ public override int GetHashCode()
var ___hashNullableValueField = NullableValueField.GetHashCode();
var ___hashNullableReferenceField =
NullableReferenceField == null ? 0 : NullableReferenceField.GetHashCode();
return ___hashByteField
return ___hashId
^ ___hashByteField
^ ___hashUshortField
^ ___hashUintField
^ ___hashUlongField
Expand Down Expand Up @@ -232,6 +238,7 @@ public override int GetHashCode()
#nullable enable
public bool Equals(PublicTable that)
{
var ___eqId = this.Id.Equals(that.Id);
var ___eqByteField = this.ByteField.Equals(that.ByteField);
var ___eqUshortField = this.UshortField.Equals(that.UshortField);
var ___eqUintField = this.UintField.Equals(that.UintField);
Expand Down Expand Up @@ -291,7 +298,8 @@ public bool Equals(PublicTable that)
this.NullableReferenceField == null
? that.NullableReferenceField == null
: this.NullableReferenceField.Equals(that.NullableReferenceField);
return ___eqByteField
return ___eqId
&& ___eqByteField
&& ___eqUshortField
&& ___eqUintField
&& ___eqUlongField
Expand Down
Loading
Loading