clockworklabs / clockworklabs/SpacetimeDB
Typesafe primary keys
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 25.2k
- Forks
- 1.1k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 46
Description
As it stands, we choose a type for primary keys from a closed set of possibilities, e.g. u32. This makes foreign keys non-typesafe.
#[table(name = foo, public)]
struct Foo {
#[primary_key],
#[auto_inc],
pub id: u32,
}
#[table(name = bar, public)]
struct Bar {
pub foo_id: u32;
}
This prevents the compiler from preventing mistakes where a u32 that did not come from a Foo.id is used as a value for Bar.foo_id. I did try to manually implement something, but it seems some of the traits needed to make this work aren't accessible to mortals. My proposal is something like this:
#[table(name = foo, public)]
struct Foo {
#[primary_key(key_type=u32],
#[auto_inc],
pub id: Foo::ID,
}
#[table(name = bar, public)]
struct Bar {
#[derive(Default)]
pub foo_id: Foo::ID;
}
This would generate:
mod Foo {
struct ID(u32);
... glue to box/unbox u32 through the SpacetimeType, Filterable, and other required machinery
}
The semantics would be that if a key_type is provided to primary_key, it must be a single-member tuple struct where the contained value is itself valid as a primary key type. The Default value would always be the "not set" flag value, to be replaced in an auto_inc field. The wrapping ID type would not appear in the wire protocol and probably not in the schema, but it may be glued back in for the client facades.
I hope I didn't fumble the rust snippets - I haven't run this through an IDE first.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing primary_key and auto_inc attribute handling, then trace the SpacetimeType, Filterable, and related trait implementations mentioned in the issue. Determine how a generated single-member ID type could preserve database and wire representations while enforcing typed foreign keys; done means the design and generated API are settled and validated against the required trait machinery.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100