You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
subSelect only works on a SqlExpr (Value a) - fixable with a subSelectRecord :: SqlQuery a -> SqlExpr (Maybe a).
The codegen for SqlY creates the field y :: SqlExpr (Value (Maybe X)). The SqlExpr (Value (Maybe _)) should be "folded in" to the Maybe _ bit.
Here's the code that determines the field type:
--| Transforms a record field type into a corresponding `SqlExpr` type.---- * @'Entity' x@ is transformed into @'SqlExpr' ('Entity' x)@.-- * @'Maybe' ('Entity' x)@ is transformed into @'SqlExpr' ('Maybe' ('Entity' x))@.-- * @x@ is transformed into @'SqlExpr' ('Value' x)@.-- * If there exists an instance @'SqlSelect' sql x@, then @x@ is transformed into @sql@.---- This function should match `sqlSelectProcessRowPat`.sqlFieldType::Type->QType
sqlFieldType fieldType =do
maybeSqlType <- reifySqlSelectType fieldType
pure$flip fromMaybe maybeSqlType $case fieldType of-- Entity x -> SqlExpr (Entity x)AppT (ConT ((==) ''Entity ->True)) _innerType ->AppT (ConT ''SqlExpr) fieldType
-- Maybe (Entity x) -> SqlExpr (Maybe (Entity x))
(ConT ((==) ''Maybe ->True))
`AppT` ((ConT ((==) ''Entity ->True))
`AppT` _innerType) ->AppT (ConT ''SqlExpr) fieldType
-- x -> SqlExpr (Value x)
_ -> (ConT ''SqlExpr)
`AppT` ((ConT ''Value)
`AppT` fieldType)
And reifySqlSelectType:
-- Given a type, find the corresponding SQL type.---- If there exists an instance `SqlSelect sql ty`, then the SQL type for `ty`-- is `sql`.---- This function definitely works for records and instances generated by this-- module, and might work for instances outside of it.reifySqlSelectType::Type->Q (MaybeType)
reifySqlSelectType originalType =do-- Here we query the compiler for Instances of `SqlSelect a $(originalType)`;-- the API for this is super weird, it interprets a list of types as being-- applied as successive arguments to the typeclass name.---- See: https://gitlab.haskell.org/ghc/ghc/-/issues/21825---- >>> reifyInstances ''SqlSelect [VarT (mkName "a"), ConT ''MyRecord]-- [ InstanceD Nothing-- []-- (AppT (AppT (ConT Database.Esqueleto.Internal.Internal.SqlSelect)-- (ConT Ghci3.SqlMyRecord))-- (ConT Ghci3.MyRecord))-- []-- ]
tyVarName <- newName "a"
instances <- reifyInstances ''SqlSelect [VarT tyVarName, originalType]
-- Given the original type (`originalType`) and an instance type for a-- `SqlSelect` instance, get the SQL type which corresponds to the original-- type.let extractSqlRecord ::Type->Type->MaybeType
extractSqlRecord originalTy instanceTy =case instanceTy of
(ConT ((==) ''SqlSelect ->True))
`AppT` sqlTy
`AppT` ((==) originalTy ->True) ->Just sqlTy
_ ->Nothing-- Filter `instances` to the instances which match `originalType`.filteredInstances:: [Type]
filteredInstances =flip mapMaybe instances
(\caseInstanceD _overlap
_constraints
(extractSqlRecord originalType ->Just sqlRecord)
_decs ->Just sqlRecord
_ ->Nothing)
pure$ listToMaybe filteredInstances
Need to experiment a bit with this
The text was updated successfully, but these errors were encountered:
I've got a record I'm
deriveEsqueletoRecord
ing:and I'm
subSelect
ing that in another record:Unfortunately this fails for a few reasons:
subSelect
only works on aSqlExpr (Value a)
- fixable with asubSelectRecord :: SqlQuery a -> SqlExpr (Maybe a)
.SqlY
creates the fieldy :: SqlExpr (Value (Maybe X))
. TheSqlExpr (Value (Maybe _))
should be "folded in" to theMaybe _
bit.Here's the code that determines the field type:
And
reifySqlSelectType
:Need to experiment a bit with this
The text was updated successfully, but these errors were encountered: