ihp-1.4.0: Haskell Web Framework
Copyright(c) digitally induced GmbH 2020
Safe HaskellNone
LanguageGHC2021

IHP.ModelSupport.Types

Description

This module contains the core types for IHP's model support. It's designed to be lightweight and avoid heavy dependencies, allowing modules that only need the types to compile faster.

For the full model API including query functions, use ModelSupport.

Synopsis

Model Context

data ModelContext Source #

Provides the db connection and some IHP-specific db configuration

Constructors

ModelContext 

Fields

Instances

Instances details
HasField "modelContext" Request ModelContext Source # 
Instance details

Defined in IHP.RequestVault.ModelContext

data RowLevelSecurityContext Source #

When row level security is enabled at runtime, this keeps track of the current logged in user and the postgresql role to switch to.

Constructors

RowLevelSecurityContext 

Fields

newtype TransactionRunner Source #

Runner that executes a hasql Session on the current transaction's connection

Constructors

TransactionRunner 

Fields

Type Families

type family GetModelById id where ... Source #

Equations

GetModelById (Maybe (Id' tableName)) = Maybe (GetModelByTableName tableName) 
GetModelById (Id' tableName) = GetModelByTableName tableName 

type family GetTableName model :: Symbol Source #

type family GetModelByTableName (tableName :: Symbol) Source #

type family PrimaryKey (tableName :: Symbol) Source #

Provides the primary key type for a given table. The instances are usually declared by the generated haskell code in Generated.Types

Example: Defining the primary key for a users table

type instance PrimaryKey "users" = UUID

Example: Defining the primary key for a table with a SERIAL pk

type instance PrimaryKey "projects" = Int

type family GetModelName model :: Symbol Source #

type family Include (name :: Symbol) model Source #

type family Include' (name :: [Symbol]) model where ... Source #

Equations

Include' ('[] :: [Symbol]) model = model 
Include' (x ': xs) model = Include' xs (Include x model) 

type NormalizeModel model = GetModelByTableName (GetTableName model) Source #

Helper type to deal with models where relations are included or that are only partially fetched Examples:

>>> NormalizeModel (Include "author_id" Post)
Post
>>> NormalizeModel Post
Post

Id Types

newtype Id' (table :: Symbol) Source #

Constructors

Id (PrimaryKey table) 

Instances

Instances details
FromJSON (PrimaryKey a) => FromJSON (Id' a) Source # 
Instance details

Defined in IHP.ModelSupport

ToJSON (PrimaryKey a) => ToJSON (Id' a) Source # 
Instance details

Defined in IHP.ModelSupport

PrimaryKey table ~ UUID => Serialize (Id' table) Source # 
Instance details

Defined in IHP.Controller.Session

Methods

put :: Putter (Id' table) Source #

get :: Get (Id' table) Source #

(KnownSymbol table, NFData (PrimaryKey table)) => NFData (Id' table) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

rnf :: Id' table -> () #

(KnownSymbol table, Data (PrimaryKey table)) => Data (Id' table) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Id' table -> c (Id' table) #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Id' table) #

toConstr :: Id' table -> Constr #

dataTypeOf :: Id' table -> DataType #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Id' table)) #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Id' table)) #

gmapT :: (forall b. Data b => b -> b) -> Id' table -> Id' table #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Id' table -> r #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Id' table -> r #

gmapQ :: (forall d. Data d => d -> u) -> Id' table -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Id' table -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Id' table -> m (Id' table) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Id' table -> m (Id' table) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Id' table -> m (Id' table) #

(Read (PrimaryKey model), ParsePrimaryKey (PrimaryKey model)) => IsString (Id' model) Source #

Sometimes you have a hardcoded UUID value which represents some record id. This instance allows you to write the Id like a string:

let projectId = "ca63aace-af4b-4e6c-bcfa-76ca061dbdc6" :: Id Project
Instance details

Defined in IHP.ModelSupport

Methods

fromString :: String -> Id' model #

Show (PrimaryKey model) => Show (Id' model) Source # 
Instance details

Defined in IHP.ModelSupport

Methods

showsPrec :: Int -> Id' model -> ShowS #

show :: Id' model -> String #

showList :: [Id' model] -> ShowS #

Eq (PrimaryKey table) => Eq (Id' table) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

(==) :: Id' table -> Id' table -> Bool #

(/=) :: Id' table -> Id' table -> Bool #

Ord (PrimaryKey table) => Ord (Id' table) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

compare :: Id' table -> Id' table -> Ordering #

(<) :: Id' table -> Id' table -> Bool #

(<=) :: Id' table -> Id' table -> Bool #

(>) :: Id' table -> Id' table -> Bool #

(>=) :: Id' table -> Id' table -> Bool #

max :: Id' table -> Id' table -> Id' table #

min :: Id' table -> Id' table -> Id' table #

Hashable (PrimaryKey table) => Hashable (Id' table) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

hashWithSalt :: Int -> Id' table -> Int Source #

hash :: Id' table -> Int Source #

PrimaryKey table ~ UUID => DefaultParamEncoder (Id' table) Source #

Encode Id table' for tables with UUID primary keys This covers the common case in IHP where most tables use UUID as the primary key.

Instance details

Defined in IHP.Hasql.Encoders

PrimaryKey table ~ UUID => DefaultParamEncoder (Maybe (Id' table)) Source #

Encode 'Maybe (Id' table)' for nullable foreign keys

Instance details

Defined in IHP.Hasql.Encoders

PrimaryKey table ~ UUID => DefaultParamEncoder [Id' table] Source #

Encode list of Id table' for tables with UUID primary keys Used by filterWhereIdIn for simple primary keys

Instance details

Defined in IHP.Hasql.Encoders

PrimaryKey table ~ UUID => DefaultParamEncoder [Maybe (Id' table)] Source #

Encode '[Maybe (Id' table)]' for filterWhereIn with nullable foreign keys

Instance details

Defined in IHP.Hasql.Encoders

(PrimaryKey a ~ UUID, PrimaryKey b ~ UUID) => DefaultParamEncoder [(Id' a, Id' b)] Source #

Encode '[(Id' a, Id' b)]' as PostgreSQL array of composite types Used by filterWhereIdIn for tables with composite primary keys of two Id columns

Instance details

Defined in IHP.Hasql.Encoders

IsEmpty (PrimaryKey table) => IsEmpty (Id' table) Source # 
Instance details

Defined in IHP.ModelSupport

Methods

isEmpty :: Id' table -> Bool Source #

PrimaryKey table ~ UUID => HasqlDecodeValue (Id' table) Source # 
Instance details

Defined in IHP.Hasql.FromRow

Methods

hasqlDecodeValue :: Value (Id' table) Source #

InputValue (PrimaryKey model') => InputValue (Id' model') Source # 
Instance details

Defined in IHP.ModelSupport

Methods

inputValue :: Id' model' -> Text Source #

InputValue (PrimaryKey table) => ApplyAttribute (Id' table) 
Instance details

Defined in IHP.ViewSupport

Methods

applyAttribute :: Text -> Text -> Id' table -> Html -> Html

FromField (PrimaryKey model) => FromField (Id' model) Source # 
Instance details

Defined in IHP.PGSimpleCompat

Methods

fromField :: FieldParser (Id' model) Source #

ToField (PrimaryKey model) => ToField (Id' model) Source # 
Instance details

Defined in IHP.PGSimpleCompat

Methods

toField :: Id' model -> Action Source #

ParamReader (PrimaryKey model') => ParamReader (Id' model') Source # 
Instance details

Defined in IHP.Controller.Param

(model ~ GetModelById (Id' table), GetTableName model ~ table, FilterPrimaryKey table) => Fetchable (Id' table) model Source # 
Instance details

Defined in IHP.Fetch

Associated Types

type FetchResult (Id' table) model 
Instance details

Defined in IHP.Fetch

type FetchResult (Id' table) model = model

Methods

fetch :: Id' table -> IO (FetchResult (Id' table) model) Source #

fetchOneOrNothing :: Id' table -> IO (Maybe model) Source #

fetchOne :: Id' table -> IO model Source #

(model ~ GetModelById (Id' table), GetTableName model ~ table, FilterPrimaryKey table) => Fetchable (Maybe (Id' table)) model Source # 
Instance details

Defined in IHP.Fetch

Associated Types

type FetchResult (Maybe (Id' table)) model 
Instance details

Defined in IHP.Fetch

type FetchResult (Maybe (Id' table)) model = [model]

Methods

fetch :: Maybe (Id' table) -> IO (FetchResult (Maybe (Id' table)) model) Source #

fetchOneOrNothing :: Maybe (Id' table) -> IO (Maybe model) Source #

fetchOne :: Maybe (Id' table) -> IO model Source #

(model ~ GetModelById (Id' table), GetModelByTableName table ~ model, GetTableName model ~ table, DefaultParamEncoder [PrimaryKey table]) => Fetchable [Id' table] model Source # 
Instance details

Defined in IHP.Fetch

Associated Types

type FetchResult [Id' table] model 
Instance details

Defined in IHP.Fetch

type FetchResult [Id' table] model = [model]

Methods

fetch :: [Id' table] -> IO (FetchResult [Id' table] model) Source #

fetchOneOrNothing :: [Id' table] -> IO (Maybe model) Source #

fetchOne :: [Id' table] -> IO model Source #

(TypeError (('Text "Looks like you forgot to pass a " ':<>: 'ShowType (GetModelByTableName record)) ':<>: 'Text " id to this data constructor.") :: Constraint) => Eq (Id' record -> controller) Source # 
Instance details

Defined in IHP.ViewSupport

Methods

(==) :: (Id' record -> controller) -> (Id' record -> controller) -> Bool #

(/=) :: (Id' record -> controller) -> (Id' record -> controller) -> Bool #

(PrimaryKey a ~ UUID, PrimaryKey b ~ UUID) => DefaultParamEncoder (Id' a, Id' b) Source #

Encode '(Id' a, Id' b)' as PostgreSQL composite/record type Used for composite primary keys with two Id columns (where both resolve to UUID)

Instance details

Defined in IHP.Hasql.Encoders

(ToField (Id' a), ToField (Id' b)) => ToField (Id' a, Id' b) Source # 
Instance details

Defined in IHP.PGSimpleCompat

Methods

toField :: (Id' a, Id' b) -> Action Source #

type FetchResult (Id' table) model Source # 
Instance details

Defined in IHP.Fetch

type FetchResult (Id' table) model = model
type FetchResult (Maybe (Id' table)) model Source # 
Instance details

Defined in IHP.Fetch

type FetchResult (Maybe (Id' table)) model = [model]
type FetchResult [Id' table] model Source # 
Instance details

Defined in IHP.Fetch

type FetchResult [Id' table] model = [model]

type Id model = Id' (GetTableName model) Source #

We need to map the model to its table name to prevent infinite recursion in the model data definition E.g. `type Project = Project' { id :: Id Project }` will not work But `type Project = Project' { id :: Id "projects" }` will

Record Metadata

data MetaBag Source #

Every IHP database record has a magic meta field which keeps a MetaBag inside. This data structure is used e.g. to keep track of the validation errors that happend.

Constructors

MetaBag 

Fields

  • annotations :: ![(Text, Violation)]

    Stores validation failures, as a list of (field name, error) pairs. E.g. annotations = [ ("name", TextViolation "cannot be empty") ]

  • touchedFields :: ![Text]

    Whenever a set is callled on a field, it will be marked as touched. Only touched fields are saved to the database when you call updateRecord

  • originalDatabaseRecord :: Maybe Dynamic

    When the record has been fetched from the database, we save the initial database record here. This is used by didChange to check if a field value is different from the initial database value.

Instances

Instances details
Default MetaBag Source # 
Instance details

Defined in IHP.ModelSupport

Methods

def :: MetaBag Source #

Show MetaBag Source # 
Instance details

Defined in IHP.ModelSupport.Types

Eq MetaBag Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

(==) :: MetaBag -> MetaBag -> Bool #

(/=) :: MetaBag -> MetaBag -> Bool #

SetField "annotations" MetaBag [(Text, Violation)] Source # 
Instance details

Defined in IHP.ModelSupport

SetField "touchedFields" MetaBag [Text] Source # 
Instance details

Defined in IHP.ModelSupport

Methods

setField :: [Text] -> MetaBag -> MetaBag Source #

data Violation Source #

The error message of a validator can be either a plain text value or a HTML formatted value

Constructors

TextViolation

Plain text validation error, like "cannot be empty"

Fields

HtmlViolation

HTML formatted, already pre-escaped validation error, like "Invalid, please href="http://example.com"check the documentation/a"

Fields

Instances

Instances details
Show Violation Source # 
Instance details

Defined in IHP.ModelSupport.Types

Eq Violation Source # 
Instance details

Defined in IHP.ModelSupport.Types

SetField "annotations" MetaBag [(Text, Violation)] Source # 
Instance details

Defined in IHP.ModelSupport

Field Wrappers

data FieldWithDefault valueType Source #

Represents fields that have a default value in an SQL schema

The Default constructor represents the default value from the schema, while the NonDefault constructor holds some other value for the field

Constructors

Default 
NonDefault valueType 

Instances

Instances details
Show valueType => Show (FieldWithDefault valueType) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

showsPrec :: Int -> FieldWithDefault valueType -> ShowS #

show :: FieldWithDefault valueType -> String #

showList :: [FieldWithDefault valueType] -> ShowS #

Eq valueType => Eq (FieldWithDefault valueType) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

(==) :: FieldWithDefault valueType -> FieldWithDefault valueType -> Bool #

(/=) :: FieldWithDefault valueType -> FieldWithDefault valueType -> Bool #

ToField valueType => ToField (FieldWithDefault valueType) Source # 
Instance details

Defined in IHP.PGSimpleCompat

Methods

toField :: FieldWithDefault valueType -> Action Source #

data FieldWithUpdate (name :: k) value Source #

Represents fields that may have been updated

The NoUpdate constructor represents the existing value in the database, while the Update constructor holds some new value for the field

Constructors

NoUpdate (Proxy name) 
Update value 

Instances

Instances details
Show value => Show (FieldWithUpdate name value) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

showsPrec :: Int -> FieldWithUpdate name value -> ShowS #

show :: FieldWithUpdate name value -> String #

showList :: [FieldWithUpdate name value] -> ShowS #

Eq value => Eq (FieldWithUpdate name value) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

(==) :: FieldWithUpdate name value -> FieldWithUpdate name value -> Bool #

(/=) :: FieldWithUpdate name value -> FieldWithUpdate name value -> Bool #

(KnownSymbol name, ToField value) => ToField (FieldWithUpdate name value) Source # 
Instance details

Defined in IHP.PGSimpleCompat

Methods

toField :: FieldWithUpdate name value -> Action Source #

Utility Types

data LabeledData a b Source #

Record type for objects of model types labeled with values from different database tables. (e.g. comments labeled with the IDs of the posts they belong to).

Constructors

LabeledData 

Fields

Instances

Instances details
(Show a, Show b) => Show (LabeledData a b) Source # 
Instance details

Defined in IHP.ModelSupport.Types

Methods

showsPrec :: Int -> LabeledData a b -> ShowS #

show :: LabeledData a b -> String #

showList :: [LabeledData a b] -> ShowS #

(HasqlDecodeColumn label, FromRowHasql a) => FromRowHasql (LabeledData label a) Source # 
Instance details

Defined in IHP.Hasql.FromRow

Methods

hasqlRowDecoder :: Row (LabeledData label a) Source #

(FromField label, FromRow a) => FromRow (LabeledData label a) Source # 
Instance details

Defined in IHP.PGSimpleCompat

Methods

fromRow :: RowParser (LabeledData label a) Source #

Exceptions

data EnhancedSqlError Source #

Whenever calls to query or execute raise an SqlError exception, we wrap that exception in this data structure. This allows us to show the actual database query that has triggered the error.

enhancedSqlErrorMessage :: EnhancedSqlError -> Text Source #

Extract the SQL error message as Text from an EnhancedSqlError.

This avoids downstream packages needing to import postgresql-simple to access the sqlErrorMsg field on SqlError.

Type Classes

class CanCreate a where Source #

Minimal complete definition

create, createMany

Methods

create :: a -> IO a Source #

createMany :: [a] -> IO [a] Source #

createRecordDiscardResult :: a -> IO () Source #

Like createRecord but doesn't return the created record

class CanUpdate a where Source #

Minimal complete definition

updateRecord

Methods

updateRecord :: a -> IO a Source #

updateRecordDiscardResult :: a -> IO () Source #

Like updateRecord but doesn't return the updated record

class ParsePrimaryKey primaryKey where Source #

Methods

parsePrimaryKey :: Text -> Maybe primaryKey Source #

Instances

Instances details
ParsePrimaryKey Text Source # 
Instance details

Defined in IHP.ModelSupport

ParsePrimaryKey UUID Source # 
Instance details

Defined in IHP.ModelSupport