Recipe for using enums#133
Conversation
…n merged into tests/include/sqlpp23/tests/postgresql/tables.sql
a0b830b to
c72557c
Compare
rbock
left a comment
There was a problem hiding this comment.
Thanks for the recipe! This is great stuff.
I did a first quick scan and added a couple of comments. I'll do a second round on the weekend (probably).
|
|
||
| ## What support does sqlpp23 provide for enums? | ||
|
|
||
| sqlpp23 doesn't have built-in support for the serialization/deserialization of C++ enums to/from a database. However, it does have support for the serialization/deserialization of [custom types](/docs/recipes/custom_types.md), which allows the user to add support for their own enum types with only a moderate amount of boilerplate code. |
There was a problem hiding this comment.
There are two options at least: Store as integral value or use a custom type. Please list both here (and then continue with the focus on the recipe, of course).
| - Your C++ enums are not assigned non-enumerated values. | ||
| - The serialization/deserialization of this enum is not performance-critical for your application. | ||
|
|
||
| If any of the above conditions are not met, then just use an integer column to store your enum. |
There was a problem hiding this comment.
As you did a couple of lines above, please add a probably or similar here.
| }; | ||
| ``` | ||
|
|
||
| A metafunction that tells the library that our enum can be serialized and sent (usually by INSERT) to the database. It should be defined in the `sqlpp` namespace. |
There was a problem hiding this comment.
I think it has to be defined in the sqlpp namespace, same for several entries below?
Also, please add UPDATE.
|
|
||
| This function will be called when the library reads a database row and comes across a field that holds our serialized enum. It should be defined in the same namespace where our enum is defined, so that the library will be able to find it through Argument-Dependent Lookup (ADL). | ||
|
|
||
| ### Enable serialization and writing of the enum to the database |
There was a problem hiding this comment.
data_type is required for selecting and comparing values.
Only things that have a data_type can be selected and the data_type controls (in combination with other templates) what is allowed in comparisons.
Serialization does not depend on the data_type template.
|
|
||
| namespace sqlpp { | ||
|
|
||
| // Required to enable serialization and writing of the enum to the database |
There was a problem hiding this comment.
This is used for is_animal_type and therefore required for assignment and comparison operators.
|
|
||
| // The actual definition of our C++ enum that will be stored in a nullable | ||
| // integer column | ||
| enum class animal_type { bird, cat, dog, fish }; |
There was a problem hiding this comment.
I think I would go with just animal and is_animal.
There are multiple lines, where the _type is relevant because that's the library's syntax. Calling the enum just animal would make the example easier to grok, IMO.
| // integer column | ||
| enum class animal_type { bird, cat, dog, fish }; | ||
|
|
||
| // Helper metafunctions that check if a variable is of our nullable enum type |
There was a problem hiding this comment.
It checks for both, nullable and non-nullable.
| requires(is_animal_type_v<L> && is_animal_type_v<R>) | ||
| struct values_are_assignable<L, R> : public std::true_type {}; | ||
|
|
||
| // Only needed if you want to use the enum in ORDER BY clauses |
There was a problem hiding this comment.
Also needed if you want to compare values with operator==. operator<, etc.
| struct values_are_comparable<L, R> : public std::true_type {}; | ||
| ``` | ||
|
|
||
| This metaflag tells sqlpp23 that our enum values can be compared. It is only required if you want to `ORDER BY` columns holding our serialized enum. If defined, it should reside in the `sqlpp` namespace. |
There was a problem hiding this comment.
Also needed if you want to compare values with operator==. operator<, etc.
This PR provides a recipe for using enums as custom types in sqlpp23. It comes with a sample program which defines two enums. The first enum,
animal_typeis serialized to a plain nullable integer column, and the second enum,shape_type, is serialized to a nullable PostgreSQL-specific enum column.Once the PR is reviewed and merged, it should close #116
EDIT: The first two commits are not really related to the recipe, but they do fix some minor issues, that I noticed in other tests. I just added them here, because I thought they were not worth separate PRs.