WIP: Start SDK tests for delete_all_by_eq_bsatn (#2164)

# Description of Changes

This API used to be unimplemented and the SDK tests did not exercise it.
Now it is implemented but while playing with blackholio I noticed the C#
implementation was wrong.

For now I am going to fix blackholio by avoiding use of this API for
now, but we should also correct the implementation and test it.

# API and ABI breaking changes

None 

# Expected complexity level and risk

0

# Testing

Working on adding tests. If someone is more familiar with the SDK tests
I would appreciate help amending them.

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
This commit is contained in:
james gilles
2026-04-28 17:04:28 -04:00
committed by GitHub
parent 599496111c
commit 193ddfd670
2 changed files with 108 additions and 93 deletions
@@ -189,7 +189,7 @@ public interface ITableView<View, T>
using var stream = new MemoryStream();
using var writer = new BinaryWriter(stream);
// `datastore_delete_all_by_eq_bsatn` expects an array-like BSATN.
// Write a length of 1 without actually wrapping the `row` into array
// Write a length of 1 without actually wrapping the `row` into an array
// (annoyingly, that would require passing `TRW` through a bunch of APIs).
writer.Write(1U);
row.WriteFields(writer);
+107 -92
View File
@@ -205,6 +205,21 @@ macro_rules! define_tables {
define_tables!(@impl_ops $name { $($($ops)*)? } $($field_name $ty,)*);
};
// Define a reducer for tables which deletes a row by equality on all columns.
(@impl_ops $name:ident
{ delete_all $delete:ident
$(, $($ops:tt)* )? }
$($field_name:ident $ty:ty),* $(,)*) => {
paste::paste! {
#[spacetimedb::reducer]
pub fn $delete (ctx: &ReducerContext, $($field_name : $ty,)*) {
ctx.db.[<$name:snake>]().delete($name { $($field_name,)* });
}
}
define_tables!(@impl_ops $name { $($($ops)*)? } $($field_name $ty,)*);
};
// Define a reducer for tables with a primary key field,
// which uses `update` to update by that primary key field.
(@impl_ops $name:ident
@@ -276,89 +291,89 @@ macro_rules! define_tables {
// Tables holding a single value.
define_tables! {
OneU8 { insert insert_one_u8 } n u8;
OneU16 { insert insert_one_u16 } n u16;
OneU32 { insert insert_one_u32 } n u32;
OneU64 { insert insert_one_u64 } n u64;
OneU128 { insert insert_one_u128 } n u128;
OneU256 { insert insert_one_u256 } n u256;
OneU8 { insert insert_one_u8, delete_all delete_all_one_u8 } n u8;
OneU16 { insert insert_one_u16, delete_all delete_all_one_u16 } n u16;
OneU32 { insert insert_one_u32, delete_all delete_all_one_u32 } n u32;
OneU64 { insert insert_one_u64, delete_all delete_all_one_u64 } n u64;
OneU128 { insert insert_one_u128, delete_all delete_all_one_u128 } n u128;
OneU256 { insert insert_one_u256, delete_all delete_all_one_u256 } n u256;
OneI8 { insert insert_one_i8 } n i8;
OneI16 { insert insert_one_i16 } n i16;
OneI32 { insert insert_one_i32 } n i32;
OneI64 { insert insert_one_i64 } n i64;
OneI128 { insert insert_one_i128 } n i128;
OneI256 { insert insert_one_i256 } n i256;
OneI8 { insert insert_one_i8, delete_all delete_all_one_i8 } n i8;
OneI16 { insert insert_one_i16, delete_all delete_all_one_i16 } n i16;
OneI32 { insert insert_one_i32, delete_all delete_all_one_i32 } n i32;
OneI64 { insert insert_one_i64, delete_all delete_all_one_i64 } n i64;
OneI128 { insert insert_one_i128, delete_all delete_all_one_i128 } n i128;
OneI256 { insert insert_one_i256, delete_all delete_all_one_i256 } n i256;
OneBool { insert insert_one_bool } b bool;
OneBool { insert insert_one_bool, delete_all delete_all_one_bool } b bool;
OneF32 { insert insert_one_f32 } f f32;
OneF64 { insert insert_one_f64 } f f64;
OneF32 { insert insert_one_f32, delete_all delete_all_one_f32 } f f32;
OneF64 { insert insert_one_f64, delete_all delete_all_one_f64 } f f64;
OneString { insert insert_one_string } s String;
OneString { insert insert_one_string, delete_all delete_all_one_string } s String;
OneIdentity { insert insert_one_identity } i Identity;
OneIdentity { insert insert_one_identity, delete_all delete_all_one_identity } i Identity;
OneConnectionId { insert insert_one_connection_id} a ConnectionId;
OneUuid { insert insert_one_uuid } u Uuid;
OneUuid { insert insert_one_uuid, delete_all delete_all_one_uuid } u Uuid;
OneTimestamp { insert insert_one_timestamp } t Timestamp;
OneTimestamp { insert insert_one_timestamp, delete_all delete_all_one_timestamp } t Timestamp;
OneSimpleEnum { insert insert_one_simple_enum } e SimpleEnum;
OneEnumWithPayload { insert insert_one_enum_with_payload } e EnumWithPayload;
OneSimpleEnum { insert insert_one_simple_enum, delete_all delete_all_one_simple_enum } e SimpleEnum;
OneEnumWithPayload { insert insert_one_enum_with_payload, delete_all delete_all_one_enum_with_payload } e EnumWithPayload;
OneUnitStruct { insert insert_one_unit_struct } s UnitStruct;
OneByteStruct { insert insert_one_byte_struct } s ByteStruct;
OneEveryPrimitiveStruct { insert insert_one_every_primitive_struct } s EveryPrimitiveStruct;
OneEveryVecStruct { insert insert_one_every_vec_struct } s EveryVecStruct;
OneUnitStruct { insert insert_one_unit_struct, delete_all delete_all_one_unit_struct } s UnitStruct;
OneByteStruct { insert insert_one_byte_struct, delete_all delete_all_one_byte_struct } s ByteStruct;
OneEveryPrimitiveStruct { insert insert_one_every_primitive_struct, delete_all delete_all_one_every_primitive_struct } s EveryPrimitiveStruct;
OneEveryVecStruct { insert insert_one_every_vec_struct, delete_all delete_all_one_every_vec_struct } s EveryVecStruct;
}
// Tables holding a Vec of various types.
define_tables! {
VecU8 { insert insert_vec_u8 } n Vec<u8>;
VecU16 { insert insert_vec_u16 } n Vec<u16>;
VecU32 { insert insert_vec_u32 } n Vec<u32>;
VecU64 { insert insert_vec_u64 } n Vec<u64>;
VecU128 { insert insert_vec_u128 } n Vec<u128>;
VecU256 { insert insert_vec_u256 } n Vec<u256>;
VecU8 { insert insert_vec_u8, delete_all delete_all_vec_u8 } n Vec<u8>;
VecU16 { insert insert_vec_u16, delete_all delete_all_vec_u16 } n Vec<u16>;
VecU32 { insert insert_vec_u32, delete_all delete_all_vec_u32 } n Vec<u32>;
VecU64 { insert insert_vec_u64, delete_all delete_all_vec_u64 } n Vec<u64>;
VecU128 { insert insert_vec_u128, delete_all delete_all_vec_u128 } n Vec<u128>;
VecU256 { insert insert_vec_u256, delete_all delete_all_vec_u256 } n Vec<u256>;
VecI8 { insert insert_vec_i8 } n Vec<i8>;
VecI16 { insert insert_vec_i16 } n Vec<i16>;
VecI32 { insert insert_vec_i32 } n Vec<i32>;
VecI64 { insert insert_vec_i64 } n Vec<i64>;
VecI128 { insert insert_vec_i128 } n Vec<i128>;
VecI256 { insert insert_vec_i256 } n Vec<i256>;
VecI8 { insert insert_vec_i8, delete_all delete_all_vec_i8 } n Vec<i8>;
VecI16 { insert insert_vec_i16, delete_all delete_all_vec_i16 } n Vec<i16>;
VecI32 { insert insert_vec_i32, delete_all delete_all_vec_i32 } n Vec<i32>;
VecI64 { insert insert_vec_i64, delete_all delete_all_vec_i64 } n Vec<i64>;
VecI128 { insert insert_vec_i128, delete_all delete_all_vec_i128 } n Vec<i128>;
VecI256 { insert insert_vec_i256, delete_all delete_all_vec_i256 } n Vec<i256>;
VecBool { insert insert_vec_bool } b Vec<bool>;
VecBool { insert insert_vec_bool, delete_all delete_all_vec_bool } b Vec<bool>;
VecF32 { insert insert_vec_f32 } f Vec<f32>;
VecF64 { insert insert_vec_f64 } f Vec<f64>;
VecF32 { insert insert_vec_f32, delete_all delete_all_vec_f32 } f Vec<f32>;
VecF64 { insert insert_vec_f64, delete_all delete_all_vec_f64 } f Vec<f64>;
VecString { insert insert_vec_string } s Vec<String>;
VecString { insert insert_vec_string, delete_all delete_all_vec_string } s Vec<String>;
VecIdentity { insert insert_vec_identity } i Vec<Identity>;
VecIdentity { insert insert_vec_identity, delete_all delete_all_vec_identity } i Vec<Identity>;
VecConnectionId { insert insert_vec_connection_id} a Vec<ConnectionId>;
VecUuid { insert insert_vec_uuid } u Vec<Uuid>;
VecUuid { insert insert_vec_uuid, delete_all delete_all_vec_uuid } u Vec<Uuid>;
VecTimestamp { insert insert_vec_timestamp } t Vec<Timestamp>;
VecTimestamp { insert insert_vec_timestamp, delete_all delete_all_vec_timestamp } t Vec<Timestamp>;
VecSimpleEnum { insert insert_vec_simple_enum } e Vec<SimpleEnum>;
VecEnumWithPayload { insert insert_vec_enum_with_payload } e Vec<EnumWithPayload>;
VecSimpleEnum { insert insert_vec_simple_enum, delete_all delete_all_vec_simple_enum } e Vec<SimpleEnum>;
VecEnumWithPayload { insert insert_vec_enum_with_payload, delete_all delete_all_vec_enum_with_payload } e Vec<EnumWithPayload>;
VecUnitStruct { insert insert_vec_unit_struct } s Vec<UnitStruct>;
VecByteStruct { insert insert_vec_byte_struct } s Vec<ByteStruct>;
VecEveryPrimitiveStruct { insert insert_vec_every_primitive_struct } s Vec<EveryPrimitiveStruct>;
VecEveryVecStruct { insert insert_vec_every_vec_struct } s Vec<EveryVecStruct>;
VecUnitStruct { insert insert_vec_unit_struct, delete_all delete_all_vec_unit_struct } s Vec<UnitStruct>;
VecByteStruct { insert insert_vec_byte_struct, delete_all delete_all_vec_byte_struct } s Vec<ByteStruct>;
VecEveryPrimitiveStruct { insert insert_vec_every_primitive_struct, delete_all delete_all_vec_every_primitive_struct } s Vec<EveryPrimitiveStruct>;
VecEveryVecStruct { insert insert_vec_every_vec_struct, delete_all delete_all_vec_every_vec_struct } s Vec<EveryVecStruct>;
}
// Tables holding an Option of various types.
define_tables! {
OptionI32 { insert insert_option_i32 } n Option<i32>;
OptionString { insert insert_option_string } s Option<String>;
OptionIdentity { insert insert_option_identity } i Option<Identity>;
OptionUuid { insert insert_option_uuid } u Option<Uuid>;
OptionSimpleEnum { insert insert_option_simple_enum } e Option<SimpleEnum>;
OptionEveryPrimitiveStruct { insert insert_option_every_primitive_struct } s Option<EveryPrimitiveStruct>;
OptionVecOptionI32 { insert insert_option_vec_option_i32 } v Option<Vec<Option<i32>>>;
OptionI32 { insert insert_option_i32, delete_all delete_all_option_i32 } n Option<i32>;
OptionString { insert insert_option_string, delete_all delete_all_option_string } s Option<String>;
OptionIdentity { insert insert_option_identity, delete_all delete_all_option_identity } i Option<Identity>;
OptionUuid { insert insert_option_uuid, delete_all delete_all_option_uuid } u Option<Uuid>;
OptionSimpleEnum { insert insert_option_simple_enum, delete_all delete_all_option_simple_enum } e Option<SimpleEnum>;
OptionEveryPrimitiveStruct { insert insert_option_every_primitive_struct, delete_all delete_all_option_every_primitive_struct } s Option<EveryPrimitiveStruct>;
OptionVecOptionI32 { insert insert_option_vec_option_i32, delete_all delete_all_option_vec_option_i32 } v Option<Vec<Option<i32>>>;
}
// Tables holding a Result of various types.
@@ -375,106 +390,106 @@ define_tables! {
// This allows us to test delete events, and the semantically correct absence of update events.
define_tables! {
UniqueU8 {
insert_or_panic insert_unique_u8,
insert_or_panic insert_unique_u8, delete_all delete_all_unique_u8,
update_non_pk_by update_unique_u8 = update_by_n(n),
delete_by delete_unique_u8 = delete_by_n(n: u8),
} #[unique] n u8, data i32;
UniqueU16 {
insert_or_panic insert_unique_u16,
insert_or_panic insert_unique_u16, delete_all delete_all_unique_u16,
update_non_pk_by update_unique_u16 = update_by_n(n),
delete_by delete_unique_u16 = delete_by_n(n: u16),
} #[unique] n u16, data i32;
UniqueU32 {
insert_or_panic insert_unique_u32,
insert_or_panic insert_unique_u32, delete_all delete_all_unique_u32,
update_non_pk_by update_unique_u32 = update_by_n(n),
delete_by delete_unique_u32 = delete_by_n(n: u32),
} #[unique] n u32, data i32;
UniqueU64 {
insert_or_panic insert_unique_u64,
insert_or_panic insert_unique_u64, delete_all delete_all_unique_u64,
update_non_pk_by update_unique_u64 = update_by_n(n),
delete_by delete_unique_u64 = delete_by_n(n: u64),
} #[unique] n u64, data i32;
UniqueU128 {
insert_or_panic insert_unique_u128,
insert_or_panic insert_unique_u128, delete_all delete_all_unique_u128,
update_non_pk_by update_unique_u128 = update_by_n(n),
delete_by delete_unique_u128 = delete_by_n(n: u128),
} #[unique] n u128, data i32;
UniqueU256 {
insert_or_panic insert_unique_u256,
insert_or_panic insert_unique_u256, delete_all delete_all_unique_u256,
update_non_pk_by update_unique_u256 = update_by_n(n),
delete_by delete_unique_u256 = delete_by_n(n: u256),
} #[unique] n u256, data i32;
UniqueI8 {
insert_or_panic insert_unique_i8,
insert_or_panic insert_unique_i8, delete_all delete_all_unique_i8,
update_non_pk_by update_unique_i8 = update_by_n(n),
delete_by delete_unique_i8 = delete_by_n(n: i8),
} #[unique] n i8, data i32;
UniqueI16 {
insert_or_panic insert_unique_i16,
insert_or_panic insert_unique_i16, delete_all delete_all_unique_i16,
update_non_pk_by update_unique_i16 = update_by_n(n),
delete_by delete_unique_i16 = delete_by_n(n: i16),
} #[unique] n i16, data i32;
UniqueI32 {
insert_or_panic insert_unique_i32,
insert_or_panic insert_unique_i32, delete_all delete_all_unique_i32,
update_non_pk_by update_unique_i32 = update_by_n(n),
delete_by delete_unique_i32 = delete_by_n(n: i32),
} #[unique] n i32, data i32;
UniqueI64 {
insert_or_panic insert_unique_i64,
insert_or_panic insert_unique_i64, delete_all delete_all_unique_i64,
update_non_pk_by update_unique_i64 = update_by_n(n),
delete_by delete_unique_i64 = delete_by_n(n: i64),
} #[unique] n i64, data i32;
UniqueI128 {
insert_or_panic insert_unique_i128,
insert_or_panic insert_unique_i128, delete_all delete_all_unique_i128,
update_non_pk_by update_unique_i128 = update_by_n(n),
delete_by delete_unique_i128 = delete_by_n(n: i128),
} #[unique] n i128, data i32;
UniqueI256 {
insert_or_panic insert_unique_i256,
insert_or_panic insert_unique_i256, delete_all delete_all_unique_i256,
update_non_pk_by update_unique_i256 = update_by_n(n),
delete_by delete_unique_i256 = delete_by_n(n: i256),
} #[unique] n i256, data i32;
UniqueBool {
insert_or_panic insert_unique_bool,
insert_or_panic insert_unique_bool, delete_all delete_all_unique_bool,
update_non_pk_by update_unique_bool = update_by_b(b),
delete_by delete_unique_bool = delete_by_b(b: bool),
} #[unique] b bool, data i32;
UniqueString {
insert_or_panic insert_unique_string,
insert_or_panic insert_unique_string, delete_all delete_all_unique_string,
update_non_pk_by update_unique_string = update_by_s(s),
delete_by delete_unique_string = delete_by_s(s: String),
} #[unique] s String, data i32;
UniqueIdentity {
insert_or_panic insert_unique_identity,
insert_or_panic insert_unique_identity, delete_all delete_all_unique_identity,
update_non_pk_by update_unique_identity = update_by_i(i),
delete_by delete_unique_identity = delete_by_i(i: Identity),
} #[unique] i Identity, data i32;
UniqueConnectionId {
insert_or_panic insert_unique_connection_id,
insert_or_panic insert_unique_connection_id, delete_all delete_all_unique_connection_id,
update_non_pk_by update_unique_connection_id = update_by_a(a),
delete_by delete_unique_connection_id = delete_by_a(a: ConnectionId),
} #[unique] a ConnectionId, data i32;
UniqueUuid {
insert_or_panic insert_unique_uuid,
insert_or_panic insert_unique_uuid, delete_all delete_all_unique_uuid,
update_non_pk_by update_unique_uuid = update_by_u(u),
delete_by delete_unique_uuid = delete_by_u(u: Uuid),
} #[unique] u Uuid, data i32;
@@ -484,109 +499,109 @@ define_tables! {
// This allows us to test update and delete events.
define_tables! {
PkU8 {
insert_or_panic insert_pk_u8,
insert_or_panic insert_pk_u8, delete_all delete_all_pk_u8,
update_by update_pk_u8 = update_by_n(n),
delete_by delete_pk_u8 = delete_by_n(n: u8),
} #[primary_key] n u8, data i32;
PkU16 {
insert_or_panic insert_pk_u16,
insert_or_panic insert_pk_u16, delete_all delete_all_pk_u16,
update_by update_pk_u16 = update_by_n(n),
delete_by delete_pk_u16 = delete_by_n(n: u16),
} #[primary_key] n u16, data i32;
PkU32 {
insert_or_panic insert_pk_u32,
insert_or_panic insert_pk_u32, delete_all delete_all_pk_u32,
update_by update_pk_u32 = update_by_n(n),
delete_by delete_pk_u32 = delete_by_n(n: u32),
} #[primary_key] n u32, data i32;
PkU32Two {
insert_or_panic insert_pk_u32_two,
insert_or_panic insert_pk_u32_two, delete_all delete_all_pk_u32_two,
update_by update_pk_u32_two = update_by_n(n),
delete_by delete_pk_u32_two = delete_by_n(n: u32),
} #[primary_key] n u32, data i32;
PkU64 {
insert_or_panic insert_pk_u64,
insert_or_panic insert_pk_u64, delete_all delete_all_pk_u64,
update_by update_pk_u64 = update_by_n(n),
delete_by delete_pk_u64 = delete_by_n(n: u64),
} #[primary_key] n u64, data i32;
PkU128 {
insert_or_panic insert_pk_u128,
insert_or_panic insert_pk_u128, delete_all delete_all_pk_u128,
update_by update_pk_u128 = update_by_n(n),
delete_by delete_pk_u128 = delete_by_n(n: u128),
} #[primary_key] n u128, data i32;
PkU256 {
insert_or_panic insert_pk_u256,
insert_or_panic insert_pk_u256, delete_all delete_all_pk_u256,
update_by update_pk_u256 = update_by_n(n),
delete_by delete_pk_u256 = delete_by_n(n: u256),
} #[primary_key] n u256, data i32;
PkI8 {
insert_or_panic insert_pk_i8,
insert_or_panic insert_pk_i8, delete_all delete_all_pk_i8,
update_by update_pk_i8 = update_by_n(n),
delete_by delete_pk_i8 = delete_by_n(n: i8),
} #[primary_key] n i8, data i32;
PkI16 {
insert_or_panic insert_pk_i16,
insert_or_panic insert_pk_i16, delete_all delete_all_pk_i16,
update_by update_pk_i16 = update_by_n(n),
delete_by delete_pk_i16 = delete_by_n(n: i16),
} #[primary_key] n i16, data i32;
PkI32 {
insert_or_panic insert_pk_i32,
insert_or_panic insert_pk_i32, delete_all delete_all_pk_i32,
update_by update_pk_i32 = update_by_n(n),
delete_by delete_pk_i32 = delete_by_n(n: i32),
} #[primary_key] n i32, data i32;
PkI64 {
insert_or_panic insert_pk_i64,
insert_or_panic insert_pk_i64, delete_all delete_all_pk_i64,
update_by update_pk_i64 = update_by_n(n),
delete_by delete_pk_i64 = delete_by_n(n: i64),
} #[primary_key] n i64, data i32;
PkI128 {
insert_or_panic insert_pk_i128,
insert_or_panic insert_pk_i128, delete_all delete_all_pk_i128,
update_by update_pk_i128 = update_by_n(n),
delete_by delete_pk_i128 = delete_by_n(n: i128),
} #[primary_key] n i128, data i32;
PkI256 {
insert_or_panic insert_pk_i256,
insert_or_panic insert_pk_i256, delete_all delete_all_pk_i256,
update_by update_pk_i256 = update_by_n(n),
delete_by delete_pk_i256 = delete_by_n(n: i256),
} #[primary_key] n i256, data i32;
PkBool {
insert_or_panic insert_pk_bool,
insert_or_panic insert_pk_bool, delete_all delete_all_pk_bool,
update_by update_pk_bool = update_by_b(b),
delete_by delete_pk_bool = delete_by_b(b: bool),
} #[primary_key] b bool, data i32;
PkString {
insert_or_panic insert_pk_string,
insert_or_panic insert_pk_string, delete_all delete_all_pk_string,
update_by update_pk_string = update_by_s(s),
delete_by delete_pk_string = delete_by_s(s: String),
} #[primary_key] s String, data i32;
PkIdentity {
insert_or_panic insert_pk_identity,
insert_or_panic insert_pk_identity, delete_all delete_all_pk_identity,
update_by update_pk_identity = update_by_i(i),
delete_by delete_pk_identity = delete_by_i(i: Identity),
} #[primary_key] i Identity, data i32;
PkConnectionId {
insert_or_panic insert_pk_connection_id,
insert_or_panic insert_pk_connection_id, delete_all delete_all_pk_connection_id,
update_by update_pk_connection_id = update_by_a(a),
delete_by delete_pk_connection_id = delete_by_a(a: ConnectionId),
} #[primary_key] a ConnectionId, data i32;
PkUuid {
insert_or_panic insert_pk_uuid,
insert_or_panic insert_pk_uuid, delete_all delete_all_pk_uuid,
update_by update_pk_uuid = update_by_u(u),
delete_by delete_pk_uuid = delete_by_u(u: Uuid),
} #[primary_key] u Uuid, data i32;