Generated columns -- handling differences between database inputs and outputs #24
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This pull request currently implements a
#[sql(generated)]
attribute, so that the query generator can skip inserting columns that would be generated by the database, such as auto-generated or calculated columns.However, since we are using Rust structs, the initial struct would also have to be initialized with dummy values and I believe leveraging the type system to differentiate between the dummy values and those returned by the database will be very useful. I can currently think of two ways of achieving this, first: would it make sense to separate the types of the data we are putting into the database and the data that is returned by the database?
An example code would be like this, assuming the
id
field is auto-generated by the database:The pros that come to my mind are:
User
struct will only have data that the database has verifiedOn the other hand, it is a design change (ie expensive) and how to create these structs is another question to be solved.
Another option is one I am lifting from how Ecto handles eager loading (ie joining relationships): any field that is to be generated has no value when initialized (Rust-side) and obtains a value after connecting to the database, ie an
Option
. But, since the interaction with database already returns aResult
, usingResult<value, Uninitialized>
as anOption
will prevent the nestedResult
->Option
(and what is anOption
anyway, but aResult
with a singleError
mode):The pros of this are:
?
for accessing database-generated fieldsHowever, this method does not encode whether we have access to the generated value in the type system; so we will always have to go through the
Result
type to access the value. In contrast, the other method will never lead to the user reaching anUninitialized
value, while the compiler does not prevent the user from accidentally trying to access anUninitialized
in this case.So, I am quite interested in which way you think I should go forward or if there are different ways of implementing the result that did not come to my mind. And I apologize for any Rust errors in the examples :D