| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Database.Esqueleto.Record
Synopsis
- deriveEsqueletoRecord :: Name -> Q [Dec]
Documentation
deriveEsqueletoRecord :: Name -> Q [Dec] Source #
Takes the name of a Haskell record type and creates a variant of that
record prefixed with Sql which can be used in esqueleto expressions. This
reduces the amount of pattern matching on large tuples required to interact
with data extracted with esqueleto.
Note that because the input record and the Sql-prefixed record share field
names, the {--} extension is required in
modules that use deriveEsqueletoRecord. Additionally, the {-# LANGUAGE
TypeApplications #-} extension is required for some of the generated code.
Given the following record:
data MyRecord = MyRecord
{ myName :: Text
, myAge :: Maybe Int
, myUser :: Entity User
, myAddress :: Maybe (Entity Address)
}
$( will generate roughly the following code:deriveEsqueletoRecord ''MyRecord)
data SqlMyRecord =
SqlMyRecord { myName :: SqlExpr (Value Text)
, myAge :: SqlExpr (Value Int)
, myUser :: SqlExpr (Entity User)
, myAddress :: SqlExpr (Maybe (Entity Address))
}
instance SqlSelect SqlMyRecord MyRecord where
sqlSelectCols
identInfo
SqlMyRecord { myName = myName
, myAge = myAge
, myUser = myUser
, myAddress = myAddress
} =
sqlSelectCols identInfo (myName :& myAge :& myUser :& myAddress)
sqlSelectColCount _ =
sqlSelectColCount
(Proxy @( (SqlExpr (Value Text))
:& (SqlExpr (Value Int))
:& (SqlExpr (Entity User))
:& (SqlExpr (Maybe (Entity Address)))))
sqlSelectProcessRow columns =
first ((fromString "Failed to parse MyRecord: ") <>)
(evalStateT process columns)
where
process = do
Value myName <- takeColumns @(SqlExpr (Value Text))
Value myAge <- takeColumns @(SqlExpr (Value Int))
myUser <- takeColumns @(SqlExpr (Entity User))
myAddress <- takeColumns @(SqlExpr (Maybe (Entity Address)))
pure MyRecord { myName = myName
, myAge = myAge
, myUser = myUser
, myAddress = myAddress
}
Then, we could write a selection function to use the record in queries:
getMyRecord ::SqlPersistTIO[MyRecord] getMyRecord =selectmyRecordQuery myRecordQuery ::SqlQuerySqlMyRecord myRecordQuery = do user:&address <-from$table@User `leftJoin`table@Address `on` (do \(user:&address) -> user^.id)pureSqlMyRecord { myName =castString$user^.#firstName , myAge =val10 , myUser = user , myAddress = address }
Since: 3.5.6.0