scripts/generate/run.sh
Configuration lives in persistent-api.yaml
. The file contains a list of objects, where each object corresponds to a persistent
function that we want to lift into the MonadSqlQuery
context. Follow the instructions in this guide to update the YAML file, which will generate the appropriate Haskell code. If you're trying to add a function that doesn't fit neatly with the instructions or categories, bring up a discussion with other developers.
First, write down the type of the function and modify it according to these instructions:
-
Remove the
forall
section -
Update type variables
-
Specialize
backend
asSqlBackend
-
Ensure the
PersistEntity
type variable is namedrecord
. If there are multiplePersistEntity
types, they should be namedrecord1
,record2
, etc. Choose an order that makes sense forwithRecord
, e.g.withRecord @(record1, record2, ...) $ ...
-
-
Simplify constraints
- Remove redundant constraints, e.g.
PersistQueryRead SqlBackend
- Substitute
PersistRecordBackend
, if applicable - Remove
BackendCompatible SqlBackend env
and replace any usage ofenv
withSqlBackend
- Remove
MonadReader SqlBackend m
and replace any usage ofm
withReaderT SqlBackend m
- e.g.
foo :: MonadReader SqlBackend m => m Foo -- change to this: foo :: ReaderT SqlBackend m Foo
- e.g.
- Remove redundant constraints, e.g.
-
Simplify monads
- If a function returns a
ReaderT r m1 (ConduitM ... m2 ...)
action, change it tom (ConduitM ... m2 ...)
- Note the change from
m1
tom
- Note the change from
- If a function
pipeSomething
returns aConduitM i o (ReaderT r m) a
action, there should be a correspondingpipeSomethingRes
function with the same type, except returningAcquire (ConduitM i o m2 a)
. ReplaceReaderT r m
with justm
and make sure to set theconduitFrom
option later. - If a function returns a
ReaderT r m a
action, change it tom a
- If a function returns a
For example, following these steps for insertRecord
would make the following changes:
insertRecord
:: forall record backend m.
( PersistEntityBackend record ~ BaseBackend backend
, PersistEntity record
, MonadIO m
, PersistStoreWrite backend
)
=> record -> ReaderT backend m record
-- Remove `forall`
insertRecord
:: ( PersistEntityBackend record ~ BaseBackend backend
, PersistEntity record
, MonadIO m
, PersistStoreWrite backend
)
=> record -> ReaderT backend m record
-- Update type variables
insertRecord
:: ( PersistEntityBackend record ~ BaseBackend SqlBackend
, PersistEntity record
, MonadIO m
, PersistStoreWrite SqlBackend
)
=> record -> ReaderT SqlBackend m record
-- Simplify constraints
insertRecord
:: ( PersistRecordBackend record SqlBackend
, MonadIO m
)
=> record -> ReaderT SqlBackend m record
-- Simplify monads
insertRecord
:: ( PersistRecordBackend record SqlBackend
, MonadIO m
)
=> record -> m record
Add the function to the YAML file in the following format:
name
: The function's namecondition
: The CPP condition that must be satisfied for the function to compile successfully- e.g.
MIN_VERSION_persistent(2,11,0)
for a function that was added in 2.11.0
- e.g.
constraints
: The function's constraints, except for anyMonad m
,MonadIO m
, orMonadUnliftIO m
constraints- If the function has another
m2
monad type variable, leave those constraints alone
- If the function has another
args
: The function's argumentsresult
: The function's result, without them
type variable- e.g. a function that returns
m (Maybe Foo)
should haveresult
set to just(Maybe Foo)
- If this function is a conduit function, leave the result as
ConduitM i o m a
- e.g. a function that returns
conduitFrom
: Set this to the name of thepipeSomethingRes
function that corresponds with this function
There should be no references to m
here.