packages feed

groundhog-th 0.7.0.1 → 0.8

raw patch · 5 files changed

+229/−202 lines, 5 filesdep ~groundhogPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: groundhog

API changes (from Hackage documentation)

- Database.Groundhog.TH: migrationFunction :: CodegenConfig -> Maybe String
- Database.Groundhog.TH: mkDbConstrAutoKeyName :: NamingStyle -> String -> String -> Int -> String
- Database.Groundhog.TH: mkDbConstrName :: NamingStyle -> String -> String -> Int -> String
- Database.Groundhog.TH: mkDbEntityName :: NamingStyle -> String -> String
- Database.Groundhog.TH: mkDbFieldName :: NamingStyle -> String -> String -> Int -> String -> Int -> String
- Database.Groundhog.TH: mkEmbeddedDecs :: CodegenConfig -> [[THEmbeddedDef] -> Q [Dec]]
- Database.Groundhog.TH: mkEntityDecs :: CodegenConfig -> [[THEntityDef] -> Q [Dec]]
- Database.Groundhog.TH: mkEntityKeyName :: NamingStyle -> String -> String
- Database.Groundhog.TH: mkExprFieldName :: NamingStyle -> String -> String -> Int -> String -> Int -> String
- Database.Groundhog.TH: mkExprSelectorName :: NamingStyle -> String -> String -> String -> Int -> String
- Database.Groundhog.TH: mkNormalDbFieldName :: NamingStyle -> String -> String -> Int -> Int -> String
- Database.Groundhog.TH: mkNormalExprFieldName :: NamingStyle -> String -> String -> Int -> Int -> String
- Database.Groundhog.TH: mkNormalExprSelectorName :: NamingStyle -> String -> String -> Int -> String
- Database.Groundhog.TH: mkNormalFieldName :: NamingStyle -> String -> String -> Int -> Int -> String
- Database.Groundhog.TH: mkPhantomName :: NamingStyle -> String -> String -> Int -> String
- Database.Groundhog.TH: mkPrimitiveDecs :: CodegenConfig -> [[THPrimitiveDef] -> Q [Dec]]
- Database.Groundhog.TH: mkUniqueKeyConstrName :: NamingStyle -> String -> String -> String -> String
- Database.Groundhog.TH: mkUniqueKeyDbName :: NamingStyle -> String -> String -> String -> String
- Database.Groundhog.TH: mkUniqueKeyPhantomName :: NamingStyle -> String -> String -> String -> String
- Database.Groundhog.TH: namingStyle :: CodegenConfig -> NamingStyle
- Database.Groundhog.TH.Settings: instance Eq PSAutoKeyDef
- Database.Groundhog.TH.Settings: instance Eq PSConstructorDef
- Database.Groundhog.TH.Settings: instance Eq PSEmbeddedDef
- Database.Groundhog.TH.Settings: instance Eq PSEntityDef
- Database.Groundhog.TH.Settings: instance Eq PSPrimitiveDef
- Database.Groundhog.TH.Settings: instance Eq PSUniqueDef
- Database.Groundhog.TH.Settings: instance Eq PSUniqueKeyDef
- Database.Groundhog.TH.Settings: instance Eq THAutoKeyDef
- Database.Groundhog.TH.Settings: instance Eq THConstructorDef
- Database.Groundhog.TH.Settings: instance Eq THEmbeddedDef
- Database.Groundhog.TH.Settings: instance Eq THEntityDef
- Database.Groundhog.TH.Settings: instance Eq THFieldDef
- Database.Groundhog.TH.Settings: instance Eq THPrimitiveDef
- Database.Groundhog.TH.Settings: instance Eq THUniqueDef
- Database.Groundhog.TH.Settings: instance Eq THUniqueKeyDef
- Database.Groundhog.TH.Settings: instance FromJSON (PSFieldDef String)
- Database.Groundhog.TH.Settings: instance FromJSON PSAutoKeyDef
- Database.Groundhog.TH.Settings: instance FromJSON PSConstructorDef
- Database.Groundhog.TH.Settings: instance FromJSON PSEmbeddedDef
- Database.Groundhog.TH.Settings: instance FromJSON PSEntityDef
- Database.Groundhog.TH.Settings: instance FromJSON PSPrimitiveDef
- Database.Groundhog.TH.Settings: instance FromJSON PSUniqueDef
- Database.Groundhog.TH.Settings: instance FromJSON PSUniqueKeyDef
- Database.Groundhog.TH.Settings: instance FromJSON PersistDefinitions
- Database.Groundhog.TH.Settings: instance FromJSON ReferenceActionType
- Database.Groundhog.TH.Settings: instance FromJSON UniqueType
- Database.Groundhog.TH.Settings: instance Lift (PSFieldDef String)
- Database.Groundhog.TH.Settings: instance Lift PSAutoKeyDef
- Database.Groundhog.TH.Settings: instance Lift PSConstructorDef
- Database.Groundhog.TH.Settings: instance Lift PSEmbeddedDef
- Database.Groundhog.TH.Settings: instance Lift PSEntityDef
- Database.Groundhog.TH.Settings: instance Lift PSPrimitiveDef
- Database.Groundhog.TH.Settings: instance Lift PSUniqueDef
- Database.Groundhog.TH.Settings: instance Lift PSUniqueKeyDef
- Database.Groundhog.TH.Settings: instance Lift PersistDefinitions
- Database.Groundhog.TH.Settings: instance Lift ReferenceActionType
- Database.Groundhog.TH.Settings: instance Lift UniqueType
- Database.Groundhog.TH.Settings: instance Show PSAutoKeyDef
- Database.Groundhog.TH.Settings: instance Show PSConstructorDef
- Database.Groundhog.TH.Settings: instance Show PSEmbeddedDef
- Database.Groundhog.TH.Settings: instance Show PSEntityDef
- Database.Groundhog.TH.Settings: instance Show PSPrimitiveDef
- Database.Groundhog.TH.Settings: instance Show PSUniqueDef
- Database.Groundhog.TH.Settings: instance Show PSUniqueKeyDef
- Database.Groundhog.TH.Settings: instance Show PersistDefinitions
- Database.Groundhog.TH.Settings: instance Show THAutoKeyDef
- Database.Groundhog.TH.Settings: instance Show THConstructorDef
- Database.Groundhog.TH.Settings: instance Show THEmbeddedDef
- Database.Groundhog.TH.Settings: instance Show THEntityDef
- Database.Groundhog.TH.Settings: instance Show THFieldDef
- Database.Groundhog.TH.Settings: instance Show THPrimitiveDef
- Database.Groundhog.TH.Settings: instance Show THUniqueDef
- Database.Groundhog.TH.Settings: instance Show THUniqueKeyDef
- Database.Groundhog.TH.Settings: instance ToJSON (PSFieldDef String)
- Database.Groundhog.TH.Settings: instance ToJSON PSAutoKeyDef
- Database.Groundhog.TH.Settings: instance ToJSON PSConstructorDef
- Database.Groundhog.TH.Settings: instance ToJSON PSEntityDef
- Database.Groundhog.TH.Settings: instance ToJSON PSUniqueDef
- Database.Groundhog.TH.Settings: instance ToJSON PSUniqueKeyDef
- Database.Groundhog.TH.Settings: instance ToJSON ReferenceActionType
- Database.Groundhog.TH.Settings: instance ToJSON UniqueType
- Database.Groundhog.TH.Settings: psAutoKey :: PSEntityDef -> Maybe (Maybe PSAutoKeyDef)
- Database.Groundhog.TH.Settings: psAutoKeyConstrName :: PSAutoKeyDef -> Maybe String
- Database.Groundhog.TH.Settings: psAutoKeyIsDef :: PSAutoKeyDef -> Maybe Bool
- Database.Groundhog.TH.Settings: psConstrFields :: PSConstructorDef -> Maybe [PSFieldDef String]
- Database.Groundhog.TH.Settings: psConstrName :: PSConstructorDef -> String
- Database.Groundhog.TH.Settings: psConstrUniques :: PSConstructorDef -> Maybe [PSUniqueDef]
- Database.Groundhog.TH.Settings: psConstructors :: PSEntityDef -> Maybe [PSConstructorDef]
- Database.Groundhog.TH.Settings: psDataName :: PSEntityDef -> String
- Database.Groundhog.TH.Settings: psDbAutoKeyName :: PSConstructorDef -> Maybe String
- Database.Groundhog.TH.Settings: psDbConstrName :: PSConstructorDef -> Maybe String
- Database.Groundhog.TH.Settings: psDbEmbeddedName :: PSEmbeddedDef -> Maybe String
- Database.Groundhog.TH.Settings: psDbEntityName :: PSEntityDef -> Maybe String
- Database.Groundhog.TH.Settings: psDbFieldName :: PSFieldDef str -> Maybe str
- Database.Groundhog.TH.Settings: psDbTypeName :: PSFieldDef str -> Maybe str
- Database.Groundhog.TH.Settings: psDefaultValue :: PSFieldDef str -> Maybe str
- Database.Groundhog.TH.Settings: psEmbeddedDef :: PSFieldDef str -> Maybe [PSFieldDef str]
- Database.Groundhog.TH.Settings: psEmbeddedFields :: PSEmbeddedDef -> Maybe [PSFieldDef String]
- Database.Groundhog.TH.Settings: psEmbeddedName :: PSEmbeddedDef -> String
- Database.Groundhog.TH.Settings: psEmbeddeds :: PersistDefinitions -> [PSEmbeddedDef]
- Database.Groundhog.TH.Settings: psEntities :: PersistDefinitions -> [PSEntityDef]
- Database.Groundhog.TH.Settings: psEntitySchema :: PSEntityDef -> Maybe String
- Database.Groundhog.TH.Settings: psExprName :: PSFieldDef str -> Maybe str
- Database.Groundhog.TH.Settings: psFieldName :: PSFieldDef str -> str
- Database.Groundhog.TH.Settings: psPhantomConstrName :: PSConstructorDef -> Maybe String
- Database.Groundhog.TH.Settings: psPrimitiveDbName :: PSPrimitiveDef -> Maybe String
- Database.Groundhog.TH.Settings: psPrimitiveName :: PSPrimitiveDef -> String
- Database.Groundhog.TH.Settings: psPrimitiveStringEnumRepresentation :: PSPrimitiveDef -> Maybe Bool
- Database.Groundhog.TH.Settings: psPrimitives :: PersistDefinitions -> [PSPrimitiveDef]
- Database.Groundhog.TH.Settings: psReferenceParent :: PSFieldDef str -> Maybe (Maybe ((Maybe str, str), [str]), Maybe ReferenceActionType, Maybe ReferenceActionType)
- Database.Groundhog.TH.Settings: psUniqueFields :: PSUniqueDef -> [Either String String]
- Database.Groundhog.TH.Settings: psUniqueKeyConstrName :: PSUniqueKeyDef -> Maybe String
- Database.Groundhog.TH.Settings: psUniqueKeyDbName :: PSUniqueKeyDef -> Maybe String
- Database.Groundhog.TH.Settings: psUniqueKeyFields :: PSUniqueKeyDef -> Maybe [PSFieldDef String]
- Database.Groundhog.TH.Settings: psUniqueKeyIsDef :: PSUniqueKeyDef -> Maybe Bool
- Database.Groundhog.TH.Settings: psUniqueKeyMakeEmbedded :: PSUniqueKeyDef -> Maybe Bool
- Database.Groundhog.TH.Settings: psUniqueKeyName :: PSUniqueKeyDef -> String
- Database.Groundhog.TH.Settings: psUniqueKeyPhantomName :: PSUniqueKeyDef -> Maybe String
- Database.Groundhog.TH.Settings: psUniqueKeys :: PSEntityDef -> Maybe [PSUniqueKeyDef]
- Database.Groundhog.TH.Settings: psUniqueName :: PSUniqueDef -> String
- Database.Groundhog.TH.Settings: psUniqueType :: PSUniqueDef -> Maybe UniqueType
- Database.Groundhog.TH.Settings: thAutoKey :: THEntityDef -> Maybe THAutoKeyDef
- Database.Groundhog.TH.Settings: thAutoKeyConstrName :: THAutoKeyDef -> String
- Database.Groundhog.TH.Settings: thAutoKeyIsDef :: THAutoKeyDef -> Bool
- Database.Groundhog.TH.Settings: thConstrFields :: THConstructorDef -> [THFieldDef]
- Database.Groundhog.TH.Settings: thConstrName :: THConstructorDef -> Name
- Database.Groundhog.TH.Settings: thConstrUniques :: THConstructorDef -> [THUniqueDef]
- Database.Groundhog.TH.Settings: thConstructors :: THEntityDef -> [THConstructorDef]
- Database.Groundhog.TH.Settings: thDataName :: THEntityDef -> Name
- Database.Groundhog.TH.Settings: thDbAutoKeyName :: THConstructorDef -> Maybe String
- Database.Groundhog.TH.Settings: thDbConstrName :: THConstructorDef -> String
- Database.Groundhog.TH.Settings: thDbEmbeddedName :: THEmbeddedDef -> String
- Database.Groundhog.TH.Settings: thDbEntityName :: THEntityDef -> String
- Database.Groundhog.TH.Settings: thDbFieldName :: THFieldDef -> String
- Database.Groundhog.TH.Settings: thDbTypeName :: THFieldDef -> Maybe String
- Database.Groundhog.TH.Settings: thDefaultValue :: THFieldDef -> Maybe String
- Database.Groundhog.TH.Settings: thEmbeddedConstructorName :: THEmbeddedDef -> Name
- Database.Groundhog.TH.Settings: thEmbeddedDef :: THFieldDef -> Maybe [PSFieldDef String]
- Database.Groundhog.TH.Settings: thEmbeddedFields :: THEmbeddedDef -> [THFieldDef]
- Database.Groundhog.TH.Settings: thEmbeddedName :: THEmbeddedDef -> Name
- Database.Groundhog.TH.Settings: thEmbeddedTypeParams :: THEmbeddedDef -> [TyVarBndr]
- Database.Groundhog.TH.Settings: thEntitySchema :: THEntityDef -> Maybe String
- Database.Groundhog.TH.Settings: thExprName :: THFieldDef -> String
- Database.Groundhog.TH.Settings: thFieldName :: THFieldDef -> String
- Database.Groundhog.TH.Settings: thFieldType :: THFieldDef -> Type
- Database.Groundhog.TH.Settings: thPhantomConstrName :: THConstructorDef -> String
- Database.Groundhog.TH.Settings: thPrimitiveDbName :: THPrimitiveDef -> String
- Database.Groundhog.TH.Settings: thPrimitiveName :: THPrimitiveDef -> Name
- Database.Groundhog.TH.Settings: thPrimitiveStringEnumRepresentation :: THPrimitiveDef -> Bool
- Database.Groundhog.TH.Settings: thReferenceParent :: THFieldDef -> Maybe (Maybe ((Maybe String, String), [String]), Maybe ReferenceActionType, Maybe ReferenceActionType)
- Database.Groundhog.TH.Settings: thTypeParams :: THEntityDef -> [TyVarBndr]
- Database.Groundhog.TH.Settings: thUniqueFields :: THUniqueDef -> [Either String String]
- Database.Groundhog.TH.Settings: thUniqueKeyConstrName :: THUniqueKeyDef -> String
- Database.Groundhog.TH.Settings: thUniqueKeyDbName :: THUniqueKeyDef -> String
- Database.Groundhog.TH.Settings: thUniqueKeyFields :: THUniqueKeyDef -> [THFieldDef]
- Database.Groundhog.TH.Settings: thUniqueKeyIsDef :: THUniqueKeyDef -> Bool
- Database.Groundhog.TH.Settings: thUniqueKeyMakeEmbedded :: THUniqueKeyDef -> Bool
- Database.Groundhog.TH.Settings: thUniqueKeyName :: THUniqueKeyDef -> String
- Database.Groundhog.TH.Settings: thUniqueKeyPhantomName :: THUniqueKeyDef -> String
- Database.Groundhog.TH.Settings: thUniqueKeys :: THEntityDef -> [THUniqueKeyDef]
- Database.Groundhog.TH.Settings: thUniqueName :: THUniqueDef -> String
- Database.Groundhog.TH.Settings: thUniqueType :: THUniqueDef -> UniqueType
+ Database.Groundhog.TH: [migrationFunction] :: CodegenConfig -> Maybe String
+ Database.Groundhog.TH: [mkDbConstrAutoKeyName] :: NamingStyle -> String -> String -> Int -> String
+ Database.Groundhog.TH: [mkDbConstrName] :: NamingStyle -> String -> String -> Int -> String
+ Database.Groundhog.TH: [mkDbEntityName] :: NamingStyle -> String -> String
+ Database.Groundhog.TH: [mkDbFieldName] :: NamingStyle -> String -> String -> Int -> String -> Int -> String
+ Database.Groundhog.TH: [mkEmbeddedDecs] :: CodegenConfig -> [[THEmbeddedDef] -> Q [Dec]]
+ Database.Groundhog.TH: [mkEntityDecs] :: CodegenConfig -> [[THEntityDef] -> Q [Dec]]
+ Database.Groundhog.TH: [mkEntityKeyName] :: NamingStyle -> String -> String
+ Database.Groundhog.TH: [mkExprFieldName] :: NamingStyle -> String -> String -> Int -> String -> Int -> String
+ Database.Groundhog.TH: [mkExprSelectorName] :: NamingStyle -> String -> String -> String -> Int -> String
+ Database.Groundhog.TH: [mkNormalDbFieldName] :: NamingStyle -> String -> String -> Int -> Int -> String
+ Database.Groundhog.TH: [mkNormalExprFieldName] :: NamingStyle -> String -> String -> Int -> Int -> String
+ Database.Groundhog.TH: [mkNormalExprSelectorName] :: NamingStyle -> String -> String -> Int -> String
+ Database.Groundhog.TH: [mkNormalFieldName] :: NamingStyle -> String -> String -> Int -> Int -> String
+ Database.Groundhog.TH: [mkPhantomName] :: NamingStyle -> String -> String -> Int -> String
+ Database.Groundhog.TH: [mkPrimitiveDecs] :: CodegenConfig -> [[THPrimitiveDef] -> Q [Dec]]
+ Database.Groundhog.TH: [mkUniqueKeyConstrName] :: NamingStyle -> String -> String -> String -> String
+ Database.Groundhog.TH: [mkUniqueKeyDbName] :: NamingStyle -> String -> String -> String -> String
+ Database.Groundhog.TH: [mkUniqueKeyPhantomName] :: NamingStyle -> String -> String -> String -> String
+ Database.Groundhog.TH: [namingStyle] :: CodegenConfig -> NamingStyle
+ Database.Groundhog.TH: enumConverter :: Enum a => (a -> Int, Int -> a)
+ Database.Groundhog.TH: showReadConverter :: (Show a, Read a) => (a -> String, String -> a)
+ Database.Groundhog.TH.Settings: [psAutoKeyConstrName] :: PSAutoKeyDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psAutoKeyIsDef] :: PSAutoKeyDef -> Maybe Bool
+ Database.Groundhog.TH.Settings: [psAutoKey] :: PSEntityDef -> Maybe (Maybe PSAutoKeyDef)
+ Database.Groundhog.TH.Settings: [psConstrFields] :: PSConstructorDef -> Maybe [PSFieldDef String]
+ Database.Groundhog.TH.Settings: [psConstrName] :: PSConstructorDef -> String
+ Database.Groundhog.TH.Settings: [psConstrUniques] :: PSConstructorDef -> Maybe [PSUniqueDef]
+ Database.Groundhog.TH.Settings: [psConstructors] :: PSEntityDef -> Maybe [PSConstructorDef]
+ Database.Groundhog.TH.Settings: [psDataName] :: PSEntityDef -> String
+ Database.Groundhog.TH.Settings: [psDbAutoKeyName] :: PSConstructorDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psDbConstrName] :: PSConstructorDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psDbEmbeddedName] :: PSEmbeddedDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psDbEntityName] :: PSEntityDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psDbFieldName] :: PSFieldDef str -> Maybe str
+ Database.Groundhog.TH.Settings: [psDbTypeName] :: PSFieldDef str -> Maybe str
+ Database.Groundhog.TH.Settings: [psDefaultValue] :: PSFieldDef str -> Maybe str
+ Database.Groundhog.TH.Settings: [psEmbeddedDef] :: PSFieldDef str -> Maybe [PSFieldDef str]
+ Database.Groundhog.TH.Settings: [psEmbeddedFields] :: PSEmbeddedDef -> Maybe [PSFieldDef String]
+ Database.Groundhog.TH.Settings: [psEmbeddedName] :: PSEmbeddedDef -> String
+ Database.Groundhog.TH.Settings: [psEmbeddeds] :: PersistDefinitions -> [PSEmbeddedDef]
+ Database.Groundhog.TH.Settings: [psEntities] :: PersistDefinitions -> [PSEntityDef]
+ Database.Groundhog.TH.Settings: [psEntitySchema] :: PSEntityDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psExprName] :: PSFieldDef str -> Maybe str
+ Database.Groundhog.TH.Settings: [psFieldConverter] :: PSFieldDef str -> Maybe str
+ Database.Groundhog.TH.Settings: [psFieldName] :: PSFieldDef str -> str
+ Database.Groundhog.TH.Settings: [psPhantomConstrName] :: PSConstructorDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psPrimitiveConverter] :: PSPrimitiveDef -> String
+ Database.Groundhog.TH.Settings: [psPrimitiveDbName] :: PSPrimitiveDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psPrimitiveName] :: PSPrimitiveDef -> String
+ Database.Groundhog.TH.Settings: [psPrimitives] :: PersistDefinitions -> [PSPrimitiveDef]
+ Database.Groundhog.TH.Settings: [psReferenceParent] :: PSFieldDef str -> Maybe (Maybe ((Maybe str, str), [str]), Maybe ReferenceActionType, Maybe ReferenceActionType)
+ Database.Groundhog.TH.Settings: [psUniqueFields] :: PSUniqueDef -> [Either String String]
+ Database.Groundhog.TH.Settings: [psUniqueKeyConstrName] :: PSUniqueKeyDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psUniqueKeyDbName] :: PSUniqueKeyDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psUniqueKeyFields] :: PSUniqueKeyDef -> Maybe [PSFieldDef String]
+ Database.Groundhog.TH.Settings: [psUniqueKeyIsDef] :: PSUniqueKeyDef -> Maybe Bool
+ Database.Groundhog.TH.Settings: [psUniqueKeyMakeEmbedded] :: PSUniqueKeyDef -> Maybe Bool
+ Database.Groundhog.TH.Settings: [psUniqueKeyName] :: PSUniqueKeyDef -> String
+ Database.Groundhog.TH.Settings: [psUniqueKeyPhantomName] :: PSUniqueKeyDef -> Maybe String
+ Database.Groundhog.TH.Settings: [psUniqueKeys] :: PSEntityDef -> Maybe [PSUniqueKeyDef]
+ Database.Groundhog.TH.Settings: [psUniqueName] :: PSUniqueDef -> String
+ Database.Groundhog.TH.Settings: [psUniqueType] :: PSUniqueDef -> Maybe UniqueType
+ Database.Groundhog.TH.Settings: [thAutoKeyConstrName] :: THAutoKeyDef -> String
+ Database.Groundhog.TH.Settings: [thAutoKeyIsDef] :: THAutoKeyDef -> Bool
+ Database.Groundhog.TH.Settings: [thAutoKey] :: THEntityDef -> Maybe THAutoKeyDef
+ Database.Groundhog.TH.Settings: [thConstrFields] :: THConstructorDef -> [THFieldDef]
+ Database.Groundhog.TH.Settings: [thConstrName] :: THConstructorDef -> Name
+ Database.Groundhog.TH.Settings: [thConstrUniques] :: THConstructorDef -> [THUniqueDef]
+ Database.Groundhog.TH.Settings: [thConstructors] :: THEntityDef -> [THConstructorDef]
+ Database.Groundhog.TH.Settings: [thDataName] :: THEntityDef -> Name
+ Database.Groundhog.TH.Settings: [thDbAutoKeyName] :: THConstructorDef -> Maybe String
+ Database.Groundhog.TH.Settings: [thDbConstrName] :: THConstructorDef -> String
+ Database.Groundhog.TH.Settings: [thDbEmbeddedName] :: THEmbeddedDef -> String
+ Database.Groundhog.TH.Settings: [thDbEntityName] :: THEntityDef -> String
+ Database.Groundhog.TH.Settings: [thDbFieldName] :: THFieldDef -> String
+ Database.Groundhog.TH.Settings: [thDbTypeName] :: THFieldDef -> Maybe String
+ Database.Groundhog.TH.Settings: [thDefaultValue] :: THFieldDef -> Maybe String
+ Database.Groundhog.TH.Settings: [thEmbeddedConstructorName] :: THEmbeddedDef -> Name
+ Database.Groundhog.TH.Settings: [thEmbeddedDef] :: THFieldDef -> Maybe [PSFieldDef String]
+ Database.Groundhog.TH.Settings: [thEmbeddedFields] :: THEmbeddedDef -> [THFieldDef]
+ Database.Groundhog.TH.Settings: [thEmbeddedName] :: THEmbeddedDef -> Name
+ Database.Groundhog.TH.Settings: [thEmbeddedTypeParams] :: THEmbeddedDef -> [TyVarBndr]
+ Database.Groundhog.TH.Settings: [thEntitySchema] :: THEntityDef -> Maybe String
+ Database.Groundhog.TH.Settings: [thExprName] :: THFieldDef -> String
+ Database.Groundhog.TH.Settings: [thFieldConverter] :: THFieldDef -> Maybe Name
+ Database.Groundhog.TH.Settings: [thFieldName] :: THFieldDef -> String
+ Database.Groundhog.TH.Settings: [thFieldType] :: THFieldDef -> Type
+ Database.Groundhog.TH.Settings: [thPhantomConstrName] :: THConstructorDef -> String
+ Database.Groundhog.TH.Settings: [thPrimitiveConverter] :: THPrimitiveDef -> Name
+ Database.Groundhog.TH.Settings: [thPrimitiveDbName] :: THPrimitiveDef -> String
+ Database.Groundhog.TH.Settings: [thPrimitiveName] :: THPrimitiveDef -> Name
+ Database.Groundhog.TH.Settings: [thReferenceParent] :: THFieldDef -> Maybe (Maybe ((Maybe String, String), [String]), Maybe ReferenceActionType, Maybe ReferenceActionType)
+ Database.Groundhog.TH.Settings: [thTypeParams] :: THEntityDef -> [TyVarBndr]
+ Database.Groundhog.TH.Settings: [thUniqueFields] :: THUniqueDef -> [Either String String]
+ Database.Groundhog.TH.Settings: [thUniqueKeyConstrName] :: THUniqueKeyDef -> String
+ Database.Groundhog.TH.Settings: [thUniqueKeyDbName] :: THUniqueKeyDef -> String
+ Database.Groundhog.TH.Settings: [thUniqueKeyFields] :: THUniqueKeyDef -> [THFieldDef]
+ Database.Groundhog.TH.Settings: [thUniqueKeyIsDef] :: THUniqueKeyDef -> Bool
+ Database.Groundhog.TH.Settings: [thUniqueKeyMakeEmbedded] :: THUniqueKeyDef -> Bool
+ Database.Groundhog.TH.Settings: [thUniqueKeyName] :: THUniqueKeyDef -> String
+ Database.Groundhog.TH.Settings: [thUniqueKeyPhantomName] :: THUniqueKeyDef -> String
+ Database.Groundhog.TH.Settings: [thUniqueKeys] :: THEntityDef -> [THUniqueKeyDef]
+ Database.Groundhog.TH.Settings: [thUniqueName] :: THUniqueDef -> String
+ Database.Groundhog.TH.Settings: [thUniqueType] :: THUniqueDef -> UniqueType
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON (Database.Groundhog.Generic.PSFieldDef GHC.Base.String)
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.Core.ReferenceActionType
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.Core.UniqueType
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.TH.Settings.PSAutoKeyDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.TH.Settings.PSConstructorDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.TH.Settings.PSEmbeddedDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.TH.Settings.PSEntityDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.TH.Settings.PSPrimitiveDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.TH.Settings.PSUniqueDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.TH.Settings.PSUniqueKeyDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Database.Groundhog.TH.Settings.PersistDefinitions
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.ToJSON.ToJSON (Database.Groundhog.Generic.PSFieldDef GHC.Base.String)
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.ToJSON.ToJSON Database.Groundhog.Core.ReferenceActionType
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.ToJSON.ToJSON Database.Groundhog.Core.UniqueType
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.ToJSON.ToJSON Database.Groundhog.TH.Settings.PSAutoKeyDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.ToJSON.ToJSON Database.Groundhog.TH.Settings.PSConstructorDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.ToJSON.ToJSON Database.Groundhog.TH.Settings.PSEntityDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.ToJSON.ToJSON Database.Groundhog.TH.Settings.PSUniqueDef
+ Database.Groundhog.TH.Settings: instance Data.Aeson.Types.ToJSON.ToJSON Database.Groundhog.TH.Settings.PSUniqueKeyDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.PSAutoKeyDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.PSConstructorDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.PSEmbeddedDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.PSEntityDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.PSPrimitiveDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.PSUniqueDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.PSUniqueKeyDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.THAutoKeyDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.THConstructorDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.THEmbeddedDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.THEntityDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.THFieldDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.THPrimitiveDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.THUniqueDef
+ Database.Groundhog.TH.Settings: instance GHC.Classes.Eq Database.Groundhog.TH.Settings.THUniqueKeyDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.PSAutoKeyDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.PSConstructorDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.PSEmbeddedDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.PSEntityDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.PSPrimitiveDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.PSUniqueDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.PSUniqueKeyDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.PersistDefinitions
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.THAutoKeyDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.THConstructorDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.THEmbeddedDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.THEntityDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.THFieldDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.THPrimitiveDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.THUniqueDef
+ Database.Groundhog.TH.Settings: instance GHC.Show.Show Database.Groundhog.TH.Settings.THUniqueKeyDef
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift (Database.Groundhog.Generic.PSFieldDef GHC.Base.String)
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.Core.ReferenceActionType
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.Core.UniqueType
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.TH.Settings.PSAutoKeyDef
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.TH.Settings.PSConstructorDef
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.TH.Settings.PSEmbeddedDef
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.TH.Settings.PSEntityDef
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.TH.Settings.PSPrimitiveDef
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.TH.Settings.PSUniqueDef
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.TH.Settings.PSUniqueKeyDef
+ Database.Groundhog.TH.Settings: instance Language.Haskell.TH.Syntax.Lift Database.Groundhog.TH.Settings.PersistDefinitions
- Database.Groundhog.TH.Settings: PSFieldDef :: str -> Maybe str -> Maybe str -> Maybe str -> Maybe [PSFieldDef str] -> Maybe str -> Maybe (Maybe ((Maybe str, str), [str]), Maybe ReferenceActionType, Maybe ReferenceActionType) -> PSFieldDef str
+ Database.Groundhog.TH.Settings: PSFieldDef :: str -> Maybe str -> Maybe str -> Maybe str -> Maybe [PSFieldDef str] -> Maybe str -> Maybe (Maybe ((Maybe str, str), [str]), Maybe ReferenceActionType, Maybe ReferenceActionType) -> Maybe str -> PSFieldDef str
- Database.Groundhog.TH.Settings: PSPrimitiveDef :: String -> Maybe String -> Maybe Bool -> PSPrimitiveDef
+ Database.Groundhog.TH.Settings: PSPrimitiveDef :: String -> Maybe String -> String -> PSPrimitiveDef
- Database.Groundhog.TH.Settings: THFieldDef :: String -> String -> Maybe String -> String -> Type -> Maybe [PSFieldDef String] -> Maybe String -> Maybe (Maybe ((Maybe String, String), [String]), Maybe ReferenceActionType, Maybe ReferenceActionType) -> THFieldDef
+ Database.Groundhog.TH.Settings: THFieldDef :: String -> String -> Maybe String -> String -> Type -> Maybe [PSFieldDef String] -> Maybe String -> Maybe (Maybe ((Maybe String, String), [String]), Maybe ReferenceActionType, Maybe ReferenceActionType) -> Maybe Name -> THFieldDef
- Database.Groundhog.TH.Settings: THPrimitiveDef :: Name -> String -> Bool -> THPrimitiveDef
+ Database.Groundhog.TH.Settings: THPrimitiveDef :: Name -> String -> Name -> THPrimitiveDef

