Skip to content

Commit

Permalink
Refactor pagination SQL queries to use generic parameters
Browse files Browse the repository at this point in the history
Change type signatures to use generic `parameters` type with `ToRow` constraint instead of `[Action]`
  • Loading branch information
rvarun11 committed Dec 29, 2024
1 parent dbd7bb5 commit 2cd71cf
Showing 1 changed file with 15 additions and 21 deletions.
36 changes: 15 additions & 21 deletions IHP/Pagination/ControllerFunctions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,12 @@ module IHP.Pagination.ControllerFunctions
import IHP.Prelude
import IHP.Controller.Context
import IHP.Controller.Param ( paramOrDefault, paramOrNothing )

import IHP.Pagination.Types
( Options(..), Pagination(..) )

import IHP.QueryBuilder
( HasQueryBuilder, filterWhereILike, limit, offset )
import IHP.Pagination.Types ( Options(..), Pagination(..) )
import IHP.QueryBuilder ( HasQueryBuilder, filterWhereILike, limit, offset )
import IHP.Fetch (fetchCount)

import IHP.ModelSupport (GetModelByTableName, sqlQuery, sqlQueryScalar, Table)

import Database.PostgreSQL.Simple.ToField (toField, Action)
import Database.PostgreSQL.Simple.Types (Query(Query))
import Database.PostgreSQL.Simple (FromRow, ToRow, Query(..), Only(Only), (:.)(..))

-- | Paginate a query, with the following default options:
--
Expand Down Expand Up @@ -173,18 +167,18 @@ defaultPaginationOptions =
--
-- __Example:__
--
-- > (users, pagination) <- paginatedSqlQuery @User "SELECT id, firstname, lastname FROM users" []
-- > (users, pagination) <- paginatedSqlQuery "SELECT id, firstname, lastname FROM users" ()
--
-- Take a look at "IHP.QueryBuilder" for a typesafe approach on building simple queries.
--
-- *AutoRefresh:* When using 'paginatedSqlQuery' with AutoRefresh, you need to use 'trackTableRead' to let AutoRefresh know that you have accessed a certain table. Otherwise AutoRefresh will not watch table of your custom sql query.
paginatedSqlQuery
:: forall model
. ( FromRow model
:: ( FromRow model
, ToRow parameters
, ?context :: ControllerContext
, ?modelContext :: ModelContext
)
=> ByteString -> [Action] -> IO ([model], Pagination)
=> Query -> parameters -> IO ([model], Pagination)
paginatedSqlQuery = paginatedSqlQueryWithOptions defaultPaginationOptions

-- | Runs a raw sql query and adds pagination to it.
Expand All @@ -193,23 +187,23 @@ paginatedSqlQuery = paginatedSqlQueryWithOptions defaultPaginationOptions
--
-- __Example:__
--
-- > (users, pagination) <- paginatedSqlQueryWithOptions @User
-- > (users, pagination) <- paginatedSqlQueryWithOptions
-- > (defaultPaginationOptions |> set #maxItems 10)
-- > "SELECT id, firstname, lastname FROM users"
-- > []
-- > ()
--
-- Take a look at "IHP.QueryBuilder" for a typesafe approach on building simple queries.
--
-- *AutoRefresh:* When using 'paginatedSqlQuery' with AutoRefresh, you need to use 'trackTableRead' to let AutoRefresh know that you have accessed a certain table. Otherwise AutoRefresh will not watch table of your custom sql query.
paginatedSqlQueryWithOptions
:: forall model
. ( FromRow model
:: ( FromRow model
, ToRow parameters
, ?context :: ControllerContext
, ?modelContext :: ModelContext
)
=> Options -> ByteString -> [Action] -> IO ([model], Pagination)
=> Options -> Query -> parameters -> IO ([model], Pagination)
paginatedSqlQueryWithOptions options sql placeholders = do
count :: Int <- sqlQueryScalar (Query $ "SELECT count(subquery.*) FROM (" <> sql <> ") as subquery") placeholders
count :: Int <- sqlQueryScalar ("SELECT count(subquery.*) FROM (" <> sql <> ") as subquery") placeholders

let pageSize = pageSize' options
pagination = Pagination
Expand All @@ -220,8 +214,8 @@ paginatedSqlQueryWithOptions options sql placeholders = do
}

results :: [model] <- sqlQuery
(Query $ "SELECT subquery.* FROM (" <> sql <> ") as subquery LIMIT ? OFFSET ?")
(placeholders ++ map toField [pageSize, offset' pageSize page])
("SELECT subquery.* FROM (" <> sql <> ") as subquery LIMIT ? OFFSET ?")
(placeholders :. Only pageSize :. Only (offset' pageSize page))

pure (results, pagination)

Expand Down

0 comments on commit 2cd71cf

Please sign in to comment.