Right now you can't do this:
#[spacetimedb(table, name = "my_table")]
pub struct MyTable {
#[primary_key]
pub id: uuid,
pub name: String,
}
Can you define the type uuid and the desired semantics of inserting to the table?
I also wonder if this is possible in some practical way. I'd use UUIDv7 for my table, therefore I don't have to store a created_at field, and could be derived from the ID, which is convenient. It also stays searchable, as it is just a u128. At least if the implementation in the DB supports it, I guess, or else it would have an unnecessary overhead?
Could be useful, if this would be natively supported.
My only concern yet if I'd use an UUID as a primary_key I guess it would work properly, but then the ecosystem around Identity would not be used, or may cause problems at some point?
(I mean, for a regular table it's probably good-to-go, but a User table? I see Identity intertwined with many things around)
... perhaps it's just better to have a separate field for the Timestamp? π€
anyhow, I didn't find too much information in the docs or in the code how these Identities are generated. Are they entirely random, or do they have some natural order/metadata to exploit? Perhaps that could be a feature to set with field column definitions?
I mean, I see there is a casting from u128 already implemented, so casting Uuid to Identity should be simple, but this should be generated by the database correctly, so from table definition code I'd go for something like that:
pub struct Person {
#[primary_key(uuid, v7)]
id: Uuid,
}
But then of course we can do this manually in a reducer too, but we have to hack around a bit, and also define the column as u128 or some string. I was thinking maybe using the spacetimedb::HexString<16>, but that doesn't implement the SpacetimeType.
I tried wrapping it in enum, and struct, and derive macros didn't really worked for me (SpacetimeType, Serialize, Deserialize).
Apparently it's not a problem with primary_key, as it persists having a regular Uuid field.
I used the serde feature of Uuid crate, but I failed.
It would seem, if I manually implement the (De)Serialize and SpacetimeType types, then it actually compiles. (but I didn't try with real implementation) The compiler itself is complaining about not satisfied trait bounds, or issues with proc-macro/undeclared module in stdb_lib.
So I gave up, and waiting for input, what should I do π
(I'm looking into the stdb code, how could I add an uuid feature in the meantime. if you could give me guidance, I'm up for implementing it)
anyhow, I didn't find too much information in the docs or in the code how these Identities are generated. Are they entirely random, or do they have some natural order/metadata to exploit? Perhaps that could be a feature to set with field column definitions?
This is documented in https://spacetimedb.com/docs#identity . In short: an Identity is derived from an OpenID Connect token by combining the sub (subject) and iss (issuer) claim, then hashing them with BLAKE3.
After a bit research and thinking around, I realized using Identity that way I imagined is probably not the right way anyways.
My current view is to most probably there should be a private table only for account stuff including the identity, and an 1-on-1 connection a separate user table, what is public. Giving out relevant metadata, like username, online status, etc. and ofc the user ID, which would be the UUID.
Now, for UUID I found this solution on the stdb discord:
https://discord.com/channels/1037340874172014652/1361787955076665607/1361787955076665607
I didn't try, but sort of makes sense. I'd suggest to reimplement it inside the stdb code, as an uuid feature (opt-in), so stdb natively could use that for generic table IDs.
The reimplementation is important, as this solution seems to store as a string, instead of a u128 or some 16-byte bin/hex
in any ways, it would be nice to use UUID instead of an autoincrement integer.
Later if I advance with my project, I report back how we solved that.
@egormanga, it doesn't fully work yet. The type exists, but we can't filter by it (at least not in Rust). This type needs to implement FilterableValue.
Note that in typescript it works filtering by uuid. I do not know if it still does not work in rust or if it has been solved for everything.