-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[api][nexus] Migrate DB-specific types into Nexus, away from API #188
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Rename from "types.rs" to "model.rs" to make @david-crespo happy 😁
(also consider splitting "model.rs" into a bunch of smaller files)
omicron-nexus/src/db/types.rs
Outdated
*/ | ||
|
||
/// Describes a project within the database. | ||
pub struct Project(internal::nexus::Project); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kinda think this should just implement the same struct independently rather than wrapping internal::nexus::Project
. Renaming internal::nexus::Project
to internal::nexus::ProjectView
(which I think is more accurate) shows why this is a little weird.
This would let us take all references to internal::nexus::Project
out of this file by moving the from/to implementations elsewhere, which fits better with my mental model — this file is about the models and their relation to the database, not their relation to the view structs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for the other uses of internal::nexus
in this file. I think it would really simplify reasoning to know that the models in this file don't know anything about the views in omicron-common
, i.e., you don't need to know anything about the latter to understand what's in here. If they happen to be the same, that's a contingent fact, not one we need to hard-code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kinda think this should just implement the same struct independently rather than wrapping
internal::nexus::Project
. Renaminginternal::nexus::Project
tointernal::nexus::ProjectView
(which I think is more accurate) shows why this is a little weird.
I agree with you here - separating the DB type from the API type is definitely the plan. I'll go ahead and update this type.
This would let us take all references to
internal::nexus::Project
out of this file by moving the from/to implementations elsewhere, which fits better with my mental model — this file is about the models and their relation to the database, not their relation to the view structs.
So I'm happy for all structs in this file to be more decoupled from the API-based types, but those conversion functions should exist somewhere, and they'll need to act on both types. Do we really want them to be separate from the struct definition if they're functions acting on that struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for the other uses of
internal::nexus
in this file. I think it would really simplify reasoning to know that the models in this file don't know anything about the views inomicron-common
, i.e., you don't need to know anything about the latter to understand what's in here. If they happen to be the same, that's a contingent fact, not one we need to hard-code.
I agree with this in principle, and I support doing it for most structures, but as an FYI, this will also require re-definitions of the all primitive types that aren't in std. external::Name
, external::ByteCount
, external::Generation
, etc.
This is possible, but it'll expand the size of this PR a bit. Do you mind if I hold off on the full extent of this until we get feedback from @davepacheco ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want them to be separate from the struct definition if they're functions acting on that struct?
Yeah, I think of them as the view layer. I think it makes sense to separate them. It might feel better if you think of it as From
on ProjectView
rather than as Into
on Project
, if that makes any sense. Even though I just learned From
gets you Into
for free anyway, so it doesn't actually matter, conceptually I like to think of the view layer as knowing about the model layer (like you said, it has to take the model as an argument) but not the other way around. And that would be mirrored in keeping the Model -> View conversions elsewhere. Here is an example of them doing it this way in the crates.io source.
By the way, why would we need to convert from the view to the model? (Though again it doesn't matter implementation-wise because From
gets you Into
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And yeah, this PR is plenty big. I just thought it was a good spot to make the note.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, this will also require re-definitions of the all primitive types that aren't in std.
external::Name
,external::ByteCount
,external::Generation
, etc.
Maybe for the primitives this makes less sense 😁 From a reasoning-about-code point of view I think importing those from common is not as big a burden as pulling in whole View structs. There are a limited number of primitives, hopefully, whereas the number of views to import is large and growing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
I have found myself repeatedly bumping into some related issues:
This PR is an attempt at addressing this imbalance, starting with the
Instance
types. If we like this direction, I could do the same for all other DB-stored types:nexus/db/model.rs
which are stored directly in the DB.The net result of this is "if you wanna store something in the database, you should update the
init.sql
file anddb/model.rs
, and you'll need to poke at little else".