| Copyright | (c) digitally induced GmbH 2020 |
|---|---|
| Safe Haskell | None |
| Language | Haskell2010 |
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
- 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)
- 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)
- 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
- newtype In a = In a
- 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]
- 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)
- 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
- class Fetchable fetchable model | fetchable -> model where
- type FetchResult fetchable model
- fetch :: fetchable -> IO (FetchResult fetchable model)
- fetchOneOrNothing :: fetchable -> IO (Maybe model)
- fetchOne :: fetchable -> IO model
- genericFetchIds :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, model ~ GetModelByTableName table, GetTableName model ~ table) => [Id model] -> IO [model]
- genericfetchIdsOneOrNothing :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, model ~ GetModelByTableName table, GetTableName model ~ table) => [Id model] -> IO (Maybe model)
- genericFetchIdsOne :: forall (table :: Symbol) model. (Table model, KnownSymbol table, FromRow model, ?modelContext :: ModelContext, model ~ GetModelByTableName table, GetTableName model ~ table) => [Id model] -> IO model
- fetchCount :: forall {k} (table :: Symbol) queryBuilderProvider (joinRegister :: k). (?modelContext :: ModelContext, KnownSymbol table, HasQueryBuilder queryBuilderProvider joinRegister) => queryBuilderProvider table -> IO Int
- fetchExists :: forall {k} (table :: Symbol) queryBuilderProvider (joinRegister :: k). (?modelContext :: ModelContext, KnownSymbol table, HasQueryBuilder queryBuilderProvider joinRegister) => queryBuilderProvider table -> IO Bool
- fetchSQLQuery :: (FromRow model, ?modelContext :: ModelContext) => SQLQuery -> IO [model]
- 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)
- 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)
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 #
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:
Use postgresql-simple's
Valuestype 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 typeValues (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)))Use sql's
COALESCEoperator to turn a logicalnullinto 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
COALESCEoperator, so if you have an index onidthen you probably don't want to write the last example withCOALESCE, which would result in a table scan. There are further caveats ifidcan be null or you want null treated sensibly as a component ofINorNOT IN.
Constructors
| In a |
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 #
Instances
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 = truefetchExists :: 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
|> fetchOneOrNothingfetchLatestBy :: 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