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

IHP.Fetch

Description

This modules builds on top of QueryBuilder and provides functions to fetch a query builder.

For more complex sql queries, use sqlQuery.

Synopsis

Documentation

findManyBy :: forall {k} {value} {name :: Symbol} {table :: Symbol} {queryBuilderProvider} {joinRegister :: k} {model}. (ToField value, HasField name (GetModelByTableName table) value, EqOrIsOperator value, HasQueryBuilder queryBuilderProvider joinRegister, Fetchable (queryBuilderProvider table) model, Table model, Table (GetModelByTableName table), FromRow model, ?modelContext :: ModelContext, KnownSymbol table, KnownSymbol name) => Proxy name -> value -> queryBuilderProvider table -> IO (FetchResult (queryBuilderProvider table) model) Source #

findMaybeBy :: forall {k} {value} {name :: Symbol} {table :: Symbol} {queryBuilderProvider} {joinRegister :: k} {model}. (ToField value, HasField name (GetModelByTableName table) value, EqOrIsOperator value, HasQueryBuilder queryBuilderProvider joinRegister, Fetchable (queryBuilderProvider table) model, Table model, Table (GetModelByTableName table), FromRow model, ?modelContext :: ModelContext, KnownSymbol table, KnownSymbol name) => Proxy name -> value -> queryBuilderProvider table -> IO (Maybe model) Source #

findBy :: forall {k} {value} {name :: Symbol} {table :: Symbol} {queryBuilderProvider} {joinRegister :: k} {model}. (ToField value, HasField name (GetModelByTableName table) value, EqOrIsOperator value, HasQueryBuilder queryBuilderProvider joinRegister, Fetchable (queryBuilderProvider table) model, Table model, Table (GetModelByTableName table), FromRow model, ?modelContext :: ModelContext, KnownSymbol table, KnownSymbol name) => Proxy name -> value -> queryBuilderProvider table -> IO model Source #

newtype In a Source #

Wrap a list of values for use in an IN clause. Replaces a single "?" character with a parenthesized list of rendered values.

Example:

query c "select * from whatever where id in ?" (Only (In [3,4,5]))

Note that In [] expands to (null), which works as expected in the query above, but evaluates to the logical null value on every row instead of TRUE. This means that changing the query above to ... id NOT in ? and supplying the empty list as the parameter returns zero rows, instead of all of them as one would expect.

Since postgresql doesn't seem to provide a syntax for actually specifying an empty list, which could solve this completely, there are two workarounds particularly worth mentioning, namely:

  1. Use postgresql-simple's Values type instead, which can handle the empty case correctly. Note however that while specifying the postgresql type "int4" is mandatory in the empty case, specifying the haskell type Values (Only Int) would not normally be needed in realistic use cases.

    query c "select * from whatever where id not in ?"
            (Only (Values ["int4"] [] :: Values (Only Int)))
  2. Use sql's COALESCE operator to turn a logical null into the correct boolean. Note however that the correct boolean depends on the use case:

    query c "select * from whatever where coalesce(id NOT in ?, TRUE)"
            (Only (In [] :: In [Int]))
    query c "select * from whatever where coalesce(id IN ?, FALSE)"
            (Only (In [] :: In [Int]))

    Note that at as of PostgreSQL 9.4, the query planner cannot see inside the COALESCE operator, so if you have an index on id then you probably don't want to write the last example with COALESCE, which would result in a table scan. There are further caveats if id can be null or you want null treated sensibly as a component of IN or NOT IN.

Constructors

In a 

Instances

Instances details
Functor In 
Instance details

Defined in Database.PostgreSQL.Simple.Types

Methods

fmap :: (a -> b) -> In a -> In b #

(<$) :: a -> In b -> In a #

Read a => Read (In a) 
Instance details

Defined in Database.PostgreSQL.Simple.Types

Show a => Show (In a) 
Instance details

Defined in Database.PostgreSQL.Simple.Types

Methods

showsPrec :: Int -> In a -> ShowS #

show :: In a -> String #

showList :: [In a] -> ShowS #

Eq a => Eq (In a) 
Instance details

Defined in Database.PostgreSQL.Simple.Types

Methods

(==) :: In a -> In a -> Bool #

(/=) :: In a -> In a -> Bool #

Ord a => Ord (In a) 
Instance details

Defined in Database.PostgreSQL.Simple.Types

Methods

compare :: In a -> In a -> Ordering #

(<) :: In a -> In a -> Bool #

(<=) :: In a -> In a -> Bool #

(>) :: In a -> In a -> Bool #

(>=) :: In a -> In a -> Bool #

max :: In a -> In a -> In a #

min :: In a -> In a -> In a #

ToField a => ToField (In [a]) 
Instance details

Defined in Database.PostgreSQL.Simple.ToField

Methods

toField :: In [a] -> Action Source #

genericFetchId :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, FilterPrimaryKey table, model ~ GetModelByTableName table, GetTableName model ~ table) => Id' table -> IO [model] Source #

genericfetchIdOneOrNothing :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, FilterPrimaryKey table, model ~ GetModelByTableName table, GetTableName model ~ table) => Id' table -> IO (Maybe model) Source #

genericFetchIdOne :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, FilterPrimaryKey table, model ~ GetModelByTableName table, GetTableName model ~ table) => Id' table -> IO model Source #

class Fetchable fetchable model | fetchable -> model where Source #

Associated Types

type FetchResult fetchable model Source #

Methods

fetch :: fetchable -> IO (FetchResult fetchable model) Source #

fetchOneOrNothing :: fetchable -> IO (Maybe model) Source #

fetchOne :: fetchable -> IO model Source #

Instances

