From 02b70d5c9464dff5b36d637cd93aca42cd3a5d89 Mon Sep 17 00:00:00 2001 From: Jeremie Pelletier Date: Fri, 4 Oct 2024 00:12:15 -0400 Subject: [PATCH] c# client generate (#1707) --- crates/bindings-csharp/BSATN.Codegen/Utils.cs | 35 +- .../bindings-csharp/BSATN.Runtime/Builtins.cs | 80 ++ .../Codegen.Tests/fixtures/diag/Lib.cs | 8 + .../ExtraCompilationErrors.verified.txt | 317 ++++++- .../diag/snapshots/Module#FFI.verified.cs | 350 +++---- .../Module#TestAutoIncNotInteger.verified.cs | 14 +- ...odule#TestIncompatibleSchedule.verified.cs | 14 +- .../Module#TestUniqueNotEquatable.verified.cs | 14 +- .../diag/snapshots/Module.verified.txt | 58 +- .../Codegen.Tests/fixtures/server/Lib.cs | 34 +- .../Module#BTreeMultiColumn.verified.cs | 86 ++ .../snapshots/Module#BTreeViews.verified.cs | 98 ++ .../server/snapshots/Module#FFI.verified.cs | 776 ++++++++------- .../Module#MultiTableRow.verified.cs | 26 +- .../snapshots/Module#PublicTable.verified.cs | 7 +- ...Module#Timers.SendMessageTimer.verified.cs | 7 +- crates/bindings-csharp/Codegen/Diag.cs | 16 + crates/bindings-csharp/Codegen/Module.cs | 176 +++- crates/bindings-csharp/Runtime/Attrs.cs | 10 + crates/bindings-csharp/Runtime/Exceptions.cs | 7 +- .../Internal/Autogen/RawColumnDefV8.cs | 1 - .../Internal/Autogen/RawConstraintDefV8.cs | 1 - .../Internal/Autogen/RawConstraintDefV9.cs | 1 - .../Runtime/Internal/Autogen/RawIndexDefV8.cs | 1 - .../Runtime/Internal/Autogen/RawIndexDefV9.cs | 1 - .../Internal/Autogen/RawModuleDefV8.cs | 1 - .../Internal/Autogen/RawModuleDefV9.cs | 1 - .../Internal/Autogen/RawReducerDefV9.cs | 1 - .../Internal/Autogen/RawScheduleDefV9.cs | 1 - .../Internal/Autogen/RawScopedTypeNameV9.cs | 1 - .../Internal/Autogen/RawSequenceDefV8.cs | 1 - .../Internal/Autogen/RawSequenceDefV9.cs | 1 - .../Runtime/Internal/Autogen/RawTableDefV8.cs | 1 - .../Runtime/Internal/Autogen/RawTableDefV9.cs | 1 - .../Runtime/Internal/Autogen/RawTypeDefV9.cs | 1 - .../Autogen/RawUniqueConstraintDataV9.cs | 1 - .../Runtime/Internal/Autogen/ReducerDef.cs | 1 - .../Runtime/Internal/Autogen/TableDesc.cs | 1 - .../Runtime/Internal/Autogen/TypeAlias.cs | 1 - .../Runtime/Internal/Autogen/Typespace.cs | 1 - .../Runtime/Internal/Bounds.cs | 413 ++++++++ .../bindings-csharp/Runtime/Internal/FFI.cs | 89 +- .../Runtime/Internal/IIndex.cs | 108 +++ .../Runtime/Internal/ITable.cs | 89 +- .../Runtime/Internal/Module.cs | 10 - .../Runtime/Internal/Timing.cs | 27 - crates/bindings-csharp/Runtime/Runtime.cs | 59 -- crates/bindings-csharp/Runtime/bindings.c | 38 +- crates/cli/src/subcommands/generate/csharp.rs | 597 +++++++----- .../snapshots/codegen__codegen_csharp.snap | 883 +++++++++--------- crates/sdk/tests/test.rs | 2 +- modules/sdk-test-connect-disconnect-cs/Lib.cs | 8 +- modules/sdk-test-cs/Lib.cs | 574 ++++++------ modules/spacetimedb-quickstart-cs/Lib.cs | 4 +- smoketests/tests/namespaces.py | 6 +- 55 files changed, 3193 insertions(+), 1867 deletions(-) create mode 100644 crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeMultiColumn.verified.cs create mode 100644 crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeViews.verified.cs create mode 100644 crates/bindings-csharp/Runtime/Internal/Bounds.cs create mode 100644 crates/bindings-csharp/Runtime/Internal/IIndex.cs delete mode 100644 crates/bindings-csharp/Runtime/Internal/Timing.cs delete mode 100644 crates/bindings-csharp/Runtime/Runtime.cs diff --git a/crates/bindings-csharp/BSATN.Codegen/Utils.cs b/crates/bindings-csharp/BSATN.Codegen/Utils.cs index f381622422..58764e8e62 100644 --- a/crates/bindings-csharp/BSATN.Codegen/Utils.cs +++ b/crates/bindings-csharp/BSATN.Codegen/Utils.cs @@ -184,18 +184,28 @@ IEnumerable values return sb; } - private static object? ResolveConstant(TypedConstant constant) => - constant.Kind switch + private static object? ResolveConstant(TypedConstant constant, System.Type targetType) + { + if (constant.Kind == TypedConstantKind.Array) { - TypedConstantKind.Array => constant.Values.Select(ResolveConstant).ToArray(), - _ => constant.Value, - }; + // We can't use LINQ ToArray() here because it doesn't support dynamic Type + // and will build `object[]` instead of the desired `T[]`. + var elementType = targetType.GetElementType(); + var array = Array.CreateInstance(elementType, constant.Values.Length); + for (var i = 0; i < constant.Values.Length; i++) + { + array.SetValue(ResolveConstant(constant.Values[i], elementType), i); + } + return array; + } + return constant.Value; + } public static T ParseAs(this AttributeData attrData, System.Type? type = null) where T : Attribute { type ??= typeof(T); - var ctorArgs = attrData.ConstructorArguments.Select(ResolveConstant).ToArray(); + // For now only support attributes with a single constructor. // // Proper overload resolution is complicated due to implicit casts @@ -203,10 +213,19 @@ public static T ParseAs(this AttributeData attrData, System.Type? type = null // which prevent APIs like `Activator.CreateInstance` from finding the constructor. // // Expand logic in the future if it ever becomes actually necessary. - var attr = (T)type.GetConstructors().Single().Invoke(ctorArgs); + var ctor = type.GetConstructors().Single(); + + var ctorArgs = attrData + .ConstructorArguments.Zip( + ctor.GetParameters().Select(param => param.ParameterType), + ResolveConstant + ) + .ToArray(); + var attr = (T)ctor.Invoke(ctorArgs); foreach (var arg in attrData.NamedArguments) { - type.GetProperty(arg.Key).SetValue(attr, ResolveConstant(arg.Value)); + var prop = type.GetProperty(arg.Key); + prop.SetValue(attr, ResolveConstant(arg.Value, prop.PropertyType)); } return attr; } diff --git a/crates/bindings-csharp/BSATN.Runtime/Builtins.cs b/crates/bindings-csharp/BSATN.Runtime/Builtins.cs index 89301a0070..01b6eddaae 100644 --- a/crates/bindings-csharp/BSATN.Runtime/Builtins.cs +++ b/crates/bindings-csharp/BSATN.Runtime/Builtins.cs @@ -1,6 +1,8 @@ namespace SpacetimeDB; using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using SpacetimeDB.BSATN; using SpacetimeDB.Internal; @@ -125,3 +127,81 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => // This must be explicitly forwarded to base, otherwise record will generate a new implementation. public override string ToString() => base.ToString(); } + +// We store time information in microseconds in internal usages. +// +// These utils allow to encode it as such in FFI and BSATN contexts +// and convert to standard C# types. + +[StructLayout(LayoutKind.Sequential)] // we should be able to use it in FFI +[SpacetimeDB.Type] // we should be able to encode it to BSATN too +public partial struct DateTimeOffsetRepr(DateTimeOffset time) +{ + public ulong MicrosecondsSinceEpoch = (ulong)time.Ticks / 10; + + public readonly DateTimeOffset ToStd() => + DateTimeOffset.UnixEpoch.AddTicks(10 * (long)MicrosecondsSinceEpoch); +} + +[StructLayout(LayoutKind.Sequential)] // we should be able to use it in FFI +[SpacetimeDB.Type] // we should be able to encode it to BSATN too +public partial struct TimeSpanRepr(TimeSpan duration) +{ + public ulong Microseconds = (ulong)duration.Ticks / 10; + + public readonly TimeSpan ToStd() => TimeSpan.FromTicks(10 * (long)Microseconds); +} + +// [SpacetimeDB.Type] - we have custom representation of time in microseconds, so implementing BSATN manually +public abstract partial record ScheduleAt + : SpacetimeDB.TaggedEnum<(DateTimeOffset Time, TimeSpan Interval)> +{ + // Manual expansion of what would be otherwise generated by the [SpacetimeDB.Type] codegen. + public sealed record Time(DateTimeOffset Time_) : ScheduleAt; + + public sealed record Interval(TimeSpan Interval_) : ScheduleAt; + + public static implicit operator ScheduleAt(DateTimeOffset time) => new Time(time); + + public static implicit operator ScheduleAt(TimeSpan interval) => new Interval(interval); + + public readonly partial struct BSATN : IReadWrite + { + [SpacetimeDB.Type] + private partial record ScheduleAtRepr + : SpacetimeDB.TaggedEnum<(DateTimeOffsetRepr Time, TimeSpanRepr Interval)>; + + private static readonly ScheduleAtRepr.BSATN ReprBSATN = new(); + + public ScheduleAt Read(BinaryReader reader) => + ReprBSATN.Read(reader) switch + { + ScheduleAtRepr.Time(var timeRepr) => new Time(timeRepr.ToStd()), + ScheduleAtRepr.Interval(var intervalRepr) => new Interval(intervalRepr.ToStd()), + _ => throw new SwitchExpressionException(), + }; + + public void Write(BinaryWriter writer, ScheduleAt value) + { + ReprBSATN.Write( + writer, + value switch + { + Time(var time) => new ScheduleAtRepr.Time(new(time)), + Interval(var interval) => new ScheduleAtRepr.Interval(new(interval)), + _ => throw new SwitchExpressionException(), + } + ); + } + + public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => + // Constructing a custom one instead of ScheduleAtRepr.GetAlgebraicType() + // to avoid leaking the internal *Repr wrappers in generated SATS. + new AlgebraicType.Sum( + [ + new("Time", new AlgebraicType.U64(default)), + new("Interval", new AlgebraicType.U64(default)), + ] + ); + } +} diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs index 33c00c39c6..61423e76db 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs @@ -374,3 +374,11 @@ public static void TestIncompatibleScheduleReducer( TestIncompatibleSchedule table ) { } } + +[SpacetimeDB.Table] +[SpacetimeDB.Index] +public partial struct TestIndexWithoutColumns { } + +[SpacetimeDB.Table] +[SpacetimeDB.Index(BTree = [])] +public partial struct TestIndexWithEmptyColumns { } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/ExtraCompilationErrors.verified.txt b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/ExtraCompilationErrors.verified.txt index 39f1bc63bb..8e1952f52b 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/ExtraCompilationErrors.verified.txt +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/ExtraCompilationErrors.verified.txt @@ -23,6 +23,29 @@ } }, {/* +[SpacetimeDB.Table] +[SpacetimeDB.Index] + ^^^^^^^^^^^^^^^^^ +public partial struct TestIndexWithoutColumns { } +*/ + Message: Required member 'IndexAttribute.BTree' must be set in the object initializer or attribute constructor., + Severity: Error, + Descriptor: { + Id: CS9035, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS9035), + MessageFormat: Required member '{0}' must be set in the object initializer or attribute constructor., + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* { internal static readonly TRW Field = new(); ^^^ @@ -160,6 +183,29 @@ internal static readonly SpacetimeDB.BSATN.IReadWrite Unsuppor ] } }, + {/* +} +public TestUniqueNotEquatableUniqueIndex PrimaryKeyField => new(this); + ^^^^^^^^^ +} +*/ + Message: The call is ambiguous between the following methods or properties: 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)' and 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)', + Severity: Error, + Descriptor: { + Id: CS0121, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0121), + MessageFormat: The call is ambiguous between the following methods or properties: '{0}' and '{1}', + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, {/* public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { Reducers.TestReducerWithoutContext((SpacetimeDB.ReducerContext)ctx); @@ -322,10 +368,10 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView Iter() => SpacetimeDB.Internal.ITableView.Iter(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.Insert(row); + + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); */ Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., Severity: Error, @@ -345,10 +391,10 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView Iter() => SpacetimeDB.Internal.ITableView.Iter(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.Insert(row); + + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); */ Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, @@ -368,10 +414,10 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView Iter() => SpacetimeDB.Internal.ITableView.Iter(); - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.Insert(row); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public IEnumerable FilterByX(int X) => + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); */ Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., Severity: Error, @@ -391,10 +437,10 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView Iter() => SpacetimeDB.Internal.ITableView.Iter(); - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.Insert(row); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public IEnumerable FilterByX(int X) => + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); */ Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, @@ -414,10 +460,10 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView FilterByX(int X) => - SpacetimeDB.Internal.ITableView.ColEq.Where(0, X, global::TestTableTaggedEnum.BSATN.X).Iter(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -public IEnumerable FilterByY(int Y) => + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); */ Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., Severity: Error, @@ -437,10 +483,10 @@ public IEnumerable FilterByY(int Y) => } }, {/* - public IEnumerable FilterByX(int X) => - SpacetimeDB.Internal.ITableView.ColEq.Where(0, X, global::TestTableTaggedEnum.BSATN.X).Iter(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -public IEnumerable FilterByY(int Y) => + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); */ Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, @@ -460,10 +506,10 @@ public IEnumerable FilterByY(int Y) => } }, {/* -public IEnumerable FilterByY(int Y) => - SpacetimeDB.Internal.ITableView.ColEq.Where(1, Y, global::TestTableTaggedEnum.BSATN.Y).Iter(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -} + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., Severity: Error, @@ -483,10 +529,10 @@ public IEnumerable FilterByY(int Y) => } }, {/* -public IEnumerable FilterByY(int Y) => - SpacetimeDB.Internal.ITableView.ColEq.Where(1, Y, global::TestTableTaggedEnum.BSATN.Y).Iter(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -} + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, @@ -504,5 +550,212 @@ public IEnumerable FilterByY(int Y) => NotConfigurable ] } + }, + {/* + + public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_UniqueField_unique") {} +*/ + Message: Partial declarations of 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' must not specify different base classes, + Severity: Error, + Descriptor: { + Id: CS0263, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0263), + MessageFormat: Partial declarations of '{0}' must not specify different base classes, + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* + public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_UniqueField_unique") {} + ^^^^ + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.UniqueField, row); +*/ + Message: 'UniqueIndex>.UniqueIndex(TestUniqueNotEquatable, string)' is inaccessible due to its protection level, + Severity: Error, + Descriptor: { + Id: CS0122, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0122), + MessageFormat: '{0}' is inaccessible due to its protection level, + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_UniqueField_unique") {} + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.UniqueField, row); + ^^^^^^^^ +} +*/ + Message: The name 'DoUpdate' does not exist in the current context, + Severity: Error, + Descriptor: { + Id: CS0103, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), + MessageFormat: The name '{0}' does not exist in the current context, + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* +} +public TestUniqueNotEquatableUniqueIndex UniqueField => new(this); + ^^^^^^^^^ +public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { +*/ + Message: The call is ambiguous between the following methods or properties: 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)' and 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)', + Severity: Error, + Descriptor: { + Id: CS0121, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0121), + MessageFormat: The call is ambiguous between the following methods or properties: '{0}' and '{1}', + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* +public TestUniqueNotEquatableUniqueIndex UniqueField => new(this); +public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_PrimaryKeyField_unique") {} +*/ + Message: The type 'TestUniqueNotEquatable' already contains a definition for 'TestUniqueNotEquatableUniqueIndex', + Severity: Error, + Descriptor: { + Id: CS0102, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0102), + MessageFormat: The type '{0}' already contains a definition for '{1}', + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* +public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_PrimaryKeyField_unique") {} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); +*/ + Message: Type 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' already defines a member called 'TestUniqueNotEquatableUniqueIndex' with the same parameter types, + Severity: Error, + Descriptor: { + Id: CS0111, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0111), + MessageFormat: Type '{1}' already defines a member called '{0}' with the same parameter types, + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* +public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_PrimaryKeyField_unique") {} + ^^^^ + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); +*/ + Message: 'UniqueIndex>.UniqueIndex(TestUniqueNotEquatable, string)' is inaccessible due to its protection level, + Severity: Error, + Descriptor: { + Id: CS0122, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0122), + MessageFormat: '{0}' is inaccessible due to its protection level, + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_PrimaryKeyField_unique") {} + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); + ^^^^^^ +} +*/ + Message: Type 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' already defines a member called 'Update' with the same parameter types, + Severity: Error, + Descriptor: { + Id: CS0111, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0111), + MessageFormat: Type '{1}' already defines a member called '{0}' with the same parameter types, + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_PrimaryKeyField_unique") {} + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); + ^^^^^^^^ +} +*/ + Message: The name 'DoUpdate' does not exist in the current context, + Severity: Error, + Descriptor: { + Id: CS0103, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), + MessageFormat: The name '{0}' does not exist in the current context, + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } } ] \ No newline at end of file diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs index dc21fb694f..563d094181 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs @@ -54,63 +54,49 @@ public readonly struct TestAutoIncNotInteger return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestAutoIncNotInteger, + global::TestAutoIncNotInteger + >.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< TestAutoIncNotInteger, global::TestAutoIncNotInteger - >.Iter(); + >.DoIter(); public global::TestAutoIncNotInteger Insert(global::TestAutoIncNotInteger row) => SpacetimeDB.Internal.ITableView< TestAutoIncNotInteger, global::TestAutoIncNotInteger - >.Insert(row); - - public IEnumerable FilterByIdentityField( - string IdentityField - ) => - SpacetimeDB - .Internal.ITableView< - TestAutoIncNotInteger, - global::TestAutoIncNotInteger - >.ColEq.Where( - 1, - IdentityField, - global::TestAutoIncNotInteger.BSATN.IdentityField - ) - .Iter(); - - public global::TestAutoIncNotInteger? FindByIdentityField(string IdentityField) => - FilterByIdentityField(IdentityField) - .Cast() - .SingleOrDefault(); - - public bool DeleteByIdentityField(string IdentityField) => - SpacetimeDB - .Internal.ITableView< - TestAutoIncNotInteger, - global::TestAutoIncNotInteger - >.ColEq.Where( - 1, - IdentityField, - global::TestAutoIncNotInteger.BSATN.IdentityField - ) - .Delete(); - - public bool UpdateByIdentityField( - string IdentityField, - global::TestAutoIncNotInteger @this - ) => - SpacetimeDB - .Internal.ITableView< - TestAutoIncNotInteger, - global::TestAutoIncNotInteger - >.ColEq.Where( - 1, - IdentityField, - global::TestAutoIncNotInteger.BSATN.IdentityField - ) - .Update(@this); + >.DoInsert(row); + + public bool Delete(global::TestAutoIncNotInteger row) => + SpacetimeDB.Internal.ITableView< + TestAutoIncNotInteger, + global::TestAutoIncNotInteger + >.DoDelete(row); + + public sealed class TestAutoIncNotIntegerUniqueIndex + : UniqueIndex< + TestAutoIncNotInteger, + global::TestAutoIncNotInteger, + string, + SpacetimeDB.BSATN.String + > + { + internal TestAutoIncNotIntegerUniqueIndex(TestAutoIncNotInteger handle) + : base( + handle, + "idx_TestAutoIncNotInteger_TestAutoIncNotInteger_IdentityField_unique" + ) { } + + public bool Update(global::TestAutoIncNotInteger row) => + DoUpdate(row.IdentityField, row); + } + + public TestAutoIncNotIntegerUniqueIndex IdentityField => new(this); } public readonly struct TestDuplicateTableName @@ -127,17 +113,29 @@ public readonly struct TestDuplicateTableName return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestDuplicateTableName, + global::TestDuplicateTableName + >.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< TestDuplicateTableName, global::TestDuplicateTableName - >.Iter(); + >.DoIter(); public global::TestDuplicateTableName Insert(global::TestDuplicateTableName row) => SpacetimeDB.Internal.ITableView< TestDuplicateTableName, global::TestDuplicateTableName - >.Insert(row); + >.DoInsert(row); + + public bool Delete(global::TestDuplicateTableName row) => + SpacetimeDB.Internal.ITableView< + TestDuplicateTableName, + global::TestDuplicateTableName + >.DoDelete(row); } public readonly struct TestIncompatibleSchedule1 @@ -160,63 +158,49 @@ public readonly struct TestIncompatibleSchedule1 return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestIncompatibleSchedule1, + global::TestIncompatibleSchedule + >.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< TestIncompatibleSchedule1, global::TestIncompatibleSchedule - >.Iter(); + >.DoIter(); public global::TestIncompatibleSchedule Insert(global::TestIncompatibleSchedule row) => SpacetimeDB.Internal.ITableView< TestIncompatibleSchedule1, global::TestIncompatibleSchedule - >.Insert(row); - - public IEnumerable FilterByScheduledId( - ulong ScheduledId - ) => - SpacetimeDB - .Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule - >.ColEq.Where( - 0, - ScheduledId, - global::TestIncompatibleSchedule.BSATN.ScheduledId - ) - .Iter(); - - public global::TestIncompatibleSchedule? FindByScheduledId(ulong ScheduledId) => - FilterByScheduledId(ScheduledId) - .Cast() - .SingleOrDefault(); - - public bool DeleteByScheduledId(ulong ScheduledId) => - SpacetimeDB - .Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule - >.ColEq.Where( - 0, - ScheduledId, - global::TestIncompatibleSchedule.BSATN.ScheduledId - ) - .Delete(); - - public bool UpdateByScheduledId( - ulong ScheduledId, - global::TestIncompatibleSchedule @this - ) => - SpacetimeDB - .Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule - >.ColEq.Where( - 0, - ScheduledId, - global::TestIncompatibleSchedule.BSATN.ScheduledId - ) - .Update(@this); + >.DoInsert(row); + + public bool Delete(global::TestIncompatibleSchedule row) => + SpacetimeDB.Internal.ITableView< + TestIncompatibleSchedule1, + global::TestIncompatibleSchedule + >.DoDelete(row); + + public sealed class TestIncompatibleSchedule1UniqueIndex + : UniqueIndex< + TestIncompatibleSchedule1, + global::TestIncompatibleSchedule, + ulong, + SpacetimeDB.BSATN.U64 + > + { + internal TestIncompatibleSchedule1UniqueIndex(TestIncompatibleSchedule1 handle) + : base( + handle, + "idx_TestIncompatibleSchedule1_TestIncompatibleSchedule1_ScheduledId_unique" + ) { } + + public bool Update(global::TestIncompatibleSchedule row) => + DoUpdate(row.ScheduledId, row); + } + + public TestIncompatibleSchedule1UniqueIndex ScheduledId => new(this); } public readonly struct TestIncompatibleSchedule2 @@ -239,63 +223,49 @@ public readonly struct TestIncompatibleSchedule2 return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestIncompatibleSchedule2, + global::TestIncompatibleSchedule + >.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< TestIncompatibleSchedule2, global::TestIncompatibleSchedule - >.Iter(); + >.DoIter(); public global::TestIncompatibleSchedule Insert(global::TestIncompatibleSchedule row) => SpacetimeDB.Internal.ITableView< TestIncompatibleSchedule2, global::TestIncompatibleSchedule - >.Insert(row); - - public IEnumerable FilterByScheduledId( - ulong ScheduledId - ) => - SpacetimeDB - .Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule - >.ColEq.Where( - 0, - ScheduledId, - global::TestIncompatibleSchedule.BSATN.ScheduledId - ) - .Iter(); - - public global::TestIncompatibleSchedule? FindByScheduledId(ulong ScheduledId) => - FilterByScheduledId(ScheduledId) - .Cast() - .SingleOrDefault(); - - public bool DeleteByScheduledId(ulong ScheduledId) => - SpacetimeDB - .Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule - >.ColEq.Where( - 0, - ScheduledId, - global::TestIncompatibleSchedule.BSATN.ScheduledId - ) - .Delete(); - - public bool UpdateByScheduledId( - ulong ScheduledId, - global::TestIncompatibleSchedule @this - ) => - SpacetimeDB - .Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule - >.ColEq.Where( - 0, - ScheduledId, - global::TestIncompatibleSchedule.BSATN.ScheduledId - ) - .Update(@this); + >.DoInsert(row); + + public bool Delete(global::TestIncompatibleSchedule row) => + SpacetimeDB.Internal.ITableView< + TestIncompatibleSchedule2, + global::TestIncompatibleSchedule + >.DoDelete(row); + + public sealed class TestIncompatibleSchedule2UniqueIndex + : UniqueIndex< + TestIncompatibleSchedule2, + global::TestIncompatibleSchedule, + ulong, + SpacetimeDB.BSATN.U64 + > + { + internal TestIncompatibleSchedule2UniqueIndex(TestIncompatibleSchedule2 handle) + : base( + handle, + "idx_TestIncompatibleSchedule2_TestIncompatibleSchedule2_ScheduledId_unique" + ) { } + + public bool Update(global::TestIncompatibleSchedule row) => + DoUpdate(row.ScheduledId, row); + } + + public TestIncompatibleSchedule2UniqueIndex ScheduledId => new(this); } public readonly struct TestTableTaggedEnum @@ -309,33 +279,29 @@ public readonly struct TestTableTaggedEnum return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestTableTaggedEnum, + global::TestTableTaggedEnum + >.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< TestTableTaggedEnum, global::TestTableTaggedEnum - >.Iter(); + >.DoIter(); public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView< TestTableTaggedEnum, global::TestTableTaggedEnum - >.Insert(row); - - public IEnumerable FilterByX(int X) => - SpacetimeDB - .Internal.ITableView< - TestTableTaggedEnum, - global::TestTableTaggedEnum - >.ColEq.Where(0, X, global::TestTableTaggedEnum.BSATN.X) - .Iter(); - - public IEnumerable FilterByY(int Y) => - SpacetimeDB - .Internal.ITableView< - TestTableTaggedEnum, - global::TestTableTaggedEnum - >.ColEq.Where(1, Y, global::TestTableTaggedEnum.BSATN.Y) - .Iter(); + >.DoInsert(row); + + public bool Delete(global::TestTableTaggedEnum row) => + SpacetimeDB.Internal.ITableView< + TestTableTaggedEnum, + global::TestTableTaggedEnum + >.DoDelete(row); } public readonly struct TestUniqueNotEquatable @@ -352,17 +318,69 @@ public readonly struct TestUniqueNotEquatable return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestUniqueNotEquatable, + global::TestUniqueNotEquatable + >.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< TestUniqueNotEquatable, global::TestUniqueNotEquatable - >.Iter(); + >.DoIter(); public global::TestUniqueNotEquatable Insert(global::TestUniqueNotEquatable row) => SpacetimeDB.Internal.ITableView< TestUniqueNotEquatable, global::TestUniqueNotEquatable - >.Insert(row); + >.DoInsert(row); + + public bool Delete(global::TestUniqueNotEquatable row) => + SpacetimeDB.Internal.ITableView< + TestUniqueNotEquatable, + global::TestUniqueNotEquatable + >.DoDelete(row); + + public sealed class TestUniqueNotEquatableUniqueIndex + : UniqueIndex< + TestUniqueNotEquatable, + global::TestUniqueNotEquatable, + int?, + SpacetimeDB.BSATN.ValueOption + > + { + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) + : base( + handle, + "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_UniqueField_unique" + ) { } + + public bool Update(global::TestUniqueNotEquatable row) => + DoUpdate(row.UniqueField, row); + } + + public TestUniqueNotEquatableUniqueIndex UniqueField => new(this); + + public sealed class TestUniqueNotEquatableUniqueIndex + : UniqueIndex< + TestUniqueNotEquatable, + global::TestUniqueNotEquatable, + TestEnumWithExplicitValues, + SpacetimeDB.BSATN.Enum + > + { + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) + : base( + handle, + "idx_TestUniqueNotEquatable_TestUniqueNotEquatable_PrimaryKeyField_unique" + ) { } + + public bool Update(global::TestUniqueNotEquatable row) => + DoUpdate(row.PrimaryKeyField, row); + } + + public TestUniqueNotEquatableUniqueIndex PrimaryKeyField => new(this); } } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestAutoIncNotInteger.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestAutoIncNotInteger.verified.cs index d36068d42e..bd8dfba24c 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestAutoIncNotInteger.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestAutoIncNotInteger.verified.cs @@ -59,16 +59,14 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar Constraints: [ new( - nameof(SpacetimeDB.Local.TestAutoIncNotInteger), - 0, - nameof(AutoIncField), - SpacetimeDB.Internal.ColumnAttrs.AutoInc + "TestAutoIncNotInteger_AutoIncField", + (byte)SpacetimeDB.Internal.ColumnAttrs.AutoInc, + [0] ), new( - nameof(SpacetimeDB.Local.TestAutoIncNotInteger), - 1, - nameof(IdentityField), - SpacetimeDB.Internal.ColumnAttrs.Identity + "TestAutoIncNotInteger_IdentityField", + (byte)SpacetimeDB.Internal.ColumnAttrs.Identity, + [1] ) ], Sequences: [], diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.verified.cs index ec88ca1f17..b19217b519 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.verified.cs @@ -63,10 +63,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar Constraints: [ new( - nameof(SpacetimeDB.Local.TestIncompatibleSchedule1), - 0, - nameof(ScheduledId), - SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto + "TestIncompatibleSchedule1_ScheduledId", + (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, + [0] ) ], Sequences: [], @@ -93,10 +92,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar Constraints: [ new( - nameof(SpacetimeDB.Local.TestIncompatibleSchedule2), - 0, - nameof(ScheduledId), - SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto + "TestIncompatibleSchedule2_ScheduledId", + (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, + [0] ) ], Sequences: [], diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestUniqueNotEquatable.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestUniqueNotEquatable.verified.cs index 4877117b36..57201dbbff 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestUniqueNotEquatable.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestUniqueNotEquatable.verified.cs @@ -66,16 +66,14 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar Constraints: [ new( - nameof(SpacetimeDB.Local.TestUniqueNotEquatable), - 0, - nameof(UniqueField), - SpacetimeDB.Internal.ColumnAttrs.Unique + "TestUniqueNotEquatable_UniqueField", + (byte)SpacetimeDB.Internal.ColumnAttrs.Unique, + [0] ), new( - nameof(SpacetimeDB.Local.TestUniqueNotEquatable), - 1, - nameof(PrimaryKeyField), - SpacetimeDB.Internal.ColumnAttrs.PrimaryKey + "TestUniqueNotEquatable_PrimaryKeyField", + (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKey, + [1] ) ], Sequences: [], diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt index c9a5b66179..d81c138058 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt @@ -77,7 +77,7 @@ public partial record TestTableTaggedEnum : SpacetimeDB.TaggedEnum<(int X, int Y Message: Table TestTableTaggedEnum is a tagged enum, which is not allowed., Severity: Error, Descriptor: { - Id: STDB0004, + Id: STDB0006, Title: Tables cannot be tagged enums, MessageFormat: Table {0} is a tagged enum, which is not allowed., Category: SpacetimeDB, @@ -102,7 +102,7 @@ public partial struct TestIncompatibleSchedule Message: Schedule adds extra fields to the row type. Either all `[Table]` attributes should have a `Schedule`, or none of them., Severity: Error, Descriptor: { - Id: STDB0008, + Id: STDB0010, Title: Incompatible `[Table(Schedule)]` attributes, MessageFormat: Schedule adds extra fields to the row type. Either all `[Table]` attributes should have a `Schedule`, or none of them., Category: SpacetimeDB, @@ -111,6 +111,48 @@ public partial struct TestIncompatibleSchedule } }, {/* + +[SpacetimeDB.Table] +^^^^^^^^^^^^^^^^^^^ +[SpacetimeDB.Index] +^^^^^^^^^^^^^^^^^^^ +public partial struct TestIndexWithoutColumns { } +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*/ + Message: An internal error occurred during codegen: Object reference not set to an instance of an object., + Severity: Error, + Descriptor: { + Id: STDBINT0001, + Title: Internal SpacetimeDB codegen error, + MessageFormat: An internal error occurred during codegen: {0}, + Category: SpacetimeDB.Internal, + DefaultSeverity: Error, + IsEnabledByDefault: true + } + }, + {/* + +[SpacetimeDB.Table] +^^^^^^^^^^^^^^^^^^^ +[SpacetimeDB.Index(BTree = [])] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +public partial struct TestIndexWithEmptyColumns { } +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*/ + Message: An internal error occurred during codegen: Object reference not set to an instance of an object., + Severity: Error, + Descriptor: { + Id: STDBINT0001, + Title: Internal SpacetimeDB codegen error, + MessageFormat: An internal error occurred during codegen: {0}, + Category: SpacetimeDB.Internal, + DefaultSeverity: Error, + IsEnabledByDefault: true + } + }, + {/* [SpacetimeDB.Reducer] public static int TestReducerReturnType(ReducerContext ctx) => 0; ^^^ @@ -136,7 +178,7 @@ public partial struct TestIncompatibleSchedule Message: Reducer method TestReducerWithoutContext does not have a ReducerContext parameter., Severity: Error, Descriptor: { - Id: STDB0006, + Id: STDB0008, Title: Reducers must have a first argument of type ReducerContext, MessageFormat: Reducer method {0} does not have a ReducerContext parameter., Category: SpacetimeDB, @@ -153,7 +195,7 @@ public partial struct TestIncompatibleSchedule Message: Reducer method OnReducerWithReservedPrefix starts with 'On', which is a reserved prefix., Severity: Error, Descriptor: { - Id: STDB0007, + Id: STDB0009, Title: Reducer method has a reserved name prefix, MessageFormat: Reducer method {0} starts with '{1}', which is a reserved prefix., Category: SpacetimeDB, @@ -170,7 +212,7 @@ public partial struct TestIncompatibleSchedule Message: Reducer method __ReducerWithReservedPrefix starts with '__', which is a reserved prefix., Severity: Error, Descriptor: { - Id: STDB0007, + Id: STDB0009, Title: Reducer method has a reserved name prefix, MessageFormat: Reducer method {0} starts with '{1}', which is a reserved prefix., Category: SpacetimeDB, @@ -183,7 +225,7 @@ public partial struct TestIncompatibleSchedule Message: Reducer with the same export name __init__ is registered in multiple places: Reducers.TestDuplicateReducerKind1, Reducers.TestDuplicateReducerKind2, Severity: Error, Descriptor: { - Id: STDB0005, + Id: STDB0007, Title: Duplicate exports, MessageFormat: {0} with the same export name {1} is registered in multiple places: {2}, Category: SpacetimeDB, @@ -196,7 +238,7 @@ public partial struct TestIncompatibleSchedule Message: Reducer with the same export name TestDuplicateReducerName is registered in multiple places: Reducers.TestDuplicateReducerName, Reducers.InAnotherNamespace.TestDuplicateReducerName, Severity: Error, Descriptor: { - Id: STDB0005, + Id: STDB0007, Title: Duplicate exports, MessageFormat: {0} with the same export name {1} is registered in multiple places: {2}, Category: SpacetimeDB, @@ -209,7 +251,7 @@ public partial struct TestIncompatibleSchedule Message: Table with the same export name TestDuplicateTableName is registered in multiple places: global::TestDuplicateTableName, global::InAnotherNamespace.TestDuplicateTableName, Severity: Error, Descriptor: { - Id: STDB0005, + Id: STDB0007, Title: Duplicate exports, MessageFormat: {0} with the same export name {1} is registered in multiple places: {2}, Category: SpacetimeDB, diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs index 8c3e73f50b..78f136f267 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs @@ -145,17 +145,18 @@ public static void Init(ReducerContext ctx) } } -[Table(Name = "MultiTable1", Public = true)] -[Table(Name = "MultiTable2")] +[SpacetimeDB.Table(Name = "MultiTable1", Public = true)] +[SpacetimeDB.Table(Name = "MultiTable2")] +[SpacetimeDB.Index(Table = "MultiTable1", BTree = ["Name"])] public partial struct MultiTableRow { public string Name; - [AutoInc] - [PrimaryKey(Table = "MultiTable1")] + [SpacetimeDB.AutoInc] + [SpacetimeDB.PrimaryKey(Table = "MultiTable1")] public uint Foo; - [Unique(Table = "MultiTable2")] + [SpacetimeDB.Unique(Table = "MultiTable2")] public uint Bar; [SpacetimeDB.Reducer] @@ -166,3 +167,26 @@ public static void InsertMultiData(ReducerContext ctx, MultiTableRow data) ctx.Db.MultiTable2.Insert(data); } } + +[SpacetimeDB.Table] +[SpacetimeDB.Index(Name = "Location", BTree = ["X", "Y", "Z"])] +partial struct BTreeMultiColumn +{ + public uint X; + public uint Y; + public uint Z; +} + +[SpacetimeDB.Table] +[SpacetimeDB.Index(Name = "Location", BTree = ["X", "Y"])] +[SpacetimeDB.Index(Name = "Faction", BTree = ["Faction"])] +partial struct BTreeViews +{ + [SpacetimeDB.PrimaryKey] + public Identity Id; + + public uint X; + public uint Y; + + public string Faction; +} diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeMultiColumn.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeMultiColumn.verified.cs new file mode 100644 index 0000000000..6c9993bc45 --- /dev/null +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeMultiColumn.verified.cs @@ -0,0 +1,86 @@ +//HintName: BTreeMultiColumn.cs +// +#nullable enable + +partial struct BTreeMultiColumn : SpacetimeDB.Internal.ITable +{ + public void ReadFields(System.IO.BinaryReader reader) + { + X = BSATN.X.Read(reader); + Y = BSATN.Y.Read(reader); + Z = BSATN.Z.Read(reader); + } + + public void WriteFields(System.IO.BinaryWriter writer) + { + BSATN.X.Write(writer, X); + BSATN.Y.Write(writer, Y); + BSATN.Z.Write(writer, Z); + } + + public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite + { + internal static readonly SpacetimeDB.BSATN.U32 X = new(); + internal static readonly SpacetimeDB.BSATN.U32 Y = new(); + internal static readonly SpacetimeDB.BSATN.U32 Z = new(); + + public BTreeMultiColumn Read(System.IO.BinaryReader reader) => + SpacetimeDB.BSATN.IStructuralReadWrite.Read(reader); + + public void Write(System.IO.BinaryWriter writer, BTreeMultiColumn value) + { + value.WriteFields(writer); + } + + public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => + registrar.RegisterType( + _ => new SpacetimeDB.BSATN.AlgebraicType.Product( + new SpacetimeDB.BSATN.AggregateElement[] + { + new(nameof(X), X.GetAlgebraicType(registrar)), + new(nameof(Y), Y.GetAlgebraicType(registrar)), + new(nameof(Z), Z.GetAlgebraicType(registrar)) + } + ) + ); + } + + static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => + [ + new( + new( + TableName: nameof(SpacetimeDB.Local.BTreeMultiColumn), + Columns: + [ + new(nameof(X), BSATN.X.GetAlgebraicType(registrar)), + new(nameof(Y), BSATN.Y.GetAlgebraicType(registrar)), + new(nameof(Z), BSATN.Z.GetAlgebraicType(registrar)) + ], + Indexes: + [ + new( + "bt_BTreeMultiColumn_Location", + false, + SpacetimeDB.Internal.IndexType.BTree, + [0, 1, 2] + ) + ], + Constraints: [], + Sequences: [], + // "system" | "user" + TableType: "user", + // "public" | "private" + TableAccess: "private", + Scheduled: null + ), + (uint) + ( + (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) + ).Ref_ + ), + ]; +} // BTreeMultiColumn diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeViews.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeViews.verified.cs new file mode 100644 index 0000000000..23304541f4 --- /dev/null +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeViews.verified.cs @@ -0,0 +1,98 @@ +//HintName: BTreeViews.cs +// +#nullable enable + +partial struct BTreeViews : SpacetimeDB.Internal.ITable +{ + public void ReadFields(System.IO.BinaryReader reader) + { + Id = BSATN.Id.Read(reader); + X = BSATN.X.Read(reader); + Y = BSATN.Y.Read(reader); + Faction = BSATN.Faction.Read(reader); + } + + public void WriteFields(System.IO.BinaryWriter writer) + { + BSATN.Id.Write(writer, Id); + BSATN.X.Write(writer, X); + BSATN.Y.Write(writer, Y); + BSATN.Faction.Write(writer, Faction); + } + + public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite + { + internal static readonly SpacetimeDB.Identity.BSATN Id = new(); + internal static readonly SpacetimeDB.BSATN.U32 X = new(); + internal static readonly SpacetimeDB.BSATN.U32 Y = new(); + internal static readonly SpacetimeDB.BSATN.String Faction = new(); + + public BTreeViews Read(System.IO.BinaryReader reader) => + SpacetimeDB.BSATN.IStructuralReadWrite.Read(reader); + + public void Write(System.IO.BinaryWriter writer, BTreeViews value) + { + value.WriteFields(writer); + } + + public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => + registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( + new SpacetimeDB.BSATN.AggregateElement[] + { + new(nameof(Id), Id.GetAlgebraicType(registrar)), + new(nameof(X), X.GetAlgebraicType(registrar)), + new(nameof(Y), Y.GetAlgebraicType(registrar)), + new(nameof(Faction), Faction.GetAlgebraicType(registrar)) + } + )); + } + + static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => + [ + new( + new( + TableName: nameof(SpacetimeDB.Local.BTreeViews), + Columns: + [ + new(nameof(Id), BSATN.Id.GetAlgebraicType(registrar)), + new(nameof(X), BSATN.X.GetAlgebraicType(registrar)), + new(nameof(Y), BSATN.Y.GetAlgebraicType(registrar)), + new(nameof(Faction), BSATN.Faction.GetAlgebraicType(registrar)) + ], + Indexes: + [ + new( + "bt_BTreeViews_Location", + false, + SpacetimeDB.Internal.IndexType.BTree, + [1, 2] + ), + new( + "bt_BTreeViews_Faction", + false, + SpacetimeDB.Internal.IndexType.BTree, + [3] + ) + ], + Constraints: + [ + new("BTreeViews_Id", (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKey, [0]) + ], + Sequences: [], + // "system" | "user" + TableType: "user", + // "public" | "private" + TableAccess: "private", + Scheduled: null + ), + (uint) + ( + (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) + ).Ref_ + ), + ]; +} // BTreeViews diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs index 1f70af143f..df6b3a8c06 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs @@ -31,6 +31,300 @@ DateTimeOffset time namespace Internal.TableHandles { + internal readonly struct BTreeMultiColumn + : SpacetimeDB.Internal.ITableView + { + static global::BTreeMultiColumn SpacetimeDB.Internal.ITableView< + BTreeMultiColumn, + global::BTreeMultiColumn + >.ReadGenFields(System.IO.BinaryReader reader, global::BTreeMultiColumn row) + { + return row; + } + + public ulong Count => + SpacetimeDB.Internal.ITableView< + BTreeMultiColumn, + global::BTreeMultiColumn + >.DoCount(); + + public IEnumerable Iter() => + SpacetimeDB.Internal.ITableView< + BTreeMultiColumn, + global::BTreeMultiColumn + >.DoIter(); + + public global::BTreeMultiColumn Insert(global::BTreeMultiColumn row) => + SpacetimeDB.Internal.ITableView< + BTreeMultiColumn, + global::BTreeMultiColumn + >.DoInsert(row); + + public bool Delete(global::BTreeMultiColumn row) => + SpacetimeDB.Internal.ITableView< + BTreeMultiColumn, + global::BTreeMultiColumn + >.DoDelete(row); + + internal sealed class LocationIndex() + : SpacetimeDB.Internal.IndexBase( + "bt_BTreeMultiColumn_Location" + ) + { + public IEnumerable Filter(uint X) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds(X) + ); + + public ulong Delete(uint X) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds(X) + ); + + public IEnumerable Filter(Bound X) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds(X) + ); + + public ulong Delete(Bound X) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds(X) + ); + + public IEnumerable Filter((uint X, uint Y) f) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public ulong Delete((uint X, uint Y) f) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public IEnumerable Filter((uint X, Bound Y) f) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public ulong Delete((uint X, Bound Y) f) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public IEnumerable Filter((uint X, uint Y, uint Z) f) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public ulong Delete((uint X, uint Y, uint Z) f) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public IEnumerable Filter( + (uint X, uint Y, Bound Z) f + ) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public ulong Delete((uint X, uint Y, Bound Z) f) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + } + + internal LocationIndex Location => new(); + } + + internal readonly struct BTreeViews + : SpacetimeDB.Internal.ITableView + { + static global::BTreeViews SpacetimeDB.Internal.ITableView< + BTreeViews, + global::BTreeViews + >.ReadGenFields(System.IO.BinaryReader reader, global::BTreeViews row) + { + return row; + } + + public ulong Count => + SpacetimeDB.Internal.ITableView.DoCount(); + + public IEnumerable Iter() => + SpacetimeDB.Internal.ITableView.DoIter(); + + public global::BTreeViews Insert(global::BTreeViews row) => + SpacetimeDB.Internal.ITableView.DoInsert(row); + + public bool Delete(global::BTreeViews row) => + SpacetimeDB.Internal.ITableView.DoDelete(row); + + internal sealed class BTreeViewsUniqueIndex + : UniqueIndex< + BTreeViews, + global::BTreeViews, + SpacetimeDB.Identity, + SpacetimeDB.Identity.BSATN + > + { + internal BTreeViewsUniqueIndex(BTreeViews handle) + : base(handle, "idx_BTreeViews_BTreeViews_Id_unique") { } + + public bool Update(global::BTreeViews row) => DoUpdate(row.Id, row); + } + + internal BTreeViewsUniqueIndex Id => new(this); + + internal sealed class LocationIndex() + : SpacetimeDB.Internal.IndexBase("bt_BTreeViews_Location") + { + public IEnumerable Filter(uint X) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds(X) + ); + + public ulong Delete(uint X) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds(X) + ); + + public IEnumerable Filter(Bound X) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds(X) + ); + + public ulong Delete(Bound X) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds(X) + ); + + public IEnumerable Filter((uint X, uint Y) f) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public ulong Delete((uint X, uint Y) f) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public IEnumerable Filter((uint X, Bound Y) f) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + + public ulong Delete((uint X, Bound Y) f) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds< + uint, + SpacetimeDB.BSATN.U32, + uint, + SpacetimeDB.BSATN.U32 + >(f) + ); + } + + internal LocationIndex Location => new(); + + internal sealed class FactionIndex() + : SpacetimeDB.Internal.IndexBase("bt_BTreeViews_Faction") + { + public IEnumerable Filter(string Faction) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds( + Faction + ) + ); + + public ulong Delete(string Faction) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds( + Faction + ) + ); + + public IEnumerable Filter(Bound Faction) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds( + Faction + ) + ); + + public ulong Delete(Bound Faction) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds( + Faction + ) + ); + } + + internal FactionIndex Faction => new(); + } + public readonly struct MultiTable1 : SpacetimeDB.Internal.ITableView { @@ -46,59 +340,62 @@ public readonly struct MultiTable1 return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView.DoCount(); + public IEnumerable Iter() => - SpacetimeDB.Internal.ITableView.Iter(); + SpacetimeDB.Internal.ITableView.DoIter(); public global::MultiTableRow Insert(global::MultiTableRow row) => - SpacetimeDB.Internal.ITableView.Insert(row); - - public IEnumerable FilterByName(string Name) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 0, - Name, - global::MultiTableRow.BSATN.Name - ) - .Iter(); - - public IEnumerable FilterByFoo(uint Foo) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 1, - Foo, - global::MultiTableRow.BSATN.Foo - ) - .Iter(); - - public global::MultiTableRow? FindByFoo(uint Foo) => - FilterByFoo(Foo).Cast().SingleOrDefault(); - - public bool DeleteByFoo(uint Foo) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 1, - Foo, - global::MultiTableRow.BSATN.Foo - ) - .Delete(); - - public bool UpdateByFoo(uint Foo, global::MultiTableRow @this) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 1, - Foo, - global::MultiTableRow.BSATN.Foo - ) - .Update(@this); - - public IEnumerable FilterByBar(uint Bar) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 2, - Bar, - global::MultiTableRow.BSATN.Bar - ) - .Iter(); + SpacetimeDB.Internal.ITableView.DoInsert(row); + + public bool Delete(global::MultiTableRow row) => + SpacetimeDB.Internal.ITableView.DoDelete(row); + + public sealed class MultiTable1UniqueIndex + : UniqueIndex + { + internal MultiTable1UniqueIndex(MultiTable1 handle) + : base(handle, "idx_MultiTable1_MultiTable1_Foo_unique") { } + + public bool Update(global::MultiTableRow row) => DoUpdate(row.Foo, row); + } + + public MultiTable1UniqueIndex Foo => new(this); + + public sealed class NameIndex() + : SpacetimeDB.Internal.IndexBase("bt_MultiTable1_Name") + { + public IEnumerable Filter(string Name) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds( + Name + ) + ); + + public ulong Delete(string Name) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds( + Name + ) + ); + + public IEnumerable Filter(Bound Name) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds( + Name + ) + ); + + public ulong Delete(Bound Name) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds( + Name + ) + ); + } + + public NameIndex Name => new(); } public readonly struct MultiTable2 @@ -116,59 +413,28 @@ public readonly struct MultiTable2 return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView.DoCount(); + public IEnumerable Iter() => - SpacetimeDB.Internal.ITableView.Iter(); + SpacetimeDB.Internal.ITableView.DoIter(); public global::MultiTableRow Insert(global::MultiTableRow row) => - SpacetimeDB.Internal.ITableView.Insert(row); - - public IEnumerable FilterByName(string Name) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 0, - Name, - global::MultiTableRow.BSATN.Name - ) - .Iter(); - - public IEnumerable FilterByFoo(uint Foo) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 1, - Foo, - global::MultiTableRow.BSATN.Foo - ) - .Iter(); - - public IEnumerable FilterByBar(uint Bar) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 2, - Bar, - global::MultiTableRow.BSATN.Bar - ) - .Iter(); - - public global::MultiTableRow? FindByBar(uint Bar) => - FilterByBar(Bar).Cast().SingleOrDefault(); - - public bool DeleteByBar(uint Bar) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 2, - Bar, - global::MultiTableRow.BSATN.Bar - ) - .Delete(); - - public bool UpdateByBar(uint Bar, global::MultiTableRow @this) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 2, - Bar, - global::MultiTableRow.BSATN.Bar - ) - .Update(@this); + SpacetimeDB.Internal.ITableView.DoInsert(row); + + public bool Delete(global::MultiTableRow row) => + SpacetimeDB.Internal.ITableView.DoDelete(row); + + public sealed class MultiTable2UniqueIndex + : UniqueIndex + { + internal MultiTable2UniqueIndex(MultiTable2 handle) + : base(handle, "idx_MultiTable2_MultiTable2_Bar_unique") { } + + public bool Update(global::MultiTableRow row) => DoUpdate(row.Bar, row); + } + + public MultiTable2UniqueIndex Bar => new(this); } public readonly struct PrivateTable @@ -182,11 +448,17 @@ public readonly struct PrivateTable return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView.DoCount(); + public IEnumerable Iter() => - SpacetimeDB.Internal.ITableView.Iter(); + SpacetimeDB.Internal.ITableView.DoIter(); public global::PrivateTable Insert(global::PrivateTable row) => - SpacetimeDB.Internal.ITableView.Insert(row); + SpacetimeDB.Internal.ITableView.DoInsert(row); + + public bool Delete(global::PrivateTable row) => + SpacetimeDB.Internal.ITableView.DoDelete(row); } public readonly struct PublicTable @@ -204,211 +476,28 @@ public readonly struct PublicTable return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView.DoCount(); + public IEnumerable Iter() => - SpacetimeDB.Internal.ITableView.Iter(); + SpacetimeDB.Internal.ITableView.DoIter(); public global::PublicTable Insert(global::PublicTable row) => - SpacetimeDB.Internal.ITableView.Insert(row); - - public IEnumerable FilterById(int Id) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 0, - Id, - global::PublicTable.BSATN.Id - ) - .Iter(); - - public global::PublicTable? FindById(int Id) => - FilterById(Id).Cast().SingleOrDefault(); - - public bool DeleteById(int Id) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 0, - Id, - global::PublicTable.BSATN.Id - ) - .Delete(); - - public bool UpdateById(int Id, global::PublicTable @this) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 0, - Id, - global::PublicTable.BSATN.Id - ) - .Update(@this); - - public IEnumerable FilterByByteField(byte ByteField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 1, - ByteField, - global::PublicTable.BSATN.ByteField - ) - .Iter(); - - public IEnumerable FilterByUshortField(ushort UshortField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 2, - UshortField, - global::PublicTable.BSATN.UshortField - ) - .Iter(); - - public IEnumerable FilterByUintField(uint UintField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 3, - UintField, - global::PublicTable.BSATN.UintField - ) - .Iter(); - - public IEnumerable FilterByUlongField(ulong UlongField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 4, - UlongField, - global::PublicTable.BSATN.UlongField - ) - .Iter(); - - public IEnumerable FilterByUInt128Field( - System.UInt128 UInt128Field - ) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 5, - UInt128Field, - global::PublicTable.BSATN.UInt128Field - ) - .Iter(); - - public IEnumerable FilterByU128Field(SpacetimeDB.U128 U128Field) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 6, - U128Field, - global::PublicTable.BSATN.U128Field - ) - .Iter(); - - public IEnumerable FilterByU256Field(SpacetimeDB.U256 U256Field) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 7, - U256Field, - global::PublicTable.BSATN.U256Field - ) - .Iter(); - - public IEnumerable FilterBySbyteField(sbyte SbyteField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 8, - SbyteField, - global::PublicTable.BSATN.SbyteField - ) - .Iter(); - - public IEnumerable FilterByShortField(short ShortField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 9, - ShortField, - global::PublicTable.BSATN.ShortField - ) - .Iter(); - - public IEnumerable FilterByIntField(int IntField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 10, - IntField, - global::PublicTable.BSATN.IntField - ) - .Iter(); - - public IEnumerable FilterByLongField(long LongField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 11, - LongField, - global::PublicTable.BSATN.LongField - ) - .Iter(); - - public IEnumerable FilterByInt128Field( - System.Int128 Int128Field - ) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 12, - Int128Field, - global::PublicTable.BSATN.Int128Field - ) - .Iter(); - - public IEnumerable FilterByI128Field(SpacetimeDB.I128 I128Field) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 13, - I128Field, - global::PublicTable.BSATN.I128Field - ) - .Iter(); - - public IEnumerable FilterByI256Field(SpacetimeDB.I256 I256Field) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 14, - I256Field, - global::PublicTable.BSATN.I256Field - ) - .Iter(); - - public IEnumerable FilterByBoolField(bool BoolField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 15, - BoolField, - global::PublicTable.BSATN.BoolField - ) - .Iter(); - - public IEnumerable FilterByStringField(string StringField) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 18, - StringField, - global::PublicTable.BSATN.StringField - ) - .Iter(); - - public IEnumerable FilterByIdentityField( - SpacetimeDB.Identity IdentityField - ) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 19, - IdentityField, - global::PublicTable.BSATN.IdentityField - ) - .Iter(); - - public IEnumerable FilterByAddressField( - SpacetimeDB.Address AddressField - ) => - SpacetimeDB - .Internal.ITableView.ColEq.Where( - 20, - AddressField, - global::PublicTable.BSATN.AddressField - ) - .Iter(); + SpacetimeDB.Internal.ITableView.DoInsert(row); + + public bool Delete(global::PublicTable row) => + SpacetimeDB.Internal.ITableView.DoDelete(row); + + public sealed class PublicTableUniqueIndex + : UniqueIndex + { + internal PublicTableUniqueIndex(PublicTable handle) + : base(handle, "idx_PublicTable_PublicTable_Id_unique") { } + + public bool Update(global::PublicTable row) => DoUpdate(row.Id, row); + } + + public PublicTableUniqueIndex Id => new(this); } public readonly struct SendMessageTimer @@ -428,64 +517,53 @@ public readonly struct SendMessageTimer return row; } + public ulong Count => + SpacetimeDB.Internal.ITableView< + SendMessageTimer, + global::Timers.SendMessageTimer + >.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< SendMessageTimer, global::Timers.SendMessageTimer - >.Iter(); + >.DoIter(); public global::Timers.SendMessageTimer Insert(global::Timers.SendMessageTimer row) => SpacetimeDB.Internal.ITableView< SendMessageTimer, global::Timers.SendMessageTimer - >.Insert(row); - - public IEnumerable FilterByText(string Text) => - SpacetimeDB - .Internal.ITableView< - SendMessageTimer, - global::Timers.SendMessageTimer - >.ColEq.Where(0, Text, global::Timers.SendMessageTimer.BSATN.Text) - .Iter(); - - public IEnumerable FilterByScheduledId( - ulong ScheduledId - ) => - SpacetimeDB - .Internal.ITableView< - SendMessageTimer, - global::Timers.SendMessageTimer - >.ColEq.Where(1, ScheduledId, global::Timers.SendMessageTimer.BSATN.ScheduledId) - .Iter(); - - public global::Timers.SendMessageTimer? FindByScheduledId(ulong ScheduledId) => - FilterByScheduledId(ScheduledId) - .Cast() - .SingleOrDefault(); - - public bool DeleteByScheduledId(ulong ScheduledId) => - SpacetimeDB - .Internal.ITableView< - SendMessageTimer, - global::Timers.SendMessageTimer - >.ColEq.Where(1, ScheduledId, global::Timers.SendMessageTimer.BSATN.ScheduledId) - .Delete(); - - public bool UpdateByScheduledId( - ulong ScheduledId, - global::Timers.SendMessageTimer @this - ) => - SpacetimeDB - .Internal.ITableView< - SendMessageTimer, - global::Timers.SendMessageTimer - >.ColEq.Where(1, ScheduledId, global::Timers.SendMessageTimer.BSATN.ScheduledId) - .Update(@this); + >.DoInsert(row); + + public bool Delete(global::Timers.SendMessageTimer row) => + SpacetimeDB.Internal.ITableView< + SendMessageTimer, + global::Timers.SendMessageTimer + >.DoDelete(row); + + public sealed class SendMessageTimerUniqueIndex + : UniqueIndex< + SendMessageTimer, + global::Timers.SendMessageTimer, + ulong, + SpacetimeDB.BSATN.U64 + > + { + internal SendMessageTimerUniqueIndex(SendMessageTimer handle) + : base(handle, "idx_SendMessageTimer_SendMessageTimer_ScheduledId_unique") { } + + public bool Update(global::Timers.SendMessageTimer row) => + DoUpdate(row.ScheduledId, row); + } + + public SendMessageTimerUniqueIndex ScheduledId => new(this); } } public sealed class Local { + internal Internal.TableHandles.BTreeMultiColumn BTreeMultiColumn => new(); + internal Internal.TableHandles.BTreeViews BTreeViews => new(); public Internal.TableHandles.MultiTable1 MultiTable1 => new(); public Internal.TableHandles.MultiTable2 MultiTable2 => new(); public Internal.TableHandles.PrivateTable PrivateTable => new(); @@ -605,6 +683,8 @@ public static void Main() SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer(); + SpacetimeDB.Internal.Module.RegisterTable(); + SpacetimeDB.Internal.Module.RegisterTable(); SpacetimeDB.Internal.Module.RegisterTable(); SpacetimeDB.Internal.Module.RegisterTable(); SpacetimeDB.Internal.Module.RegisterTable(); diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.verified.cs index 28f5a120fc..d88953294e 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.verified.cs @@ -58,14 +58,16 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(Foo), BSATN.Foo.GetAlgebraicType(registrar)), new(nameof(Bar), BSATN.Bar.GetAlgebraicType(registrar)) ], - Indexes: [], + Indexes: + [ + new("bt_MultiTable1_Name", false, SpacetimeDB.Internal.IndexType.BTree, [0]) + ], Constraints: [ new( - nameof(SpacetimeDB.Local.MultiTable1), - 1, - nameof(Foo), - SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto + "MultiTable1_Foo", + (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, + [1] ) ], Sequences: [], @@ -92,18 +94,8 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar Indexes: [], Constraints: [ - new( - nameof(SpacetimeDB.Local.MultiTable2), - 1, - nameof(Foo), - SpacetimeDB.Internal.ColumnAttrs.AutoInc - ), - new( - nameof(SpacetimeDB.Local.MultiTable2), - 2, - nameof(Bar), - SpacetimeDB.Internal.ColumnAttrs.Unique - ) + new("MultiTable2_Foo", (byte)SpacetimeDB.Internal.ColumnAttrs.AutoInc, [1]), + new("MultiTable2_Bar", (byte)SpacetimeDB.Internal.ColumnAttrs.Unique, [2]) ], Sequences: [], // "system" | "user" diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs index e975a9352a..94ded4ff37 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs @@ -256,10 +256,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar Constraints: [ new( - nameof(SpacetimeDB.Local.PublicTable), - 0, - nameof(Id), - SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto + "PublicTable_Id", + (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, + [0] ) ], Sequences: [], diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs index 9fbaa28953..94c5a2f8e6 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs @@ -70,10 +70,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar Constraints: [ new( - nameof(SpacetimeDB.Local.SendMessageTimer), - 1, - nameof(ScheduledId), - SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto + "SendMessageTimer_ScheduledId", + (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, + [1] ) ], Sequences: [], diff --git a/crates/bindings-csharp/Codegen/Diag.cs b/crates/bindings-csharp/Codegen/Diag.cs index 03e205b959..c0c052ce96 100644 --- a/crates/bindings-csharp/Codegen/Diag.cs +++ b/crates/bindings-csharp/Codegen/Diag.cs @@ -34,6 +34,22 @@ internal static class ErrorDescriptor field => field ); + public static readonly ErrorDescriptor EmptyIndexColumns = + new( + group, + "Index attribute must specify index Columns.", + table => $"Table {table.Identifier} has an Index.BTree attribute, but no columns.", + table => table.BaseList! + ); + + public static readonly ErrorDescriptor InvalidTableVisibility = + new( + group, + "Table row visibility must be public or internal, including container types.", + table => $"Table {table.Identifier} and its parent types must be public or internal.", + table => table.BaseList! + ); + public static readonly ErrorDescriptor TableTaggedEnum = new( group, diff --git a/crates/bindings-csharp/Codegen/Module.cs b/crates/bindings-csharp/Codegen/Module.cs index fa36b78c53..95d49d0163 100644 --- a/crates/bindings-csharp/Codegen/Module.cs +++ b/crates/bindings-csharp/Codegen/Module.cs @@ -148,10 +148,49 @@ public TableView(TableDeclaration table, AttributeData data) } } +abstract record ViewIndex +{ + public EquatableArray Columns; + public string? Table; + public string Name; + + protected abstract string Type { get; } + + public ViewIndex(AttributeData data, TypeDeclarationSyntax decl, DiagReporter diag) + { + var attr = data.ParseAs(); + Columns = new((attr.BTree ?? []).ToImmutableArray()); + Table = attr.Table; + Name = attr.Name ?? string.Join("", Columns); + + if (Columns.Length == 0) + { + diag.Report(ErrorDescriptor.EmptyIndexColumns, decl); + } + } + + public string GenerateIndexDef(string viewName, IEnumerable columns) + { + var cols = Columns.Select(c => + columns.Select((c, i) => (c, i)).First(cd => cd.c.Name == c).i + ); + return $"new(\"bt_{viewName}_{Name}\", false, SpacetimeDB.Internal.IndexType.{Type}, [{string.Join(", ", cols)}])"; + } +} + +record ViewBTree : ViewIndex +{ + public ViewBTree(AttributeData data, TypeDeclarationSyntax decl, DiagReporter diag) + : base(data, decl, diag) { } + + protected override string Type => "BTree"; +} + record TableDeclaration : BaseTypeDeclaration { public readonly Accessibility Visibility; public readonly EquatableArray Views; + public readonly EquatableArray BTrees; private static ColumnDeclaration[] ScheduledColumns(string tableName) => [ @@ -191,8 +230,16 @@ public TableDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter di case Accessibility.NotApplicable: case Accessibility.Internal: case Accessibility.Public: + if (Visibility < container.DeclaredAccessibility) + { + Visibility = container.DeclaredAccessibility; + } break; default: + diag.Report( + ErrorDescriptor.InvalidTableVisibility, + (TypeDeclarationSyntax)context.TargetNode + ); throw new Exception( "Table row type visibility must be public or internal, including containing types." ); @@ -202,6 +249,13 @@ public TableDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter di } Views = new(context.Attributes.Select(a => new TableView(this, a)).ToImmutableArray()); + BTrees = new( + context + .TargetSymbol.GetAttributes() + .Where(a => a.AttributeClass?.ToString() == typeof(IndexAttribute).FullName) + .Select(a => new ViewBTree(a, (TypeDeclarationSyntax)context.TargetNode, diag)) + .ToImmutableArray() + ); var hasScheduled = Views.Select(t => t.Scheduled is not null).Distinct(); @@ -225,37 +279,83 @@ public TableDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter di protected override ColumnDeclaration ConvertMember(IFieldSymbol field, DiagReporter diag) => new(FullName, field, diag); - public IEnumerable GenerateViewFilters(string viewName, string iTable) + public IEnumerable GenerateViewFilters(string viewName) { + var vis = SyntaxFacts.GetText(Visibility); + var globalName = $"global::{FullName}"; + foreach ( - var (f, i) in Members - .Select((field, i) => (field, i)) - .Where(pair => pair.field.IsEquatable) + var ct in GetConstraints(viewName) + .Where(tuple => tuple.attr.HasFlag(ColumnAttrs.Unique)) ) { - var globalName = $"global::{FullName}"; - var colEqWhere = $"{iTable}.ColEq.Where({i}, {f.Name}, {globalName}.BSATN.{f.Name})"; + var f = ct.col; + if (f.GetAttrs(viewName).HasFlag(ColumnAttrs.Unique)) + { + var iUniqueIndex = $""; + yield return $$""" + {{vis}} sealed class {{viewName}}UniqueIndex : UniqueIndex<{{viewName}}, {{globalName}}, {{f.Type}}, {{f.TypeInfo}}> { + internal {{viewName}}UniqueIndex({{viewName}} handle) : base(handle, "idx_{{viewName}}_{{viewName}}_{{ct.col.Name}}_unique") {} + public bool Update({{globalName}} row) => DoUpdate(row.{{f.Name}}, row); + } + {{vis}} {{viewName}}UniqueIndex {{f.Name}} => new(this); + """; + } + } + + foreach (var btree in BTrees) + { + if (btree.Table != null && btree.Table != viewName) + { + continue; + } - yield return $""" - public IEnumerable<{globalName}> FilterBy{f.Name}({f.Type} {f.Name}) => - {colEqWhere}.Iter(); + yield return $$""" + {{vis}} sealed class {{btree.Name}}Index() : SpacetimeDB.Internal.IndexBase<{{globalName}}>("bt_{{viewName}}_{{btree.Name}}") { """; - if (f.GetAttrs(viewName).HasFlag(ColumnAttrs.Unique)) + var members = btree.Columns.Select(s => Members.First(x => x.Name == s)).ToArray(); + + for (var n = 0; n < members.Length; n++) { - yield return $""" - public {globalName}? FindBy{f.Name}({f.Type} {f.Name}) => - FilterBy{f.Name}({f.Name}) - .Cast<{globalName}?>() - .SingleOrDefault(); + var types = string.Join( + ", ", + members.Take(n + 1).Select(m => $"{m.Type}, {m.TypeInfo}") + ); + var scalars = members.Take(n).Select(m => $"{m.Type} {m.Name}"); + var lastScalar = $"{members[n].Type} {members[n].Name}"; + var lastBounds = $"Bound<{members[n].Type}> {members[n].Name}"; + var argsScalar = string.Join(", ", scalars.Append(lastScalar)); + var argsBounds = string.Join(", ", scalars.Append(lastBounds)); + string argName; + if (n > 0) + { + argName = "f"; + argsScalar = $"({argsScalar}) f"; + argsBounds = $"({argsBounds}) f"; + } + else + { + argName = members[0].Name; + } + + yield return $$""" + public IEnumerable<{{globalName}}> Filter({{argsScalar}}) => + DoFilter(new SpacetimeDB.Internal.BTreeIndexBounds<{{types}}>({{argName}})); + + public ulong Delete({{argsScalar}}) => + DoDelete(new SpacetimeDB.Internal.BTreeIndexBounds<{{types}}>({{argName}})); - public bool DeleteBy{f.Name}({f.Type} {f.Name}) => - {colEqWhere}.Delete(); + public IEnumerable<{{globalName}}> Filter({{argsBounds}}) => + DoFilter(new SpacetimeDB.Internal.BTreeIndexBounds<{{types}}>({{argName}})); - public bool UpdateBy{f.Name}({f.Type} {f.Name}, {globalName} @this) => - {colEqWhere}.Update(@this); + public ulong Delete({{argsBounds}}) => + DoDelete(new SpacetimeDB.Internal.BTreeIndexBounds<{{types}}>({{argName}})); + """; } + + yield return $"}}\n {vis} {btree.Name}Index {btree.Name} => new();\n"; } } @@ -290,9 +390,13 @@ public IEnumerable GenerateViews() )}} return row; } - public IEnumerable<{{globalName}}> Iter() => {{iTable}}.Iter(); - public {{globalName}} Insert({{globalName}} row) => {{iTable}}.Insert(row); - {{string.Join("\n", GenerateViewFilters(v.Name, iTable))}} + + public ulong Count => {{iTable}}.DoCount(); + public IEnumerable<{{globalName}}> Iter() => {{iTable}}.DoIter(); + public {{globalName}} Insert({{globalName}} row) => {{iTable}}.DoInsert(row); + public bool Delete({{globalName}} row) => {{iTable}}.DoDelete(row); + + {{string.Join("\n", GenerateViewFilters(v.Name))}} } """, $"{SyntaxFacts.GetText(Visibility)} Internal.TableHandles.{v.Name} {v.Name} => new();" @@ -300,6 +404,14 @@ public IEnumerable GenerateViews() } } + public record struct Constraint(ColumnDeclaration col, int pos, ColumnAttrs attr); + + public IEnumerable GetConstraints(string viewName) => + Members + // Important: the position must be stored here, before filtering. + .Select((col, pos) => new Constraint(col, pos, col.GetAttrs(viewName))) + .Where(c => c.attr != ColumnAttrs.UnSet); + public override Scope.Extensions ToExtensions() { var extensions = base.ToExtensions(); @@ -345,21 +457,21 @@ public override Scope.Extensions ToExtensions() Columns: [ {{string.Join(",\n", Members.Select(m => m.GenerateColumnDef()))}} ], - Indexes: [], + Indexes: [ + {{string.Join(",\n", BTrees + .Where(b => b.Table == null || b.Table == v.Name) + .Select(b => b.GenerateIndexDef(v.Name, Members)))}} + ], Constraints: [ {{string.Join( ",\n", - Members - // Important: the position must be stored here, before filtering. - .Select((col, pos) => (col, pos, attr: col.GetAttrs(v.Name))) - .Where(tuple => tuple.attr != ColumnAttrs.UnSet) - .Select(tuple => + GetConstraints(v.Name) + .Select(ct => $$""" new ( - nameof(SpacetimeDB.Local.{{v.Name}}), - {{tuple.pos}}, - nameof({{tuple.col.Name}}), - SpacetimeDB.Internal.ColumnAttrs.{{tuple.attr}} + "{{v.Name}}_{{ct.col.Name}}", + (byte)SpacetimeDB.Internal.ColumnAttrs.{{ct.attr}}, + [{{ct.pos}}] ) """ ) diff --git a/crates/bindings-csharp/Runtime/Attrs.cs b/crates/bindings-csharp/Runtime/Attrs.cs index 2c1c5c0cf1..1c5d4420a7 100644 --- a/crates/bindings-csharp/Runtime/Attrs.cs +++ b/crates/bindings-csharp/Runtime/Attrs.cs @@ -51,6 +51,16 @@ public sealed class TableAttribute : Attribute public string? Scheduled { get; init; } } + [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true)] + public sealed class IndexAttribute : Attribute + { + public string? Table { get; init; } + + public string? Name { get; init; } + + public required string[] BTree { get; init; } + } + public sealed class AutoIncAttribute : Internal.ColumnAttribute { internal override Internal.ColumnAttrs Mask => Internal.ColumnAttrs.AutoInc; diff --git a/crates/bindings-csharp/Runtime/Exceptions.cs b/crates/bindings-csharp/Runtime/Exceptions.cs index 57113dc0c4..96b59deca2 100644 --- a/crates/bindings-csharp/Runtime/Exceptions.cs +++ b/crates/bindings-csharp/Runtime/Exceptions.cs @@ -22,7 +22,12 @@ public class NoSuchTableException : StdbException public override string Message => "No such table"; } -public class UniqueAlreadyExistsException : StdbException +public class NoSuchIndexException : StdbException +{ + public override string Message => "No such index"; +} + +public class UniqueConstraintViolationException : StdbException { public override string Message => "Value with given unique identifier already exists"; } diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefV8.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefV8.cs index 03c46c42c0..0ca3c3d640 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefV8.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefV8.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV8.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV8.cs index d08bcef32b..5042850639 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV8.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV8.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV9.cs index ecd300be15..d5eef90dc9 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV8.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV8.cs index 64c15e3683..721779ab34 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV8.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV8.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV9.cs index 71aa4c3a6e..8ac8b6328e 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV8.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV8.cs index c4933cd334..65a329c59e 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV8.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV8.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV9.cs index a6979b6159..adf37df0b7 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawReducerDefV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawReducerDefV9.cs index 0d3268a10a..4811d4cf91 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawReducerDefV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawReducerDefV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawScheduleDefV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawScheduleDefV9.cs index 260bb28c21..e361088054 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawScheduleDefV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawScheduleDefV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawScopedTypeNameV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawScopedTypeNameV9.cs index b2329d0a22..b794739ae7 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawScopedTypeNameV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawScopedTypeNameV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV8.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV8.cs index abc372d315..e8461f5926 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV8.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV8.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV9.cs index 768eb01176..d429418230 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV8.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV8.cs index 844b4d134b..e32ed3cbff 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV8.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV8.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV9.cs index 506da87e29..2c243f5c56 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTypeDefV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTypeDefV9.cs index 62fdcc0f9b..be2d34ce67 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTypeDefV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTypeDefV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawUniqueConstraintDataV9.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawUniqueConstraintDataV9.cs index 93171c5352..35abef5e88 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawUniqueConstraintDataV9.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawUniqueConstraintDataV9.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/ReducerDef.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/ReducerDef.cs index c7592876b2..c3cfb6e702 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/ReducerDef.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/ReducerDef.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/TableDesc.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/TableDesc.cs index 59190a1cc9..26630eac87 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/TableDesc.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/TableDesc.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/TypeAlias.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/TypeAlias.cs index ab3dea846b..41622dcbbc 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/TypeAlias.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/TypeAlias.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/Typespace.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/Typespace.cs index 36811803be..d997891627 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/Typespace.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/Typespace.cs @@ -7,7 +7,6 @@ using System; using SpacetimeDB; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB.Internal diff --git a/crates/bindings-csharp/Runtime/Internal/Bounds.cs b/crates/bindings-csharp/Runtime/Internal/Bounds.cs new file mode 100644 index 0000000000..4de9ac851f --- /dev/null +++ b/crates/bindings-csharp/Runtime/Internal/Bounds.cs @@ -0,0 +1,413 @@ +namespace SpacetimeDB.Internal; + +using SpacetimeDB.BSATN; + +enum BoundVariant : byte +{ + Inclusive, + Exclusive, + Unbounded, +} + +public interface IBTreeIndexBounds +{ + ushort PrefixElems { get; } + void Prefix(BinaryWriter w); + void RStart(BinaryWriter w); + void REnd(BinaryWriter w); +} + +public readonly struct Bound(T min, T max) + where T : IEquatable +{ + public T Min => min; + public T Max => max; + + public static implicit operator Bound(T value) => new(value, value); + + public static implicit operator Bound((T min, T max) span) => new(span.min, span.max); +} + +public readonly struct BTreeIndexBounds(Bound t) : IBTreeIndexBounds + where T : IEquatable + where TRW : struct, IReadWrite +{ + public ushort PrefixElems => 0; + + public void Prefix(BinaryWriter _) { } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new TRW().Write(w, t.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new TRW().Write(w, t.Max); + } +} + +public readonly struct BTreeIndexBounds((T t, Bound u) b) : IBTreeIndexBounds + where U : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite +{ + public ushort PrefixElems => 1; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new URW().Write(w, b.u.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new URW().Write(w, b.u.Max); + } +} + +public readonly struct BTreeIndexBounds((T t, U u, Bound v) b) + : IBTreeIndexBounds + where V : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite + where VRW : struct, IReadWrite +{ + public ushort PrefixElems => 2; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + new URW().Write(w, b.u); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new VRW().Write(w, b.v.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new VRW().Write(w, b.v.Max); + } +} + +public readonly struct BTreeIndexBounds( + (T t, U u, V v, Bound w) b +) : IBTreeIndexBounds + where W : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite + where VRW : struct, IReadWrite + where WRW : struct, IReadWrite +{ + public ushort PrefixElems => 3; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + new URW().Write(w, b.u); + new VRW().Write(w, b.v); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new WRW().Write(w, b.w.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new WRW().Write(w, b.w.Max); + } +} + +public readonly struct BTreeIndexBounds( + (T t, U u, V v, W w, Bound x) b +) : IBTreeIndexBounds + where X : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite + where VRW : struct, IReadWrite + where WRW : struct, IReadWrite + where XRW : struct, IReadWrite +{ + public ushort PrefixElems => 4; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + new URW().Write(w, b.u); + new VRW().Write(w, b.v); + new WRW().Write(w, b.w); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new XRW().Write(w, b.x.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new XRW().Write(w, b.x.Max); + } +} + +public readonly struct BTreeIndexBounds( + (T t, U u, V v, W w, X x, Bound y) b +) : IBTreeIndexBounds + where Y : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite + where VRW : struct, IReadWrite + where WRW : struct, IReadWrite + where XRW : struct, IReadWrite + where YRW : struct, IReadWrite +{ + public ushort PrefixElems => 5; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + new URW().Write(w, b.u); + new VRW().Write(w, b.v); + new WRW().Write(w, b.w); + new XRW().Write(w, b.x); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new YRW().Write(w, b.y.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new YRW().Write(w, b.y.Max); + } +} + +public readonly struct BTreeIndexBounds( + (T t, U u, V v, W w, X x, Y y, Bound z) b +) : IBTreeIndexBounds + where Z : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite + where VRW : struct, IReadWrite + where WRW : struct, IReadWrite + where XRW : struct, IReadWrite + where YRW : struct, IReadWrite + where ZRW : struct, IReadWrite +{ + public ushort PrefixElems => 6; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + new URW().Write(w, b.u); + new VRW().Write(w, b.v); + new WRW().Write(w, b.w); + new XRW().Write(w, b.x); + new YRW().Write(w, b.y); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new ZRW().Write(w, b.z.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new ZRW().Write(w, b.z.Max); + } +} + +public readonly struct BTreeIndexBounds< + T, + TRW, + U, + URW, + V, + VRW, + W, + WRW, + X, + XRW, + Y, + YRW, + Z, + ZRW, + A, + ARW +>((T t, U u, V v, W w, X x, Y y, Z z, Bound a) b) : IBTreeIndexBounds + where A : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite + where VRW : struct, IReadWrite + where WRW : struct, IReadWrite + where XRW : struct, IReadWrite + where YRW : struct, IReadWrite + where ZRW : struct, IReadWrite + where ARW : struct, IReadWrite +{ + public ushort PrefixElems => 7; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + new URW().Write(w, b.u); + new VRW().Write(w, b.v); + new WRW().Write(w, b.w); + new XRW().Write(w, b.x); + new YRW().Write(w, b.y); + new ZRW().Write(w, b.z); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new ARW().Write(w, b.a.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new ARW().Write(w, b.a.Max); + } +} + +public readonly struct BTreeIndexBounds< + T, + TRW, + U, + URW, + V, + VRW, + W, + WRW, + X, + XRW, + Y, + YRW, + Z, + ZRW, + A, + ARW, + B, + BRW +>((T t, U u, V v, W w, X x, Y y, Z z, A a, Bound b) b) : IBTreeIndexBounds + where B : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite + where VRW : struct, IReadWrite + where WRW : struct, IReadWrite + where XRW : struct, IReadWrite + where YRW : struct, IReadWrite + where ZRW : struct, IReadWrite + where ARW : struct, IReadWrite + where BRW : struct, IReadWrite +{ + public ushort PrefixElems => 8; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + new URW().Write(w, b.u); + new VRW().Write(w, b.v); + new WRW().Write(w, b.w); + new XRW().Write(w, b.x); + new YRW().Write(w, b.y); + new ZRW().Write(w, b.z); + new ARW().Write(w, b.a); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new BRW().Write(w, b.b.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new BRW().Write(w, b.b.Max); + } +} + +public readonly struct BTreeIndexBounds< + T, + TRW, + U, + URW, + V, + VRW, + W, + WRW, + X, + XRW, + Y, + YRW, + Z, + ZRW, + A, + ARW, + B, + BRW, + C, + CRW +>((T t, U u, V v, W w, X x, Y y, Z z, A a, B b, Bound c) b) : IBTreeIndexBounds + where C : IEquatable + where TRW : struct, IReadWrite + where URW : struct, IReadWrite + where VRW : struct, IReadWrite + where WRW : struct, IReadWrite + where XRW : struct, IReadWrite + where YRW : struct, IReadWrite + where ZRW : struct, IReadWrite + where ARW : struct, IReadWrite + where BRW : struct, IReadWrite + where CRW : struct, IReadWrite +{ + public ushort PrefixElems => 9; + + public void Prefix(BinaryWriter w) + { + new TRW().Write(w, b.t); + new URW().Write(w, b.u); + new VRW().Write(w, b.v); + new WRW().Write(w, b.w); + new XRW().Write(w, b.x); + new YRW().Write(w, b.y); + new ZRW().Write(w, b.z); + new ARW().Write(w, b.a); + new BRW().Write(w, b.b); + } + + public void RStart(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new CRW().Write(w, b.c.Min); + } + + public void REnd(BinaryWriter w) + { + w.Write((byte)BoundVariant.Inclusive); + new CRW().Write(w, b.c.Max); + } +} diff --git a/crates/bindings-csharp/Runtime/Internal/FFI.cs b/crates/bindings-csharp/Runtime/Internal/FFI.cs index c6e9e8a08d..97f7543c2d 100644 --- a/crates/bindings-csharp/Runtime/Internal/FFI.cs +++ b/crates/bindings-csharp/Runtime/Internal/FFI.cs @@ -26,6 +26,7 @@ public enum Errno : short NOT_IN_TRANSACTION = 2, BSATN_DECODE_ERROR = 3, NO_SUCH_TABLE = 4, + NO_SUCH_INDEX = 5, NO_SUCH_ITER = 6, NO_SUCH_CONSOLE_TIMER = 7, NO_SUCH_BYTES = 8, @@ -75,12 +76,13 @@ public static CheckedStatus ConvertToManaged(Errno status) Errno.NOT_IN_TRANSACTION => new NotInTransactionException(), Errno.BSATN_DECODE_ERROR => new BsatnDecodeException(), Errno.NO_SUCH_TABLE => new NoSuchTableException(), + Errno.NO_SUCH_INDEX => new NoSuchIndexException(), Errno.NO_SUCH_ITER => new NoSuchIterException(), Errno.NO_SUCH_CONSOLE_TIMER => new NoSuchLogStopwatch(), Errno.NO_SUCH_BYTES => new NoSuchBytesException(), Errno.NO_SPACE => new NoSpaceException(), Errno.BUFFER_TOO_SMALL => new BufferTooSmallException(), - Errno.UNIQUE_ALREADY_EXISTS => new UniqueAlreadyExistsException(), + Errno.UNIQUE_ALREADY_EXISTS => new UniqueConstraintViolationException(), Errno.SCHEDULE_AT_DELAY_TOO_LONG => new ScheduleAtDelayTooLongException(), _ => new UnknownException(status), }; @@ -94,6 +96,12 @@ public readonly struct TableId private readonly uint table_id; } + [StructLayout(LayoutKind.Sequential)] + public readonly struct IndexId + { + private readonly uint index_id; + } + [StructLayout(LayoutKind.Sequential)] public readonly struct ColId(ushort col_id) { @@ -121,6 +129,13 @@ public static partial CheckedStatus table_id_from_name( out TableId out_ ); + [LibraryImport(StdbNamespace)] + public static partial CheckedStatus index_id_from_name( + [In] byte[] name, + uint name_len, + out IndexId out_ + ); + [LibraryImport(StdbNamespace)] public static partial CheckedStatus datastore_table_row_count(TableId table_id, out ulong out_); @@ -131,10 +146,16 @@ out RowIter out_ ); [LibraryImport(StdbNamespace)] - public static partial CheckedStatus datastore_insert_bsatn( - TableId table_id, - Span row, - ref uint row_len + public static partial CheckedStatus datastore_btree_scan_bsatn( + IndexId index_id, + ReadOnlySpan prefix, + uint prefix_len, + ColId prefix_elems, + ReadOnlySpan rstart, + uint rstart_len, + ReadOnlySpan rend, + uint rend_len, + out RowIter out_ ); [LibraryImport(StdbNamespace)] @@ -147,6 +168,26 @@ ref uint buffer_len [LibraryImport(StdbNamespace)] public static partial CheckedStatus row_iter_bsatn_close(RowIter iter_handle); + [LibraryImport(StdbNamespace)] + public static partial CheckedStatus datastore_insert_bsatn( + TableId table_id, + Span row, + ref uint row_len + ); + + [LibraryImport(StdbNamespace)] + public static partial CheckedStatus datastore_delete_by_btree_scan_bsatn( + IndexId index_id, + ReadOnlySpan prefix, + uint prefix_len, + ColId prefix_elems, + ReadOnlySpan rstart, + uint rstart_len, + ReadOnlySpan rend, + uint rend_len, + out uint out_ + ); + [LibraryImport(StdbNamespace)] public static partial CheckedStatus datastore_delete_all_by_eq_bsatn( TableId table_id, @@ -156,11 +197,17 @@ out uint out_ ); [LibraryImport(StdbNamespace)] - public static partial void volatile_nonatomic_schedule_immediate( - [In] byte[] name, - uint name_len, - [In] byte[] args, - uint args_len + public static partial Errno bytes_source_read( + BytesSource source, + Span buffer, + ref uint buffer_len + ); + + [LibraryImport(StdbNamespace)] + public static partial CheckedStatus bytes_sink_write( + BytesSink sink, + ReadOnlySpan buffer, + ref uint buffer_len ); public enum LogLevel : byte @@ -185,20 +232,6 @@ public static partial void console_log( uint message_len ); - [LibraryImport(StdbNamespace)] - public static partial Errno bytes_source_read( - BytesSource source, - Span buffer, - ref uint buffer_len - ); - - [LibraryImport(StdbNamespace)] - public static partial CheckedStatus bytes_sink_write( - BytesSink sink, - ReadOnlySpan buffer, - ref uint buffer_len - ); - [NativeMarshalling(typeof(ConsoleTimerIdMarshaller))] [StructLayout(LayoutKind.Sequential)] public readonly struct ConsoleTimerId @@ -229,4 +262,12 @@ internal static class ConsoleTimerIdMarshaller [LibraryImport(StdbNamespace)] public static partial CheckedStatus console_timer_end(ConsoleTimerId stopwatch_id); + + [LibraryImport(StdbNamespace)] + public static partial void volatile_nonatomic_schedule_immediate( + [In] byte[] name, + uint name_len, + [In] byte[] args, + uint args_len + ); } diff --git a/crates/bindings-csharp/Runtime/Internal/IIndex.cs b/crates/bindings-csharp/Runtime/Internal/IIndex.cs new file mode 100644 index 0000000000..40f9aabeff --- /dev/null +++ b/crates/bindings-csharp/Runtime/Internal/IIndex.cs @@ -0,0 +1,108 @@ +namespace SpacetimeDB.Internal; + +using System; +using System.Linq; + +public abstract class IndexBase + where Row : ITable, new() +{ + private readonly FFI.IndexId indexId; + + public IndexBase(string name) + { + var name_bytes = System.Text.Encoding.UTF8.GetBytes(name); + FFI.index_id_from_name(name_bytes, (uint)name_bytes.Length, out indexId); + } + + private static void ToParams( + Bounds bounds, + out FFI.ColId prefixElems, + out ReadOnlySpan prefix, + out ReadOnlySpan rstart, + out ReadOnlySpan rend + ) + where Bounds : IBTreeIndexBounds + { + prefixElems = new FFI.ColId(bounds.PrefixElems); + + using var s = new MemoryStream(); + using var w = new BinaryWriter(s); + bounds.Prefix(w); + var prefix_idx = (int)s.Length; + bounds.RStart(w); + var rstart_idx = (int)s.Length; + bounds.REnd(w); + var rend_idx = (int)s.Length; + + var bytes = s.GetBuffer().AsSpan(); + prefix = bytes[..prefix_idx]; + rstart = bytes[prefix_idx..rstart_idx]; + rend = bytes[rstart_idx..rend_idx]; + } + + protected IEnumerable DoFilter(Bounds bounds) + where Bounds : IBTreeIndexBounds => new RawTableIter(indexId, bounds).Parse(); + + protected uint DoDelete(Bounds bounds) + where Bounds : IBTreeIndexBounds + { + ToParams(bounds, out var prefixElems, out var prefix, out var rstart, out var rend); + FFI.datastore_delete_by_btree_scan_bsatn( + indexId, + prefix, + (uint)prefix.Length, + prefixElems, + rstart, + (uint)rstart.Length, + rend, + (uint)rend.Length, + out var out_ + ); + return out_; + } + + private class RawTableIter(FFI.IndexId indexId, Bounds bounds) + : ITable.RawTableIterBase + where Bounds : IBTreeIndexBounds + { + protected override void IterStart(out FFI.RowIter handle) + { + ToParams(bounds, out var prefixElems, out var prefix, out var rstart, out var rend); + FFI.datastore_btree_scan_bsatn( + indexId, + prefix, + (uint)prefix.Length, + prefixElems, + rstart, + (uint)rstart.Length, + rend, + (uint)rend.Length, + out handle + ); + } + } +} + +public abstract class UniqueIndex(Handle table, string name) + : IndexBase(name) + where Handle : ITableView + where Row : ITable, new() + where T : IEquatable + where RW : struct, BSATN.IReadWrite +{ + private static BTreeIndexBounds ToBounds(T key) => new(key); + + public Row? Find(T key) => DoFilter(ToBounds(key)).Cast().SingleOrDefault(); + + public bool Delete(T key) => DoDelete(ToBounds(key)) > 0; + + protected bool DoUpdate(T key, Row row) + { + if (!Delete(key)) + { + return false; + } + table.Insert(row); + return true; + } +} diff --git a/crates/bindings-csharp/Runtime/Internal/ITable.cs b/crates/bindings-csharp/Runtime/Internal/ITable.cs index 726d80ef3c..efb589facc 100644 --- a/crates/bindings-csharp/Runtime/Internal/ITable.cs +++ b/crates/bindings-csharp/Runtime/Internal/ITable.cs @@ -7,16 +7,8 @@ public interface ITable : IStructuralReadWrite { // These are the methods that codegen needs to implement. static abstract IEnumerable MakeTableDesc(ITypeRegistrar registrar); -} -public interface ITableView - where View : ITableView - where T : ITable, new() -{ - static abstract T ReadGenFields(BinaryReader reader, T row); - - // These are static helpers that codegen can use. - private abstract class RawTableIterBase + internal abstract class RawTableIterBase { public class Enumerator(FFI.RowIter handle) : IDisposable { @@ -108,29 +100,27 @@ public IEnumerable Parse() using var reader = new BinaryReader(stream); while (stream.Position < stream.Length) { - yield return IStructuralReadWrite.Read(reader); + yield return Read(reader); } } } } +} + +public interface ITableView + where View : ITableView + where T : ITable, new() +{ + static abstract T ReadGenFields(BinaryReader reader, T row); + + // These are static helpers that codegen can use. - private class RawTableIter(FFI.TableId tableId) : RawTableIterBase + private class RawTableIter(FFI.TableId tableId) : ITable.RawTableIterBase { protected override void IterStart(out FFI.RowIter handle) => FFI.datastore_table_scan_bsatn(tableId, out handle); } - private class RawTableIterByColEq(FFI.TableId tableId, FFI.ColId colId, byte[] value) - : RawTableIterBase - { - protected override void IterStart(out FFI.RowIter handle) - { - _ = (tableId, colId, value); - // Needs to be implemented via datastore_table_scan_bsatn - throw new NotImplementedException(); - } - } - // Note: this must be Lazy to ensure that we don't try to get the tableId during startup, before the module is initialized. private static readonly Lazy tableId_ = new(() => @@ -142,9 +132,23 @@ protected override void IterStart(out FFI.RowIter handle) private static FFI.TableId tableId => tableId_.Value; - public static IEnumerable Iter() => new RawTableIter(tableId).Parse(); + ulong Count { get; } - protected static T Insert(T row) + IEnumerable Iter(); + + T Insert(T row); + + bool Delete(T row); + + protected static ulong DoCount() + { + FFI.datastore_table_row_count(tableId, out var count); + return count; + } + + protected static IEnumerable DoIter() => new RawTableIter(tableId).Parse(); + + protected static T DoInsert(T row) { // Insert the row. var bytes = IStructuralReadWrite.ToBytes(row); @@ -157,39 +161,10 @@ protected static T Insert(T row) return View.ReadGenFields(reader, row); } - protected readonly ref struct ColEq + protected static bool DoDelete(T row) { - private readonly FFI.ColId colId; - private readonly byte[] value; - - private ColEq(FFI.ColId colId, byte[] value) - { - this.colId = colId; - this.value = value; - } - - public static ColEq Where(ushort colId, TCol colValue, TColRW rw) - where TColRW : IReadWrite - { - return new(new FFI.ColId(colId), IStructuralReadWrite.ToBytes(rw, colValue)); - } - - // Note: do not inline FindBy from the Codegen as a helper API here. - // C# handles nullables on generics in a weird way, and will break if [SpacetimeDB.Type] is used on a struct. - public IEnumerable Iter() => new RawTableIterByColEq(tableId, colId, value).Parse(); - - // Needs to be implemented via `datastore_delete_all_by_eq_bsatn`. - public bool Delete() => throw new NotImplementedException(); - - public bool Update(T row) - { - // Just like in Rust bindings, updating is just deleting and inserting for now. - if (!Delete()) - { - return false; - } - Insert(row); - return true; - } + var bytes = IStructuralReadWrite.ToBytes(row); + FFI.datastore_delete_all_by_eq_bsatn(tableId, bytes, (uint)bytes.Length, out var out_); + return out_ > 0; } } diff --git a/crates/bindings-csharp/Runtime/Internal/Module.cs b/crates/bindings-csharp/Runtime/Internal/Module.cs index 109b9bb096..e912a10612 100644 --- a/crates/bindings-csharp/Runtime/Internal/Module.cs +++ b/crates/bindings-csharp/Runtime/Internal/Module.cs @@ -5,16 +5,6 @@ namespace SpacetimeDB.Internal; using SpacetimeDB; using SpacetimeDB.BSATN; -partial class RawConstraintDefV8 -{ - public RawConstraintDefV8(string tableName, ushort colIndex, string colName, ColumnAttrs attrs) - : this( - ConstraintName: $"ct_{tableName}_{colName}_{attrs}", - Constraints: (byte)attrs, - Columns: [colIndex] - ) { } -} - partial class RawModuleDefV8 { // Note: this intends to generate a valid identifier, but it's not guaranteed to be unique as it's not proper mangling. diff --git a/crates/bindings-csharp/Runtime/Internal/Timing.cs b/crates/bindings-csharp/Runtime/Internal/Timing.cs deleted file mode 100644 index d703381876..0000000000 --- a/crates/bindings-csharp/Runtime/Internal/Timing.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace SpacetimeDB.Internal; - -using System.Runtime.InteropServices; - -// We store time information in microseconds in internal usages. -// -// These utils allow to encode it as such in FFI and BSATN contexts -// and convert to standard C# types. - -[StructLayout(LayoutKind.Sequential)] // we should be able to use it in FFI -[SpacetimeDB.Type] // we should be able to encode it to BSATN too -public partial struct DateTimeOffsetRepr(DateTimeOffset time) -{ - public ulong MicrosecondsSinceEpoch = (ulong)time.Ticks / 10; - - internal readonly DateTimeOffset ToStd() => - DateTimeOffset.UnixEpoch.AddTicks(10 * (long)MicrosecondsSinceEpoch); -} - -[StructLayout(LayoutKind.Sequential)] // we should be able to use it in FFI -[SpacetimeDB.Type] // we should be able to encode it to BSATN too -public partial struct TimeSpanRepr(TimeSpan duration) -{ - public ulong Microseconds = (ulong)duration.Ticks / 10; - - internal readonly TimeSpan ToStd() => TimeSpan.FromTicks(10 * (long)Microseconds); -} diff --git a/crates/bindings-csharp/Runtime/Runtime.cs b/crates/bindings-csharp/Runtime/Runtime.cs deleted file mode 100644 index badb81a053..0000000000 --- a/crates/bindings-csharp/Runtime/Runtime.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace SpacetimeDB; - -using System.Runtime.CompilerServices; -using SpacetimeDB.BSATN; -using SpacetimeDB.Internal; - -// [SpacetimeDB.Type] - we have custom representation of time in microseconds, so implementing BSATN manually -public abstract partial record ScheduleAt - : SpacetimeDB.TaggedEnum<(DateTimeOffset Time, TimeSpan Interval)> -{ - // Manual expansion of what would be otherwise generated by the [SpacetimeDB.Type] codegen. - public sealed record Time(DateTimeOffset Time_) : ScheduleAt; - - public sealed record Interval(TimeSpan Interval_) : ScheduleAt; - - public static implicit operator ScheduleAt(DateTimeOffset time) => new Time(time); - - public static implicit operator ScheduleAt(TimeSpan interval) => new Interval(interval); - - public readonly partial struct BSATN : IReadWrite - { - [SpacetimeDB.Type] - private partial record ScheduleAtRepr - : SpacetimeDB.TaggedEnum<(DateTimeOffsetRepr Time, TimeSpanRepr Interval)>; - - private static readonly ScheduleAtRepr.BSATN ReprBSATN = new(); - - public ScheduleAt Read(BinaryReader reader) => - ReprBSATN.Read(reader) switch - { - ScheduleAtRepr.Time(var timeRepr) => new Time(timeRepr.ToStd()), - ScheduleAtRepr.Interval(var intervalRepr) => new Interval(intervalRepr.ToStd()), - _ => throw new SwitchExpressionException(), - }; - - public void Write(BinaryWriter writer, ScheduleAt value) - { - ReprBSATN.Write( - writer, - value switch - { - Time(var time) => new ScheduleAtRepr.Time(new(time)), - Interval(var interval) => new ScheduleAtRepr.Interval(new(interval)), - _ => throw new SwitchExpressionException(), - } - ); - } - - public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => - // Constructing a custom one instead of ScheduleAtRepr.GetAlgebraicType() - // to avoid leaking the internal *Repr wrappers in generated SATS. - new AlgebraicType.Sum( - [ - new("Time", new AlgebraicType.U64(default)), - new("Interval", new AlgebraicType.U64(default)), - ] - ); - } -} diff --git a/crates/bindings-csharp/Runtime/bindings.c b/crates/bindings-csharp/Runtime/bindings.c index 0a2b03d900..43c5dfdd28 100644 --- a/crates/bindings-csharp/Runtime/bindings.c +++ b/crates/bindings-csharp/Runtime/bindings.c @@ -15,6 +15,7 @@ OPAQUE_TYPEDEF(Status, uint16_t); OPAQUE_TYPEDEF(TableId, uint32_t); +OPAQUE_TYPEDEF(IndexId, uint32_t); OPAQUE_TYPEDEF(ColId, uint16_t); OPAQUE_TYPEDEF(IndexType, uint8_t); OPAQUE_TYPEDEF(LogLevel, uint8_t); @@ -36,44 +37,55 @@ OPAQUE_TYPEDEF(ConsoleTimerId, uint32_t); #define IMPORT(ret, name, params, args) STDB_EXTERN(name) ret name params; #endif -IMPORT(void, console_log, - (LogLevel level, const uint8_t* target_ptr, uint32_t target_len, - const uint8_t* filename_ptr, uint32_t filename_len, uint32_t line_number, - const uint8_t* message_ptr, uint32_t message_len), - (level, target_ptr, target_len, filename_ptr, filename_len, line_number, - message_ptr, message_len)); - IMPORT(Status, table_id_from_name, (const uint8_t* name, uint32_t name_len, TableId* id), (name, name_len, id)); +IMPORT(Status, index_id_from_name, + (const uint8_t* name, uint32_t name_len, IndexId* id), + (name, name_len, id)); IMPORT(Status, datastore_table_row_count, (TableId table_id, uint64_t* count), (table_id, count)); -IMPORT(Status, datastore_table_scan_bsatn, (TableId table_id, RowIter* iter), +IMPORT(Status, datastore_table_scan_bsatn, + (TableId table_id, RowIter* iter), (table_id, iter)); -IMPORT(Status, datastore_insert_bsatn, (TableId table_id, const uint8_t* row_ptr, size_t* row_len_ptr), - (table_id, row_ptr, row_len_ptr)); +IMPORT(Status, datastore_btree_scan_bsatn, + (IndexId index_id, const uint8_t* prefix, uint32_t prefix_len, ColId prefix_elems, + const uint8_t* rstart, uint32_t rstart_len, const uint8_t* rend, uint32_t rend_len, RowIter* iter), + (index_id, prefix, prefix_len, prefix_elems, rstart, rstart_len, rend, rend_len, iter)); IMPORT(int16_t, row_iter_bsatn_advance, (RowIter iter, uint8_t* buffer_ptr, size_t* buffer_len_ptr), (iter, buffer_ptr, buffer_len_ptr)); IMPORT(uint16_t, row_iter_bsatn_close, (RowIter iter), (iter)); +IMPORT(Status, datastore_insert_bsatn, (TableId table_id, const uint8_t* row_ptr, size_t* row_len_ptr), + (table_id, row_ptr, row_len_ptr)); +IMPORT(Status, datastore_delete_by_btree_scan_bsatn, + (IndexId index_id, const uint8_t* prefix, uint32_t prefix_len, ColId prefix_elems, + const uint8_t* rstart, uint32_t rstart_len, const uint8_t* rend, uint32_t rend_len, uint32_t* num_deleted), + (index_id, prefix, prefix_len, prefix_elems, rstart, rstart_len, rend, rend_len, num_deleted)); IMPORT(Status, datastore_delete_all_by_eq_bsatn, (TableId table_id, const uint8_t* rel_ptr, uint32_t rel_len, uint32_t* num_deleted), (table_id, rel_ptr, rel_len, num_deleted)); -IMPORT(void, volatile_nonatomic_schedule_immediate, - (const uint8_t* name, size_t name_len, const uint8_t* args, size_t args_len), - (name, name_len, args, args_len)); IMPORT(int16_t, bytes_source_read, (BytesSource source, uint8_t* buffer_ptr, size_t* buffer_len_ptr), (source, buffer_ptr, buffer_len_ptr)); IMPORT(uint16_t, bytes_sink_write, (BytesSink sink, const uint8_t* buffer_ptr, size_t* buffer_len_ptr), (sink, buffer_ptr, buffer_len_ptr)); +IMPORT(void, console_log, + (LogLevel level, const uint8_t* target_ptr, uint32_t target_len, + const uint8_t* filename_ptr, uint32_t filename_len, uint32_t line_number, + const uint8_t* message_ptr, uint32_t message_len), + (level, target_ptr, target_len, filename_ptr, filename_len, line_number, + message_ptr, message_len)); IMPORT(ConsoleTimerId, console_timer_start, (const uint8_t* name, size_t name_len), (name, name_len)); IMPORT(Status, console_timer_end, (ConsoleTimerId stopwatch_id), (stopwatch_id)); +IMPORT(void, volatile_nonatomic_schedule_immediate, + (const uint8_t* name, size_t name_len, const uint8_t* args, size_t args_len), + (name, name_len, args, args_len)); #ifndef EXPERIMENTAL_WASM_AOT static MonoClass* ffi_class; diff --git a/crates/cli/src/subcommands/generate/csharp.rs b/crates/cli/src/subcommands/generate/csharp.rs index 5eaaf0d52f..e19c7d9b0a 100644 --- a/crates/cli/src/subcommands/generate/csharp.rs +++ b/crates/cli/src/subcommands/generate/csharp.rs @@ -8,6 +8,7 @@ use convert_case::{Case, Casing}; use spacetimedb_lib::sats::{AlgebraicType, AlgebraicTypeRef, ArrayType, ProductType, SumType}; use spacetimedb_lib::ReducerDef; use spacetimedb_primitives::ColList; +use spacetimedb_schema::def::{BTreeAlgorithm, IndexAlgorithm}; use spacetimedb_schema::schema::TableSchema; use super::code_indenter::CodeIndenter; @@ -56,7 +57,6 @@ fn ty_fmt<'a>(ctx: &'a GenCtx, ty: &'a AlgebraicType, namespace: &'a str) -> imp } // Arbitrary product types should fail. AlgebraicType::Product(_) => unimplemented!(), - ty if ty.is_bytes() => f.write_str("byte[]"), AlgebraicType::Array(ArrayType { elem_ty }) => { write!( f, @@ -104,8 +104,6 @@ fn default_init(ctx: &GenCtx, ty: &AlgebraicType) -> Option<&'static str> { AlgebraicType::Sum(sum_type) if sum_type.is_option() || sum_type.is_simple_enum() => None, // TODO: generate some proper default here (what would it be for tagged enums?). AlgebraicType::Sum(_) => Some("null!"), - // Byte arrays must be initialized to an empty array. - ty if ty.is_bytes() => Some("Array.Empty()"), // For product types, arrays, and maps, we can use the default constructor. AlgebraicType::Product(_) | AlgebraicType::Array(_) | AlgebraicType::Map(_) => Some("new()"), // Strings must have explicit default value of "". @@ -301,26 +299,14 @@ fn autogen_csharp_product_table_common( ) -> String { let mut output = CsharpAutogen::new( namespace, - &[ - "System.Collections.Generic", - "System.Linq", - "System.Runtime.Serialization", - ], + &["System.Collections.Generic", "System.Runtime.Serialization"], ); writeln!(output, "[SpacetimeDB.Type]"); writeln!(output, "[DataContract]"); write!(output, "public partial class {name}"); - if let Some(schema) = &schema { - write!( - output, - " : SpacetimeDB.{parent}<{name}, {namespace}.ReducerEvent>", - parent = if schema.primary_key.is_some() { - "DatabaseTableWithPrimaryKey" - } else { - "DatabaseTable" - } - ); + if schema.is_some() { + write!(output, " : IDatabaseRow"); } writeln!(output); indented_block(&mut output, |output| { @@ -378,57 +364,6 @@ fn autogen_csharp_product_table_common( }); writeln!(output); } - - // If this is a table, we want to generate event accessor and indexes - if let Some(schema) = &schema { - let constraints = schema.backcompat_column_constraints(); - let mut unique_indexes = Vec::new(); - // Declare custom index dictionaries - for col in schema.columns() { - let field_name = col.col_name.replace("r#", "").to_case(Case::Pascal); - if !constraints[&ColList::new(col.col_pos)].has_unique() { - continue; - } - let type_name = ty_fmt(ctx, &col.col_type, namespace); - writeln!( - output, - "private static Dictionary<{type_name}, {name}> {field_name}_Index = new(16);" - ); - unique_indexes.push(field_name); - } - if !unique_indexes.is_empty() { - writeln!(output); - // OnInsert method for updating indexes - writeln!(output, "public override void InternalOnValueInserted()"); - indented_block(output, |output| { - for col in schema.columns() { - let field_name = col.col_name.replace("r#", "").to_case(Case::Pascal); - if !constraints[&ColList::new(col.col_pos)].has_unique() { - continue; - } - writeln!(output, "{field_name}_Index[{field_name}] = this;"); - } - }); - writeln!(output); - // OnDelete method for updating indexes - writeln!(output, "public override void InternalOnValueDeleted()"); - indented_block(output, |output| { - for col in schema.columns() { - let field_name = col.col_name.replace("r#", "").to_case(Case::Pascal); - if !constraints[&ColList::new(col.col_pos)].has_unique() { - continue; - } - writeln!(output, "{field_name}_Index.Remove({field_name});"); - } - }); - writeln!(output); - } - - // If this is a table, we want to include functions for accessing the table data - // Insert the funcs for accessing this struct - autogen_csharp_access_funcs_for_struct(output, name, product_type, name, schema); - writeln!(output); - } }); output.into_inner() @@ -441,43 +376,55 @@ fn indented_block(output: &mut CodeIndenter, f: impl FnOnce(&mut Code res } +fn csharp_field_type(field_type: &AlgebraicType) -> Option<&str> { + match field_type { + AlgebraicType::Product(product) => { + if product.is_identity() { + Some("SpacetimeDB.Identity") + } else if product.is_address() { + Some("SpacetimeDB.Address") + } else { + None + } + } + AlgebraicType::Sum(_) | AlgebraicType::Ref(_) => None, + ty => match scalar_or_string_name(ty) { + Some(ty) => Some(ty), + _ => None, + }, + } +} + fn autogen_csharp_access_funcs_for_struct( output: &mut CodeIndenter, struct_name_pascal_case: &str, product_type: &ProductType, - _table_name: &str, + table_name: &str, schema: &TableSchema, ) { + let csharp_table_name = table_name.to_case(Case::Pascal); let constraints = schema.backcompat_column_constraints(); for col in schema.columns() { - let is_unique = constraints[&ColList::new(col.col_pos)].has_unique(); + if !constraints[&ColList::new(col.col_pos)].has_unique() { + continue; + } let field = &product_type.elements[col.col_pos.idx()]; let field_name = field.name.as_ref().expect("autogen'd tuples should have field names"); let field_type = &field.algebraic_type; let csharp_field_name_pascal = field_name.replace("r#", "").to_case(Case::Pascal); - - let csharp_field_type = match field_type { - AlgebraicType::Product(product) => { - if product.is_identity() { - "SpacetimeDB.Identity" - } else if product.is_address() { - "SpacetimeDB.Address" - } else { - continue; - } - } - AlgebraicType::Sum(_) | AlgebraicType::Ref(_) => continue, - ty => match scalar_or_string_name(ty) { - Some(ty) => ty, - _ => continue, - }, + let csharp_field_type = match csharp_field_type(field_type) { + None => continue, + Some(x) => x, }; - - if is_unique { + writeln!( + output, + "public readonly ref struct {csharp_field_name_pascal}UniqueIndex" + ); + indented_block(output, |output| { writeln!( output, - "public static {struct_name_pascal_case}? FindBy{csharp_field_name_pascal}({csharp_field_type} value)" + "public {struct_name_pascal_case}? Find({csharp_field_type} value)" ); indented_block(output, |output| { writeln!( @@ -487,30 +434,82 @@ fn autogen_csharp_access_funcs_for_struct( writeln!(output, "return r;"); }); writeln!(output); - } - + }); + writeln!(output); writeln!( output, - "public static IEnumerable<{struct_name_pascal_case}> FilterBy{csharp_field_name_pascal}({csharp_field_type} value)" + "public {csharp_field_name_pascal}UniqueIndex {csharp_field_name_pascal} => new();" ); - indented_block(output, |output| { - if is_unique { - // Yield a single item iff `FindBy` returns a non-null record. - writeln!(output, "if (FindBy{csharp_field_name_pascal}(value) is {{}} found)"); + writeln!(output); + } + + for idx in &schema.indexes { + match &idx.index_algorithm { + IndexAlgorithm::BTree(BTreeAlgorithm { columns }) => { + let col_pos = columns.head().unwrap().idx(); + if constraints[&ColList::new(col_pos.into())].has_unique() { + continue; + } + + let field = &product_type.elements[col_pos]; + let field_name = field.name.as_ref().expect("autogen'd tuples should have field names"); + let field_type = &field.algebraic_type; + let csharp_field_name_pascal = field_name.replace("r#", "").to_case(Case::Pascal); + // NOTE skipping the btree prefix and the table name from the index name + let csharp_index_name = (&idx.index_name[table_name.len() + 7..]).to_case(Case::Pascal); + let csharp_field_type = match csharp_field_type(field_type) { + None => continue, + Some(x) => x, + }; + writeln!(output, "public class {csharp_index_name}Index"); indented_block(output, |output| { - writeln!(output, "yield return found;"); + writeln!(output, "{csharp_table_name}Handle Handle;"); + writeln!( + output, + "internal {csharp_index_name}Index({csharp_table_name}Handle handle) => Handle = handle;" + ); + writeln!( + output, + "public IEnumerable<{struct_name_pascal_case}> Filter({csharp_field_type} value) =>" + ); + { + indent_scope!(output); + writeln!(output, "Handle.Query(x => x.{csharp_field_name_pascal} == value);"); + } }); - } else { - writeln!(output, "return Query(x => x.{csharp_field_name_pascal} == value);"); + writeln!(output); + writeln!( + output, + "public {csharp_index_name}Index {csharp_index_name} {{ get; init; }}" + ); + writeln!(output); } - }); - writeln!(output); + _ => todo!(), + } } + writeln!(output, "internal {csharp_table_name}Handle()"); + indented_block(output, |output| { + for idx in &schema.indexes { + match &idx.index_algorithm { + IndexAlgorithm::BTree(BTreeAlgorithm { columns }) => { + let col_pos = columns.head().unwrap().idx(); + if constraints[&ColList::new(col_pos.into())].has_unique() { + continue; + } + } + _ => continue, + } + + let csharp_index_name = (&idx.index_name[table_name.len() + 7..]).to_case(Case::Pascal); + writeln!(output, "{csharp_index_name} = new(this);"); + } + }); + if let Some(primary_col_index) = schema.pk() { writeln!( output, - "public override object GetPrimaryKeyValue() => {col_name_pascal_case};", + "public override object GetPrimaryKey(IDatabaseRow row) => (({struct_name_pascal_case})row).{col_name_pascal_case};", col_name_pascal_case = primary_col_index.col_name.replace("r#", "").to_case(Case::Pascal) ); } @@ -518,113 +517,49 @@ fn autogen_csharp_access_funcs_for_struct( pub fn autogen_csharp_reducer(ctx: &GenCtx, reducer: &ReducerDef, namespace: &str) -> String { let func_name = &*reducer.name; - // let reducer_pascal_name = func_name.to_case(Case::Pascal); let func_name_pascal_case = func_name.to_case(Case::Pascal); let mut output = CsharpAutogen::new(namespace, &[]); //Args struct writeln!(output, "[SpacetimeDB.Type]"); - writeln!( - output, - "public partial class {func_name_pascal_case}ArgsStruct : IReducerArgs" - ); - - let mut func_params: String = String::new(); - let mut field_inits: String = String::new(); - + writeln!(output, "public partial class {func_name_pascal_case} : IReducerArgs"); indented_block(&mut output, |output| { - writeln!( - output, - "ReducerType IReducerArgs.ReducerType => ReducerType.{func_name_pascal_case};" - ); - writeln!(output, "string IReducerArgsBase.ReducerName => \"{func_name}\";"); - writeln!(output, "bool IReducerArgs.InvokeHandler(ReducerEvent reducerEvent) => Reducer.On{func_name_pascal_case}(reducerEvent, this);"); + writeln!(output, "string IReducerArgs.ReducerName => \"{func_name}\";"); if !reducer.args.is_empty() { writeln!(output); } - for (arg_i, arg) in reducer.args.iter().enumerate() { + for arg in reducer.args.iter() { let name = arg .name .as_deref() .unwrap_or_else(|| panic!("reducer args should have names: {func_name}")); - let arg_name = name.to_case(Case::Camel); - let field_name = name.to_case(Case::Pascal); let arg_type_str = ty_fmt(ctx, &arg.algebraic_type, namespace); + let field_name = name.to_case(Case::Pascal); - if arg_i != 0 { - func_params.push_str(", "); - field_inits.push_str(", "); - } write!(output, "public {arg_type_str} {field_name}"); // Skip default initializer if it's the same as the implicit default. if let Some(default) = default_init(ctx, &arg.algebraic_type) { write!(output, " = {default}"); } writeln!(output, ";"); - write!(func_params, "{arg_type_str} {arg_name}").unwrap(); - write!(field_inits, "{field_name} = {arg_name}").unwrap(); } }); - writeln!(output); - - writeln!(output, "public static partial class Reducer"); - indented_block(&mut output, |output| { - let delegate_separator = if !reducer.args.is_empty() { ", " } else { "" }; - writeln!( - output, - "public delegate void {func_name_pascal_case}Handler(ReducerEvent reducerEvent{delegate_separator}{func_params});" - ); - writeln!( - output, - "public static event {func_name_pascal_case}Handler? On{func_name_pascal_case}Event;" - ); - - writeln!(output); - - writeln!(output, "public static void {func_name_pascal_case}({func_params})"); - indented_block(output, |output| { - writeln!( - output, - "SpacetimeDBClient.instance.InternalCallReducer(new {func_name_pascal_case}ArgsStruct {{ {field_inits} }});" - ); - }); - writeln!(output); - - writeln!( - output, - "public static bool On{func_name_pascal_case}(ReducerEvent reducerEvent, {func_name_pascal_case}ArgsStruct args)" - ); - indented_block(output, |output| { - writeln!(output, "if (On{func_name_pascal_case}Event == null) return false;"); - writeln!(output, "On{func_name_pascal_case}Event("); - // Write out arguments one per line - { - indent_scope!(output); - write!(output, "reducerEvent"); - for (i, arg) in reducer.args.iter().enumerate() { - writeln!(output, ","); - let arg_name = arg - .name - .as_deref() - .map_or_else(|| format!("Arg{i}"), |name| name.to_case(Case::Pascal)); - write!(output, "args.{arg_name}"); - } - writeln!(output); - } - writeln!(output, ");"); - writeln!(output, "return true;"); - }); - }); - writeln!(output); - output.into_inner() } pub fn autogen_csharp_globals(ctx: &GenCtx, items: &[GenItem], namespace: &str) -> Vec<(String, String)> { let mut results = Vec::new(); + let tables = items.iter().filter_map(|i| { + if let GenItem::Table(table) = i { + Some(table) + } else { + None + } + }); + let reducers: Vec<&ReducerDef> = items .iter() .filter_map(|i| { @@ -640,144 +575,294 @@ pub fn autogen_csharp_globals(ctx: &GenCtx, items: &[GenItem], namespace: &str) .map(|reducer| reducer.name.deref().to_case(Case::Pascal)) .collect(); - let mut output = CsharpAutogen::new(namespace, &["SpacetimeDB.ClientApi"]); + let mut output = CsharpAutogen::new(namespace, &["SpacetimeDB.ClientApi", "System.Collections.Generic"]); - writeln!(output, "public enum ReducerType"); + writeln!(output, "public sealed class RemoteTables"); indented_block(&mut output, |output| { - writeln!(output, "None,"); - for reducer_name in &reducer_names { - writeln!(output, "{reducer_name},"); + for table in tables { + let schema = &table.schema; + let name = &schema.table_name; + let csharp_name = name.as_ref().to_case(Case::Pascal); + let table_type = csharp_typename(ctx, table.data); + + writeln!( + output, + "public class {csharp_name}Handle : RemoteTableHandle" + ); + indented_block(output, |output| { + // If this is a table, we want to generate event accessor and indexes + let constraints = schema.backcompat_column_constraints(); + let mut unique_indexes = Vec::new(); + // Declare custom index dictionaries + for col in schema.columns() { + let field_name = col.col_name.replace("r#", "").to_case(Case::Pascal); + if !constraints[&ColList::new(col.col_pos)].has_unique() { + continue; + } + let type_name = ty_fmt(ctx, &col.col_type, namespace); + writeln!( + output, + "private static Dictionary<{type_name}, {table_type}> {field_name}_Index = new(16);" + ); + unique_indexes.push(field_name); + } + if !unique_indexes.is_empty() { + writeln!(output); + // OnInsert method for updating indexes + writeln!( + output, + "public override void InternalInvokeValueInserted(IDatabaseRow row)" + ); + indented_block(output, |output| { + writeln!(output, "var value = ({table_type})row;"); + for col in schema.columns() { + let field_name = col.col_name.replace("r#", "").to_case(Case::Pascal); + if !constraints[&ColList::new(col.col_pos)].has_unique() { + continue; + } + writeln!(output, "{field_name}_Index[value.{field_name}] = value;"); + } + }); + writeln!(output); + // OnDelete method for updating indexes + writeln!( + output, + "public override void InternalInvokeValueDeleted(IDatabaseRow row)" + ); + indented_block(output, |output| { + for col in schema.columns() { + let field_name = col.col_name.replace("r#", "").to_case(Case::Pascal); + if !constraints[&ColList::new(col.col_pos)].has_unique() { + continue; + } + writeln!(output, "{field_name}_Index.Remove((({table_type})row).{field_name});"); + } + }); + writeln!(output); + } + + // If this is a table, we want to include functions for accessing the table data + // Insert the funcs for accessing this struct + let product_type = ctx.typespace[table.data].as_product().unwrap(); + autogen_csharp_access_funcs_for_struct(output, table_type, product_type, name, schema); + writeln!(output); + }); + writeln!(output); + writeln!(output, "public readonly {csharp_name}Handle {csharp_name} = new();"); + writeln!(output); } }); writeln!(output); - writeln!(output, "public interface IReducerArgs : IReducerArgsBase"); + writeln!(output, "public sealed class RemoteReducers : RemoteBase"); indented_block(&mut output, |output| { - writeln!(output, "ReducerType ReducerType {{ get; }}"); - writeln!(output, "bool InvokeHandler(ReducerEvent reducerEvent);"); - }); - writeln!(output); + writeln!(output, "internal RemoteReducers(DbConnection conn) : base(conn) {{}}"); + + for reducer in &reducers { + let func_name = &*reducer.name; + let func_name_pascal_case = func_name.to_case(Case::Pascal); + let delegate_separator = if !reducer.args.is_empty() { ", " } else { "" }; + + let mut func_params: String = String::new(); + let mut field_inits: String = String::new(); + + for (arg_i, arg) in reducer.args.iter().enumerate() { + if arg_i != 0 { + func_params.push_str(", "); + field_inits.push_str(", "); + } + + let name = arg + .name + .as_deref() + .unwrap_or_else(|| panic!("reducer args should have names: {func_name}")); + let arg_type_str = ty_fmt(ctx, &arg.algebraic_type, namespace); + let arg_name = name.to_case(Case::Camel); + let field_name = name.to_case(Case::Pascal); + + write!(func_params, "{arg_type_str} {arg_name}").unwrap(); + write!(field_inits, "{field_name} = {arg_name}").unwrap(); + } - writeln!(output, "public partial class ReducerEvent : ReducerEventBase"); - indented_block(&mut output, |output| { - writeln!(output, "public IReducerArgs? Args {{ get; }}"); - writeln!(output); - writeln!(output, "public string ReducerName => Args?.ReducerName ?? \"\";"); - writeln!(output); - writeln!( - output, - r#"[Obsolete("ReducerType is deprecated, please match directly on type of .Args instead.")]"# - ); - writeln!( - output, - "public ReducerType Reducer => Args?.ReducerType ?? ReducerType.None;" - ); - writeln!(output); - writeln!( - output, - "public ReducerEvent(IReducerArgs? args) : base() => Args = args;" - ); - writeln!( - output, - "public ReducerEvent(TransactionUpdate update, IReducerArgs? args) : base(update) => Args = args;" - ); - writeln!(output); - // Properties for reducer args - for reducer_name in &reducer_names { writeln!( output, - r#"[Obsolete("Accessors that implicitly cast `Args` are deprecated, please match `Args` against the desired type explicitly instead.")]"# + "public delegate void {func_name_pascal_case}Handler(EventContext ctx{delegate_separator}{func_params});" ); writeln!( output, - "public {reducer_name}ArgsStruct {reducer_name}Args => ({reducer_name}ArgsStruct)Args!;" + "public event {func_name_pascal_case}Handler? On{func_name_pascal_case};" + ); + writeln!(output); + + writeln!(output, "public void {func_name_pascal_case}({func_params})"); + indented_block(output, |output| { + writeln!( + output, + "conn.InternalCallReducer(new {func_name_pascal_case} {{ {field_inits} }});" + ); + }); + writeln!(output); + + writeln!( + output, + "public bool Invoke{func_name_pascal_case}(EventContext ctx, {func_name_pascal_case} args)" ); + indented_block(output, |output| { + writeln!(output, "if (On{func_name_pascal_case} == null) return false;"); + writeln!(output, "On{func_name_pascal_case}("); + // Write out arguments one per line + { + indent_scope!(output); + write!(output, "ctx"); + for (i, arg) in reducer.args.iter().enumerate() { + writeln!(output, ","); + let arg_name = arg + .name + .as_deref() + .map_or_else(|| format!("Arg{i}"), |name| name.to_case(Case::Pascal)); + write!(output, "args.{arg_name}"); + } + writeln!(output); + } + writeln!(output, ");"); + writeln!(output, "return true;"); + }); } + }); + writeln!(output); + + writeln!( + output, + "public partial record EventContext : DbContext, IEventContext" + ); + indented_block(&mut output, |output| { + writeln!(output, "public readonly RemoteReducers Reducers;"); + writeln!(output, "public readonly Event Event;"); writeln!(output); - // Event handlers. writeln!( output, - "public override bool InvokeHandler() => Args?.InvokeHandler(this) ?? false;" + "internal EventContext(DbConnection conn, Event reducerEvent) : base(conn.Db)" ); + indented_block(output, |output| { + writeln!(output, "Reducers = conn.Reducers;"); + writeln!(output, "Event = reducerEvent;"); + }); }); writeln!(output); + writeln!(output, "[Type]"); + writeln!(output, "public partial record Reducer : TaggedEnum<("); + { + indent_scope!(output); + for reducer_name in &reducer_names { + writeln!(output, "{reducer_name} {reducer_name},"); + } + writeln!(output, "Unit StdbNone,"); + writeln!(output, "Unit StdbIdentityConnected,"); + writeln!(output, "Unit StdbIdentityDisconnected"); + } + writeln!(output, ")>;"); + writeln!( output, - "public class SpacetimeDBClient : SpacetimeDBClientBase" + "public class DbConnection : DbConnectionBase" ); indented_block(&mut output, |output| { - writeln!(output, "protected SpacetimeDBClient()"); + writeln!(output, "public readonly RemoteTables Db = new();"); + writeln!(output, "public readonly RemoteReducers Reducers;"); + writeln!(output); + + writeln!(output, "public DbConnection()"); indented_block(output, |output| { + writeln!(output, "Reducers = new(this);"); + writeln!(output); + for item in items { if let GenItem::Table(table) = item { writeln!( output, - "clientDB.AddTable<{table_name}>();", - table_name = csharp_typename(ctx, table.data) + "clientDB.AddTable<{table_type}>(\"{table_name}\", Db.{csharp_table_name});", + table_type = csharp_typename(ctx, table.data), + table_name = table.schema.table_name, + csharp_table_name = table.schema.table_name.as_ref().to_case(Case::Pascal) ); } } }); writeln!(output); - writeln!(output, "public static readonly SpacetimeDBClient instance = new();"); - writeln!(output); - - writeln!( - output, - "protected override ReducerEvent ReducerEventFromDbEvent(TransactionUpdate update)" - ); + writeln!(output, "protected override Reducer ToReducer(TransactionUpdate update)"); indented_block(output, |output| { writeln!(output, "var encodedArgs = update.ReducerCall.Args;"); - writeln!(output, "IReducerArgs? args = update.ReducerCall.ReducerName switch {{"); + writeln!(output, "return update.ReducerCall.ReducerName switch {{"); { indent_scope!(output); for (reducer, reducer_name) in std::iter::zip(&reducers, &reducer_names) { let reducer_str_name = &reducer.name; writeln!( output, - "\"{reducer_str_name}\" => BSATNHelpers.Decode<{reducer_name}ArgsStruct>(encodedArgs)," + "\"{reducer_str_name}\" => new Reducer.{reducer_name}(BSATNHelpers.Decode<{reducer_name}>(encodedArgs))," ); } - writeln!(output, "\"\" => null,"); - writeln!(output, "\"__identity_connected__\" => null,"); - writeln!(output, "\"__identity_disconnected__\" => null,"); - writeln!(output, "\"\" => null,"); //Transaction from CLI command + writeln!(output, "\"\" => new Reducer.StdbNone(default),"); + writeln!( + output, + "\"__identity_connected__\" => new Reducer.StdbIdentityConnected(default)," + ); + writeln!( + output, + "\"__identity_disconnected__\" => new Reducer.StdbIdentityDisconnected(default)," + ); + writeln!(output, "\"\" => new Reducer.StdbNone(default),"); //Transaction from CLI command writeln!( output, r#"var reducer => throw new ArgumentOutOfRangeException("Reducer", $"Unknown reducer {{reducer}}")"# ); } writeln!(output, "}};"); - writeln!(output, "return new ReducerEvent(update, args);"); }); - }); - - results.push(("_Globals/SpacetimeDBClient.cs".to_owned(), output.into_inner())); + writeln!(output); - // Note: Unity requires script classes to have the same name as the file they are in. - // That's why we're generating a separate file for Unity-specific code. + writeln!( + output, + "protected override IEventContext ToEventContext(Event reducerEvent) =>" + ); + writeln!(output, "new EventContext(this, reducerEvent);"); + writeln!(output); - let mut output = CsharpAutogen::new(namespace, &[]); + writeln!( + output, + "protected override bool Dispatch(IEventContext context, Reducer reducer)" + ); + indented_block(output, |output| { + writeln!(output, "var eventContext = (EventContext)context;"); + writeln!(output, "return reducer switch {{"); + { + indent_scope!(output); + for reducer_name in &reducer_names { + writeln!( + output, + "Reducer.{reducer_name}(var args) => Reducers.Invoke{reducer_name}(eventContext, args)," + ); + } + writeln!(output, "Reducer.StdbNone or"); + writeln!(output, "Reducer.StdbIdentityConnected or"); + writeln!(output, "Reducer.StdbIdentityDisconnected => true,"); + writeln!( + output, + r#"_ => throw new ArgumentOutOfRangeException("Reducer", $"Unknown reducer {{reducer}}")"# + ); + } + writeln!(output, "}};"); + }); + writeln!(output); - writeln!(output, "// This class is only used in Unity projects."); - writeln!( - output, - "// Attach this to a gameobject in your scene to use SpacetimeDB." - ); - writeln!(output, "#if UNITY_5_3_OR_NEWER"); - writeln!(output, "public class UnityNetworkManager : UnityEngine.MonoBehaviour"); - indented_block(&mut output, |output| { writeln!( output, - "private void OnDestroy() => SpacetimeDBClient.instance.Close();" + "public SubscriptionBuilder SubscriptionBuilder() => new(this);" ); - writeln!(output, "private void Update() => SpacetimeDBClient.instance.Update();"); }); - writeln!(output, "#endif"); - - results.push(("_Globals/UnityNetworkManager.cs".to_owned(), output.into_inner())); + results.push(("_Globals/SpacetimeDBClient.cs".to_owned(), output.into_inner())); results } diff --git a/crates/cli/tests/snapshots/codegen__codegen_csharp.snap b/crates/cli/tests/snapshots/codegen__codegen_csharp.snap index ccdab7b3a6..4e82c6af79 100644 --- a/crates/cli/tests/snapshots/codegen__codegen_csharp.snap +++ b/crates/cli/tests/snapshots/codegen__codegen_csharp.snap @@ -14,36 +14,12 @@ using System; namespace SpacetimeDB { [SpacetimeDB.Type] - public partial class AddPlayerArgsStruct : IReducerArgs + public partial class AddPlayer : IReducerArgs { - ReducerType IReducerArgs.ReducerType => ReducerType.AddPlayer; - string IReducerArgsBase.ReducerName => "add_player"; - bool IReducerArgs.InvokeHandler(ReducerEvent reducerEvent) => Reducer.OnAddPlayer(reducerEvent, this); + string IReducerArgs.ReducerName => "add_player"; public string Name = ""; } - - public static partial class Reducer - { - public delegate void AddPlayerHandler(ReducerEvent reducerEvent, string name); - public static event AddPlayerHandler? OnAddPlayerEvent; - - public static void AddPlayer(string name) - { - SpacetimeDBClient.instance.InternalCallReducer(new AddPlayerArgsStruct { Name = name }); - } - - public static bool OnAddPlayer(ReducerEvent reducerEvent, AddPlayerArgsStruct args) - { - if (OnAddPlayerEvent == null) return false; - OnAddPlayerEvent( - reducerEvent, - args.Name - ); - return true; - } - } - } ''' "AddPrivateReducer.cs" = ''' @@ -58,36 +34,12 @@ using System; namespace SpacetimeDB { [SpacetimeDB.Type] - public partial class AddPrivateArgsStruct : IReducerArgs + public partial class AddPrivate : IReducerArgs { - ReducerType IReducerArgs.ReducerType => ReducerType.AddPrivate; - string IReducerArgsBase.ReducerName => "add_private"; - bool IReducerArgs.InvokeHandler(ReducerEvent reducerEvent) => Reducer.OnAddPrivate(reducerEvent, this); + string IReducerArgs.ReducerName => "add_private"; public string Name = ""; } - - public static partial class Reducer - { - public delegate void AddPrivateHandler(ReducerEvent reducerEvent, string name); - public static event AddPrivateHandler? OnAddPrivateEvent; - - public static void AddPrivate(string name) - { - SpacetimeDBClient.instance.InternalCallReducer(new AddPrivateArgsStruct { Name = name }); - } - - public static bool OnAddPrivate(ReducerEvent reducerEvent, AddPrivateArgsStruct args) - { - if (OnAddPrivateEvent == null) return false; - OnAddPrivateEvent( - reducerEvent, - args.Name - ); - return true; - } - } - } ''' "Baz.cs" = ''' @@ -99,7 +51,6 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB @@ -138,36 +89,12 @@ using System; namespace SpacetimeDB { [SpacetimeDB.Type] - public partial class DeletePlayerArgsStruct : IReducerArgs + public partial class DeletePlayer : IReducerArgs { - ReducerType IReducerArgs.ReducerType => ReducerType.DeletePlayer; - string IReducerArgsBase.ReducerName => "delete_player"; - bool IReducerArgs.InvokeHandler(ReducerEvent reducerEvent) => Reducer.OnDeletePlayer(reducerEvent, this); + string IReducerArgs.ReducerName => "delete_player"; public ulong Id; } - - public static partial class Reducer - { - public delegate void DeletePlayerHandler(ReducerEvent reducerEvent, ulong id); - public static event DeletePlayerHandler? OnDeletePlayerEvent; - - public static void DeletePlayer(ulong id) - { - SpacetimeDBClient.instance.InternalCallReducer(new DeletePlayerArgsStruct { Id = id }); - } - - public static bool OnDeletePlayer(ReducerEvent reducerEvent, DeletePlayerArgsStruct args) - { - if (OnDeletePlayerEvent == null) return false; - OnDeletePlayerEvent( - reducerEvent, - args.Id - ); - return true; - } - } - } ''' "DeletePlayersByNameReducer.cs" = ''' @@ -182,36 +109,12 @@ using System; namespace SpacetimeDB { [SpacetimeDB.Type] - public partial class DeletePlayersByNameArgsStruct : IReducerArgs + public partial class DeletePlayersByName : IReducerArgs { - ReducerType IReducerArgs.ReducerType => ReducerType.DeletePlayersByName; - string IReducerArgsBase.ReducerName => "delete_players_by_name"; - bool IReducerArgs.InvokeHandler(ReducerEvent reducerEvent) => Reducer.OnDeletePlayersByName(reducerEvent, this); + string IReducerArgs.ReducerName => "delete_players_by_name"; public string Name = ""; } - - public static partial class Reducer - { - public delegate void DeletePlayersByNameHandler(ReducerEvent reducerEvent, string name); - public static event DeletePlayersByNameHandler? OnDeletePlayersByNameEvent; - - public static void DeletePlayersByName(string name) - { - SpacetimeDBClient.instance.InternalCallReducer(new DeletePlayersByNameArgsStruct { Name = name }); - } - - public static bool OnDeletePlayersByName(ReducerEvent reducerEvent, DeletePlayersByNameArgsStruct args) - { - if (OnDeletePlayersByNameEvent == null) return false; - OnDeletePlayersByNameEvent( - reducerEvent, - args.Name - ); - return true; - } - } - } ''' "Foobar.cs" = ''' @@ -242,14 +145,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class HasSpecialStuff : SpacetimeDB.DatabaseTable + public partial class HasSpecialStuff : IDatabaseRow { [DataMember(Name = "identity")] public SpacetimeDB.Identity Identity; @@ -271,17 +173,6 @@ namespace SpacetimeDB this.Address = new(); } - public static IEnumerable FilterByIdentity(SpacetimeDB.Identity value) - { - return Query(x => x.Identity == value); - } - - public static IEnumerable FilterByAddress(SpacetimeDB.Address value) - { - return Query(x => x.Address == value); - } - - } } ''' @@ -344,14 +235,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class PkMultiIdentity : SpacetimeDB.DatabaseTableWithPrimaryKey + public partial class PkMultiIdentity : IDatabaseRow { [DataMember(Name = "id")] public uint Id; @@ -371,51 +261,6 @@ namespace SpacetimeDB { } - private static Dictionary Id_Index = new(16); - private static Dictionary Other_Index = new(16); - - public override void InternalOnValueInserted() - { - Id_Index[Id] = this; - Other_Index[Other] = this; - } - - public override void InternalOnValueDeleted() - { - Id_Index.Remove(Id); - Other_Index.Remove(Other); - } - - public static PkMultiIdentity? FindById(uint value) - { - Id_Index.TryGetValue(value, out var r); - return r; - } - - public static IEnumerable FilterById(uint value) - { - if (FindById(value) is {} found) - { - yield return found; - } - } - - public static PkMultiIdentity? FindByOther(uint value) - { - Other_Index.TryGetValue(value, out var r); - return r; - } - - public static IEnumerable FilterByOther(uint value) - { - if (FindByOther(value) is {} found) - { - yield return found; - } - } - - public override object GetPrimaryKeyValue() => Id; - } } ''' @@ -428,14 +273,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class Point : SpacetimeDB.DatabaseTable + public partial class Point : IDatabaseRow { [DataMember(Name = "x")] public long X; @@ -455,17 +299,6 @@ namespace SpacetimeDB { } - public static IEnumerable FilterByX(long value) - { - return Query(x => x.X == value); - } - - public static IEnumerable FilterByY(long value) - { - return Query(x => x.Y == value); - } - - } } ''' @@ -478,14 +311,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class Private : SpacetimeDB.DatabaseTable + public partial class Private : IDatabaseRow { [DataMember(Name = "name")] public string Name; @@ -502,12 +334,6 @@ namespace SpacetimeDB this.Name = ""; } - public static IEnumerable FilterByName(string value) - { - return Query(x => x.Name == value); - } - - } } ''' @@ -523,33 +349,10 @@ using System; namespace SpacetimeDB { [SpacetimeDB.Type] - public partial class QueryPrivateArgsStruct : IReducerArgs - { - ReducerType IReducerArgs.ReducerType => ReducerType.QueryPrivate; - string IReducerArgsBase.ReducerName => "query_private"; - bool IReducerArgs.InvokeHandler(ReducerEvent reducerEvent) => Reducer.OnQueryPrivate(reducerEvent, this); - } - - public static partial class Reducer + public partial class QueryPrivate : IReducerArgs { - public delegate void QueryPrivateHandler(ReducerEvent reducerEvent); - public static event QueryPrivateHandler? OnQueryPrivateEvent; - - public static void QueryPrivate() - { - SpacetimeDBClient.instance.InternalCallReducer(new QueryPrivateArgsStruct { }); - } - - public static bool OnQueryPrivate(ReducerEvent reducerEvent, QueryPrivateArgsStruct args) - { - if (OnQueryPrivateEvent == null) return false; - OnQueryPrivateEvent( - reducerEvent - ); - return true; - } + string IReducerArgs.ReducerName => "query_private"; } - } ''' "RepeatingTestArg.cs" = ''' @@ -561,14 +364,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class RepeatingTestArg : SpacetimeDB.DatabaseTableWithPrimaryKey + public partial class RepeatingTestArg : IDatabaseRow { [DataMember(Name = "prev_time")] public ulong PrevTime; @@ -593,39 +395,6 @@ namespace SpacetimeDB this.ScheduledAt = null!; } - private static Dictionary ScheduledId_Index = new(16); - - public override void InternalOnValueInserted() - { - ScheduledId_Index[ScheduledId] = this; - } - - public override void InternalOnValueDeleted() - { - ScheduledId_Index.Remove(ScheduledId); - } - - public static IEnumerable FilterByPrevTime(ulong value) - { - return Query(x => x.PrevTime == value); - } - - public static RepeatingTestArg? FindByScheduledId(ulong value) - { - ScheduledId_Index.TryGetValue(value, out var r); - return r; - } - - public static IEnumerable FilterByScheduledId(ulong value) - { - if (FindByScheduledId(value) is {} found) - { - yield return found; - } - } - - public override object GetPrimaryKeyValue() => ScheduledId; - } } ''' @@ -641,36 +410,12 @@ using System; namespace SpacetimeDB { [SpacetimeDB.Type] - public partial class RepeatingTestArgsStruct : IReducerArgs + public partial class RepeatingTest : IReducerArgs { - ReducerType IReducerArgs.ReducerType => ReducerType.RepeatingTest; - string IReducerArgsBase.ReducerName => "repeating_test"; - bool IReducerArgs.InvokeHandler(ReducerEvent reducerEvent) => Reducer.OnRepeatingTest(reducerEvent, this); + string IReducerArgs.ReducerName => "repeating_test"; public SpacetimeDB.RepeatingTestArg Arg = new(); } - - public static partial class Reducer - { - public delegate void RepeatingTestHandler(ReducerEvent reducerEvent, SpacetimeDB.RepeatingTestArg arg); - public static event RepeatingTestHandler? OnRepeatingTestEvent; - - public static void RepeatingTest(SpacetimeDB.RepeatingTestArg arg) - { - SpacetimeDBClient.instance.InternalCallReducer(new RepeatingTestArgsStruct { Arg = arg }); - } - - public static bool OnRepeatingTest(ReducerEvent reducerEvent, RepeatingTestArgsStruct args) - { - if (OnRepeatingTestEvent == null) return false; - OnRepeatingTestEvent( - reducerEvent, - args.Arg - ); - return true; - } - } - } ''' "TestA.cs" = ''' @@ -682,14 +427,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class TestA : SpacetimeDB.DatabaseTable + public partial class TestA : IDatabaseRow { [DataMember(Name = "x")] public uint X; @@ -714,22 +458,6 @@ namespace SpacetimeDB this.Z = ""; } - public static IEnumerable FilterByX(uint value) - { - return Query(x => x.X == value); - } - - public static IEnumerable FilterByY(uint value) - { - return Query(x => x.Y == value); - } - - public static IEnumerable FilterByZ(string value) - { - return Query(x => x.Z == value); - } - - } } ''' @@ -742,7 +470,6 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB @@ -778,14 +505,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class TestD : SpacetimeDB.DatabaseTable + public partial class TestD : IDatabaseRow { [DataMember(Name = "test_c")] public SpacetimeDB.Namespace.Types.TestC? TestC; @@ -801,7 +527,6 @@ namespace SpacetimeDB { } - } } ''' @@ -814,14 +539,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class TestE : SpacetimeDB.DatabaseTableWithPrimaryKey + public partial class TestE : IDatabaseRow { [DataMember(Name = "id")] public ulong Id; @@ -842,39 +566,6 @@ namespace SpacetimeDB this.Name = ""; } - private static Dictionary Id_Index = new(16); - - public override void InternalOnValueInserted() - { - Id_Index[Id] = this; - } - - public override void InternalOnValueDeleted() - { - Id_Index.Remove(Id); - } - - public static TestE? FindById(ulong value) - { - Id_Index.TryGetValue(value, out var r); - return r; - } - - public static IEnumerable FilterById(ulong value) - { - if (FindById(value) is {} found) - { - yield return found; - } - } - - public static IEnumerable FilterByName(string value) - { - return Query(x => x.Name == value); - } - - public override object GetPrimaryKeyValue() => Id; - } } ''' @@ -887,14 +578,13 @@ namespace SpacetimeDB using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; namespace SpacetimeDB { [SpacetimeDB.Type] [DataContract] - public partial class TestFoobar : SpacetimeDB.DatabaseTable + public partial class TestFoobar : IDatabaseRow { [DataMember(Name = "field")] public SpacetimeDB.Foobar Field; @@ -911,7 +601,6 @@ namespace SpacetimeDB this.Field = null!; } - } } ''' @@ -927,42 +616,15 @@ using System; namespace SpacetimeDB { [SpacetimeDB.Type] - public partial class TestArgsStruct : IReducerArgs + public partial class Test : IReducerArgs { - ReducerType IReducerArgs.ReducerType => ReducerType.Test; - string IReducerArgsBase.ReducerName => "test"; - bool IReducerArgs.InvokeHandler(ReducerEvent reducerEvent) => Reducer.OnTest(reducerEvent, this); + string IReducerArgs.ReducerName => "test"; public SpacetimeDB.TestA Arg = new(); public SpacetimeDB.TestB Arg2 = new(); public SpacetimeDB.Namespace.Types.TestC Arg3; public SpacetimeDB.Namespace.TestF Arg4 = null!; } - - public static partial class Reducer - { - public delegate void TestHandler(ReducerEvent reducerEvent, SpacetimeDB.TestA arg, SpacetimeDB.TestB arg2, SpacetimeDB.Namespace.Types.TestC arg3, SpacetimeDB.Namespace.TestF arg4); - public static event TestHandler? OnTestEvent; - - public static void Test(SpacetimeDB.TestA arg, SpacetimeDB.TestB arg2, SpacetimeDB.Namespace.Types.TestC arg3, SpacetimeDB.Namespace.TestF arg4) - { - SpacetimeDBClient.instance.InternalCallReducer(new TestArgsStruct { Arg = arg, Arg2 = arg2, Arg3 = arg3, Arg4 = arg4 }); - } - - public static bool OnTest(ReducerEvent reducerEvent, TestArgsStruct args) - { - if (OnTestEvent == null) return false; - OnTestEvent( - reducerEvent, - args.Arg, - args.Arg2, - args.Arg3, - args.Arg4 - ); - return true; - } - } - } ''' "_Globals/SpacetimeDBClient.cs" = ''' @@ -974,115 +636,442 @@ namespace SpacetimeDB using System; using SpacetimeDB.ClientApi; +using System.Collections.Generic; namespace SpacetimeDB { - public enum ReducerType + public sealed class RemoteTables { - None, - AddPlayer, - AddPrivate, - DeletePlayer, - DeletePlayersByName, - QueryPrivate, - RepeatingTest, - Test, + public class HasSpecialStuffHandle : RemoteTableHandle + { + internal HasSpecialStuffHandle() + { + } + + } + + public readonly HasSpecialStuffHandle HasSpecialStuff = new(); + + public class PkMultiIdentityHandle : RemoteTableHandle + { + private static Dictionary Id_Index = new(16); + private static Dictionary Other_Index = new(16); + + public override void InternalInvokeValueInserted(IDatabaseRow row) + { + var value = (PkMultiIdentity)row; + Id_Index[value.Id] = value; + Other_Index[value.Other] = value; + } + + public override void InternalInvokeValueDeleted(IDatabaseRow row) + { + Id_Index.Remove(((PkMultiIdentity)row).Id); + Other_Index.Remove(((PkMultiIdentity)row).Other); + } + + public readonly ref struct IdUniqueIndex + { + public PkMultiIdentity? Find(uint value) + { + Id_Index.TryGetValue(value, out var r); + return r; + } + + } + + public IdUniqueIndex Id => new(); + + public readonly ref struct OtherUniqueIndex + { + public PkMultiIdentity? Find(uint value) + { + Other_Index.TryGetValue(value, out var r); + return r; + } + + } + + public OtherUniqueIndex Other => new(); + + internal PkMultiIdentityHandle() + { + } + public override object GetPrimaryKey(IDatabaseRow row) => ((PkMultiIdentity)row).Id; + + } + + public readonly PkMultiIdentityHandle PkMultiIdentity = new(); + + public class PointsHandle : RemoteTableHandle + { + public class XYIndex + { + PointsHandle Handle; + internal XYIndex(PointsHandle handle) => Handle = handle; + public IEnumerable Filter(long value) => + Handle.Query(x => x.X == value); + } + + public XYIndex XY { get; init; } + + internal PointsHandle() + { + XY = new(this); + } + + } + + public readonly PointsHandle Points = new(); + + public class PrivateHandle : RemoteTableHandle + { + internal PrivateHandle() + { + } + + } + + public readonly PrivateHandle Private = new(); + + public class RepeatingTestArgHandle : RemoteTableHandle + { + private static Dictionary ScheduledId_Index = new(16); + + public override void InternalInvokeValueInserted(IDatabaseRow row) + { + var value = (RepeatingTestArg)row; + ScheduledId_Index[value.ScheduledId] = value; + } + + public override void InternalInvokeValueDeleted(IDatabaseRow row) + { + ScheduledId_Index.Remove(((RepeatingTestArg)row).ScheduledId); + } + + public readonly ref struct ScheduledIdUniqueIndex + { + public RepeatingTestArg? Find(ulong value) + { + ScheduledId_Index.TryGetValue(value, out var r); + return r; + } + + } + + public ScheduledIdUniqueIndex ScheduledId => new(); + + internal RepeatingTestArgHandle() + { + } + public override object GetPrimaryKey(IDatabaseRow row) => ((RepeatingTestArg)row).ScheduledId; + + } + + public readonly RepeatingTestArgHandle RepeatingTestArg = new(); + + public class TestAHandle : RemoteTableHandle + { + public class XIndex + { + TestAHandle Handle; + internal XIndex(TestAHandle handle) => Handle = handle; + public IEnumerable Filter(uint value) => + Handle.Query(x => x.X == value); + } + + public XIndex X { get; init; } + + internal TestAHandle() + { + X = new(this); + } + + } + + public readonly TestAHandle TestA = new(); + + public class TestDHandle : RemoteTableHandle + { + internal TestDHandle() + { + } + + } + + public readonly TestDHandle TestD = new(); + + public class TestEHandle : RemoteTableHandle + { + private static Dictionary Id_Index = new(16); + + public override void InternalInvokeValueInserted(IDatabaseRow row) + { + var value = (TestE)row; + Id_Index[value.Id] = value; + } + + public override void InternalInvokeValueDeleted(IDatabaseRow row) + { + Id_Index.Remove(((TestE)row).Id); + } + + public readonly ref struct IdUniqueIndex + { + public TestE? Find(ulong value) + { + Id_Index.TryGetValue(value, out var r); + return r; + } + + } + + public IdUniqueIndex Id => new(); + + public class NameIndex + { + TestEHandle Handle; + internal NameIndex(TestEHandle handle) => Handle = handle; + public IEnumerable Filter(string value) => + Handle.Query(x => x.Name == value); + } + + public NameIndex Name { get; init; } + + internal TestEHandle() + { + Name = new(this); + } + public override object GetPrimaryKey(IDatabaseRow row) => ((TestE)row).Id; + + } + + public readonly TestEHandle TestE = new(); + + public class TestFHandle : RemoteTableHandle + { + internal TestFHandle() + { + } + + } + + public readonly TestFHandle TestF = new(); + } - public interface IReducerArgs : IReducerArgsBase + public sealed class RemoteReducers : RemoteBase { - ReducerType ReducerType { get; } - bool InvokeHandler(ReducerEvent reducerEvent); + internal RemoteReducers(DbConnection conn) : base(conn) {} + public delegate void AddPlayerHandler(EventContext ctx, string name); + public event AddPlayerHandler? OnAddPlayer; + + public void AddPlayer(string name) + { + conn.InternalCallReducer(new AddPlayer { Name = name }); + } + + public bool InvokeAddPlayer(EventContext ctx, AddPlayer args) + { + if (OnAddPlayer == null) return false; + OnAddPlayer( + ctx, + args.Name + ); + return true; + } + public delegate void AddPrivateHandler(EventContext ctx, string name); + public event AddPrivateHandler? OnAddPrivate; + + public void AddPrivate(string name) + { + conn.InternalCallReducer(new AddPrivate { Name = name }); + } + + public bool InvokeAddPrivate(EventContext ctx, AddPrivate args) + { + if (OnAddPrivate == null) return false; + OnAddPrivate( + ctx, + args.Name + ); + return true; + } + public delegate void DeletePlayerHandler(EventContext ctx, ulong id); + public event DeletePlayerHandler? OnDeletePlayer; + + public void DeletePlayer(ulong id) + { + conn.InternalCallReducer(new DeletePlayer { Id = id }); + } + + public bool InvokeDeletePlayer(EventContext ctx, DeletePlayer args) + { + if (OnDeletePlayer == null) return false; + OnDeletePlayer( + ctx, + args.Id + ); + return true; + } + public delegate void DeletePlayersByNameHandler(EventContext ctx, string name); + public event DeletePlayersByNameHandler? OnDeletePlayersByName; + + public void DeletePlayersByName(string name) + { + conn.InternalCallReducer(new DeletePlayersByName { Name = name }); + } + + public bool InvokeDeletePlayersByName(EventContext ctx, DeletePlayersByName args) + { + if (OnDeletePlayersByName == null) return false; + OnDeletePlayersByName( + ctx, + args.Name + ); + return true; + } + public delegate void QueryPrivateHandler(EventContext ctx); + public event QueryPrivateHandler? OnQueryPrivate; + + public void QueryPrivate() + { + conn.InternalCallReducer(new QueryPrivate { }); + } + + public bool InvokeQueryPrivate(EventContext ctx, QueryPrivate args) + { + if (OnQueryPrivate == null) return false; + OnQueryPrivate( + ctx + ); + return true; + } + public delegate void RepeatingTestHandler(EventContext ctx, SpacetimeDB.RepeatingTestArg arg); + public event RepeatingTestHandler? OnRepeatingTest; + + public void RepeatingTest(SpacetimeDB.RepeatingTestArg arg) + { + conn.InternalCallReducer(new RepeatingTest { Arg = arg }); + } + + public bool InvokeRepeatingTest(EventContext ctx, RepeatingTest args) + { + if (OnRepeatingTest == null) return false; + OnRepeatingTest( + ctx, + args.Arg + ); + return true; + } + public delegate void TestHandler(EventContext ctx, SpacetimeDB.TestA arg, SpacetimeDB.TestB arg2, SpacetimeDB.Namespace.Types.TestC arg3, SpacetimeDB.Namespace.TestF arg4); + public event TestHandler? OnTest; + + public void Test(SpacetimeDB.TestA arg, SpacetimeDB.TestB arg2, SpacetimeDB.Namespace.Types.TestC arg3, SpacetimeDB.Namespace.TestF arg4) + { + conn.InternalCallReducer(new Test { Arg = arg, Arg2 = arg2, Arg3 = arg3, Arg4 = arg4 }); + } + + public bool InvokeTest(EventContext ctx, Test args) + { + if (OnTest == null) return false; + OnTest( + ctx, + args.Arg, + args.Arg2, + args.Arg3, + args.Arg4 + ); + return true; + } } - public partial class ReducerEvent : ReducerEventBase + public partial record EventContext : DbContext, IEventContext { - public IReducerArgs? Args { get; } - - public string ReducerName => Args?.ReducerName ?? ""; - - [Obsolete("ReducerType is deprecated, please match directly on type of .Args instead.")] - public ReducerType Reducer => Args?.ReducerType ?? ReducerType.None; - - public ReducerEvent(IReducerArgs? args) : base() => Args = args; - public ReducerEvent(TransactionUpdate update, IReducerArgs? args) : base(update) => Args = args; - - [Obsolete("Accessors that implicitly cast `Args` are deprecated, please match `Args` against the desired type explicitly instead.")] - public AddPlayerArgsStruct AddPlayerArgs => (AddPlayerArgsStruct)Args!; - [Obsolete("Accessors that implicitly cast `Args` are deprecated, please match `Args` against the desired type explicitly instead.")] - public AddPrivateArgsStruct AddPrivateArgs => (AddPrivateArgsStruct)Args!; - [Obsolete("Accessors that implicitly cast `Args` are deprecated, please match `Args` against the desired type explicitly instead.")] - public DeletePlayerArgsStruct DeletePlayerArgs => (DeletePlayerArgsStruct)Args!; - [Obsolete("Accessors that implicitly cast `Args` are deprecated, please match `Args` against the desired type explicitly instead.")] - public DeletePlayersByNameArgsStruct DeletePlayersByNameArgs => (DeletePlayersByNameArgsStruct)Args!; - [Obsolete("Accessors that implicitly cast `Args` are deprecated, please match `Args` against the desired type explicitly instead.")] - public QueryPrivateArgsStruct QueryPrivateArgs => (QueryPrivateArgsStruct)Args!; - [Obsolete("Accessors that implicitly cast `Args` are deprecated, please match `Args` against the desired type explicitly instead.")] - public RepeatingTestArgsStruct RepeatingTestArgs => (RepeatingTestArgsStruct)Args!; - [Obsolete("Accessors that implicitly cast `Args` are deprecated, please match `Args` against the desired type explicitly instead.")] - public TestArgsStruct TestArgs => (TestArgsStruct)Args!; - - public override bool InvokeHandler() => Args?.InvokeHandler(this) ?? false; + public readonly RemoteReducers Reducers; + public readonly Event Event; + + internal EventContext(DbConnection conn, Event reducerEvent) : base(conn.Db) + { + Reducers = conn.Reducers; + Event = reducerEvent; + } } - public class SpacetimeDBClient : SpacetimeDBClientBase + [Type] + public partial record Reducer : TaggedEnum<( + AddPlayer AddPlayer, + AddPrivate AddPrivate, + DeletePlayer DeletePlayer, + DeletePlayersByName DeletePlayersByName, + QueryPrivate QueryPrivate, + RepeatingTest RepeatingTest, + Test Test, + Unit StdbNone, + Unit StdbIdentityConnected, + Unit StdbIdentityDisconnected + )>; + public class DbConnection : DbConnectionBase { - protected SpacetimeDBClient() + public readonly RemoteTables Db = new(); + public readonly RemoteReducers Reducers; + + public DbConnection() { - clientDB.AddTable(); - clientDB.AddTable(); - clientDB.AddTable(); - clientDB.AddTable(); - clientDB.AddTable(); - clientDB.AddTable(); - clientDB.AddTable(); - clientDB.AddTable(); - clientDB.AddTable(); - } + Reducers = new(this); - public static readonly SpacetimeDBClient instance = new(); + clientDB.AddTable("has_special_stuff", Db.HasSpecialStuff); + clientDB.AddTable("pk_multi_identity", Db.PkMultiIdentity); + clientDB.AddTable("points", Db.Points); + clientDB.AddTable("private", Db.Private); + clientDB.AddTable("repeating_test_arg", Db.RepeatingTestArg); + clientDB.AddTable("test_a", Db.TestA); + clientDB.AddTable("test_d", Db.TestD); + clientDB.AddTable("test_e", Db.TestE); + clientDB.AddTable("test_f", Db.TestF); + } - protected override ReducerEvent ReducerEventFromDbEvent(TransactionUpdate update) + protected override Reducer ToReducer(TransactionUpdate update) { var encodedArgs = update.ReducerCall.Args; - IReducerArgs? args = update.ReducerCall.ReducerName switch { - "add_player" => BSATNHelpers.Decode(encodedArgs), - "add_private" => BSATNHelpers.Decode(encodedArgs), - "delete_player" => BSATNHelpers.Decode(encodedArgs), - "delete_players_by_name" => BSATNHelpers.Decode(encodedArgs), - "query_private" => BSATNHelpers.Decode(encodedArgs), - "repeating_test" => BSATNHelpers.Decode(encodedArgs), - "test" => BSATNHelpers.Decode(encodedArgs), - "" => null, - "__identity_connected__" => null, - "__identity_disconnected__" => null, - "" => null, + return update.ReducerCall.ReducerName switch { + "add_player" => new Reducer.AddPlayer(BSATNHelpers.Decode(encodedArgs)), + "add_private" => new Reducer.AddPrivate(BSATNHelpers.Decode(encodedArgs)), + "delete_player" => new Reducer.DeletePlayer(BSATNHelpers.Decode(encodedArgs)), + "delete_players_by_name" => new Reducer.DeletePlayersByName(BSATNHelpers.Decode(encodedArgs)), + "query_private" => new Reducer.QueryPrivate(BSATNHelpers.Decode(encodedArgs)), + "repeating_test" => new Reducer.RepeatingTest(BSATNHelpers.Decode(encodedArgs)), + "test" => new Reducer.Test(BSATNHelpers.Decode(encodedArgs)), + "" => new Reducer.StdbNone(default), + "__identity_connected__" => new Reducer.StdbIdentityConnected(default), + "__identity_disconnected__" => new Reducer.StdbIdentityDisconnected(default), + "" => new Reducer.StdbNone(default), var reducer => throw new ArgumentOutOfRangeException("Reducer", $"Unknown reducer {reducer}") }; - return new ReducerEvent(update, args); } - } -} -''' -"_Globals/UnityNetworkManager.cs" = ''' -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN RUST INSTEAD. -// - -#nullable enable -using System; + protected override IEventContext ToEventContext(Event reducerEvent) => + new EventContext(this, reducerEvent); + + protected override bool Dispatch(IEventContext context, Reducer reducer) + { + var eventContext = (EventContext)context; + return reducer switch { + Reducer.AddPlayer(var args) => Reducers.InvokeAddPlayer(eventContext, args), + Reducer.AddPrivate(var args) => Reducers.InvokeAddPrivate(eventContext, args), + Reducer.DeletePlayer(var args) => Reducers.InvokeDeletePlayer(eventContext, args), + Reducer.DeletePlayersByName(var args) => Reducers.InvokeDeletePlayersByName(eventContext, args), + Reducer.QueryPrivate(var args) => Reducers.InvokeQueryPrivate(eventContext, args), + Reducer.RepeatingTest(var args) => Reducers.InvokeRepeatingTest(eventContext, args), + Reducer.Test(var args) => Reducers.InvokeTest(eventContext, args), + Reducer.StdbNone or + Reducer.StdbIdentityConnected or + Reducer.StdbIdentityDisconnected => true, + _ => throw new ArgumentOutOfRangeException("Reducer", $"Unknown reducer {reducer}") + }; + } -namespace SpacetimeDB -{ - // This class is only used in Unity projects. - // Attach this to a gameobject in your scene to use SpacetimeDB. - #if UNITY_5_3_OR_NEWER - public class UnityNetworkManager : UnityEngine.MonoBehaviour - { - private void OnDestroy() => SpacetimeDBClient.instance.Close(); - private void Update() => SpacetimeDBClient.instance.Update(); + public SubscriptionBuilder SubscriptionBuilder() => new(this); } - #endif } ''' diff --git a/crates/sdk/tests/test.rs b/crates/sdk/tests/test.rs index 699ca7227e..b78d65ceb3 100644 --- a/crates/sdk/tests/test.rs +++ b/crates/sdk/tests/test.rs @@ -177,4 +177,4 @@ macro_rules! declare_tests_with_suffix { declare_tests_with_suffix!(rust, ""); // TODO: migrate csharp to snake_case table names -// declare_tests_with_suffix!(csharp, "-cs"); +declare_tests_with_suffix!(csharp, "-cs"); diff --git a/modules/sdk-test-connect-disconnect-cs/Lib.cs b/modules/sdk-test-connect-disconnect-cs/Lib.cs index fb3ad8aca6..426b853993 100644 --- a/modules/sdk-test-connect-disconnect-cs/Lib.cs +++ b/modules/sdk-test-connect-disconnect-cs/Lib.cs @@ -2,13 +2,13 @@ namespace SpacetimeDB.Sdk.Test.ConnectDisconnect; using SpacetimeDB; -[SpacetimeDB.Table(Public = true)] +[SpacetimeDB.Table(Name = "connected", Public = true)] public partial struct Connected { public Identity identity; } -[SpacetimeDB.Table(Public = true)] +[SpacetimeDB.Table(Name = "disconnected", Public = true)] public partial struct Disconnected { public Identity identity; @@ -19,12 +19,12 @@ static partial class Module [SpacetimeDB.Reducer(ReducerKind.ClientConnected)] public static void Connected(ReducerContext ctx) { - ctx.Db.Connected.Insert(new Connected { identity = ctx.CallerIdentity }); + ctx.Db.connected.Insert(new Connected { identity = ctx.CallerIdentity }); } [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)] public static void Disconnected(ReducerContext ctx) { - ctx.Db.Disconnected.Insert(new Disconnected { identity = ctx.CallerIdentity }); + ctx.Db.disconnected.Insert(new Disconnected { identity = ctx.CallerIdentity }); } } diff --git a/modules/sdk-test-cs/Lib.cs b/modules/sdk-test-cs/Lib.cs index ab2aa073f9..670e639024 100644 --- a/modules/sdk-test-cs/Lib.cs +++ b/modules/sdk-test-cs/Lib.cs @@ -94,7 +94,7 @@ public partial struct EveryVecStruct public List
r; } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_u8", Public = true)] public partial struct OneU8 { public byte n; @@ -103,10 +103,10 @@ public partial struct OneU8 [SpacetimeDB.Reducer] public static void insert_one_u8(ReducerContext ctx, byte n) { - ctx.Db.OneU8.Insert(new OneU8 { n = n }); + ctx.Db.one_u8.Insert(new OneU8 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_u16", Public = true)] public partial struct OneU16 { public ushort n; @@ -115,10 +115,10 @@ public partial struct OneU16 [SpacetimeDB.Reducer] public static void insert_one_u16(ReducerContext ctx, ushort n) { - ctx.Db.OneU16.Insert(new OneU16 { n = n }); + ctx.Db.one_u16.Insert(new OneU16 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_u32", Public = true)] public partial struct OneU32 { public uint n; @@ -127,10 +127,10 @@ public partial struct OneU32 [SpacetimeDB.Reducer] public static void insert_one_u32(ReducerContext ctx, uint n) { - ctx.Db.OneU32.Insert(new OneU32 { n = n }); + ctx.Db.one_u32.Insert(new OneU32 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_u64", Public = true)] public partial struct OneU64 { public ulong n; @@ -139,10 +139,10 @@ public partial struct OneU64 [SpacetimeDB.Reducer] public static void insert_one_u64(ReducerContext ctx, ulong n) { - ctx.Db.OneU64.Insert(new OneU64 { n = n }); + ctx.Db.one_u64.Insert(new OneU64 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_u128", Public = true)] public partial struct OneU128 { public U128 n; @@ -151,10 +151,10 @@ public partial struct OneU128 [SpacetimeDB.Reducer] public static void insert_one_u128(ReducerContext ctx, U128 n) { - ctx.Db.OneU128.Insert(new OneU128 { n = n }); + ctx.Db.one_u128.Insert(new OneU128 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_u256", Public = true)] public partial struct OneU256 { public U256 n; @@ -163,10 +163,10 @@ public partial struct OneU256 [SpacetimeDB.Reducer] public static void insert_one_u256(ReducerContext ctx, U256 n) { - ctx.Db.OneU256.Insert(new OneU256 { n = n }); + ctx.Db.one_u256.Insert(new OneU256 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_i8", Public = true)] public partial struct OneI8 { public sbyte n; @@ -175,10 +175,10 @@ public partial struct OneI8 [SpacetimeDB.Reducer] public static void insert_one_i8(ReducerContext ctx, sbyte n) { - ctx.Db.OneI8.Insert(new OneI8 { n = n }); + ctx.Db.one_i8.Insert(new OneI8 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_i16", Public = true)] public partial struct OneI16 { public short n; @@ -187,10 +187,10 @@ public partial struct OneI16 [SpacetimeDB.Reducer] public static void insert_one_i16(ReducerContext ctx, short n) { - ctx.Db.OneI16.Insert(new OneI16 { n = n }); + ctx.Db.one_i16.Insert(new OneI16 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_i32", Public = true)] public partial struct OneI32 { public int n; @@ -199,10 +199,10 @@ public partial struct OneI32 [SpacetimeDB.Reducer] public static void insert_one_i32(ReducerContext ctx, int n) { - ctx.Db.OneI32.Insert(new OneI32 { n = n }); + ctx.Db.one_i32.Insert(new OneI32 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_i64", Public = true)] public partial struct OneI64 { public long n; @@ -211,10 +211,10 @@ public partial struct OneI64 [SpacetimeDB.Reducer] public static void insert_one_i64(ReducerContext ctx, long n) { - ctx.Db.OneI64.Insert(new OneI64 { n = n }); + ctx.Db.one_i64.Insert(new OneI64 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_i128", Public = true)] public partial struct OneI128 { public I128 n; @@ -223,10 +223,10 @@ public partial struct OneI128 [SpacetimeDB.Reducer] public static void insert_one_i128(ReducerContext ctx, I128 n) { - ctx.Db.OneI128.Insert(new OneI128 { n = n }); + ctx.Db.one_i128.Insert(new OneI128 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_i256", Public = true)] public partial struct OneI256 { public I256 n; @@ -235,10 +235,10 @@ public partial struct OneI256 [SpacetimeDB.Reducer] public static void insert_one_i256(ReducerContext ctx, I256 n) { - ctx.Db.OneI256.Insert(new OneI256 { n = n }); + ctx.Db.one_i256.Insert(new OneI256 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_bool", Public = true)] public partial struct OneBool { public bool b; @@ -247,10 +247,10 @@ public partial struct OneBool [SpacetimeDB.Reducer] public static void insert_one_bool(ReducerContext ctx, bool b) { - ctx.Db.OneBool.Insert(new OneBool { b = b }); + ctx.Db.one_bool.Insert(new OneBool { b = b }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_f32", Public = true)] public partial struct OneF32 { public float f; @@ -259,10 +259,10 @@ public partial struct OneF32 [SpacetimeDB.Reducer] public static void insert_one_f32(ReducerContext ctx, float f) { - ctx.Db.OneF32.Insert(new OneF32 { f = f }); + ctx.Db.one_f32.Insert(new OneF32 { f = f }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_f64", Public = true)] public partial struct OneF64 { public double f; @@ -271,10 +271,10 @@ public partial struct OneF64 [SpacetimeDB.Reducer] public static void insert_one_f64(ReducerContext ctx, double f) { - ctx.Db.OneF64.Insert(new OneF64 { f = f }); + ctx.Db.one_f64.Insert(new OneF64 { f = f }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_string", Public = true)] public partial struct OneString { public string s; @@ -283,10 +283,10 @@ public partial struct OneString [SpacetimeDB.Reducer] public static void insert_one_string(ReducerContext ctx, string s) { - ctx.Db.OneString.Insert(new OneString { s = s }); + ctx.Db.one_string.Insert(new OneString { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_identity", Public = true)] public partial struct OneIdentity { public Identity i; @@ -295,10 +295,10 @@ public partial struct OneIdentity [SpacetimeDB.Reducer] public static void insert_one_identity(ReducerContext ctx, Identity i) { - ctx.Db.OneIdentity.Insert(new OneIdentity { i = i }); + ctx.Db.one_identity.Insert(new OneIdentity { i = i }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_address", Public = true)] public partial struct OneAddress { public Address a; @@ -307,10 +307,10 @@ public partial struct OneAddress [SpacetimeDB.Reducer] public static void insert_one_address(ReducerContext ctx, Address a) { - ctx.Db.OneAddress.Insert(new OneAddress { a = a }); + ctx.Db.one_address.Insert(new OneAddress { a = a }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_simple_enum", Public = true)] public partial struct OneSimpleEnum { public SimpleEnum e; @@ -319,10 +319,10 @@ public partial struct OneSimpleEnum [SpacetimeDB.Reducer] public static void insert_one_simple_enum(ReducerContext ctx, SimpleEnum e) { - ctx.Db.OneSimpleEnum.Insert(new OneSimpleEnum { e = e }); + ctx.Db.one_simple_enum.Insert(new OneSimpleEnum { e = e }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_enum_with_payload", Public = true)] public partial struct OneEnumWithPayload { public EnumWithPayload e; @@ -331,10 +331,10 @@ public partial struct OneEnumWithPayload [SpacetimeDB.Reducer] public static void insert_one_enum_with_payload(ReducerContext ctx, EnumWithPayload e) { - ctx.Db.OneEnumWithPayload.Insert(new OneEnumWithPayload { e = e }); + ctx.Db.one_enum_with_payload.Insert(new OneEnumWithPayload { e = e }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_unit_struct", Public = true)] public partial struct OneUnitStruct { public UnitStruct s; @@ -343,10 +343,10 @@ public partial struct OneUnitStruct [SpacetimeDB.Reducer] public static void insert_one_unit_struct(ReducerContext ctx, UnitStruct s) { - ctx.Db.OneUnitStruct.Insert(new OneUnitStruct { s = s }); + ctx.Db.one_unit_struct.Insert(new OneUnitStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_byte_struct", Public = true)] public partial struct OneByteStruct { public ByteStruct s; @@ -355,10 +355,10 @@ public partial struct OneByteStruct [SpacetimeDB.Reducer] public static void insert_one_byte_struct(ReducerContext ctx, ByteStruct s) { - ctx.Db.OneByteStruct.Insert(new OneByteStruct { s = s }); + ctx.Db.one_byte_struct.Insert(new OneByteStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_every_primitive_struct", Public = true)] public partial struct OneEveryPrimitiveStruct { public EveryPrimitiveStruct s; @@ -367,10 +367,10 @@ public partial struct OneEveryPrimitiveStruct [SpacetimeDB.Reducer] public static void insert_one_every_primitive_struct(ReducerContext ctx, EveryPrimitiveStruct s) { - ctx.Db.OneEveryPrimitiveStruct.Insert(new OneEveryPrimitiveStruct { s = s }); + ctx.Db.one_every_primitive_struct.Insert(new OneEveryPrimitiveStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "one_every_vec_struct", Public = true)] public partial struct OneEveryVecStruct { public EveryVecStruct s; @@ -379,10 +379,10 @@ public partial struct OneEveryVecStruct [SpacetimeDB.Reducer] public static void insert_one_every_vec_struct(ReducerContext ctx, EveryVecStruct s) { - ctx.Db.OneEveryVecStruct.Insert(new OneEveryVecStruct { s = s }); + ctx.Db.one_every_vec_struct.Insert(new OneEveryVecStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_u8", Public = true)] public partial struct VecU8 { public List n; @@ -391,10 +391,10 @@ public partial struct VecU8 [SpacetimeDB.Reducer] public static void insert_vec_u8(ReducerContext ctx, List n) { - ctx.Db.VecU8.Insert(new VecU8 { n = n }); + ctx.Db.vec_u8.Insert(new VecU8 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_u16", Public = true)] public partial struct VecU16 { public List n; @@ -403,10 +403,10 @@ public partial struct VecU16 [SpacetimeDB.Reducer] public static void insert_vec_u16(ReducerContext ctx, List n) { - ctx.Db.VecU16.Insert(new VecU16 { n = n }); + ctx.Db.vec_u16.Insert(new VecU16 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_u32", Public = true)] public partial struct VecU32 { public List n; @@ -415,10 +415,10 @@ public partial struct VecU32 [SpacetimeDB.Reducer] public static void insert_vec_u32(ReducerContext ctx, List n) { - ctx.Db.VecU32.Insert(new VecU32 { n = n }); + ctx.Db.vec_u32.Insert(new VecU32 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_u64", Public = true)] public partial struct VecU64 { public List n; @@ -427,10 +427,10 @@ public partial struct VecU64 [SpacetimeDB.Reducer] public static void insert_vec_u64(ReducerContext ctx, List n) { - ctx.Db.VecU64.Insert(new VecU64 { n = n }); + ctx.Db.vec_u64.Insert(new VecU64 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_u128", Public = true)] public partial struct VecU128 { public List n; @@ -439,10 +439,10 @@ public partial struct VecU128 [SpacetimeDB.Reducer] public static void insert_vec_u128(ReducerContext ctx, List n) { - ctx.Db.VecU128.Insert(new VecU128 { n = n }); + ctx.Db.vec_u128.Insert(new VecU128 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_u256", Public = true)] public partial struct VecU256 { public List n; @@ -451,10 +451,10 @@ public partial struct VecU256 [SpacetimeDB.Reducer] public static void insert_vec_u256(ReducerContext ctx, List n) { - ctx.Db.VecU256.Insert(new VecU256 { n = n }); + ctx.Db.vec_u256.Insert(new VecU256 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_i8", Public = true)] public partial struct VecI8 { public List n; @@ -463,10 +463,10 @@ public partial struct VecI8 [SpacetimeDB.Reducer] public static void insert_vec_i8(ReducerContext ctx, List n) { - ctx.Db.VecI8.Insert(new VecI8 { n = n }); + ctx.Db.vec_i8.Insert(new VecI8 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_i16", Public = true)] public partial struct VecI16 { public List n; @@ -475,10 +475,10 @@ public partial struct VecI16 [SpacetimeDB.Reducer] public static void insert_vec_i16(ReducerContext ctx, List n) { - ctx.Db.VecI16.Insert(new VecI16 { n = n }); + ctx.Db.vec_i16.Insert(new VecI16 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_i32", Public = true)] public partial struct VecI32 { public List n; @@ -487,10 +487,10 @@ public partial struct VecI32 [SpacetimeDB.Reducer] public static void insert_vec_i32(ReducerContext ctx, List n) { - ctx.Db.VecI32.Insert(new VecI32 { n = n }); + ctx.Db.vec_i32.Insert(new VecI32 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_i64", Public = true)] public partial struct VecI64 { public List n; @@ -499,10 +499,10 @@ public partial struct VecI64 [SpacetimeDB.Reducer] public static void insert_vec_i64(ReducerContext ctx, List n) { - ctx.Db.VecI64.Insert(new VecI64 { n = n }); + ctx.Db.vec_i64.Insert(new VecI64 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_i128", Public = true)] public partial struct VecI128 { public List n; @@ -511,10 +511,10 @@ public partial struct VecI128 [SpacetimeDB.Reducer] public static void insert_vec_i128(ReducerContext ctx, List n) { - ctx.Db.VecI128.Insert(new VecI128 { n = n }); + ctx.Db.vec_i128.Insert(new VecI128 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_i256", Public = true)] public partial struct VecI256 { public List n; @@ -523,10 +523,10 @@ public partial struct VecI256 [SpacetimeDB.Reducer] public static void insert_vec_i256(ReducerContext ctx, List n) { - ctx.Db.VecI256.Insert(new VecI256 { n = n }); + ctx.Db.vec_i256.Insert(new VecI256 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_bool", Public = true)] public partial struct VecBool { public List b; @@ -535,10 +535,10 @@ public partial struct VecBool [SpacetimeDB.Reducer] public static void insert_vec_bool(ReducerContext ctx, List b) { - ctx.Db.VecBool.Insert(new VecBool { b = b }); + ctx.Db.vec_bool.Insert(new VecBool { b = b }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_f32", Public = true)] public partial struct VecF32 { public List f; @@ -547,10 +547,10 @@ public partial struct VecF32 [SpacetimeDB.Reducer] public static void insert_vec_f32(ReducerContext ctx, List f) { - ctx.Db.VecF32.Insert(new VecF32 { f = f }); + ctx.Db.vec_f32.Insert(new VecF32 { f = f }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_f64", Public = true)] public partial struct VecF64 { public List f; @@ -559,10 +559,10 @@ public partial struct VecF64 [SpacetimeDB.Reducer] public static void insert_vec_f64(ReducerContext ctx, List f) { - ctx.Db.VecF64.Insert(new VecF64 { f = f }); + ctx.Db.vec_f64.Insert(new VecF64 { f = f }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_string", Public = true)] public partial struct VecString { public List s; @@ -571,10 +571,10 @@ public partial struct VecString [SpacetimeDB.Reducer] public static void insert_vec_string(ReducerContext ctx, List s) { - ctx.Db.VecString.Insert(new VecString { s = s }); + ctx.Db.vec_string.Insert(new VecString { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_identity", Public = true)] public partial struct VecIdentity { public List i; @@ -583,10 +583,10 @@ public partial struct VecIdentity [SpacetimeDB.Reducer] public static void insert_vec_identity(ReducerContext ctx, List i) { - ctx.Db.VecIdentity.Insert(new VecIdentity { i = i }); + ctx.Db.vec_identity.Insert(new VecIdentity { i = i }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_address", Public = true)] public partial struct VecAddress { public List
a; @@ -595,10 +595,10 @@ public partial struct VecAddress [SpacetimeDB.Reducer] public static void insert_vec_address(ReducerContext ctx, List
a) { - ctx.Db.VecAddress.Insert(new VecAddress { a = a }); + ctx.Db.vec_address.Insert(new VecAddress { a = a }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_simple_enum", Public = true)] public partial struct VecSimpleEnum { public List e; @@ -607,10 +607,10 @@ public partial struct VecSimpleEnum [SpacetimeDB.Reducer] public static void insert_vec_simple_enum(ReducerContext ctx, List e) { - ctx.Db.VecSimpleEnum.Insert(new VecSimpleEnum { e = e }); + ctx.Db.vec_simple_enum.Insert(new VecSimpleEnum { e = e }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_enum_with_payload", Public = true)] public partial struct VecEnumWithPayload { public List e; @@ -619,10 +619,10 @@ public partial struct VecEnumWithPayload [SpacetimeDB.Reducer] public static void insert_vec_enum_with_payload(ReducerContext ctx, List e) { - ctx.Db.VecEnumWithPayload.Insert(new VecEnumWithPayload { e = e }); + ctx.Db.vec_enum_with_payload.Insert(new VecEnumWithPayload { e = e }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_unit_struct", Public = true)] public partial struct VecUnitStruct { public List s; @@ -631,10 +631,10 @@ public partial struct VecUnitStruct [SpacetimeDB.Reducer] public static void insert_vec_unit_struct(ReducerContext ctx, List s) { - ctx.Db.VecUnitStruct.Insert(new VecUnitStruct { s = s }); + ctx.Db.vec_unit_struct.Insert(new VecUnitStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_byte_struct", Public = true)] public partial struct VecByteStruct { public List s; @@ -643,25 +643,22 @@ public partial struct VecByteStruct [SpacetimeDB.Reducer] public static void insert_vec_byte_struct(ReducerContext ctx, List s) { - ctx.Db.VecByteStruct.Insert(new VecByteStruct { s = s }); + ctx.Db.vec_byte_struct.Insert(new VecByteStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_every_primitive_struct", Public = true)] public partial struct VecEveryPrimitiveStruct { public List s; } [SpacetimeDB.Reducer] - public static void insert_vec_every_primitive_struct( - ReducerContext ctx, - List s - ) + public static void insert_vec_every_primitive_struct(ReducerContext ctx, List s) { - ctx.Db.VecEveryPrimitiveStruct.Insert(new VecEveryPrimitiveStruct { s = s }); + ctx.Db.vec_every_primitive_struct.Insert(new VecEveryPrimitiveStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "vec_every_vec_struct", Public = true)] public partial struct VecEveryVecStruct { public List s; @@ -670,10 +667,10 @@ public partial struct VecEveryVecStruct [SpacetimeDB.Reducer] public static void insert_vec_every_vec_struct(ReducerContext ctx, List s) { - ctx.Db.VecEveryVecStruct.Insert(new VecEveryVecStruct { s = s }); + ctx.Db.vec_every_vec_struct.Insert(new VecEveryVecStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "option_i32", Public = true)] public partial struct OptionI32 { public int? n; @@ -682,10 +679,10 @@ public partial struct OptionI32 [SpacetimeDB.Reducer] public static void insert_option_i32(ReducerContext ctx, int? n) { - ctx.Db.OptionI32.Insert(new OptionI32 { n = n }); + ctx.Db.option_i32.Insert(new OptionI32 { n = n }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "option_string", Public = true)] public partial struct OptionString { public string? s; @@ -694,10 +691,10 @@ public partial struct OptionString [SpacetimeDB.Reducer] public static void insert_option_string(ReducerContext ctx, string? s) { - ctx.Db.OptionString.Insert(new OptionString { s = s }); + ctx.Db.option_string.Insert(new OptionString { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "option_identity", Public = true)] public partial struct OptionIdentity { public Identity? i; @@ -706,10 +703,10 @@ public partial struct OptionIdentity [SpacetimeDB.Reducer] public static void insert_option_identity(ReducerContext ctx, Identity? i) { - ctx.Db.OptionIdentity.Insert(new OptionIdentity { i = i }); + ctx.Db.option_identity.Insert(new OptionIdentity { i = i }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "option_simple_enum", Public = true)] public partial struct OptionSimpleEnum { public SimpleEnum? e; @@ -718,25 +715,22 @@ public partial struct OptionSimpleEnum [SpacetimeDB.Reducer] public static void insert_option_simple_enum(ReducerContext ctx, SimpleEnum? e) { - ctx.Db.OptionSimpleEnum.Insert(new OptionSimpleEnum { e = e }); + ctx.Db.option_simple_enum.Insert(new OptionSimpleEnum { e = e }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "option_every_primitive_struct", Public = true)] public partial struct OptionEveryPrimitiveStruct { public EveryPrimitiveStruct? s; } [SpacetimeDB.Reducer] - public static void insert_option_every_primitive_struct( - ReducerContext ctx, - EveryPrimitiveStruct? s - ) + public static void insert_option_every_primitive_struct(ReducerContext ctx, EveryPrimitiveStruct? s) { - ctx.Db.OptionEveryPrimitiveStruct.Insert(new OptionEveryPrimitiveStruct { s = s }); + ctx.Db.option_every_primitive_struct.Insert(new OptionEveryPrimitiveStruct { s = s }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "option_vec_option_i32", Public = true)] public partial struct OptionVecOptionI32 { public List? v; @@ -745,10 +739,10 @@ public partial struct OptionVecOptionI32 [SpacetimeDB.Reducer] public static void insert_option_vec_option_i32(ReducerContext ctx, List? v) { - ctx.Db.OptionVecOptionI32.Insert(new OptionVecOptionI32 { v = v }); + ctx.Db.option_vec_option_i32.Insert(new OptionVecOptionI32 { v = v }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_u8", Public = true)] public partial struct UniqueU8 { [SpacetimeDB.Unique] @@ -759,23 +753,23 @@ public partial struct UniqueU8 [SpacetimeDB.Reducer] public static void insert_unique_u8(ReducerContext ctx, byte n, int data) { - ctx.Db.UniqueU8.Insert(new UniqueU8 { n = n, data = data }); + ctx.Db.unique_u8.Insert(new UniqueU8 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_u8(ReducerContext ctx, byte n, int data) { var key = n; - ctx.Db.UniqueU8.UpdateByn(key, new UniqueU8 { n = n, data = data }); + ctx.Db.unique_u8.n.Update(new UniqueU8 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_u8(ReducerContext ctx, byte n) { - ctx.Db.UniqueU8.DeleteByn(n); + ctx.Db.unique_u8.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_u16", Public = true)] public partial struct UniqueU16 { [SpacetimeDB.Unique] @@ -786,23 +780,23 @@ public partial struct UniqueU16 [SpacetimeDB.Reducer] public static void insert_unique_u16(ReducerContext ctx, ushort n, int data) { - ctx.Db.UniqueU16.Insert(new UniqueU16 { n = n, data = data }); + ctx.Db.unique_u16.Insert(new UniqueU16 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_u16(ReducerContext ctx, ushort n, int data) { var key = n; - ctx.Db.UniqueU16.UpdateByn(key, new UniqueU16 { n = n, data = data }); + ctx.Db.unique_u16.n.Update(new UniqueU16 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_u16(ReducerContext ctx, ushort n) { - ctx.Db.UniqueU16.DeleteByn(n); + ctx.Db.unique_u16.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_u32", Public = true)] public partial struct UniqueU32 { [SpacetimeDB.Unique] @@ -813,23 +807,23 @@ public partial struct UniqueU32 [SpacetimeDB.Reducer] public static void insert_unique_u32(ReducerContext ctx, uint n, int data) { - ctx.Db.UniqueU32.Insert(new UniqueU32 { n = n, data = data }); + ctx.Db.unique_u32.Insert(new UniqueU32 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_u32(ReducerContext ctx, uint n, int data) { var key = n; - ctx.Db.UniqueU32.UpdateByn(key, new UniqueU32 { n = n, data = data }); + ctx.Db.unique_u32.n.Update(new UniqueU32 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_u32(ReducerContext ctx, uint n) { - ctx.Db.UniqueU32.DeleteByn(n); + ctx.Db.unique_u32.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_u64", Public = true)] public partial struct UniqueU64 { [SpacetimeDB.Unique] @@ -840,23 +834,23 @@ public partial struct UniqueU64 [SpacetimeDB.Reducer] public static void insert_unique_u64(ReducerContext ctx, ulong n, int data) { - ctx.Db.UniqueU64.Insert(new UniqueU64 { n = n, data = data }); + ctx.Db.unique_u64.Insert(new UniqueU64 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_u64(ReducerContext ctx, ulong n, int data) { var key = n; - ctx.Db.UniqueU64.UpdateByn(key, new UniqueU64 { n = n, data = data }); + ctx.Db.unique_u64.n.Update(new UniqueU64 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_u64(ReducerContext ctx, ulong n) { - ctx.Db.UniqueU64.DeleteByn(n); + ctx.Db.unique_u64.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_u128", Public = true)] public partial struct UniqueU128 { [SpacetimeDB.Unique] @@ -867,23 +861,23 @@ public partial struct UniqueU128 [SpacetimeDB.Reducer] public static void insert_unique_u128(ReducerContext ctx, U128 n, int data) { - ctx.Db.UniqueU128.Insert(new UniqueU128 { n = n, data = data }); + ctx.Db.unique_u128.Insert(new UniqueU128 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_u128(ReducerContext ctx, U128 n, int data) { var key = n; - ctx.Db.UniqueU128.UpdateByn(key, new UniqueU128 { n = n, data = data }); + ctx.Db.unique_u128.n.Update(new UniqueU128 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_u128(ReducerContext ctx, U128 n) { - ctx.Db.UniqueU128.DeleteByn(n); + ctx.Db.unique_u128.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_u256", Public = true)] public partial struct UniqueU256 { [SpacetimeDB.Unique] @@ -894,23 +888,23 @@ public partial struct UniqueU256 [SpacetimeDB.Reducer] public static void insert_unique_u256(ReducerContext ctx, U256 n, int data) { - ctx.Db.UniqueU256.Insert(new UniqueU256 { n = n, data = data }); + ctx.Db.unique_u256.Insert(new UniqueU256 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_u256(ReducerContext ctx, U256 n, int data) { var key = n; - ctx.Db.UniqueU256.UpdateByn(key, new UniqueU256 { n = n, data = data }); + ctx.Db.unique_u256.n.Update(new UniqueU256 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_u256(ReducerContext ctx, U256 n) { - ctx.Db.UniqueU256.DeleteByn(n); + ctx.Db.unique_u256.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_i8", Public = true)] public partial struct UniqueI8 { [SpacetimeDB.Unique] @@ -921,23 +915,23 @@ public partial struct UniqueI8 [SpacetimeDB.Reducer] public static void insert_unique_i8(ReducerContext ctx, sbyte n, int data) { - ctx.Db.UniqueI8.Insert(new UniqueI8 { n = n, data = data }); + ctx.Db.unique_i8.Insert(new UniqueI8 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_i8(ReducerContext ctx, sbyte n, int data) { var key = n; - ctx.Db.UniqueI8.UpdateByn(key, new UniqueI8 { n = n, data = data }); + ctx.Db.unique_i8.n.Update(new UniqueI8 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_i8(ReducerContext ctx, sbyte n) { - ctx.Db.UniqueI8.DeleteByn(n); + ctx.Db.unique_i8.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_i16", Public = true)] public partial struct UniqueI16 { [SpacetimeDB.Unique] @@ -948,23 +942,23 @@ public partial struct UniqueI16 [SpacetimeDB.Reducer] public static void insert_unique_i16(ReducerContext ctx, short n, int data) { - ctx.Db.UniqueI16.Insert(new UniqueI16 { n = n, data = data }); + ctx.Db.unique_i16.Insert(new UniqueI16 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_i16(ReducerContext ctx, short n, int data) { var key = n; - ctx.Db.UniqueI16.UpdateByn(key, new UniqueI16 { n = n, data = data }); + ctx.Db.unique_i16.n.Update(new UniqueI16 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_i16(ReducerContext ctx, short n) { - ctx.Db.UniqueI16.DeleteByn(n); + ctx.Db.unique_i16.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_i32", Public = true)] public partial struct UniqueI32 { [SpacetimeDB.Unique] @@ -975,23 +969,23 @@ public partial struct UniqueI32 [SpacetimeDB.Reducer] public static void insert_unique_i32(ReducerContext ctx, int n, int data) { - ctx.Db.UniqueI32.Insert(new UniqueI32 { n = n, data = data }); + ctx.Db.unique_i32.Insert(new UniqueI32 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_i32(ReducerContext ctx, int n, int data) { var key = n; - ctx.Db.UniqueI32.UpdateByn(key, new UniqueI32 { n = n, data = data }); + ctx.Db.unique_i32.n.Update(new UniqueI32 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_i32(ReducerContext ctx, int n) { - ctx.Db.UniqueI32.DeleteByn(n); + ctx.Db.unique_i32.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_i64", Public = true)] public partial struct UniqueI64 { [SpacetimeDB.Unique] @@ -1002,23 +996,23 @@ public partial struct UniqueI64 [SpacetimeDB.Reducer] public static void insert_unique_i64(ReducerContext ctx, long n, int data) { - ctx.Db.UniqueI64.Insert(new UniqueI64 { n = n, data = data }); + ctx.Db.unique_i64.Insert(new UniqueI64 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_i64(ReducerContext ctx, long n, int data) { var key = n; - ctx.Db.UniqueI64.UpdateByn(key, new UniqueI64 { n = n, data = data }); + ctx.Db.unique_i64.n.Update(new UniqueI64 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_i64(ReducerContext ctx, long n) { - ctx.Db.UniqueI64.DeleteByn(n); + ctx.Db.unique_i64.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_i128", Public = true)] public partial struct UniqueI128 { [SpacetimeDB.Unique] @@ -1029,23 +1023,23 @@ public partial struct UniqueI128 [SpacetimeDB.Reducer] public static void insert_unique_i128(ReducerContext ctx, I128 n, int data) { - ctx.Db.UniqueI128.Insert(new UniqueI128 { n = n, data = data }); + ctx.Db.unique_i128.Insert(new UniqueI128 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_i128(ReducerContext ctx, I128 n, int data) { var key = n; - ctx.Db.UniqueI128.UpdateByn(key, new UniqueI128 { n = n, data = data }); + ctx.Db.unique_i128.n.Update(new UniqueI128 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_i128(ReducerContext ctx, I128 n) { - ctx.Db.UniqueI128.DeleteByn(n); + ctx.Db.unique_i128.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_i256", Public = true)] public partial struct UniqueI256 { [SpacetimeDB.Unique] @@ -1056,23 +1050,23 @@ public partial struct UniqueI256 [SpacetimeDB.Reducer] public static void insert_unique_i256(ReducerContext ctx, I256 n, int data) { - ctx.Db.UniqueI256.Insert(new UniqueI256 { n = n, data = data }); + ctx.Db.unique_i256.Insert(new UniqueI256 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_i256(ReducerContext ctx, I256 n, int data) { var key = n; - ctx.Db.UniqueI256.UpdateByn(key, new UniqueI256 { n = n, data = data }); + ctx.Db.unique_i256.n.Update(new UniqueI256 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_i256(ReducerContext ctx, I256 n) { - ctx.Db.UniqueI256.DeleteByn(n); + ctx.Db.unique_i256.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_bool", Public = true)] public partial struct UniqueBool { [SpacetimeDB.Unique] @@ -1083,23 +1077,23 @@ public partial struct UniqueBool [SpacetimeDB.Reducer] public static void insert_unique_bool(ReducerContext ctx, bool b, int data) { - ctx.Db.UniqueBool.Insert(new UniqueBool { b = b, data = data }); + ctx.Db.unique_bool.Insert(new UniqueBool { b = b, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_bool(ReducerContext ctx, bool b, int data) { var key = b; - ctx.Db.UniqueBool.UpdateByb(key, new UniqueBool { b = b, data = data }); + ctx.Db.unique_bool.b.Update(new UniqueBool { b = b, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_bool(ReducerContext ctx, bool b) { - ctx.Db.UniqueBool.DeleteByb(b); + ctx.Db.unique_bool.b.Delete(b); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_string", Public = true)] public partial struct UniqueString { [SpacetimeDB.Unique] @@ -1110,23 +1104,23 @@ public partial struct UniqueString [SpacetimeDB.Reducer] public static void insert_unique_string(ReducerContext ctx, string s, int data) { - ctx.Db.UniqueString.Insert(new UniqueString { s = s, data = data }); + ctx.Db.unique_string.Insert(new UniqueString { s = s, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_string(ReducerContext ctx, string s, int data) { var key = s; - ctx.Db.UniqueString.UpdateBys(key, new UniqueString { s = s, data = data }); + ctx.Db.unique_string.s.Update(new UniqueString { s = s, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_string(ReducerContext ctx, string s) { - ctx.Db.UniqueString.DeleteBys(s); + ctx.Db.unique_string.s.Delete(s); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_identity", Public = true)] public partial struct UniqueIdentity { [SpacetimeDB.Unique] @@ -1137,23 +1131,23 @@ public partial struct UniqueIdentity [SpacetimeDB.Reducer] public static void insert_unique_identity(ReducerContext ctx, Identity i, int data) { - ctx.Db.UniqueIdentity.Insert(new UniqueIdentity { i = i, data = data }); + ctx.Db.unique_identity.Insert(new UniqueIdentity { i = i, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_identity(ReducerContext ctx, Identity i, int data) { var key = i; - ctx.Db.UniqueIdentity.UpdateByi(key, new UniqueIdentity { i = i, data = data }); + ctx.Db.unique_identity.i.Update(new UniqueIdentity { i = i, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_identity(ReducerContext ctx, Identity i) { - ctx.Db.UniqueIdentity.DeleteByi(i); + ctx.Db.unique_identity.i.Delete(i); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "unique_address", Public = true)] public partial struct UniqueAddress { [SpacetimeDB.Unique] @@ -1164,23 +1158,23 @@ public partial struct UniqueAddress [SpacetimeDB.Reducer] public static void insert_unique_address(ReducerContext ctx, Address a, int data) { - ctx.Db.UniqueAddress.Insert(new UniqueAddress { a = a, data = data }); + ctx.Db.unique_address.Insert(new UniqueAddress { a = a, data = data }); } [SpacetimeDB.Reducer] public static void update_unique_address(ReducerContext ctx, Address a, int data) { var key = a; - ctx.Db.UniqueAddress.UpdateBya(key, new UniqueAddress { a = a, data = data }); + ctx.Db.unique_address.a.Update(new UniqueAddress { a = a, data = data }); } [SpacetimeDB.Reducer] public static void delete_unique_address(ReducerContext ctx, Address a) { - ctx.Db.UniqueAddress.DeleteBya(a); + ctx.Db.unique_address.a.Delete(a); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_u8", Public = true)] public partial struct PkU8 { [SpacetimeDB.PrimaryKey] @@ -1191,23 +1185,23 @@ public partial struct PkU8 [SpacetimeDB.Reducer] public static void insert_pk_u8(ReducerContext ctx, byte n, int data) { - ctx.Db.PkU8.Insert(new PkU8 { n = n, data = data }); + ctx.Db.pk_u8.Insert(new PkU8 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_u8(ReducerContext ctx, byte n, int data) { var key = n; - ctx.Db.PkU8.UpdateByn(key, new PkU8 { n = n, data = data }); + ctx.Db.pk_u8.n.Update(new PkU8 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_u8(ReducerContext ctx, byte n) { - ctx.Db.PkU8.DeleteByn(n); + ctx.Db.pk_u8.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_u16", Public = true)] public partial struct PkU16 { [SpacetimeDB.PrimaryKey] @@ -1218,23 +1212,23 @@ public partial struct PkU16 [SpacetimeDB.Reducer] public static void insert_pk_u16(ReducerContext ctx, ushort n, int data) { - ctx.Db.PkU16.Insert(new PkU16 { n = n, data = data }); + ctx.Db.pk_u16.Insert(new PkU16 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_u16(ReducerContext ctx, ushort n, int data) { var key = n; - ctx.Db.PkU16.UpdateByn(key, new PkU16 { n = n, data = data }); + ctx.Db.pk_u16.n.Update(new PkU16 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_u16(ReducerContext ctx, ushort n) { - ctx.Db.PkU16.DeleteByn(n); + ctx.Db.pk_u16.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_u32", Public = true)] public partial struct PkU32 { [SpacetimeDB.PrimaryKey] @@ -1245,23 +1239,23 @@ public partial struct PkU32 [SpacetimeDB.Reducer] public static void insert_pk_u32(ReducerContext ctx, uint n, int data) { - ctx.Db.PkU32.Insert(new PkU32 { n = n, data = data }); + ctx.Db.pk_u32.Insert(new PkU32 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_u32(ReducerContext ctx, uint n, int data) { var key = n; - ctx.Db.PkU32.UpdateByn(key, new PkU32 { n = n, data = data }); + ctx.Db.pk_u32.n.Update(new PkU32 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_u32(ReducerContext ctx, uint n) { - ctx.Db.PkU32.DeleteByn(n); + ctx.Db.pk_u32.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_u64", Public = true)] public partial struct PkU64 { [SpacetimeDB.PrimaryKey] @@ -1272,23 +1266,23 @@ public partial struct PkU64 [SpacetimeDB.Reducer] public static void insert_pk_u64(ReducerContext ctx, ulong n, int data) { - ctx.Db.PkU64.Insert(new PkU64 { n = n, data = data }); + ctx.Db.pk_u64.Insert(new PkU64 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_u64(ReducerContext ctx, ulong n, int data) { var key = n; - ctx.Db.PkU64.UpdateByn(key, new PkU64 { n = n, data = data }); + ctx.Db.pk_u64.n.Update(new PkU64 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_u64(ReducerContext ctx, ulong n) { - ctx.Db.PkU64.DeleteByn(n); + ctx.Db.pk_u64.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_u128", Public = true)] public partial struct PkU128 { [SpacetimeDB.PrimaryKey] @@ -1299,23 +1293,23 @@ public partial struct PkU128 [SpacetimeDB.Reducer] public static void insert_pk_u128(ReducerContext ctx, U128 n, int data) { - ctx.Db.PkU128.Insert(new PkU128 { n = n, data = data }); + ctx.Db.pk_u128.Insert(new PkU128 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_u128(ReducerContext ctx, U128 n, int data) { var key = n; - ctx.Db.PkU128.UpdateByn(key, new PkU128 { n = n, data = data }); + ctx.Db.pk_u128.n.Update(new PkU128 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_u128(ReducerContext ctx, U128 n) { - ctx.Db.PkU128.DeleteByn(n); + ctx.Db.pk_u128.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_u256", Public = true)] public partial struct PkU256 { [SpacetimeDB.PrimaryKey] @@ -1326,23 +1320,23 @@ public partial struct PkU256 [SpacetimeDB.Reducer] public static void insert_pk_u256(ReducerContext ctx, U256 n, int data) { - ctx.Db.PkU256.Insert(new PkU256 { n = n, data = data }); + ctx.Db.pk_u256.Insert(new PkU256 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_u256(ReducerContext ctx, U256 n, int data) { var key = n; - ctx.Db.PkU256.UpdateByn(key, new PkU256 { n = n, data = data }); + ctx.Db.pk_u256.n.Update(new PkU256 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_u256(ReducerContext ctx, U256 n) { - ctx.Db.PkU256.DeleteByn(n); + ctx.Db.pk_u256.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_i8", Public = true)] public partial struct PkI8 { [SpacetimeDB.PrimaryKey] @@ -1353,23 +1347,23 @@ public partial struct PkI8 [SpacetimeDB.Reducer] public static void insert_pk_i8(ReducerContext ctx, sbyte n, int data) { - ctx.Db.PkI8.Insert(new PkI8 { n = n, data = data }); + ctx.Db.pk_i8.Insert(new PkI8 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_i8(ReducerContext ctx, sbyte n, int data) { var key = n; - ctx.Db.PkI8.UpdateByn(key, new PkI8 { n = n, data = data }); + ctx.Db.pk_i8.n.Update(new PkI8 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_i8(ReducerContext ctx, sbyte n) { - ctx.Db.PkI8.DeleteByn(n); + ctx.Db.pk_i8.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_i16", Public = true)] public partial struct PkI16 { [SpacetimeDB.PrimaryKey] @@ -1380,23 +1374,23 @@ public partial struct PkI16 [SpacetimeDB.Reducer] public static void insert_pk_i16(ReducerContext ctx, short n, int data) { - ctx.Db.PkI16.Insert(new PkI16 { n = n, data = data }); + ctx.Db.pk_i16.Insert(new PkI16 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_i16(ReducerContext ctx, short n, int data) { var key = n; - ctx.Db.PkI16.UpdateByn(key, new PkI16 { n = n, data = data }); + ctx.Db.pk_i16.n.Update(new PkI16 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_i16(ReducerContext ctx, short n) { - ctx.Db.PkI16.DeleteByn(n); + ctx.Db.pk_i16.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_i32", Public = true)] public partial struct PkI32 { [SpacetimeDB.PrimaryKey] @@ -1407,23 +1401,23 @@ public partial struct PkI32 [SpacetimeDB.Reducer] public static void insert_pk_i32(ReducerContext ctx, int n, int data) { - ctx.Db.PkI32.Insert(new PkI32 { n = n, data = data }); + ctx.Db.pk_i32.Insert(new PkI32 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_i32(ReducerContext ctx, int n, int data) { var key = n; - ctx.Db.PkI32.UpdateByn(key, new PkI32 { n = n, data = data }); + ctx.Db.pk_i32.n.Update(new PkI32 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_i32(ReducerContext ctx, int n) { - ctx.Db.PkI32.DeleteByn(n); + ctx.Db.pk_i32.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_i64", Public = true)] public partial struct PkI64 { [SpacetimeDB.PrimaryKey] @@ -1434,23 +1428,23 @@ public partial struct PkI64 [SpacetimeDB.Reducer] public static void insert_pk_i64(ReducerContext ctx, long n, int data) { - ctx.Db.PkI64.Insert(new PkI64 { n = n, data = data }); + ctx.Db.pk_i64.Insert(new PkI64 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_i64(ReducerContext ctx, long n, int data) { var key = n; - ctx.Db.PkI64.UpdateByn(key, new PkI64 { n = n, data = data }); + ctx.Db.pk_i64.n.Update(new PkI64 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_i64(ReducerContext ctx, long n) { - ctx.Db.PkI64.DeleteByn(n); + ctx.Db.pk_i64.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_i128", Public = true)] public partial struct PkI128 { [SpacetimeDB.PrimaryKey] @@ -1461,23 +1455,23 @@ public partial struct PkI128 [SpacetimeDB.Reducer] public static void insert_pk_i128(ReducerContext ctx, I128 n, int data) { - ctx.Db.PkI128.Insert(new PkI128 { n = n, data = data }); + ctx.Db.pk_i128.Insert(new PkI128 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_i128(ReducerContext ctx, I128 n, int data) { var key = n; - ctx.Db.PkI128.UpdateByn(key, new PkI128 { n = n, data = data }); + ctx.Db.pk_i128.n.Update(new PkI128 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_i128(ReducerContext ctx, I128 n) { - ctx.Db.PkI128.DeleteByn(n); + ctx.Db.pk_i128.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_i256", Public = true)] public partial struct PkI256 { [SpacetimeDB.PrimaryKey] @@ -1488,23 +1482,23 @@ public partial struct PkI256 [SpacetimeDB.Reducer] public static void insert_pk_i256(ReducerContext ctx, I256 n, int data) { - ctx.Db.PkI256.Insert(new PkI256 { n = n, data = data }); + ctx.Db.pk_i256.Insert(new PkI256 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_i256(ReducerContext ctx, I256 n, int data) { var key = n; - ctx.Db.PkI256.UpdateByn(key, new PkI256 { n = n, data = data }); + ctx.Db.pk_i256.n.Update(new PkI256 { n = n, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_i256(ReducerContext ctx, I256 n) { - ctx.Db.PkI256.DeleteByn(n); + ctx.Db.pk_i256.n.Delete(n); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_bool", Public = true)] public partial struct PkBool { [SpacetimeDB.PrimaryKey] @@ -1515,23 +1509,23 @@ public partial struct PkBool [SpacetimeDB.Reducer] public static void insert_pk_bool(ReducerContext ctx, bool b, int data) { - ctx.Db.PkBool.Insert(new PkBool { b = b, data = data }); + ctx.Db.pk_bool.Insert(new PkBool { b = b, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_bool(ReducerContext ctx, bool b, int data) { var key = b; - ctx.Db.PkBool.UpdateByb(key, new PkBool { b = b, data = data }); + ctx.Db.pk_bool.b.Update(new PkBool { b = b, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_bool(ReducerContext ctx, bool b) { - ctx.Db.PkBool.DeleteByb(b); + ctx.Db.pk_bool.b.Delete(b); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_string", Public = true)] public partial struct PkString { [SpacetimeDB.PrimaryKey] @@ -1542,23 +1536,23 @@ public partial struct PkString [SpacetimeDB.Reducer] public static void insert_pk_string(ReducerContext ctx, string s, int data) { - ctx.Db.PkString.Insert(new PkString { s = s, data = data }); + ctx.Db.pk_string.Insert(new PkString { s = s, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_string(ReducerContext ctx, string s, int data) { var key = s; - ctx.Db.PkString.UpdateBys(key, new PkString { s = s, data = data }); + ctx.Db.pk_string.s.Update(new PkString { s = s, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_string(ReducerContext ctx, string s) { - ctx.Db.PkString.DeleteBys(s); + ctx.Db.pk_string.s.Delete(s); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_identity", Public = true)] public partial struct PkIdentity { [SpacetimeDB.PrimaryKey] @@ -1569,23 +1563,23 @@ public partial struct PkIdentity [SpacetimeDB.Reducer] public static void insert_pk_identity(ReducerContext ctx, Identity i, int data) { - ctx.Db.PkIdentity.Insert(new PkIdentity { i = i, data = data }); + ctx.Db.pk_identity.Insert(new PkIdentity { i = i, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_identity(ReducerContext ctx, Identity i, int data) { var key = i; - ctx.Db.PkIdentity.UpdateByi(key, new PkIdentity { i = i, data = data }); + ctx.Db.pk_identity.i.Update(new PkIdentity { i = i, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_identity(ReducerContext ctx, Identity i) { - ctx.Db.PkIdentity.DeleteByi(i); + ctx.Db.pk_identity.i.Delete(i); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "pk_address", Public = true)] public partial struct PkAddress { [SpacetimeDB.PrimaryKey] @@ -1596,52 +1590,50 @@ public partial struct PkAddress [SpacetimeDB.Reducer] public static void insert_pk_address(ReducerContext ctx, Address a, int data) { - ctx.Db.PkAddress.Insert(new PkAddress { a = a, data = data }); + ctx.Db.pk_address.Insert(new PkAddress { a = a, data = data }); } [SpacetimeDB.Reducer] public static void update_pk_address(ReducerContext ctx, Address a, int data) { var key = a; - ctx.Db.PkAddress.UpdateBya(key, new PkAddress { a = a, data = data }); + ctx.Db.pk_address.a.Update(new PkAddress { a = a, data = data }); } [SpacetimeDB.Reducer] public static void delete_pk_address(ReducerContext ctx, Address a) { - ctx.Db.PkAddress.DeleteBya(a); + ctx.Db.pk_address.a.Delete(a); } [SpacetimeDB.Reducer] public static void insert_caller_one_identity(ReducerContext ctx) { - ctx.Db.OneIdentity.Insert(new OneIdentity { i = ctx.CallerIdentity }); + ctx.Db.one_identity.Insert(new OneIdentity { i = ctx.CallerIdentity }); } [SpacetimeDB.Reducer] public static void insert_caller_vec_identity(ReducerContext ctx) { - ctx.Db.VecIdentity.Insert( - new VecIdentity { i = new List { ctx.CallerIdentity } } - ); + ctx.Db.vec_identity.Insert(new VecIdentity { i = new List { ctx.CallerIdentity } }); } [SpacetimeDB.Reducer] public static void insert_caller_unique_identity(ReducerContext ctx, int data) { - ctx.Db.UniqueIdentity.Insert(new UniqueIdentity { i = ctx.CallerIdentity, data = data }); + ctx.Db.unique_identity.Insert(new UniqueIdentity { i = ctx.CallerIdentity, data = data }); } [SpacetimeDB.Reducer] public static void insert_caller_pk_identity(ReducerContext ctx, int data) { - ctx.Db.PkIdentity.Insert(new PkIdentity { i = ctx.CallerIdentity, data = data }); + ctx.Db.pk_identity.Insert(new PkIdentity { i = ctx.CallerIdentity, data = data }); } [SpacetimeDB.Reducer] public static void insert_caller_one_address(ReducerContext ctx) { - ctx.Db.OneAddress.Insert(new OneAddress { a = (Address)ctx.CallerAddress! }); + ctx.Db.one_address.Insert(new OneAddress { a = (Address)ctx.CallerAddress!, }); } [SpacetimeDB.Reducer] @@ -1650,7 +1642,7 @@ public static void insert_caller_vec_address(ReducerContext ctx) // VecAddress::insert(VecAddress { // < a[_]>::into_vec( // #[rustc_box] - // ::alloc::boxed::Box::new([ctx.CallerAddress.context("No address in reducer context")?]), + // ::alloc::boxed::Box::new([ctx.Address.context("No address in reducer context")?]), // ), // }); } @@ -1658,18 +1650,16 @@ public static void insert_caller_vec_address(ReducerContext ctx) [SpacetimeDB.Reducer] public static void insert_caller_unique_address(ReducerContext ctx, int data) { - ctx.Db.UniqueAddress.Insert( - new UniqueAddress { a = (Address)ctx.CallerAddress!, data = data } - ); + ctx.Db.unique_address.Insert(new UniqueAddress { a = (Address)ctx.CallerAddress!, data = data }); } [SpacetimeDB.Reducer] public static void insert_caller_pk_address(ReducerContext ctx, int data) { - ctx.Db.PkAddress.Insert(new PkAddress { a = (Address)ctx.CallerAddress!, data = data }); + ctx.Db.pk_address.Insert(new PkAddress { a = (Address)ctx.CallerAddress!, data = data }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "large_table", Public = true)] public partial struct LargeTable { public byte a; @@ -1723,50 +1713,44 @@ public static void insert_large_table( EveryVecStruct v ) { - ctx.Db.LargeTable.Insert( - new LargeTable - { - a = a, - b = b, - c = c, - d = d, - e = e, - f = f, - g = g, - h = h, - i = i, - j = j, - k = k, - l = l, - m = m, - n = n, - o = o, - p = p, - q = q, - r = r, - s = s, - t = t, - u = u, - v = v, - } - ); + ctx.Db.large_table.Insert(new LargeTable { + a = a, + b = b, + c = c, + d = d, + e = e, + f = f, + g = g, + h = h, + i = i, + j = j, + k = k, + l = l, + m = m, + n = n, + o = o, + p = p, + q = q, + r = r, + s = s, + t = t, + u = u, + v = v, + }); } [SpacetimeDB.Reducer] public static void insert_primitives_as_strings(ReducerContext ctx, EveryPrimitiveStruct s) { - ctx.Db.VecString.Insert( - new VecString - { - s = typeof(EveryPrimitiveStruct) - .GetFields() - .Select(f => f.GetValue(s)!.ToString()!.ToLowerInvariant()) - .ToList(), - } - ); + ctx.Db.vec_string.Insert(new VecString { + s = typeof(EveryPrimitiveStruct) + .GetFields() + .Select(f => f.GetValue(s)!.ToString()!.ToLowerInvariant()) + .ToList() + }); } - [SpacetimeDB.Table(Public = true)] + [SpacetimeDB.Table(Name = "table_holds_table", Public = true)] public partial struct TableHoldsTable { public OneU8 a; @@ -1776,7 +1760,7 @@ public partial struct TableHoldsTable [SpacetimeDB.Reducer] public static void insert_table_holds_table(ReducerContext ctx, OneU8 a, VecU8 b) { - ctx.Db.TableHoldsTable.Insert(new TableHoldsTable { a = a, b = b }); + ctx.Db.table_holds_table.Insert(new TableHoldsTable { a = a, b = b }); } [SpacetimeDB.Reducer] diff --git a/modules/spacetimedb-quickstart-cs/Lib.cs b/modules/spacetimedb-quickstart-cs/Lib.cs index ac88dab7d0..8936514c4f 100644 --- a/modules/spacetimedb-quickstart-cs/Lib.cs +++ b/modules/spacetimedb-quickstart-cs/Lib.cs @@ -3,6 +3,7 @@ namespace SpacetimeDB.Examples.QuickStart.Server; using SpacetimeDB; [Table(Public = true)] +[Index(Name = "Age", BTree = ["Age"])] public partial struct Person { [AutoInc] @@ -33,8 +34,7 @@ public static void say_hello(ReducerContext ctx) [SpacetimeDB.Reducer] public static void list_over_age(ReducerContext ctx, byte age) { - // TODO: convert this to use BTree index. - foreach (var person in ctx.Db.Person.Iter().Where(person => person.Age >= age)) + foreach (var person in ctx.Db.Person.Age.Filter((age, byte.MaxValue))) { Log.Info($"{person.Name} has age {person.Age} >= {age}"); } diff --git a/smoketests/tests/namespaces.py b/smoketests/tests/namespaces.py index 2341d74ddb..b1bd0eb268 100644 --- a/smoketests/tests/namespaces.py +++ b/smoketests/tests/namespaces.py @@ -23,7 +23,7 @@ def test_spacetimedb_ns_csharp(self): with tempfile.TemporaryDirectory() as tmpdir: self.spacetime("generate", "--out-dir", tmpdir, "--lang=cs", "--project-path", self.project_path) - self.assertEqual(count_matches(tmpdir, f"namespace {namespace}"), 5) + self.assertEqual(count_matches(tmpdir, f"namespace {namespace}"), 4) def test_custom_ns_csharp(self): """Ensure that when a custom namespace is specified on the command line, it actually gets used in generation""" @@ -33,5 +33,5 @@ def test_custom_ns_csharp(self): with tempfile.TemporaryDirectory() as tmpdir: self.spacetime("generate", "--out-dir", tmpdir, "--lang=cs", "--namespace", namespace, "--project-path", self.project_path) - self.assertEqual(count_matches(tmpdir, f"namespace {namespace}"), 5) - self.assertEqual(count_matches(tmpdir, "using SpacetimeDB;"), 5) + self.assertEqual(count_matches(tmpdir, f"namespace {namespace}"), 4) + self.assertEqual(count_matches(tmpdir, "using SpacetimeDB;"), 4)