Skip to content

Recipe for using enums#133

Open
MeanSquaredError wants to merge 4 commits into
rbock:mainfrom
MeanSquaredError:enum_type
Open

Recipe for using enums#133
MeanSquaredError wants to merge 4 commits into
rbock:mainfrom
MeanSquaredError:enum_type

Conversation

@MeanSquaredError

@MeanSquaredError MeanSquaredError commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

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_type is 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.

@rbock rbock left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Comment thread docs/recipes/enums.md

## 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.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Comment thread docs/recipes/enums.md
- 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.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you did a couple of lines above, please add a probably or similar here.

Comment thread docs/recipes/enums.md
};
```

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.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it has to be defined in the sqlpp namespace, same for several entries below?

Also, please add UPDATE.

Comment thread docs/recipes/enums.md

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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 };

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also needed if you want to compare values with operator==. operator<, etc.

Comment thread docs/recipes/enums.md
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.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also needed if you want to compare values with operator==. operator<, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide recipe for handling enums as custom types

2 participants