-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Database persistence using generics -- -- Please see the README on GitHub at -- https://github.com/githubuser/generic-persistence#readme @package generic-persistence @version 0.2.0.0 module Database.GP.TypeInfo -- | A data type holding meta-data about a type. The Phantom type parameter -- a ensures type safety for reflective functions that use this -- type to create type instances (See module RecordtypeReflection). data TypeInfo a typeConstructor :: TypeInfo a -> Constr fieldNames :: TypeInfo a -> [String] fieldTypes :: TypeInfo a -> [TypeRep] -- | This function returns the (unqualified) type name of a from a -- `TypeInfo a` object. typeName :: TypeInfo a -> String -- | this function is a smart constructor for TypeInfo objects. It takes a -- value of type a and returns a `TypeInfo a` object. If the -- type has no named fields, an error is thrown. If the type has more -- than one constructor, an error is thrown. typeInfo :: Data a => a -> TypeInfo a -- | This function creates a TypeInfo object from the context of a function -- call. The Phantom Type parameter a is used to convince the -- compiler that the `TypeInfo a` object really describes type -- a. See also -- https://stackoverflow.com/questions/75171829/how-to-obtain-a-data-data-constr-etc-from-a-type-representation typeInfoFromContext :: forall a. Data a => TypeInfo a instance forall k (a :: k). GHC.Show.Show (Database.GP.TypeInfo.TypeInfo a) module Database.GP.RecordtypeReflection -- | A function that takes an entity and a field name as input parameters -- and returns the value of the field as a String. Example: fieldValue -- (Person John 42) "name" = SqlString John Example: -- fieldValue (Person John 42) "age" = SqlInt64 42 if the field is -- not present in the entity, an error is thrown. fieldValue :: Data a => a -> String -> SqlValue gFromRow :: forall a. Data a => [SqlValue] -> a gToRow :: Data a => a -> [SqlValue] module Database.GP.Entity class (Data a) => Entity a -- | Converts a database row to a value of type a. fromRow :: Entity a => [SqlValue] -> GP a -- | Converts a value of type a to a database row. toRow :: Entity a => a -> GP [SqlValue] -- | Returns the name of the primary key field for a type a. idField :: Entity a => a -> String -- | Returns a list of tuples that map field names to column names for a -- type a. fieldsToColumns :: Entity a => a -> [(String, String)] -- | Returns the name of the table for a type a. tableName :: Entity a => a -> String -- | Converts a database row to a value of type a. fromRow :: Entity a => [SqlValue] -> GP a -- | Converts a value of type a to a database row. toRow :: Entity a => a -> GP [SqlValue] -- | Returns the name of the primary key field for a type a. idField :: Entity a => a -> String -- | Returns a list of tuples that map field names to column names for a -- type a. fieldsToColumns :: Entity a => a -> [(String, String)] -- | Returns the name of the table for a type a. tableName :: Entity a => a -> String -- | A convenience function: returns the name of the column for a field of -- a type a. columnNameFor :: Entity a => a -> String -> String -- | A convenience function: returns the TypeRep of a field of a type -- a. fieldTypeFor :: Entity a => a -> String -> TypeRep maybeFieldTypeFor :: Entity a => a -> String -> Maybe TypeRep -- | Returns a string representation of a value of type a. toString :: Entity a => a -> String -- | A convenience function: returns an evidence instance of type -- a. This is useful for type inference where no instance is -- available. evidence :: forall a. Entity a => a evidenceFrom :: forall a. Entity a => TypeInfo a -> a -- | The resolution cache maps an EntityId to a Dynamic value (representing -- an Entity). It is used to resolve circular references during loading -- and storing of Entities. type ResolutionCache = [(EntityId, Dynamic)] -- | The EntityId is a tuple of the TypeRep and the primary key value of an -- Entity. It is used as a key in the resolution cache. type EntityId = (TypeRep, SqlValue) -- | type Ctx defines the context in which the persistence operations are -- executed. It contains a connection to the database and a resolution -- cache for circular lookups. data Ctx Ctx :: ConnWrapper -> ResolutionCache -> Ctx [connection] :: Ctx -> ConnWrapper [cache] :: Ctx -> ResolutionCache type GP = RIO Ctx module Database.GP.SqlGenerator -- | A function that returns an SQL insert statement for an entity. Type -- a must be an instance of Data. The function will use the -- field names of the data type to generate the column names in the -- insert statement. The values of the fields will be used as the values -- in the insert statement. Output example: INSERT INTO Person (id, name, -- age, address) VALUES (123456, Alice, 25, "123 Main St"); insertStmtFor :: Entity a => a -> String -- | A function that returns an SQL update statement for an entity. Type -- a must be an instance of Entity. updateStmtFor :: Entity a => a -> String -- | A function that returns an SQL select statement for entity type -- a with primary key id. selectStmtFor :: forall a. Entity a => TypeInfo a -> String deleteStmtFor :: Entity a => a -> String selectAllStmtFor :: forall a. Entity a => TypeInfo a -> String selectAllWhereStmtFor :: forall a. Entity a => TypeInfo a -> String -> String createTableStmtFor :: forall a. Entity a => TypeInfo a -> String dropTableStmtFor :: forall a. Entity a => TypeInfo a -> String module Database.GP.GenericPersistence -- | A function that retrieves an entity from a database. The function -- takes entity id as parameter. If an entity with the given id exists in -- the database, it is returned as a Just value. If no such entity -- exists, Nothing is returned. An error is thrown if there are more than -- one entity with the given id. retrieveById :: forall a id. (Entity a, Convertible id SqlValue) => id -> GP (Maybe a) -- | This function retrieves all entities of type a from a -- database. The function takes an HDBC connection as parameter. The type -- a is determined by the context of the function call. retrieveAll :: forall a. Entity a => GP [a] retrieveAllWhere :: forall a. Entity a => String -> SqlValue -> GP [a] -- | A function that persists an entity to a database. The function takes -- an HDBC connection and an entity as parameters. The entity is either -- inserted or updated, depending on whether it already exists in the -- database. The required SQL statements are generated dynamically using -- Haskell generics and reflection persist :: Entity a => a -> GP () -- | A function that explicitely inserts an entity into a database. insert :: Entity a => a -> GP () -- | A function that explicitely updates an entity in a database. update :: Entity a => a -> GP () delete :: Entity a => a -> GP () -- | set up a table for a given entity type. The table is dropped and -- recreated. setupTableFor :: forall a. Entity a => GP a -- | A function that returns the primary key value of an entity as a -- SqlValue. idValue :: forall a. Entity a => a -> SqlValue class (Data a) => Entity a -- | Converts a database row to a value of type a. fromRow :: Entity a => [SqlValue] -> GP a -- | Converts a value of type a to a database row. toRow :: Entity a => a -> GP [SqlValue] -- | Returns the name of the primary key field for a type a. idField :: Entity a => a -> String -- | Returns a list of tuples that map field names to column names for a -- type a. fieldsToColumns :: Entity a => a -> [(String, String)] -- | Returns the name of the table for a type a. tableName :: Entity a => a -> String -- | Converts a database row to a value of type a. fromRow :: Entity a => [SqlValue] -> GP a -- | Converts a value of type a to a database row. toRow :: Entity a => a -> GP [SqlValue] -- | Returns the name of the primary key field for a type a. idField :: Entity a => a -> String -- | Returns a list of tuples that map field names to column names for a -- type a. fieldsToColumns :: Entity a => a -> [(String, String)] -- | Returns the name of the table for a type a. tableName :: Entity a => a -> String -- | A convenience function: returns the name of the column for a field of -- a type a. columnNameFor :: Entity a => a -> String -> String -- | A convenience function: returns the TypeRep of a field of a type -- a. fieldTypeFor :: Entity a => a -> String -> TypeRep maybeFieldTypeFor :: Entity a => a -> String -> Maybe TypeRep -- | Returns a string representation of a value of type a. toString :: Entity a => a -> String -- | A convenience function: returns an evidence instance of type -- a. This is useful for type inference where no instance is -- available. evidence :: forall a. Entity a => a evidenceFrom :: forall a. Entity a => TypeInfo a -> a -- | The resolution cache maps an EntityId to a Dynamic value (representing -- an Entity). It is used to resolve circular references during loading -- and storing of Entities. type ResolutionCache = [(EntityId, Dynamic)] -- | The EntityId is a tuple of the TypeRep and the primary key value of an -- Entity. It is used as a key in the resolution cache. type EntityId = (TypeRep, SqlValue) -- | Computes the EntityId of an entity. The EntityId of an entity is a -- (typeRep, idValue) tuple. entityId :: Entity a => a -> EntityId -- | Lookup an entity in the cache, or retrieve it from the database. The -- Entity is identified by its EntityId, which is a (typeRep, idValue) -- tuple. getElseRetrieve :: forall a. Entity a => EntityId -> GP (Maybe a) -- | A data type holding meta-data about a type. The Phantom type parameter -- a ensures type safety for reflective functions that use this -- type to create type instances (See module RecordtypeReflection). data TypeInfo a -- | This function creates a TypeInfo object from the context of a function -- call. The Phantom Type parameter a is used to convince the -- compiler that the `TypeInfo a` object really describes type -- a. See also -- https://stackoverflow.com/questions/75171829/how-to-obtain-a-data-data-constr-etc-from-a-type-representation typeInfoFromContext :: forall a. Data a => TypeInfo a -- | this function is a smart constructor for TypeInfo objects. It takes a -- value of type a and returns a `TypeInfo a` object. If the -- type has no named fields, an error is thrown. If the type has more -- than one constructor, an error is thrown. typeInfo :: Data a => a -> TypeInfo a -- | type Ctx defines the context in which the persistence operations are -- executed. It contains a connection to the database and a resolution -- cache for circular lookups. data Ctx Ctx :: ConnWrapper -> ResolutionCache -> Ctx [connection] :: Ctx -> ConnWrapper [cache] :: Ctx -> ResolutionCache type GP = RIO Ctx extendCtxCache :: Entity a => a -> Ctx -> Ctx runGP :: (MonadIO m, IConnection conn) => conn -> RIO Ctx a -> m a -- | Lift a computation from the IO monad. This allows us to run IO -- computations in any monadic stack, so long as it supports these kinds -- of operations (i.e. IO is the base monad for the stack). -- --