Files

Database/Groundhog/TH.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell, RecordWildCards #-}+{-# LANGUAGE TemplateHaskell, RecordWildCards, CPP #-}  -- | This module provides functions to generate the auxiliary structures for the user data type module Database.Groundhog.TH@@ -29,6 +29,9 @@   , applyEntitySettings   , applyEmbeddedSettings   , applyPrimitiveSettings+  -- * Helpers+  , showReadConverter+  , enumConverter   ) where  import Database.Groundhog.Core (delim, UniqueType(..))@@ -200,10 +203,7 @@   let getDecl name = do         info <- reify $ mkName name         return $ case info of-          TyConI x -> case x of-            d@DataD{}  -> d-            NewtypeD{} -> error "Newtypes are not supported"-            _ -> error $ "Unknown declaration type: " ++ name ++ " " ++ show x+          TyConI d -> d           _        -> error $ "Only datatypes can be processed: " ++ name          entities   <- forM psEntities $ \e ->@@ -270,6 +270,7 @@       , thEmbeddedDef = psEmbeddedDef       , thDefaultValue = psDefaultValue       , thReferenceParent = psReferenceParent+      , thFieldConverter = fmap mkName psFieldConverter       }  applyEmbeddedSettings :: PSEmbeddedDef -> THEmbeddedDef -> THEmbeddedDef@@ -282,7 +283,7 @@ applyPrimitiveSettings :: PSPrimitiveDef -> THPrimitiveDef -> THPrimitiveDef applyPrimitiveSettings PSPrimitiveDef{..} def@(THPrimitiveDef{..}) =   def { thPrimitiveDbName = fromMaybe thPrimitiveDbName psPrimitiveDbName-      , thPrimitiveStringEnumRepresentation = fromMaybe thPrimitiveStringEnumRepresentation psPrimitiveStringEnumRepresentation+      , thPrimitiveConverter = mkName psPrimitiveConverter       }  mkFieldsForUniqueKey :: NamingStyle -> String -> THUniqueKeyDef -> THConstructorDef -> [THFieldDef]@@ -358,10 +359,11 @@   return def  mkTHEntityDef :: NamingStyle -> Dec -> THEntityDef-mkTHEntityDef NamingStyle{..} (DataD _ dName typeVars cons _) =-  THEntityDef dName (mkDbEntityName dName') Nothing (Just $ THAutoKeyDef (mkEntityKeyName dName') True) [] typeVars constrs where+mkTHEntityDef NamingStyle{..} dec = THEntityDef dName (mkDbEntityName dName') Nothing autokey [] typeVars constrs where+  (dName, typeVars, cons) = fromDataD dec   constrs = zipWith mkConstr [0..] cons   dName' = nameBase dName+  autokey = Just $ THAutoKeyDef (mkEntityKeyName dName') True    mkConstr cNum c = case c of     NormalC name params -> mkConstr' name $ zipWith (mkField (nameBase name)) params [0..]@@ -373,17 +375,17 @@       apply f = f dName' (nameBase name) cNum      mkField :: String -> StrictType -> Int -> THFieldDef-    mkField cName (_, t) fNum = THFieldDef (apply mkNormalFieldName) (apply mkNormalDbFieldName) Nothing (apply mkNormalExprFieldName) t Nothing Nothing Nothing where+    mkField cName (_, t) fNum = THFieldDef (apply mkNormalFieldName) (apply mkNormalDbFieldName) Nothing (apply mkNormalExprFieldName) t Nothing Nothing Nothing Nothing where       apply f = f dName' cName cNum fNum     mkVarField :: String -> VarStrictType -> Int -> THFieldDef-    mkVarField cName (fName, _, t) fNum = THFieldDef fName' (apply mkDbFieldName) Nothing (apply mkExprFieldName) t Nothing Nothing Nothing where+    mkVarField cName (fName, _, t) fNum = THFieldDef fName' (apply mkDbFieldName) Nothing (apply mkExprFieldName) t Nothing Nothing Nothing Nothing where       apply f = f dName' cName cNum fName' fNum       fName' = nameBase fName-mkTHEntityDef _ _ = error "Only datatypes can be processed"  mkTHEmbeddedDef :: NamingStyle -> Dec -> THEmbeddedDef-mkTHEmbeddedDef (NamingStyle{..}) (DataD _ dName typeVars cons _) =-  THEmbeddedDef dName cName (mkDbEntityName dName') typeVars fields where+mkTHEmbeddedDef (NamingStyle{..}) dec = THEmbeddedDef dName cName (mkDbEntityName dName') typeVars fields where++  (dName, typeVars, cons) = fromDataD dec   dName' = nameBase dName      (cName, fields) = case cons of@@ -395,20 +397,32 @@     _ -> error $ "An embedded datatype must have exactly one constructor: " ++ show dName      mkField :: String -> StrictType -> Int -> THFieldDef-  mkField cName' (_, t) fNum = THFieldDef (apply mkNormalFieldName) (apply mkNormalDbFieldName) Nothing (mkNormalExprSelectorName dName' cName' fNum) t Nothing Nothing Nothing where+  mkField cName' (_, t) fNum = THFieldDef (apply mkNormalFieldName) (apply mkNormalDbFieldName) Nothing (mkNormalExprSelectorName dName' cName' fNum) t Nothing Nothing Nothing Nothing where     apply f = f dName' cName' 0 fNum   mkVarField :: String -> VarStrictType -> Int -> THFieldDef-  mkVarField cName' (fName, _, t) fNum = THFieldDef fName' (apply mkDbFieldName) Nothing (mkExprSelectorName dName' cName' fName' fNum) t Nothing Nothing Nothing where+  mkVarField cName' (fName, _, t) fNum = THFieldDef fName' (apply mkDbFieldName) Nothing (mkExprSelectorName dName' cName' fName' fNum) t Nothing Nothing Nothing Nothing where     apply f = f dName' cName' 0 fName' fNum     fName' = nameBase fName-mkTHEmbeddedDef _ _ = error "Only datatypes can be processed"  mkTHPrimitiveDef :: NamingStyle -> Dec -> THPrimitiveDef-mkTHPrimitiveDef (NamingStyle{..}) (DataD _ dName _ _ _) =-  THPrimitiveDef dName (mkDbEntityName dName') True where+mkTHPrimitiveDef (NamingStyle{..}) dec = THPrimitiveDef dName (mkDbEntityName dName') 'showReadConverter where+  dName = case dec of+#if MIN_VERSION_template_haskell(2, 11, 0)+    DataD _ dName _ _ _ _ -> dName+    NewtypeD _ dName _ _ _ _ -> dName+#else+    DataD _ dName _ _ _ -> dName+    NewtypeD _ dName _ _ _ -> dName+#endif+    _ -> error $ "Only datatypes and newtypes can be declared as primitive: " ++ show dec   dName' = nameBase dName-mkTHPrimitiveDef _ _ = error "Only datatypes can be processed" +showReadConverter :: (Show a, Read a) => (a -> String, String -> a)+showReadConverter = (show, read)++enumConverter :: Enum a => (a -> Int, Int -> a)+enumConverter = (fromEnum, toEnum)+ firstChar :: (Char -> Char) -> String -> String firstChar f s = f (head s):tail s @@ -553,9 +567,9 @@ --mkPersist defaultCodegenConfig [groundhog| --definitions: --  - primitive: WeekDay---    representation: enum                # Its column will have integer type. The conversion will use Enum instance.+--    converter: enumConverter            # Its column will have integer type. The conversion will use Enum instance. --  - primitive: Point---    representation: showread            # Its column will have string type. The conversion will use Show/Read instances. If representation is omitted, showread will be used by default.+--    converter: showReadConverter        # Its column will have string type. The conversion will use Show/Read instances. If representation is omitted, showread will be used by default. -- |] -- @ @@ -631,3 +645,12 @@     ] --  runIO $ putStrLn $ pprint decs   return decs)++fromDataD :: InstanceDec -> (Name, [TyVarBndr], [Con])+fromDataD d = case d of+#if MIN_VERSION_template_haskell(2, 11, 0)+  (DataD _ dName typeVars _ constrs _) -> (dName, typeVars, constrs)+#else+  (DataD _ dName typeVars constrs _) -> (dName, typeVars, constrs)+#endif+  d -> error $ "Only datatypes can be processed: " ++ show d
Database/Groundhog/TH/CodeGen.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell, RecordWildCards, DoAndIfThenElse #-}
+{-# LANGUAGE TemplateHaskell, RecordWildCards, DoAndIfThenElse, ExplicitForAll #-}
 {-# LANGUAGE CPP #-}
 
 module Database.Groundhog.TH.CodeGen
@@ -30,8 +30,8 @@ import Language.Haskell.TH
 import Language.Haskell.TH.Syntax (Lift(..))
 import Control.Applicative
-import Control.Arrow (second)
-import Control.Monad (liftM, liftM2, forM, forM_, foldM, filterM, replicateM)
+import Control.Arrow (first)
+import Control.Monad (liftM, liftM2, forM, forM_, filterM, replicateM, zipWithM)
 import Data.Either (lefts, rights)
 import Data.List (findIndex, nub, partition)
 import Data.Maybe (catMaybes, mapMaybe)
@@ -54,24 +54,8 @@     funD 'persistName $ [ clause [pat] body [] ]
 
   toPersistValues' <- do
-    vars <- mapM (\f -> newName "x" >>= \fname -> return (fname, thFieldType f)) $ thEmbeddedFields def
-    let pat = conP (thEmbeddedConstructorName def) $ map (varP . fst) vars
-    proxy <- newName "p"
-    (lastPrims, fields) <- spanM (isPrim . snd) $ reverse vars
-    let lastPrims' = map (\(x, _) -> [| toPrimitivePersistValue $(varE proxy) $(varE x) |]) $ reverse $ lastPrims
-    let body = if null fields
-        then [| return $ ($(listE lastPrims')++) |]
-        else do
-          let go (m, f) (fname, t) = isPrim t >>= \isP -> if isP
-              then return (m, [| (toPrimitivePersistValue $(varE proxy) $(varE fname):) |]:f)
-              else newName "x" >>= \x -> return (bindS (varP x) [| toPersistValues $(varE fname) |]:m, varE x:f)
-          (stmts, func) <- foldM go ([], []) fields        -- foldM puts reversed fields in normal order
-          let nonPrimFields' = foldr1 (\a b -> [|$a . $b|]) func
-          let result = if null lastPrims' then nonPrimFields' else [| $nonPrimFields' . ($(listE lastPrims')++) |]
-          doE $ stmts ++ [noBindS [| return $ $result |]]
-    anyPrim <- liftM or $ mapM (isPrim . snd) vars
-    let body' = if anyPrim then [| phantomDb >>= $(lamE [varP proxy] body) |] else body
-    funD 'toPersistValues [clause [pat] (normalB body') []]
+    (pat, body) <- mkToPersistValues (thEmbeddedConstructorName def) (thEmbeddedFields def) id
+    funD 'toPersistValues [clause [pat] (normalB body) []]
 
   fromPersistValues' <- do
     xs <- newName "xs"
@@ -99,84 +83,101 @@ 
   let context = paramsContext (thEmbeddedTypeParams def) (thEmbeddedFields def)
   let decs = [persistName', toPersistValues', fromPersistValues', dbType']
-  return $ [InstanceD context (AppT (ConT ''PersistField) embedded) decs]
+  return $ [instanceD' context (AppT (ConT ''PersistField) embedded) decs]
 
+mkToPersistValues :: Name -> [THFieldDef] -> (ExpQ -> ExpQ) -> Q (PatQ, ExpQ)
+mkToPersistValues constrName fieldDefs processResult = do
+  patVars <- mapM (const $ newName "x") fieldDefs
+  let processField fName fDef = do
+        isP <- isPrim (thFieldType fDef)
+        let field = maybe id (\convName x -> [| fst $(varE convName) $ $x |]) (thFieldConverter fDef) (varE fName)
+        if isP
+          then return (Nothing, [| (toPrimitivePersistValue $field:) |])
+          else newName "x" >>= \x -> return (Just $ bindS (varP x) [| toPersistValues $field |], varE x)
+  (binds, funcs) <- liftM (first catMaybes . unzip) $ zipWithM processField patVars fieldDefs
+  let pat = conP constrName $ map varP patVars
+      result = [| return $ $(processResult $ if null funcs then [| id |] else foldr1 (\a b -> [|$a . $b|]) funcs) |]
+      body = if null binds then result else doE $ binds ++ [noBindS result]
+  return (pat, body)
+
 mkFromPersistValues :: Name -> Name -> Name -> [THFieldDef] -> Q (Bool, Exp)
 mkFromPersistValues failureName values constrName fieldDefs = do
-  proxy <- newName "p"
-  allVars <- mapM (\f -> newName "x" >>= \fname -> return (fname, thFieldType f)) fieldDefs
+  patVars <- mapM (const $ newName "x") fieldDefs
   let failure = match wildP (normalB $ varE failureName) []
-      mkArg (fname, t) = do
-        isP <- isPrim t
-        if isP
-          then [| fromPrimitivePersistValue $(varE proxy) $(varE fname) |]
-          else varE fname
-      result = foldl (\a f -> appE a $ mkArg f) (conE constrName) allVars
+      mkArg (fName, fDef) = do
+        isP <- isPrim $ thFieldType fDef
+        let x = if isP
+                  then [| fromPrimitivePersistValue $(varE fName) |]
+                  else varE fName
+        maybe x (\convName -> [| snd $(varE convName) $ $x |]) $ thFieldConverter fDef
+      result = foldl (\func f -> appE func $ mkArg f) (conE constrName) $ zip patVars fieldDefs
       goField xs vars = do
-        (fields, rest) <- spanM (liftM not . isPrim . snd) vars
+        (fields, rest) <- spanM (liftM not . isPrim . thFieldType . snd) vars
         xss <- liftM (xs:) $ mapM (const $ newName "xs") fields
         let f oldXs newXs (fname, _) = bindS (conP '(,) [varP fname, varP newXs]) [| fromPersistValues $(varE oldXs) |]
-        let stmts = zipWith3 f xss (tail xss) fields
-        expr <- goPrim (last xss) rest
-        return $ doE $ stmts ++ [noBindS expr]
+            stmts = zipWith3 f xss (tail xss) fields
+            expr = goPrim (last xss) rest
+        doE $ stmts ++ [noBindS expr]
       goPrim xs vars = do
         xs' <- newName "xs"
-        (prims, rest) <- spanM (isPrim . snd) vars
-        body' <- case rest of
-          [] -> return [| return ($result, $(varE xs')) |]
-          _  -> goField xs' rest
-        let m = match (foldr (\(fname, _) p -> infixP (varP fname) '(:) p) (varP xs') prims) (normalB body') []
-        return $ if null prims
+        (prims, rest) <- spanM (isPrim . thFieldType . snd) vars
+        let body' = case rest of
+              [] -> [| return ($result, $(varE xs')) |]
+              _  -> goField xs' rest
+            m = match (foldr (\(fName, _) p -> infixP (varP fName) '(:) p) (varP xs') prims) (normalB body') []
+        if null prims
           then caseE (varE xs) [m]
           else caseE (varE xs) [m, failure]
-  body <- goPrim values allVars
-  anyPrim <- liftM or $ mapM (isPrim . snd) allVars
-  body' <- if anyPrim then [| phantomDb >>= $(lamE [varP proxy] body) |] else body
-  return (anyPrim, body')
+  body <- goPrim values $ zip patVars fieldDefs
+  anyPrim <- liftM or $ mapM (isPrim . thFieldType) fieldDefs
+  return (anyPrim, body)
 
 mkPurePersistFieldInstance :: Type -> Name -> [THFieldDef] -> Cxt -> Q [Dec]
-mkPurePersistFieldInstance dataType cName fDefs context = do
+mkPurePersistFieldInstance dataType cName fieldDefs context = do
   toPurePersistValues' <- do
-    vars <- mapM (\f -> newName "x" >>= \fname -> return (fname, thFieldType f)) fDefs
-    let pat = conP cName $ map (varP . fst) vars
-    proxy <- newName "p"
-    let body = mkToPurePersistValues proxy vars
-    funD 'toPurePersistValues [clause [varP proxy, pat] (normalB body) []]
+    vars <- mapM (const $ newName "x") fieldDefs
+    let pat = conP cName $ map varP vars
+        body = mkToPurePersistValues $ zip vars fieldDefs
+    funD 'toPurePersistValues [clause [pat] (normalB body) []]
 
   fromPurePersistValues' <- let
-    goField xs vars result failure proxy = do
-      (fields, rest) <- spanM (liftM not . isPrim . snd) vars
+    goField xs vars result failure = do
+      (fields, rest) <- spanM (liftM not . isPrim . thFieldType . snd) vars
       xss <- liftM (xs:) $ mapM (const $ newName "xs") fields
-      let f oldXs newXs (fname, _) = valD (conP '(,) [varP fname, varP newXs]) (normalB [| fromPurePersistValues $(varE proxy) $(varE oldXs) |]) []
+      let f oldXs newXs (fName, _) = valD (conP '(,) [varP fName, varP newXs]) (normalB [| fromPurePersistValues $(varE oldXs) |]) []
       let stmts = zipWith3 f xss (tail xss) fields
-      (isFailureUsed, expr) <- goPrim (last xss) rest result failure proxy
+      (isFailureUsed, expr) <- goPrim (last xss) rest result failure
       return (isFailureUsed, letE stmts expr)
-    goPrim xs vars result failure proxy = do
+    goPrim xs vars result failure = do
       xs' <- newName "xs"
-      (prims, rest) <- spanM (isPrim . snd) vars
+      (prims, rest) <- spanM (isPrim . thFieldType . snd) vars
       (isFailureUsed, body') <- case rest of
         [] -> return (False, [| ($result, $(varE xs')) |])
-        _  -> goField xs' rest result failure proxy
-      let m = match (foldr (\(fname, _) p -> infixP (varP fname) '(:) p) (varP xs') prims) (normalB body') []
+        _  -> goField xs' rest result failure
+      let m = match (foldr (\(fName, _) p -> infixP (varP fName) '(:) p) (varP xs') prims) (normalB body') []
       return $ if null prims
          then (isFailureUsed, caseE (varE xs) [m])
          else (True, caseE (varE xs) [m, failure])
-    mkArg proxy (fname, t) = isPrim t >>= \isP -> (if isP then [| fromPrimitivePersistValue $(varE proxy) $(varE fname) |] else (varE fname))
+    mkArg (fName, fDef) = do
+      isP <- isPrim $ thFieldType fDef
+      let x = if isP
+                then [| fromPrimitivePersistValue $(varE fName) |]
+                else varE fName
+      maybe x (\convName -> [| snd $(varE convName) $ $x |]) $ thFieldConverter fDef
     in do
       xs <- newName "xs"
       let failureBody = normalB [| (\a -> error (failMessage a $(varE xs)) `asTypeOf` (a, [])) undefined |]
       failureName <- newName "failure"
-      proxy <- newName "p"
-      vars <- mapM (\f -> newName "x" >>= \fname -> return (fname, thFieldType f)) fDefs
+      patVars <- mapM (const $ newName "x") fieldDefs
       let failure = match wildP (normalB $ varE failureName) []
-      let result = foldl (\a f -> appE a $ mkArg proxy f) (conE cName) vars
-      (isFailureUsed, start) <- goPrim xs vars result failure proxy
+          result = foldl (\a f -> appE a $ mkArg f) (conE cName) $ zip patVars fieldDefs
+      (isFailureUsed, start) <- goPrim xs (zip patVars fieldDefs) result failure
       let failureFunc = funD failureName [clause [] failureBody []]
-      let locals = if isFailureUsed then [failureFunc] else []
-      funD 'fromPurePersistValues [clause [varP proxy, varP xs] (normalB start) locals]
+          locals = if isFailureUsed then [failureFunc] else []
+      funD 'fromPurePersistValues [clause [varP xs] (normalB start) locals]
 
   let decs = [toPurePersistValues', fromPurePersistValues']
-  return $ [InstanceD context (AppT (ConT ''PurePersistField) dataType) decs]
+  return $ [instanceD' context (AppT (ConT ''PurePersistField) dataType) decs]
 
 mkEmbeddedPurePersistFieldInstance :: THEmbeddedDef -> Q [Dec]
 mkEmbeddedPurePersistFieldInstance def = do
@@ -204,12 +205,12 @@       proxy <- newName "p"
       a <- newName "a"
       let e = [| entityDef $(varE proxy) ((undefined :: Key v a -> v) $(varE a)) |]
-          body = [| DbTypePrimitive (getAutoKeyType $(varE proxy)) False Nothing (Just (Left ($e, Nothing), Nothing, Nothing)) |]
+          body = [| DbTypePrimitive (getDefaultAutoKeyType $(varE proxy)) False Nothing (Just (Left ($e, Nothing), Nothing, Nothing)) |]
       funD 'dbType [clause [varP proxy, varP a] (normalB body) []]
     
     let context = paramsContext (thTypeParams def) (thConstructors def >>= thConstrFields)
     let decs = [persistName', toPersistValues', fromPersistValues', dbType']
-    return [InstanceD context (AppT (ConT ''PersistField) keyType) decs]
+    return [instanceD' context (AppT (ConT ''PersistField) keyType) decs]
   _ -> return []
 
 mkAutoKeyPrimitivePersistFieldInstance :: THEntityDef -> Q [Dec]
@@ -219,15 +220,14 @@     keyType <- [t| Key $(return entity) BackendSpecific |]
     let conName = mkName $ thAutoKeyConstrName autoKey
     toPrim' <- do
-      proxy <- newName "p"
       x <- newName "x"
-      let body = [| toPrimitivePersistValue $(varE proxy) $ ((fromPrimitivePersistValue :: DbDescriptor db => proxy db -> PersistValue -> AutoKeyType db) $(varE proxy)) $(varE x) |]
-      funD 'toPrimitivePersistValue [clause [varP proxy, conP conName [varP x]] (normalB body) []]
-    fromPrim' <- funD 'fromPrimitivePersistValue [clause [wildP] (normalB $ conE conName) []]
+      let body = [| $(varE x) |]
+      funD 'toPrimitivePersistValue [clause [conP conName [varP x]] (normalB body) []]
+    fromPrim' <- funD 'fromPrimitivePersistValue [clause [] (normalB $ conE conName) []]
     let context = paramsContext (thTypeParams def) (thConstructors def >>= thConstrFields)
     let decs = [toPrim', fromPrim']
-    sequence [ return $ InstanceD context (AppT (ConT ''PrimitivePersistField) keyType) decs
-             , return $ InstanceD context (AppT (ConT ''NeverNull) keyType) []
+    sequence [ return $ instanceD' context (AppT (ConT ''PrimitivePersistField) keyType) decs
+             , return $ instanceD' context (AppT (ConT ''NeverNull) keyType) []
              , mkDefaultPurePersistFieldInstance context keyType
              , mkDefaultSinglePersistFieldInstance context keyType]
   _ -> return []
@@ -237,14 +237,14 @@   toPurePersistValues' <- funD 'toPurePersistValues [clause [] (normalB [| primToPurePersistValues |]) []]
   fromPurePersistValues' <- funD 'fromPurePersistValues [clause [] (normalB [| primFromPurePersistValues |]) []]
   let decs = [toPurePersistValues', fromPurePersistValues']
-  return $ InstanceD context (AppT (ConT ''PurePersistField) typ) decs
+  return $ instanceD' context (AppT (ConT ''PurePersistField) typ) decs
 
 mkDefaultSinglePersistFieldInstance :: Cxt -> Type -> Q Dec
 mkDefaultSinglePersistFieldInstance context typ = do
   toSinglePersistValue' <- funD 'toSinglePersistValue [clause [] (normalB [| primToSinglePersistValue |]) []]
   fromSinglePersistValue' <- funD 'fromSinglePersistValue [clause [] (normalB [| primFromSinglePersistValue |]) []]
   let decs = [toSinglePersistValue', fromSinglePersistValue']
-  return $ InstanceD context (AppT (ConT ''SinglePersistField) typ) decs
+  return $ instanceD' context (AppT (ConT ''SinglePersistField) typ) decs
 
 mkUniqueKeysIsUniqueInstances :: THEntityDef -> Q [Dec]
 mkUniqueKeysIsUniqueInstances def = do
@@ -263,7 +263,7 @@       let uNum = maybe (error $ "mkUniqueKeysIsUniqueInstances: cannot find unique definition for unique key " ++ thUniqueKeyName unique) id index
       funD 'uniqueNum [clause [wildP] (normalB [| uNum |]) []]
     let context = paramsContext (thTypeParams def) (thConstructors def >>= thConstrFields)
-    return $ InstanceD context (AppT (ConT ''IsUniqueKey) uniqKeyType) [extractUnique', uniqueNum']
+    return $ instanceD' context (AppT (ConT ''IsUniqueKey) uniqKeyType) [extractUnique', uniqueNum']
 
 mkUniqueKeysEmbeddedInstances :: THEntityDef -> Q [Dec]
 mkUniqueKeysEmbeddedInstances def = do
@@ -299,7 +299,7 @@       funD 'dbType [clause [varP proxy, varP a] (normalB body) []]
     let context = paramsContext (thTypeParams def) (thConstructors def >>= thConstrFields)
     let decs = [persistName', toPersistValues', fromPersistValues', dbType']
-    return $ InstanceD context (AppT (ConT ''PersistField) uniqKeyType) decs
+    return $ instanceD' context (AppT (ConT ''PersistField) uniqKeyType) decs
     
 mkUniqueKeysPrimitiveOrPurePersistFieldInstances :: THEntityDef -> Q [Dec]
 mkUniqueKeysPrimitiveOrPurePersistFieldInstances def = do
@@ -313,14 +313,13 @@       _      -> return False
     if isUniquePrim
       then do
-        proxy <- newName "p"
         x <- newName "x"
         toPrim' <- do
-          funD 'toPrimitivePersistValue [clause [varP proxy, conP conName [varP x]] (normalB [| toPrimitivePersistValue $(varE proxy) $(varE x) |]) []]
-        fromPrim' <- funD 'fromPrimitivePersistValue [clause [varP proxy, varP x] (normalB [| $(conE conName) (fromPrimitivePersistValue $(varE proxy) $(varE x)) |]) []]
+          funD 'toPrimitivePersistValue [clause [conP conName [varP x]] (normalB [| toPrimitivePersistValue $(varE x) |]) []]
+        fromPrim' <- funD 'fromPrimitivePersistValue [clause [varP x] (normalB [| $(conE conName) (fromPrimitivePersistValue $(varE x)) |]) []]
         let decs = [toPrim', fromPrim']
-        sequence [ return $ InstanceD context (AppT (ConT ''PrimitivePersistField) uniqKeyType) decs
-                 , return $ InstanceD context (AppT (ConT ''NeverNull) uniqKeyType) decs
+        sequence [ return $ instanceD' context (AppT (ConT ''PrimitivePersistField) uniqKeyType) decs
+                 , return $ instanceD' context (AppT (ConT ''NeverNull) uniqKeyType) decs
                  , mkDefaultPurePersistFieldInstance context uniqKeyType
                  , mkDefaultSinglePersistFieldInstance context uniqKeyType]
       else mkPurePersistFieldInstance uniqKeyType conName (thUniqueKeyFields unique) context
@@ -364,12 +363,12 @@       keyType <- [t| Key $(return entity) $u |]
       readPrec' <- funD 'R.readPrec [clause [] (normalB body) []]
       readListPrec' <- funD 'R.readListPrec [clause [] (normalB [| R.readListPrecDefault |]) []]
-      return $ InstanceD context (AppT (ConT ''Read) keyType) [readPrec', readListPrec']
+      return $ instanceD' context (AppT (ConT ''Read) keyType) [readPrec', readListPrec']
     in mapM mkRead keysInfo
 
   return $ if null keysInfo
     then []
-    else [InstanceD context (AppT (ConT ''Eq) typ) [eq'], InstanceD context (AppT (ConT ''Show) typ) [showsPrec']] ++ read'
+    else [instanceD' context (AppT (ConT ''Eq) typ) [eq'], instanceD' context (AppT (ConT ''Show) typ) [showsPrec']] ++ read'
 
 mkEmbeddedInstance :: THEmbeddedDef -> Q [Dec]
 mkEmbeddedInstance def = do
@@ -383,7 +382,7 @@   selector' <- do
     fParam <- newName "f"
     let mkField field = ForallC [] ([equalP' (VarT fParam) (thFieldType field)]) $ NormalC (mkName $ thExprName field) []
-    return $ DataInstD [] ''Selector [dataType, VarT fParam] (map mkField fDefs) []
+    return $ dataInstD' [] ''Selector [dataType, VarT fParam] (map mkField fDefs) []
 
   selectorNum' <- do
     let mkClause fNum field = clause [conP (mkName $ thExprName field) []] (normalB $ lift fNum) []
@@ -391,7 +390,7 @@     funD 'selectorNum clauses
 
   let decs = [selector', selectorNum']
-  return $ [InstanceD context (AppT (ConT ''Embedded) dataType) decs]
+  return $ [instanceD' context (AppT (ConT ''Embedded) dataType) decs]
 
 mkEntityPhantomConstructors :: THEntityDef -> Q [Dec]
 mkEntityPhantomConstructors def = do
@@ -401,7 +400,7 @@     let name = mkName $ thPhantomConstrName c
     phantom <- [t| ConstructorMarker $(return entity) |]
     let constr = ForallC (thTypeParams def) [equalP' (VarT v) phantom] $ NormalC name []
-    return $ DataD [] name [PlainTV v] [constr] []
+    return $ dataD' [] name [PlainTV v] [constr] []
   
 mkEntityPhantomConstructorInstances :: THEntityDef -> Q [Dec]
 mkEntityPhantomConstructorInstances def = sequence $ zipWith f [0..] $ thConstructors def where
@@ -420,7 +419,7 @@         let name = mkName $ thUniqueKeyPhantomName u
         phantom <- [t| UniqueMarker $(return entity) |]
         let constr = ForallC (thTypeParams def) [equalP' (VarT v) phantom] $ NormalC name []
-        return [DataD [] name [PlainTV v] [constr] []]
+        return [dataD' [] name [PlainTV v] [constr] []]
       else return []
     
 mkPersistEntityInstance :: THEntityDef -> Q [Dec]
@@ -433,15 +432,15 @@       Nothing -> return []
       Just k -> do
         keyDescr <- [t| BackendSpecific |]
-        return [ForallC [] [equalP' (VarT uParam) keyDescr] $ NormalC (mkName $ thAutoKeyConstrName k) [(NotStrict, ConT ''PersistValue)]]
+        return [ForallC [] [equalP' (VarT uParam) keyDescr] $ NormalC (mkName $ thAutoKeyConstrName k) [(notStrict', ConT ''PersistValue)]]
     uniques <- forM (thUniqueKeys def) $ \unique -> do
       uniqType <- [t| Unique $(conT $ mkName $ thUniqueKeyPhantomName unique) |]
       let cDef = head $ thConstructors def
           uniqFieldNames = lefts $ thUniqueFields $ findOne "unique" thUniqueName (thUniqueKeyName unique) $ thConstrUniques cDef
           uniqFields = concat $ flip map uniqFieldNames $ \name -> (filter ((== name) . thFieldName) $ thConstrFields cDef)
-          uniqFields' = map (\f -> (NotStrict, thFieldType f)) uniqFields
+          uniqFields' = map (\f -> (notStrict', thFieldType f)) uniqFields
       return $ ForallC [] [equalP' (VarT uParam) uniqType] $ NormalC (mkName $ thUniqueKeyConstrName unique) uniqFields'
-    return $ DataInstD [] ''Key [entity, VarT uParam] (autoKey ++ uniques) []
+    return $ dataInstD' [] ''Key [entity, VarT uParam] (autoKey ++ uniques) []
 
   autoKey' <- do
     autoType <- case thAutoKey def of
@@ -469,7 +468,7 @@     let mkField name field = ForallC [] [equalP' (VarT cParam) (ConT name), equalP' (VarT fParam) (thFieldType field)] $ NormalC (mkName $ thExprName field) []
     let f cdef = map (mkField $ mkName $ thPhantomConstrName cdef) $ thConstrFields cdef
     let constrs = concatMap f $ thConstructors def
-    return $ DataInstD [] ''Field [entity, VarT cParam, VarT fParam] constrs []
+    return $ dataInstD' [] ''Field [entity, VarT cParam, VarT fParam] constrs []
     
   entityDef' <- do
     v <- newName "v"
@@ -504,27 +503,12 @@     funD 'entityDef $ [ clause [varP proxy, entityPat] body [] ]
 
   toEntityPersistValues' <- liftM (FunD 'toEntityPersistValues) $ forM (zip [0 :: Int ..] $ thConstructors def) $ \(cNum, c) -> do
-    vars <- mapM (\f -> newName "x" >>= \fname -> return (fname, thFieldType f)) $ thConstrFields c
-    let pat = conP (thConstrName c) $ map (varP . fst) vars
-    proxy <- newName "p"
-    (lastPrims, fields) <- spanM (isPrim . snd) $ reverse vars
-    let lastPrims' = map (\(x, _) -> [| toPrimitivePersistValue $(varE proxy) $(varE x) |]) $ reverse $ lastPrims
-    let body = if null fields
-        then [| return $ ($(listE $ [|toPrimitivePersistValue $(varE proxy) ($(lift cNum) :: Int) |]:lastPrims')++) |]
-        else do
-          let go (m, f) (fname, t) = isPrim t >>= \isP -> if isP
-              then return (m, [| (toPrimitivePersistValue $(varE proxy) $(varE fname):) |]:f)
-              else newName "x" >>= \x -> return (bindS (varP x) [| toPersistValues $(varE fname) |]:m, varE x:f)
-          (stmts, func) <- foldM go ([], []) fields        -- foldM puts reversed fields in normal order
-          let nonPrimFields' = foldr1 (\a b -> [|$a . $b|]) func
-          let result = if null lastPrims' then nonPrimFields' else [| $nonPrimFields' . ($(listE lastPrims')++) |]
-          doE $ stmts ++ [noBindS [| return $ (toPrimitivePersistValue $(varE proxy) ($(lift cNum) :: Int):) . $result |]]
-    let body' = [| phantomDb >>= $(lamE [varP proxy] body) |]
-    clause [pat] (normalB body') []
+    (pat, body) <- mkToPersistValues (thConstrName c) (thConstrFields c) (\result -> [| (toPrimitivePersistValue ($(lift cNum) :: Int) :) . $result |])
+    clause [pat] (normalB body) []
 
   fromEntityPersistValues' <- do
       xs <- newName "xs"
-      let failureBody = normalB [| (\a -> phantomDb >>= \proxy -> fail (failMessageNamed (entityName $ entityDef proxy a) $(varE xs)) >> return (a, [])) undefined |]
+      let failureBody = normalB [| fail (failMessageNamed $(stringE $ show $ thDataName def) $(varE xs)) |]
       failureName <- newName "failure"
       let failure = match wildP (normalB $ varE failureName) []
       matches <- forM (zip [0..] (thConstructors def)) $ \(cNum, c) -> do
@@ -539,22 +523,21 @@   getUniques' <- let
     hasConstraints = not . null . thConstrUniques
     clauses = zipWith mkClause [0::Int ..] (thConstructors def)
-    mkClause cNum cdef | not (hasConstraints cdef) = clause [wildP, conP (thConstrName cdef) pats] (normalB [| (cNum, []) |]) [] where
+    mkClause cNum cdef | not (hasConstraints cdef) = clause [conP (thConstrName cdef) pats] (normalB [| (cNum, []) |]) [] where
       pats = map (const wildP) $ thConstrFields cdef
     mkClause cNum cdef = do
       let allConstrainedFields = lefts $ concatMap thUniqueFields $ thConstrUniques cdef
       vars <- mapM (\f -> newName "x" >>= \x -> return $ if thFieldName f `elem` allConstrainedFields then Just (x, f) else Nothing) $ thConstrFields cdef
-      proxy <- newName "p"
       let pat = conP (thConstrName cdef) $ map (maybe wildP (varP . fst)) vars
           body = normalB $ [| (cNum, $(listE $ mapMaybe mkUnique $ thConstrUniques cdef)) |]
           mkUnique (THUniqueDef uName _ fnames) = if null $ rights fnames
             then let
               -- find corresponding field from vars
               uFields = map (\f -> findOne "field" (thFieldName . snd) f $ catMaybes vars) $ lefts fnames
-              result = mkToPurePersistValues proxy $ map (second thFieldType) uFields
+              result = mkToPurePersistValues uFields
               in Just [| (uName, $result) |]
             else Nothing
-      clause [varP proxy, pat] body []
+      clause [pat] body []
     in funD 'getUniques clauses
 
   entityFieldChain' <- let
@@ -572,22 +555,19 @@ 
   let context = paramsContext (thTypeParams def) (thConstructors def >>= thConstrFields)
   let decs = [key', autoKey', defaultKey', isSumType', fields', entityDef', toEntityPersistValues', fromEntityPersistValues', getUniques', entityFieldChain']
-  return $ [InstanceD context (AppT (ConT ''PersistEntity) entity) decs]
+  return $ [instanceD' context (AppT (ConT ''PersistEntity) entity) decs]
 
-mkToPurePersistValues :: Name -> [(Name, Type)] -> Q Exp
-mkToPurePersistValues proxy vars = do
-  (lastPrims, fields) <- spanM (isPrim . snd) $ reverse vars
-  let lastPrims' = map (\(x, _) -> [| toPrimitivePersistValue $(varE proxy) $(varE x) |]) $ reverse $ lastPrims
-  if null fields
-    then [| ($(listE lastPrims')++) |]
-    else do
-      let go (m, f) (fname, t) = isPrim t >>= \isP -> if isP
-          then return (m, [| (toPrimitivePersistValue $(varE proxy) $(varE fname):) |]:f)
-          else newName "x" >>= \x -> return (valD (varP x) (normalB [| toPurePersistValues $(varE proxy) $(varE fname) |]) []:m, varE x:f)
-      (stmts, func) <- foldM go ([], []) fields        -- foldM puts reversed fields in normal order
-      let nonPrimFields' = foldr1 (\a b -> [|$a . $b|]) func
-      let result = if null lastPrims' then nonPrimFields' else [| $nonPrimFields' . ($(listE lastPrims')++) |]
-      letE stmts result
+mkToPurePersistValues :: [(Name, THFieldDef)] -> Q Exp
+mkToPurePersistValues vars = do
+  let processField (fName, fDef) = do
+        isP <- isPrim (thFieldType fDef)
+        let field = maybe id (\convName x -> [| fst $(varE convName) $ $x |]) (thFieldConverter fDef) (varE fName)
+        if isP
+          then return (Nothing, [| (toPrimitivePersistValue $field:) |])
+          else newName "x" >>= \x -> return (Just $ valD (varP x) (normalB [| toPurePersistValues $(varE fName) |]) [], varE x)
+  (lets, funcs) <- liftM (first catMaybes . unzip) $ mapM processField vars
+  let result = if null funcs then [| id |] else foldr1 (\a b -> [|$a . $b|]) funcs
+  if null lets then result else letE lets result
 
 mkEntityPersistFieldInstance :: THEntityDef -> Q [Dec]
 mkEntityPersistFieldInstance def = case getDefaultKey def of
@@ -633,7 +613,7 @@ 
     let context = paramsContext (thTypeParams def) (thConstructors def >>= thConstrFields)
     let decs = [persistName', toPersistValues', fromPersistValues', dbType']
-    return $ [InstanceD context (AppT (ConT ''PersistField) entity) decs]
+    return $ [instanceD' context (AppT (ConT ''PersistField) entity) decs]
   Nothing -> return []
 
 mkEntitySinglePersistFieldInstance :: THEntityDef -> Q [Dec]
@@ -651,7 +631,7 @@     toSinglePersistValue' <- funD 'toSinglePersistValue $ [ clause [] (normalB to) [] ]
     fromSinglePersistValue' <- funD 'fromSinglePersistValue $ [ clause [] (normalB from) []]
     let decs = [toSinglePersistValue', fromSinglePersistValue']
-    return [InstanceD context (AppT (ConT ''SinglePersistField) entity) decs]
+    return [instanceD' context (AppT (ConT ''SinglePersistField) entity) decs]
   _ -> return []
 
 mkEntityNeverNullInstance :: THEntityDef -> Q [Dec]
@@ -661,7 +641,7 @@       context = paramsContext (thTypeParams def) (thConstructors def >>= thConstrFields)
   isOne <- isDefaultKeyOneColumn def
   return $ if isOne
-    then [InstanceD context (AppT (ConT ''NeverNull) entity) []]
+    then [instanceD' context (AppT (ConT ''NeverNull) entity) []]
     else []
 
 mkPrimitivePersistFieldInstance :: THPrimitiveDef -> Q [Dec]
@@ -673,37 +653,27 @@   fromPersistValues' <- funD 'fromPersistValues [clause [] (normalB [| primFromPersistValue |]) []]
   toPersistValues' <- funD 'toPersistValues [clause [] (normalB [| primToPersistValue |]) []]
   dbType' <- do
-    let typ = if thPrimitiveStringEnumRepresentation def
-          then [| DbTypePrimitive DbString False Nothing Nothing |]
-          else [| DbTypePrimitive DbInt32  False Nothing Nothing |]
-    funD 'dbType $ [ clause [wildP, wildP] (normalB typ) [] ]
+    proxy <- newName "p"
+    x <- newName "x"
+    let body = [| dbType $(varE proxy) $ fst $(varE $ thPrimitiveConverter def) $ $(varE x) |]
+    funD 'dbType $ [ clause [varP proxy, varP x] (normalB body) [] ]
   let decs = [persistName', toPersistValues', fromPersistValues', dbType']
-  return [ InstanceD [] (AppT (ConT ''PersistField) primitive) decs
-         , InstanceD [] (AppT (ConT ''NeverNull) primitive) []
+  return [ instanceD' [] (AppT (ConT ''PersistField) primitive) decs
+         , instanceD' [] (AppT (ConT ''NeverNull) primitive) []
          ]
 
 mkPrimitivePrimitivePersistFieldInstance :: THPrimitiveDef -> Q [Dec]
 mkPrimitivePrimitivePersistFieldInstance def = do
   let primitive = ConT (thPrimitiveName def)
   toPrim' <- do
-    proxy <- newName "p"
-    x <- newName "x"
-    let value = if thPrimitiveStringEnumRepresentation def
-          then [| show $(varE x) |]
-          else [| fromEnum $(varE x) |]
-        body = [| toPrimitivePersistValue $(varE proxy) $value |]
-    funD 'toPrimitivePersistValue [clause [varP proxy, varP x] (normalB body) []]
+    let body = [| toPrimitivePersistValue . fst $(varE $ thPrimitiveConverter def) |]
+    funD 'toPrimitivePersistValue [clause [] (normalB body) []]
   fromPrim' <- do
-    proxy <- newName "p"
-    x <- newName "x"
-    let value = [| fromPrimitivePersistValue $(varE proxy) $(varE x) |]
-        body = if thPrimitiveStringEnumRepresentation def
-          then [| read $value |]
-          else [| toEnum $value |]
-    funD 'fromPrimitivePersistValue [clause [varP proxy, varP x] (normalB body) []]
+    let body = [| snd $(varE $ thPrimitiveConverter def) . fromPrimitivePersistValue |]
+    funD 'fromPrimitivePersistValue [clause [] (normalB body) []]
   let context = []
   let decs = [toPrim', fromPrim']
-  sequence $ [return $ InstanceD context (AppT (ConT ''PrimitivePersistField) primitive) decs
+  sequence $ [return $ instanceD' context (AppT (ConT ''PrimitivePersistField) primitive) decs
            , mkDefaultPurePersistFieldInstance context primitive
            , mkDefaultSinglePersistFieldInstance context primitive]
 
@@ -712,7 +682,7 @@   let (normal, polymorhpic) = partition (null . thTypeParams) defs
   forM_ polymorhpic $ \def -> reportWarning $ "Datatype " ++ show (thDataName def) ++ " will not be migrated automatically by function " ++ name ++ " because it has type parameters"
   let body = doE $ map (\def -> noBindS [| migrate (undefined :: $(conT $ thDataName def)) |]) normal
-  sig <- sigD (mkName name) [t| PersistBackend m => Migration m |]
+  sig <- sigD (mkName name) [t| forall m . PersistBackend m => Migration m |]
   func <- funD (mkName name) [clause [] (normalB body) []]
   return [sig, func]
 
@@ -809,13 +779,14 @@       else return ([], x:xs)
 
 mkType :: THFieldDef -> Name -> ExpQ -> ExpQ
-mkType THFieldDef{..} proxy nvar = t2 where
-  psField = PSFieldDef thFieldName (Just thDbFieldName) thDbTypeName (Just thExprName) thEmbeddedDef thDefaultValue thReferenceParent
-  t1 = [| dbType $(varE proxy) $nvar |]
+mkType THFieldDef{..} proxy nvar = t3 where
+  psField = PSFieldDef thFieldName (Just thDbFieldName) thDbTypeName (Just thExprName) thEmbeddedDef thDefaultValue thReferenceParent (fmap show thFieldConverter)
+  t1 = maybe id (\convName x -> [| fst $(varE convName) $ $x |]) thFieldConverter nvar
+  t2 = [| dbType $(varE proxy) $t1 |]
   -- if there are any type settings, apply them in runtime
-  t2 = case (thDbTypeName, thEmbeddedDef, thDefaultValue, thReferenceParent) of
-    (Nothing, Nothing, Nothing, Nothing) -> t1
-    _ -> [| applyDbTypeSettings $(lift psField) $t1 |]
+  t3 = case (thDbTypeName, thEmbeddedDef, thDefaultValue, thReferenceParent) of
+    (Nothing, Nothing, Nothing, Nothing) -> t2
+    _ -> [| applyDbTypeSettings $(lift psField) $t2 |]
 
 mkTySynInstD :: Name -> [Type] -> Type -> Dec
 mkTySynInstD name ts t =
@@ -839,4 +810,36 @@   foldl AppT EqualityT [t1, t2]
 #else
   EqualP t1 t2
+#endif
+
+instanceD' :: Cxt -> Type -> [Dec] -> InstanceDec
+instanceD' =
+#if MIN_VERSION_template_haskell(2, 11, 0)
+  InstanceD Nothing
+#else
+  InstanceD
+#endif
+
+dataInstD' :: Cxt -> Name -> [Type] -> [Con] -> [Name] -> InstanceDec
+dataInstD' cxt name types constrs derives =
+#if MIN_VERSION_template_haskell(2, 11, 0)
+  DataInstD cxt name types Nothing constrs (map ConT derives)
+#else
+  DataInstD cxt name types constrs derives
+#endif
+
+dataD' :: Cxt -> Name -> [TyVarBndr] -> [Con] -> [Name] -> InstanceDec
+dataD' cxt name types constrs derives =
+#if MIN_VERSION_template_haskell(2, 11, 0)
+  DataD cxt name types Nothing constrs (map ConT derives)
+#else
+  DataD cxt name types constrs derives
+#endif
+
+#if MIN_VERSION_template_haskell(2, 11, 0)
+notStrict' :: Bang
+notStrict' = Bang NoSourceUnpackedness NoSourceStrictness
+#else
+notStrict' :: Strict
+notStrict' = NotStrict
 #endif
Database/Groundhog/TH/Settings.hs view
@@ -26,7 +26,7 @@ import Language.Haskell.TH
 import Language.Haskell.TH.Syntax (Lift(..))
 import Control.Applicative
-import Control.Monad (forM, mzero)
+import Control.Monad (forM, mzero, when)
 import Data.Aeson
 import Data.Aeson.Types (Pair)
 import qualified Data.Foldable as Fold
@@ -64,7 +64,7 @@ data THPrimitiveDef = THPrimitiveDef {
     thPrimitiveName :: Name
   , thPrimitiveDbName :: String -- ^ It is used only to set polymorphic part of name of its container
-  , thPrimitiveStringEnumRepresentation :: Bool -- ^ Store in database as string using Show/Read instances (True) or as integer using Enum instance (False).
+  , thPrimitiveConverter :: Name -- ^ Name of a pair of functions converting the value to and from a type that is an instance of `PrimitivePersistField`
 } deriving (Eq, Show)
 
 data THConstructorDef = THConstructorDef {
@@ -77,14 +77,15 @@ } deriving (Eq, Show)
 
 data THFieldDef = THFieldDef {
-    thFieldName :: String -- bar
-  , thDbFieldName :: String -- SQLbar
-  , thDbTypeName :: Maybe String -- inet, NUMERIC(5, 2), VARCHAR(50)
-  , thExprName :: String -- BarField
+    thFieldName :: String -- ^ name in the record, bar
+  , thDbFieldName :: String -- ^ column name, SQLbar
+  , thDbTypeName :: Maybe String -- ^ column type, inet, NUMERIC(5, 2), VARCHAR(50), etc.
+  , thExprName :: String -- ^ name of constructor in the Field GADT, BarField
   , thFieldType :: Type
   , thEmbeddedDef :: Maybe [PSFieldDef String]
-  , thDefaultValue :: Maybe String
+  , thDefaultValue :: Maybe String -- ^ default value in the database
   , thReferenceParent :: Maybe (Maybe ((Maybe String, String), [String]), Maybe ReferenceActionType, Maybe ReferenceActionType)
+  , thFieldConverter :: Maybe Name -- ^ name of a pair of functions
 } deriving (Eq, Show)
 
 data THUniqueDef = THUniqueDef {
@@ -122,7 +123,7 @@ data PSPrimitiveDef = PSPrimitiveDef {
     psPrimitiveName :: String
   , psPrimitiveDbName :: Maybe String -- ^ It is used only to set polymorphic part of name of its container
-  , psPrimitiveStringEnumRepresentation :: Maybe Bool -- ^ Store in database as string using Show/Read instances (True) or as integer using Enum instance (False).
+  , psPrimitiveConverter :: String -- ^ Name of a pair of functions converting the value to and from a type that is an instance of `PrimitivePersistField`
 } deriving (Eq, Show)
 
 data PSConstructorDef = PSConstructorDef {
@@ -156,7 +157,7 @@ } deriving (Eq, Show)
 
 instance Lift PSPrimitiveDef where
-  lift (PSPrimitiveDef {..}) = [| PSPrimitiveDef $(lift psPrimitiveName) $(lift psPrimitiveDbName) $(lift psPrimitiveStringEnumRepresentation) |]
+  lift (PSPrimitiveDef {..}) = [| PSPrimitiveDef $(lift psPrimitiveName) $(lift psPrimitiveDbName) $(lift psPrimitiveConverter) |]
 
 instance Lift PersistDefinitions where
   lift (PersistDefinitions {..}) = [| PersistDefinitions $(lift psEntities) $(lift psEmbeddeds) $(lift psPrimitives) |]
@@ -186,7 +187,7 @@   lift SetDefault = [| SetDefault |]
 
 instance Lift (PSFieldDef String) where
-  lift (PSFieldDef {..}) = [| PSFieldDef $(lift psFieldName) $(lift psDbFieldName) $(lift psDbTypeName) $(lift psExprName) $(lift psEmbeddedDef) $(lift psDefaultValue) $(lift psReferenceParent) |]
+  lift (PSFieldDef {..}) = [| PSFieldDef $(lift psFieldName) $(lift psDbFieldName) $(lift psDbTypeName) $(lift psExprName) $(lift psEmbeddedDef) $(lift psDefaultValue) $(lift psReferenceParent) $(lift psFieldConverter) |]
 
 instance Lift PSUniqueKeyDef where
   lift (PSUniqueKeyDef {..}) = [| PSUniqueKeyDef $(lift psUniqueKeyName) $(lift psUniqueKeyPhantomName) $(lift psUniqueKeyConstrName) $(lift psUniqueKeyDbName) $(lift psUniqueKeyFields) $(lift psUniqueKeyMakeEmbedded) $(lift psUniqueKeyIsDef) |]
@@ -230,13 +231,8 @@ 
 instance FromJSON PSPrimitiveDef where
   parseJSON = withObject "primitive" $ \v -> do
-    x <- v .:? "representation"
-    let representation = case x of
-          Nothing -> pure True
-          Just "showread" -> pure True
-          Just "enum" -> pure False
-          Just r -> fail $ "parseJSON: representation expected [\"showread\",\"enum\"], but got " ++ r
-    PSPrimitiveDef <$> v .: "primitive" <*> v .:? "dbName" <*> pure representation
+    when (H.member "representation" v) $ fail $ "parseJSON: field 'representation' is deprecated. Use 'converter' instead: " ++ show v
+    PSPrimitiveDef <$> v .: "primitive" <*> v .:? "dbName" <*> v .: "converter"
 
 instance FromJSON PSConstructorDef where
   parseJSON = withObject "constructor" $ \v ->
@@ -268,7 +264,7 @@ 
 instance FromJSON (PSFieldDef String) where
   parseJSON = withObject "field" $ \v ->
-    PSFieldDef <$> v .: "name" <*> v .:? "dbName" <*> v .:? "type" <*> v .:? "exprName" <*> v .:? "embeddedType" <*> v .:? "default" <*> mkRefSettings v where
+    PSFieldDef <$> v .: "name" <*> v .:? "dbName" <*> v .:? "type" <*> v .:? "exprName" <*> v .:? "embeddedType" <*> v .:? "default" <*> mkRefSettings v <*> v .:? "converter" where
     mkRefSettings v = do
       ref <- v .:? "reference"
       (parent, onDel, onUpd) <- case ref of
changelog view
@@ -1,3 +1,8 @@+0.8+* Support for GHC 8+* Generation of instances for newtype+* Converter functions for primitive datatypes+ 0.7.0.1 * Compatibility with template-haskell-2.10 
groundhog-th.cabal view
@@ -1,5 +1,5 @@ name:            groundhog-th-version:         0.7.0.1+version:         0.8 license:         BSD3 license-file:    LICENSE author:          Boris Lykah <lykahb@gmail.com>@@ -17,7 +17,7 @@ library     build-depends:   base                     >= 4         && < 5                    , bytestring               >= 0.9-                   , groundhog                >= 0.7       && < 0.8+                   , groundhog                >= 0.8       && < 0.9                    , template-haskell                    , time                     >= 1.1.4                    , containers               >= 0.2