Instances details
(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 ~ GetModelByTableName table, KnownSymbol table) => Fetchable (NoJoinQueryBuilderWrapper table) model Source # 
Instance details

Defined in IHP.Fetch

Associated Types

type FetchResult (NoJoinQueryBuilderWrapper table) model 
Instance details

Defined in IHP.Fetch

type FetchResult (NoJoinQueryBuilderWrapper table) model = [model]
(model ~ GetModelByTableName table, KnownSymbol table) => Fetchable (QueryBuilder table) model Source # 
Instance details

Defined in IHP.Fetch

Associated Types

type FetchResult (QueryBuilder table) model 
Instance details

Defined in IHP.Fetch

type FetchResult (QueryBuilder table) model = [model]

Methods

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

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

fetchOne :: QueryBuilder 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) => 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 ~ GetModelByTableName table, KnownSymbol table) => Fetchable (JoinQueryBuilderWrapper r table) model Source # 
Instance details

Defined in IHP.Fetch

Associated Types

type FetchResult (JoinQueryBuilderWrapper r table) model 
Instance details

Defined in IHP.Fetch

type FetchResult (JoinQueryBuilderWrapper r table) model = [model]
(model ~ GetModelByTableName table, KnownSymbol table, FromField value, KnownSymbol foreignTable, foreignModel ~ GetModelByTableName foreignTable, KnownSymbol columnName, HasField columnName foreignModel value, HasQueryBuilder (LabeledQueryBuilderWrapper foreignTable columnName value) NoJoins) => Fetchable (LabeledQueryBuilderWrapper foreignTable columnName value table) model Source # 
Instance details

Defined in IHP.Fetch

Associated Types

type FetchResult (LabeledQueryBuilderWrapper foreignTable columnName value table) model 
Instance details

Defined in IHP.Fetch

type FetchResult (LabeledQueryBuilderWrapper foreignTable columnName value table) model = [LabeledData value model]

Methods

fetch :: LabeledQueryBuilderWrapper foreignTable columnName value table -> IO (FetchResult (LabeledQueryBuilderWrapper foreignTable columnName value table) model) Source #

fetchOneOrNothing :: LabeledQueryBuilderWrapper foreignTable columnName value table -> IO (Maybe model) Source #

fetchOne :: LabeledQueryBuilderWrapper foreignTable columnName value table -> IO model Source #

genericFetchIds :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, model ~ GetModelByTableName table, GetTableName model ~ table) => [Id model] -> IO [model] Source #

genericfetchIdsOneOrNothing :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, model ~ GetModelByTableName table, GetTableName model ~ table) => [Id model] -> IO (Maybe model) Source #

genericFetchIdsOne :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, model ~ GetModelByTableName table, GetTableName model ~ table) => [Id model] -> IO model Source #

fetchCount :: forall {k} (table :: Symbol) queryBuilderProvider (joinRegister :: k). (?modelContext :: ModelContext, KnownSymbol table, HasQueryBuilder queryBuilderProvider joinRegister) => queryBuilderProvider table -> IO Int Source #

Returns the count of records selected by the query builder.

Example: Counting all users.

allUsersCount <- query @User |> fetchCount -- SELECT COUNT(*) FROM users

Example: Counting all active projects

    activeProjectsCount <- query @Project
        |> filterWhere (#isActive, True)
        |> fetchCount
    -- SELECT COUNT(*) FROM projects WHERE is_active = true

fetchExists :: forall {k} (table :: Symbol) queryBuilderProvider (joinRegister :: k). (?modelContext :: ModelContext, KnownSymbol table, HasQueryBuilder queryBuilderProvider joinRegister) => queryBuilderProvider table -> IO Bool Source #

Checks whether the query has any results.

Returns True when there is at least one row matching the conditions of the query. Returns False otherwise.

Example: Checking whether there are unread messages

    hasUnreadMessages <- query @Message
        |> filterWhere (#isUnread, True)
        |> fetchExists
    -- SELECT EXISTS (SELECT * FROM messages WHERE is_unread = true)

fetchSQLQuery :: (FromRow model, ?modelContext :: ModelContext) => SQLQuery -> IO [model] Source #

fetchLatest :: forall {k} (table :: Symbol) queryBuilderProvider (joinRegister :: k) model. (?modelContext :: ModelContext, model ~ GetModelByTableName table, KnownSymbol table, HasQueryBuilder queryBuilderProvider joinRegister, HasField "createdAt" model UTCTime, Fetchable (queryBuilderProvider table) model, Table model, FromRow model) => queryBuilderProvider table -> IO (Maybe model) Source #

Returns the latest record or Nothing

Example:

latestUser <-
    query @User
        |> fetchLatest

fetchLatest is mainly a shortcut for code like this:

latestUser <-
    query @User
        |> orderByDesc #createdAt
        |> fetchOneOrNothing

fetchLatestBy :: forall {k} (table :: Symbol) (createdAt :: Symbol) queryBuilderProvider (joinRegister :: k) model. (?modelContext :: ModelContext, KnownSymbol createdAt, model ~ GetModelByTableName table, KnownSymbol table, HasQueryBuilder queryBuilderProvider joinRegister, HasField createdAt model UTCTime, Fetchable (queryBuilderProvider table) model, Table model, FromRow model) => Proxy createdAt -> queryBuilderProvider table -> IO (Maybe model) Source #

Provided a field name, it returns the latest record or Nothing

See fetchLatest if you're looking for the latest record by the createdAt timestamp.

Example:

latestTrialUser <-
    query @User
        |> fetchLatestBy #trialStartedAt

fetchLatestBy is mainly a shortcut for code like this:

latestUser <-
    query @User
        |> orderByDesc #trialStartedAt
        |> fetchOneOrNothing