yesodweb / yesodweb/persistent
Feature request: PersistField types with multiple DB fields
Nobody has claimed this yet.
- Dominant language
- Haskell
- Stars
- 486
- Forks
- 306
- PR merge metrics
- No merged PRs in 30d
Description
I would like to be able to define a Haskell type that can be contained in multiple database fields.
This has two example use cases:
Inlining Records
Suppose I have a datatype like
data Tax = Tax { location :: Text, amount :: Integer }
I want to include this on a record. I can manually use a schema like:
Purchase1
subtotal Integer
taxLocation Text
taxAmount Integer
and then define an intermediary data model
data Purchase2 = Purchase2
{ purchaseSubtotal :: Integer
, purchaseTax :: Tax
}
and relevant conversion functions.
However, I'd prefer to write something like:
Purchase3
subtotal Integer
tax (Inline Tax)
which would "expand" to a schema like Purchase1 defined above. The Inline type can be used to distinguish inlining the columns vs a composite type (which Postgres supports, and possible other databases).
"One Of" sum types
Suppose I write a data type like
data Choice
= A Int
| B
| C Char
| D
And I want to include this model in a field. One option is to "inline" the constructors as nullable value fields, and then use a CHECK constraint to ensure that exactly one value is present.
So a schema like:
User
name Text
choice (OneOf Choice)
could expand out to:
CREATE TABLE user (
id SERIAL PRIMARY KEY,
choice_a INT,
choice_b BOOL,
choice_c CHAR,
choice_d BOOL,
CHECK (
( choice_a IS NOT NULL AND choice_b IS NULL AND choice_c IS NULL AND choice_d IS NULL)
OR
( etc etc etc )
)
Then parsing code can safely assume that exactly one is present and provide the right constructor. This is an automated way of doing "absorption" on sub-tables, where it would be error prone to do so in app code.
As far as I can tell, this would require modifying the PersistField and PersistFieldSql definitions to be able to talk about a variable amount of columns. I'm not sure the best way to approach that would be.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the PersistField and PersistFieldSql definitions and the existing schema-generation path; the issue names no files or tests. Determine how variable-width fields, Inline records, and OneOf values would fit the supported database backends, then define acceptance cases for generated columns, constraints, and round-trip parsing before implementation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- haskell
- Domain
- database
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100