Example

-- --
--   import Control.Monad.Trans.State -- from the "transformers" library
--   
--   printState :: Show s => StateT s IO ()
--   printState = do
--     state <- get
--     liftIO $ print state
--   
-- -- Had we omitted liftIO, we would have ended up with -- this error: -- --
--   • Couldn't match type ‘IO’ with ‘StateT s IO’
--    Expected type: StateT s IO ()
--      Actual type: IO ()
--   
-- -- The important part here is the mismatch between StateT s IO -- () and IO (). -- -- Luckily, we know of a function that takes an IO a and -- returns an (m a): liftIO, enabling us to run -- the program and see the expected results: -- --
--   > evalStateT printState "hello"
--   "hello"
--   
--   > evalStateT printState 3
--   3
--   
liftIO :: MonadIO m => IO a -> m a -- | Executes a computation in a modified environment. local :: MonadReader r m => (r -> r) -> m a -> m a -- | Retrieves the monad environment. ask :: MonadReader r m => m r instance GHC.Enum.Enum a => Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue a instance GHC.Enum.Enum a => Data.Convertible.Base.Convertible a Database.HDBC.SqlValue.SqlValue module Database.GP -- | A function that retrieves an entity from a database. The function -- takes entity id as parameter. If an entity with the given id exists in -- the database, it is returned as a Just value. If no such entity -- exists, Nothing is returned. An error is thrown if there are more than -- one entity with the given id. retrieveById :: forall a id. (Entity a, Convertible id SqlValue) => id -> GP (Maybe a) -- | This function retrieves all entities of type a from a -- database. The function takes an HDBC connection as parameter. The type -- a is determined by the context of the function call. retrieveAll :: forall a. Entity a => GP [a] retrieveAllWhere :: forall a. Entity a => String -> SqlValue -> GP [a] -- | A function that persists an entity to a database. The function takes -- an HDBC connection and an entity as parameters. The entity is either -- inserted or updated, depending on whether it already exists in the -- database. The required SQL statements are generated dynamically using -- Haskell generics and reflection persist :: Entity a => a -> GP () -- | A function that explicitely inserts an entity into a database. insert :: Entity a => a -> GP () -- | A function that explicitely updates an entity in a database. update :: Entity a => a -> GP () delete :: Entity a => a -> GP () -- | set up a table for a given entity type. The table is dropped and -- recreated. setupTableFor :: forall a. Entity a => GP a -- | A function that returns the primary key value of an entity as a -- SqlValue. idValue :: forall a. Entity a => a -> SqlValue class (Data a) => Entity a -- | Converts a database row to a value of type a. fromRow :: Entity a => [SqlValue] -> GP a -- | Converts a value of type a to a database row. toRow :: Entity a => a -> GP [SqlValue] -- | Returns the name of the primary key field for a type a. idField :: Entity a => a -> String -- | Returns a list of tuples that map field names to column names for a -- type a. fieldsToColumns :: Entity a => a -> [(String, String)] -- | Returns the name of the table for a type a. tableName :: Entity a => a -> String -- | Converts a database row to a value of type a. fromRow :: Entity a => [SqlValue] -> GP a -- | Converts a value of type a to a database row. toRow :: Entity a => a -> GP [SqlValue] -- | Returns the name of the primary key field for a type a. idField :: Entity a => a -> String -- | Returns a list of tuples that map field names to column names for a -- type a. fieldsToColumns :: Entity a => a -> [(String, String)] -- | Returns the name of the table for a type a. tableName :: Entity a => a -> String -- | A convenience function: returns the name of the column for a field of -- a type a. columnNameFor :: Entity a => a -> String -> String -- | A convenience function: returns the TypeRep of a field of a type -- a. fieldTypeFor :: Entity a => a -> String -> TypeRep maybeFieldTypeFor :: Entity a => a -> String -> Maybe TypeRep -- | Returns a string representation of a value of type a. toString :: Entity a => a -> String -- | A convenience function: returns an evidence instance of type -- a. This is useful for type inference where no instance is -- available. evidence :: forall a. Entity a => a evidenceFrom :: forall a. Entity a => TypeInfo a -> a -- | The resolution cache maps an EntityId to a Dynamic value (representing -- an Entity). It is used to resolve circular references during loading -- and storing of Entities. type ResolutionCache = [(EntityId, Dynamic)] -- | The EntityId is a tuple of the TypeRep and the primary key value of an -- Entity. It is used as a key in the resolution cache. type EntityId = (TypeRep, SqlValue) -- | Computes the EntityId of an entity. The EntityId of an entity is a -- (typeRep, idValue) tuple. entityId :: Entity a => a -> EntityId -- | Lookup an entity in the cache, or retrieve it from the database. The -- Entity is identified by its EntityId, which is a (typeRep, idValue) -- tuple. getElseRetrieve :: forall a. Entity a => EntityId -> GP (Maybe a) -- | A data type holding meta-data about a type. The Phantom type parameter -- a ensures type safety for reflective functions that use this -- type to create type instances (See module RecordtypeReflection). data TypeInfo a -- | This function creates a TypeInfo object from the context of a function -- call. The Phantom Type parameter a is used to convince the -- compiler that the `TypeInfo a` object really describes type -- a. See also -- https://stackoverflow.com/questions/75171829/how-to-obtain-a-data-data-constr-etc-from-a-type-representation typeInfoFromContext :: forall a. Data a => TypeInfo a -- | this function is a smart constructor for TypeInfo objects. It takes a -- value of type a and returns a `TypeInfo a` object. If the -- type has no named fields, an error is thrown. If the type has more -- than one constructor, an error is thrown. typeInfo :: Data a => a -> TypeInfo a -- | type Ctx defines the context in which the persistence operations are -- executed. It contains a connection to the database and a resolution -- cache for circular lookups. data Ctx Ctx :: ConnWrapper -> ResolutionCache -> Ctx [connection] :: Ctx -> ConnWrapper [cache] :: Ctx -> ResolutionCache type GP = RIO Ctx extendCtxCache :: Entity a => a -> Ctx -> Ctx runGP :: (MonadIO m, IConnection conn) => conn -> RIO Ctx a -> m a -- | Lift a computation from the IO monad. This allows us to run IO -- computations in any monadic stack, so long as it supports these kinds -- of operations (i.e. IO is the base monad for the stack). -- --

Example

-- --
--   import Control.Monad.Trans.State -- from the "transformers" library
--   
--   printState :: Show s => StateT s IO ()
--   printState = do
--     state <- get
--     liftIO $ print state
--   
-- -- Had we omitted liftIO, we would have ended up with -- this error: -- --
--   • Couldn't match type ‘IO’ with ‘StateT s IO’
--    Expected type: StateT s IO ()
--      Actual type: IO ()
--   
-- -- The important part here is the mismatch between StateT s IO -- () and IO (). -- -- Luckily, we know of a function that takes an IO a and -- returns an (m a): liftIO, enabling us to run -- the program and see the expected results: -- --
--   > evalStateT printState "hello"
--   "hello"
--   
--   > evalStateT printState 3
--   3
--   
liftIO :: MonadIO m => IO a -> m a -- | Executes a computation in a modified environment. local :: MonadReader r m => (r -> r) -> m a -> m a -- | Retrieves the monad environment. ask :: MonadReader r m => m r