Skip to content

Commit da71d0f

Browse files
authored
WASM ABI: insert -> datastore_insert_bsatn & impl new semantics (#1639)
1 parent 68e3565 commit da71d0f

File tree

31 files changed

+383
-176
lines changed

31 files changed

+383
-176
lines changed

crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PrivateTable.verified.cs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-csharp/Codegen/Module.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ public override Scope.Extensions ToExtensions()
176176
);
177177
}
178178

179-
var hasAutoIncFields = Members.Any(f => f.Attrs.HasFlag(ColumnAttrs.AutoInc));
179+
var autoIncFields = Members
180+
.Where(f => f.Attrs.HasFlag(ColumnAttrs.AutoInc))
181+
.Select(f => f.Name);
180182

181183
var iTable = $"SpacetimeDB.Internal.ITable<{ShortName}>";
182184

@@ -186,7 +188,19 @@ public override Scope.Extensions ToExtensions()
186188

187189
extensions.Contents.Append(
188190
$$"""
189-
static bool {{iTable}}.HasAutoIncFields => {{hasAutoIncFields.ToString().ToLower()}};
191+
public void ReadGenFields(System.IO.BinaryReader reader) {
192+
{{string.Join(
193+
"\n",
194+
autoIncFields.Select(name =>
195+
$$"""
196+
if ({{name}} == default)
197+
{
198+
{{name}} = BSATN.{{name}}.Read(reader);
199+
}
200+
"""
201+
)
202+
)}}
203+
}
190204
191205
static SpacetimeDB.Internal.Module.TableDesc {{iTable}}.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => new (
192206
new (

crates/bindings-csharp/Runtime/Exceptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public class UniqueAlreadyExistsException : StdbException
2727
public override string Message => "Value with given unique identifier already exists";
2828
}
2929

30+
public class ScheduleAtDelayTooLongException : StdbException
31+
{
32+
public override string Message => "Specified delay in scheduling row was too long";
33+
}
34+
3035
public class BufferTooSmallException : StdbException
3136
{
3237
public override string Message => "The provided buffer is not large enough to store the data";

crates/bindings-csharp/Runtime/Internal/FFI.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public enum Errno : short
3131
NO_SPACE = 9,
3232
BUFFER_TOO_SMALL = 11,
3333
UNIQUE_ALREADY_EXISTS = 12,
34+
SCHEDULE_AT_DELAY_TOO_LONG = 13,
3435
}
3536

3637
#pragma warning disable IDE1006 // Naming Styles - Not applicable to FFI stuff.
@@ -78,6 +79,7 @@ public static CheckedStatus ConvertToManaged(Errno status)
7879
Errno.NO_SPACE => new NoSpaceException(),
7980
Errno.BUFFER_TOO_SMALL => new BufferTooSmallException(),
8081
Errno.UNIQUE_ALREADY_EXISTS => new UniqueAlreadyExistsException(),
82+
Errno.SCHEDULE_AT_DELAY_TOO_LONG => new ScheduleAtDelayTooLongException(),
8183
_ => new UnknownException(status),
8284
};
8385
}
@@ -145,7 +147,11 @@ out RowIter out_
145147
);
146148

147149
[LibraryImport(StdbNamespace)]
148-
public static partial CheckedStatus _insert(TableId table_id, byte[] row, uint row_len);
150+
public static partial CheckedStatus _datastore_insert_bsatn(
151+
TableId table_id,
152+
Span<byte> row,
153+
ref uint row_len
154+
);
149155

150156
[LibraryImport(StdbNamespace)]
151157
public static partial CheckedStatus _delete_by_col_eq(

crates/bindings-csharp/Runtime/Internal/ITable.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ public interface ITable<T> : IStructuralReadWrite
77
where T : ITable<T>, new()
88
{
99
// These are the methods that codegen needs to implement.
10+
void ReadGenFields(BinaryReader reader);
1011
static abstract Module.TableDesc MakeTableDesc(ITypeRegistrar registrar);
1112
static abstract Filter CreateFilter();
12-
static abstract bool HasAutoIncFields { get; }
1313

1414
// These are static helpers that codegen can use.
1515

@@ -150,14 +150,15 @@ public static IEnumerable<T> Query(Expression<Func<T, bool>> query) =>
150150

151151
protected static void Insert(T row)
152152
{
153+
// Insert the row.
153154
var bytes = ToBytes(row);
154-
FFI._insert(tableId, bytes, (uint)bytes.Length);
155-
if (T.HasAutoIncFields)
156-
{
157-
using var stream = new MemoryStream(bytes);
158-
using var reader = new BinaryReader(stream);
159-
row.ReadFields(reader);
160-
}
155+
var bytes_len = (uint)bytes.Length;
156+
FFI._datastore_insert_bsatn(tableId, bytes, ref bytes_len);
157+
158+
// Write back any generated column values.
159+
using var stream = new MemoryStream(bytes, 0, (int)bytes_len);
160+
using var reader = new BinaryReader(stream);
161+
row.ReadGenFields(reader);
161162
}
162163

163164
protected readonly ref struct ColEq

crates/bindings-csharp/Runtime/bindings.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ IMPORT(Status, _iter_by_col_eq,
5454
(TableId table_id, ColId col_id, const uint8_t* value,
5555
uint32_t value_len, RowIter* iter),
5656
(table_id, col_id, value, value_len, iter));
57-
IMPORT(Status, _insert, (TableId table_id, const uint8_t* row, uint32_t len),
58-
(table_id, row, len));
57+
IMPORT(Status, _datastore_insert_bsatn, (TableId table_id, const uint8_t* row_ptr, size_t* row_len_ptr),
58+
(table_id, row_ptr, row_len_ptr));
5959
IMPORT(Status, _delete_by_col_eq,
6060
(TableId table_id, ColId col_id, const uint8_t* value,
6161
uint32_t value_len, uint32_t* num_deleted),

crates/bindings-csharp/Runtime/build/SpacetimeDB.Runtime.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<UnmanagedEntryPointsAssembly Include="SpacetimeDB.Runtime" />
66
<WasmImport Include="$(SpacetimeNamespace)!_console_log" />
77
<WasmImport Include="$(SpacetimeNamespace)!_iter_by_col_eq" />
8-
<WasmImport Include="$(SpacetimeNamespace)!_insert" />
98
<WasmImport Include="$(SpacetimeNamespace)!_delete_by_col_eq" />
109
<WasmImport Include="$(SpacetimeNamespace)!_iter_start_filtered" />
1110
<WasmImport Include="$(SpacetimeNamespace)!_table_id_from_name" />
1211
<WasmImport Include="$(SpacetimeNamespace)!_datastore_table_row_count" />
1312
<WasmImport Include="$(SpacetimeNamespace)!_datastore_table_scan_bsatn" />
1413
<WasmImport Include="$(SpacetimeNamespace)!_row_iter_bsatn_advance" />
1514
<WasmImport Include="$(SpacetimeNamespace)!_row_iter_bsatn_close" />
15+
<WasmImport Include="$(SpacetimeNamespace)!_datastore_insert_bsatn" />
1616
<WasmImport Include="$(SpacetimeNamespace)!_datastore_delete_all_by_eq_bsatn" />
1717
<WasmImport Include="$(SpacetimeNamespace)!_bytes_source_read" />
1818
<WasmImport Include="$(SpacetimeNamespace)!_bytes_sink_write" />

crates/bindings-macro/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,26 @@ fn spacetimedb_tabletype_impl(item: syn::DeriveInput) -> syn::Result<TokenStream
759759
)
760760
});
761761

762+
// Generate `integrate_generated_columns`
763+
// which will integrate all generated auto-inc col values into `_row`.
764+
let integrate_gen_col = columns
765+
.iter()
766+
.filter(|col| col.attr.has_autoinc())
767+
.map(|col| col.field.ident.unwrap())
768+
.map(|field| {
769+
quote_spanned!(field.span()=>
770+
if spacetimedb::IsSequenceTrigger::is_sequence_trigger(&_row.#field) {
771+
_row.#field = spacetimedb::sats::bsatn::from_reader(_in).unwrap();
772+
}
773+
)
774+
});
775+
let integrate_generated_columns = quote_spanned!(item.span() =>
776+
fn integrate_generated_columns(_row: &mut Self, mut _generated_cols: &[u8]) {
777+
let mut _in = &mut _generated_cols;
778+
#(#integrate_gen_col)*
779+
}
780+
);
781+
762782
let scheduled_constant = match sats_ty.scheduled {
763783
Some(reducer_name) => quote!(Some(#reducer_name)),
764784
None => quote!(None),
@@ -774,6 +794,7 @@ fn spacetimedb_tabletype_impl(item: syn::DeriveInput) -> syn::Result<TokenStream
774794
];
775795
const INDEXES: &'static [spacetimedb::IndexDesc<'static>] = &[#(#indexes),*];
776796
type InsertResult = #insert_result;
797+
#integrate_generated_columns
777798
#table_id_from_name_func
778799
}
779800
};

0 commit comments

Comments
 (0)