Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ public void Write(BinaryWriter writer, Inner? value)

public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) =>
AlgebraicType.MakeOption(innerRW.GetAlgebraicType(registrar));

// Return a List BSATN serializer that can serialize this option as an array
public static List<Inner, InnerRW> GetListSerializer()
{
return new List<Inner, InnerRW>();
}
}

// This implementation is nearly identical to RefOption. The only difference is the constraint on T.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//HintName: FFI.cs
//HintName: FFI.cs
// <auto-generated />
#nullable enable
// The runtime already defines SpacetimeDB.Internal.LocalReadOnly in Runtime\Internal\Module.cs as an empty partial type.
Expand Down Expand Up @@ -1699,6 +1699,9 @@ public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx
public static List<T> ToListOrEmpty<T>(T? value)
where T : struct => value is null ? new List<T>() : new List<T> { value.Value };

public static List<T> ToListOrEmpty<T>(T? value)
where T : class => value is null ? new List<T>() : new List<T> { value };

#if EXPERIMENTAL_WASM_AOT
// In AOT mode we're building a library.
// Main method won't be called automatically, so we need to export it as a preinit function.
Expand Down
10 changes: 8 additions & 2 deletions crates/bindings-csharp/Codegen/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ public ViewDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter dia
// Validate return type: must be Option<T> or Vec<T>
if (
!ReturnType.BSATNName.Contains("SpacetimeDB.BSATN.ValueOption")
&& !ReturnType.BSATNName.Contains("SpacetimeDB.BSATN.RefOption")
&& !ReturnType.BSATNName.Contains("SpacetimeDB.BSATN.List")
)
{
Expand Down Expand Up @@ -1030,8 +1031,10 @@ public string GenerateDispatcherClass(uint index)
? "SpacetimeDB.AnonymousViewContext"
: "SpacetimeDB.ViewContext";

var isValueOption = ReturnType.BSATNName.Contains("SpacetimeDB.BSATN.ValueOption");
var writeOutput = isValueOption
var isOption =
ReturnType.BSATNName.Contains("SpacetimeDB.BSATN.ValueOption")
|| ReturnType.BSATNName.Contains("SpacetimeDB.BSATN.RefOption");
var writeOutput = isOption
? $$$"""
var listSerializer = {{{ReturnType.BSATNName}}}.GetListSerializer();
var listValue = ModuleRegistration.ToListOrEmpty(returnValue);
Expand Down Expand Up @@ -1934,6 +1937,9 @@ static class ModuleRegistration {
public static List<T> ToListOrEmpty<T>(T? value) where T : struct
=> value is null ? new List<T>() : new List<T> { value.Value };

public static List<T> ToListOrEmpty<T>(T? value) where T : class
=> value is null ? new List<T>() : new List<T> { value };

#if EXPERIMENTAL_WASM_AOT
// In AOT mode we're building a library.
// Main method won't be called automatically, so we need to export it as a preinit function.
Expand Down
12 changes: 12 additions & 0 deletions sdks/csharp/examples~/regression-tests/client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ void OnConnected(DbConnection conn, Identity identity, string authToken)
.Subscribe([
"SELECT * FROM example_data",
"SELECT * FROM my_player",
"SELECT * FROM my_account",
"SELECT * FROM my_account_missing",
"SELECT * FROM players_at_level_one",
"SELECT * FROM my_table",
"SELECT * FROM null_string_nonnullable",
Expand Down Expand Up @@ -296,11 +298,21 @@ void OnSubscriptionApplied(SubscriptionEventContext context)
// Views test
Log.Debug("Checking Views are populated");
Debug.Assert(context.Db.MyPlayer != null, "context.Db.MyPlayer != null");
Debug.Assert(context.Db.MyAccount != null, "context.Db.MyAccount != null");
Debug.Assert(context.Db.MyAccountMissing != null, "context.Db.MyAccountMissing != null");
Debug.Assert(context.Db.PlayersAtLevelOne != null, "context.Db.PlayersAtLevelOne != null");
Debug.Assert(
context.Db.MyPlayer.Count > 0,
$"context.Db.MyPlayer.Count = {context.Db.MyPlayer.Count}"
);
Debug.Assert(
context.Db.MyAccount.Count == 1,
$"context.Db.MyAccount.Count = {context.Db.MyAccount.Count}"
);
Debug.Assert(
context.Db.MyAccountMissing.Count == 0,
$"context.Db.MyAccountMissing.Count = {context.Db.MyAccountMissing.Count}"
);
Debug.Assert(
context.Db.PlayersAtLevelOne.Count > 0,
$"context.Db.PlayersAtLevelOne.Count = {context.Db.PlayersAtLevelOne.Count}"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 31 additions & 1 deletion sdks/csharp/examples~/regression-tests/server/Lib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ public partial struct Player
public string Name;
}

[SpacetimeDB.Table(Name = "account", Public = true)]
public partial class Account
{
[SpacetimeDB.PrimaryKey]
[SpacetimeDB.AutoInc]
public ulong Id;

[SpacetimeDB.Unique]
public Identity Identity;

public string Name = "";
}

[SpacetimeDB.Table(Name = "player_level", Public = true)]
public partial struct PlayerLevel
{
Expand Down Expand Up @@ -137,7 +150,19 @@ public partial struct NullStringNullable
[SpacetimeDB.View(Name = "my_player", Public = true)]
public static Player? MyPlayer(ViewContext ctx)
{
return ctx.Db.player.Identity.Find(ctx.Sender) as Player?;
return ctx.Db.player.Identity.Find(ctx.Sender);
}

[SpacetimeDB.View(Name = "my_account", Public = true)]
public static Account? MyAccount(ViewContext ctx)
{
return ctx.Db.account.Identity.Find(ctx.Sender) as Account;
}

[SpacetimeDB.View(Name = "my_account_missing", Public = true)]
public static Account? MyAccountMissing(ViewContext ctx)
{
return null;
}

// Multiple rows: return a list
Expand Down Expand Up @@ -269,6 +294,11 @@ public static void ClientConnected(ReducerContext ctx)
ctx.Db.player_level.Insert(new PlayerLevel { PlayerId = playerId, Level = 1 });
}

if (ctx.Db.account.Identity.Find(ctx.Sender) is null)
{
ctx.Db.account.Insert(new Account { Identity = ctx.Sender, Name = "Account" });
}

if (ctx.Db.nullable_vec.Id.Find(1) is null)
{
ctx.Db.nullable_vec.Insert(new NullableVec
Expand Down
Loading