yesodweb / yesodweb/persistent
persist-template: Thoughts on adding a function to derive Postgres enums?
Nobody has claimed this yet.
- Dominant language
- Haskell
- Stars
- 486
- Forks
- 306
- PR merge metrics
- No merged PRs in 30d
Description
Postgres enum support is a widely requested feature for Persistent. However, that's a moderately difficult project and hasn't seen any progress in several years.
One way users could start benefitting from Postgres enums now is by starting with support for deriving PersistField and PersistFieldSql. This wouldn't help users who are 100% relying on Persistent to generate their types, but it would help:
- People who manually migrate. I believe many production users of Persistent write their own migrations anyway, because they don't want to run automatic migrations on a production system (e.g. @bitemyapp does this)
- People who run some migrations manually before Persistent's automatic ones. Some users do this already to e.g. enable Postgres extensions; they could create their enums here as well.
- People connecting to an existing database
How would people feel about adding this function (possibly marked as experimental?) to Database.Persist.TH:
derivePostgresEnum :: String -> String -> Q [Dec]
derivePostgresEnum s postgresType = do
ss <- [|SqlOther (pack postgresType)|]
tpv <- [|PersistText . pack . show|]
fpv <- [|\dt v ->
case fromPersistValue v of
Left e -> Left e
Right s' ->
case reads $ unpack s' of
(x, _):_ -> Right x
[] -> Left $ pack "Invalid " ++ pack dt ++ pack ": " ++ s'|]
return
[ persistFieldInstanceD False (ConT $ mkName s)
[ FunD 'toPersistValue
[ normalClause [] tpv
]
, FunD 'fromPersistValue
[ normalClause [] (fpv `AppE` LitE (StringL s))
]
]
, persistFieldSqlInstanceD False (ConT $ mkName s)
[ sqlTypeFunD ss
]
]
Example usage:
data Pixel = Green | Red | Blue
deriving (Show, Read, Eq)
derivePostgresEnum "Pixel" "pixel"
I do have a selfish motivation for this as well: We would like to use this function at work. I wrote a version that doesn't use any private internals of persistent-th, but it's extremely ugly without persistent-th's many private helper functions.
cc @eugenk @jairoGilC @danclien
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 in Database.Persist.TH and compare the proposed derivePostgresEnum with the linked gist, focusing on the persistent-th helper functions mentioned in the issue. Before implementation, resolve the API and experimental-status questions; the issue does not name tests or define a settled completion criterion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- haskell, postgresql
- Domain
- databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100