From e295a216515474a946d4b101e2a332e3ee9fc074 Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Thu, 1 Oct 2020 17:03:57 +0200 Subject: [PATCH] Added sqlQueryScalar and fixed documentation on sqlQuery --- Guide/database.markdown | 8 +++++--- IHP/ModelSupport.hs | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Guide/database.markdown b/Guide/database.markdown index b4b2b3e14..6725d239c 100644 --- a/Guide/database.markdown +++ b/Guide/database.markdown @@ -234,13 +234,15 @@ do result :: Project <- sqlQuery "SELECT * FROM projects WHERE id = ?" (Only id) ``` -You can query any kind of information, not only records: +### Scalar Results + +The `sqlQuery` function always returns a list of rows as the result. When the result of your query is a single value (such as a integer or a string) use `sqlQueryScalar`: ```haskell do - count :: Int <- sqlQuery "SELECT COUNT(*) FROM projects" [] + count :: Int <- sqlQueryScalar "SELECT COUNT(*) FROM projects" () - randomString :: Text <- sqlQuery "SELECT md5(random()::text)" [] + randomString :: Text <- sqlQueryScalar "SELECT md5(random()::text)" () ``` ## Create diff --git a/IHP/ModelSupport.hs b/IHP/ModelSupport.hs index 652c9ddea..e015d8dab 100644 --- a/IHP/ModelSupport.hs +++ b/IHP/ModelSupport.hs @@ -234,13 +234,29 @@ instance Default (PrimaryKey model) => Default (Id' model) where -- -- __Example:__ -- --- > users <- sqlQuery "SELECT id, firstname, lastname FROM users" +-- > users <- sqlQuery "SELECT id, firstname, lastname FROM users" () -- -- Take a look at "IHP.QueryBuilder" for a typesafe approach on building simple queries. sqlQuery :: (?modelContext :: ModelContext) => (PG.ToRow q, PG.FromRow r) => Query -> q -> IO [r] sqlQuery = let ModelContext { databaseConnection } = ?modelContext in PG.query databaseConnection {-# INLINE sqlQuery #-} +-- | Runs a raw sql query which results in a single scalar value such as an integer or string +-- +-- __Example:__ +-- +-- > usersCount <- sqlQuery "SELECT COUNT(*) FROM users" +-- +-- Take a look at "IHP.QueryBuilder" for a typesafe approach on building simple queries. +sqlQueryScalar :: (?modelContext :: ModelContext) => (PG.ToRow q, FromField value) => Query -> q -> IO value +sqlQueryScalar query parameters = do + let ModelContext { databaseConnection } = ?modelContext + result <- PG.query databaseConnection query parameters + pure case result of + [PG.Only result] -> result + _ -> error "sqlQueryScalar: Expected a scalar result value" +{-# INLINE sqlQueryScalar #-} + -- | Returns the table name of a given model. -- -- __Example:__