mirror of
https://github.com/clockworklabs/SpacetimeDB.git
synced 2026-05-11 18:36:15 -04:00
e4098f98d9
## Description of Changes
This PR primarily affects the `bindings-macro` and `schema` crates to
review:
### Core changes
1. Replaces the `name` macro with `accessor` for **Tables, Views,
Procedures, and Reducers** in Rust modules.
2. Extends `RawModuleDefV10` with a new section for:
* case conversion policies
* explicit names
New sections are not validated in this PR so not functional.
3. Updates index behavior:
* Index names are now always **system-generated** for clients. Which
will be fixed in follow-up PR when we start validating RawModuleDef with
explicit names.
* The `accessor` name for an index is used only inside the module.
## Breaking changes (API/ABI)
1. **Rust modules**
* The `name` macro must be replaced with `accessor`.
2. **Client bindings (all languages)**
* Index names are now system-generated instead of using explicitly
provided names.
**Complexity:** 3
A follow-up PR will reintroduce explicit names with support for case
conversion.
---------
Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
94 lines
2.7 KiB
Python
94 lines
2.7 KiB
Python
from .. import Smoketest, random_string
|
|
import time
|
|
|
|
|
|
class ClearDatabase(Smoketest):
|
|
AUTOPUBLISH = False
|
|
|
|
MODULE_CODE = """
|
|
use spacetimedb::{ReducerContext, Table, duration};
|
|
|
|
#[spacetimedb::table(accessor = counter, public)]
|
|
pub struct Counter {
|
|
#[primary_key]
|
|
id: u64,
|
|
val: u64
|
|
}
|
|
|
|
#[spacetimedb::table(accessor = scheduled_counter, public, scheduled(inc, at = sched_at))]
|
|
pub struct ScheduledCounter {
|
|
#[primary_key]
|
|
#[auto_inc]
|
|
scheduled_id: u64,
|
|
sched_at: spacetimedb::ScheduleAt,
|
|
}
|
|
|
|
#[spacetimedb::reducer]
|
|
pub fn inc(ctx: &ReducerContext, arg: ScheduledCounter) {
|
|
if let Some(mut counter) = ctx.db.counter().id().find(arg.scheduled_id) {
|
|
counter.val += 1;
|
|
ctx.db.counter().id().update(counter);
|
|
} else {
|
|
ctx.db.counter().insert(Counter {
|
|
id: arg.scheduled_id,
|
|
val: 1,
|
|
});
|
|
}
|
|
}
|
|
|
|
#[spacetimedb::reducer(init)]
|
|
pub fn init(ctx: &ReducerContext) {
|
|
ctx.db.scheduled_counter().insert(ScheduledCounter {
|
|
scheduled_id: 0,
|
|
sched_at: duration!(100ms).into(),
|
|
});
|
|
}
|
|
"""
|
|
|
|
def test_publish_clear_database(self):
|
|
"""
|
|
Test that publishing with the clear flag stops the old module.
|
|
This relies on private control database internals.
|
|
"""
|
|
|
|
name = random_string()
|
|
|
|
# Initial publish
|
|
replicas_1 = self.publish(name, clear = False)
|
|
self.assertTrue(len(replicas_1) >= 1)
|
|
|
|
# Publish with clear = True, destroying `replicas_1`
|
|
replicas_2 = self.publish(name, clear = True)
|
|
self.assertTrue(len(replicas_2) >= 1)
|
|
self.assertNotEqual(replicas_1, replicas_2)
|
|
|
|
# Delete the replicas created in the second publish
|
|
self.spacetime("delete", name)
|
|
|
|
# State updates don't happen instantly
|
|
time.sleep(0.25)
|
|
|
|
# Check that all replicas have state `Deleted`
|
|
replicas = replicas_1 + replicas_2
|
|
state_filter = f'replica_id = {" OR replica_id = ".join(replicas)}'
|
|
states = self.query_control(f"select lifecycle from replica_state where {state_filter}")
|
|
self.assertEqual(len(states), len(replicas))
|
|
self.assertTrue(all([x == "(Deleted = ())" for x in states]))
|
|
|
|
def publish(self, name, clear):
|
|
self.publish_module(name, clear = clear)
|
|
replicas = self.query_control(f"""
|
|
select replica.id from replica
|
|
join database on database.id = replica.database_id
|
|
where database.database_identity = '0x{self.resolved_identity}'
|
|
""")
|
|
|
|
return replicas
|
|
|
|
|
|
def query_control(self, sql):
|
|
out = self.spacetime("sql", "spacetime-control", sql)
|
|
out = [line.strip() for line in out.splitlines()]
|
|
out = out[2:] # Remove header
|
|
return out
|