clockworklabs / clockworklabs/SpacetimeDB

Typesafe primary keys

Open
#3,472 4 comments 1 reaction 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.