Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

persist quasiquoters have dummy ID fields #902

Closed
parsonsmatt opened this issue May 2, 2019 · 1 comment
Closed

persist quasiquoters have dummy ID fields #902

parsonsmatt opened this issue May 2, 2019 · 1 comment

Comments

@parsonsmatt
Copy link
Collaborator

This is surfacing in the persistent-documentation library, where non-int64 keys are kept as dummy Int64 values.

The library fixes this up in liftAndFixKeys, but this really ought to be fixed up before it gets out of the quasiquoter stage.

@parsonsmatt
Copy link
Collaborator Author

This is a bit tricky! "Why are we even doing this liftANDFixKey stuff?" you might wonder. Well, the reason is because we can't quite recover a type at this point. Here's liftAndFixKey:

liftAndFixKey :: EntityMap -> FieldDef -> Q Exp
liftAndFixKey entMap (FieldDef a b c sqlTyp e f fieldRef mcomments) =
  [|FieldDef a b c $(sqlTyp') e f fieldRef' mcomments|]
  where
    (fieldRef', sqlTyp') = fromMaybe (fieldRef, lift sqlTyp) $
      case fieldRef of
        ForeignRef refName _ft -> case M.lookup refName entMap of
          Nothing ->
            Nothing
          Just ent ->
            case fieldReference $ entityId ent of
              fr@(ForeignRef _Name ft) ->
                Just (fr, lift $ SqlTypeExp ft)
              _ ->
                Nothing
        _ -> Nothing

(That's lift :: Lift a => a -> Q Exp, fwiw).

SqlTypeExp being a bit clever. To figure out what's going on here, we need to look at it's Lift instance:

data SqlTypeExp = SqlTypeExp FieldType
                | SqlType' SqlType
                deriving Show

instance Lift SqlTypeExp where
    lift (SqlType' t)       = lift t
    lift (SqlTypeExp ftype) = return st
      where
        typ = ftToType ftype
        mtyp = (ConT ''Proxy `AppT` typ)
        typedNothing = SigE (ConE 'Proxy) mtyp
        st = VarE 'sqlType `AppE` typedNothing

If we have a SqlType' SqlType, then we return the SqlType directly.

If we have a FieldType, however, we will make a Q Exp corresponding to the expression sqlType (Proxy :: Proxy typ) where typ = ftToType ftype.

I have a Type (as TemplateHaskell knows it). I want a SqlType. Is there any way to bridge this gap, without sending the FieldDef into the Q Exp world?!

(Maybe this is the wrong way around all this...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant