mkEntityDefSqlTypeExp :: EmbedEntityMap -> EntityMap -> EntityDef -> EntityDefSqlTypeExp
mkEntityDefSqlTypeExp emEntities entMap ent = EntityDefSqlTypeExp ent
    (getSqlType $ entityId ent)
    $ (map getSqlType $ entityFields ent)
  where
    getSqlType field = maybe
        (defaultSqlTypeExp field)
        (SqlType' . SqlOther)
        (listToMaybe $ mapMaybe (stripPrefix "sqltype=") $ fieldAttrs field)


    -- In the case of embedding, there won't be any datatype created yet.
    -- We just use SqlString, as the data will be serialized to JSON.
    defaultSqlTypeExp field = case mEmbedded emEntities ftype of
        Right _ -> SqlType' SqlString
        Left (Just FTKeyCon) -> SqlType' SqlString
        Left Nothing -> case fieldReference field of
            ForeignRef refName ft  -> case M.lookup refName entMap of
                Nothing  -> SqlTypeExp ft
                -- A ForeignRef is blindly set to an Int in setEmbedField
                -- correct that now
                Just ent -> case entityPrimary ent of
                    Nothing -> SqlTypeExp ft
                    Just pdef -> case compositeFields pdef of
                        [] -> error "mkEntityDefSqlTypeExp: no composite fields"
                        [x] -> SqlTypeExp $ fieldType x
                        _ -> SqlType' $ SqlOther "Composite Reference"
            CompositeRef _  -> SqlType' $ SqlOther "Composite Reference"
            _ -> case ftype of
                    -- In the case of lists, we always serialize to a string
                    -- value (via JSON).
                    --
                    -- Normally, this would be determined automatically by
                    -- SqlTypeExp. However, there's one corner case: if there's
                    -- a list of entity IDs, the datatype for the ID has not
                    -- yet been created, so the compiler will fail. This extra
                    -- clause works around this limitation.
                    FTList _ -> SqlType' SqlString
                    _ -> SqlTypeExp ftype
      where
        ftype = fieldType field

-- | Create data types and appropriate 'PersistEntity' instances for the given
-- 'EntityDef's. Works well with the persist quasi-quoter.
mkEntityDefSqlTypeExp :: EmbedEntityMap -> EntityMap -> EntityDef -> EntityDefSqlTypeExp
mkEntityDefSqlTypeExp emEntities entMap ent = EntityDefSqlTypeExp ent
    (getSqlType $ entityId ent)
    $ (map getSqlType $ entityFields ent)
  where
    getSqlType field = maybe
        (defaultSqlTypeExp field)
        (SqlType' . SqlOther)
        (listToMaybe $ mapMaybe (stripPrefix "sqltype=") $ fieldAttrs field)


    -- In the case of embedding, there won't be any datatype created yet.
    -- We just use SqlString, as the data will be serialized to JSON.
    defaultSqlTypeExp field = case mEmbedded emEntities ftype of
        Right _ -> SqlType' SqlString
        Left (Just FTKeyCon) -> SqlType' SqlString
        Left Nothing -> case fieldReference field of
            ForeignRef refName ft  -> case M.lookup refName entMap of
                Nothing  -> SqlTypeExp ft
                -- A ForeignRef is blindly set to an Int in setEmbedField
                -- correct that now
                Just ent -> case entityPrimary ent of
                    Nothing -> SqlTypeExp ft
                    Just pdef -> case compositeFields pdef of
                        [] -> error "mkEntityDefSqlTypeExp: no composite fields"
                        [x] -> SqlTypeExp $ fieldType x
                        _ -> SqlType' $ SqlOther "Composite Reference"
            CompositeRef _  -> SqlType' $ SqlOther "Composite Reference"
            _ -> case ftype of
                    -- In the case of lists, we always serialize to a string
                    -- value (via JSON).
                    --
                    -- Normally, this would be determined automatically by
                    -- SqlTypeExp. However, there's one corner case: if there's
                    -- a list of entity IDs, the datatype for the ID has not
                    -- yet been created, so the compiler will fail. This extra
                    -- clause works around this limitation.
                    FTList _ -> SqlType' SqlString
                    _ -> SqlTypeExp ftype
      where
        ftype = fieldType field

-- | Create data types and appropriate 'PersistEntity' instances for the given
-- 'EntityDef's. Works well with the persist quasi-quoter.
mkEntityDefSqlTypeExp emEntities entMap ent = EntityDefSqlTypeExp ent
    (getSqlType $ entityId ent)
    $ (map getSqlType $ entityFields ent)
  where
    getSqlType field = maybe
        (defaultSqlTypeExp field)
        (SqlType' . SqlOther)
        (listToMaybe $ mapMaybe (stripPrefix "sqltype=") $ fieldAttrs field)


    -- In the case of embedding, there won't be any datatype created yet.
    -- We just use SqlString, as the data will be serialized to JSON.
    defaultSqlTypeExp field = case mEmbedded emEntities ftype of
        Right _ -> SqlType' SqlString
        Left (Just FTKeyCon) -> SqlType' SqlString
        Left Nothing -> case fieldReference field of
            ForeignRef refName ft  -> case M.lookup refName entMap of
                Nothing  -> SqlTypeExp ft
                -- A ForeignRef is blindly set to an Int in setEmbedField
                -- correct that now
                Just ent -> case entityPrimary ent of
                    Nothing -> SqlTypeExp ft
                    Just pdef -> case compositeFields pdef of
                        [] -> error "mkEntityDefSqlTypeExp: no composite fields"
                        [x] -> SqlTypeExp $ fieldType x
                        _ -> SqlType' $ SqlOther "Composite Reference"
            CompositeRef _  -> SqlType' $ SqlOther "Composite Reference"
            _ -> case ftype of
                    -- In the case of lists, we always serialize to a string
                    -- value (via JSON).
                    --
                    -- Normally, this would be determined automatically by
                    -- SqlTypeExp. However, there's one corner case: if there's
                    -- a list of entity IDs, the datatype for the ID has not
                    -- yet been created, so the compiler will fail. This extra
                    -- clause works around this limitation.
                    FTList _ -> SqlType' SqlString
                    _ -> SqlTypeExp ftype
      where
        ftype = fieldType field

-- | Create data types and appropriate 'PersistEntity' instances for the given
-- 'EntityDef's. Works well with the persist quasi-quoter.