WIP: Pagination

This commit is contained in:
Correl Roush 2022-07-13 00:04:35 -04:00
parent cc1ae8e395
commit 19980acc0c
4 changed files with 30 additions and 9 deletions

View file

@ -27,9 +27,11 @@ import GHC.Generics (Generic)
import qualified Paths_tutor as PT import qualified Paths_tutor as PT
import Servant import Servant
import Servant.OpenApi (HasOpenApi (toOpenApi)) import Servant.OpenApi (HasOpenApi (toOpenApi))
import qualified Tutor.Pagination as Pagination
import Tutor.Card import Tutor.Card
import Tutor.Config import Tutor.Config
import Tutor.Database import Tutor.Database
import Data.Maybe (fromMaybe)
data Status = Status data Status = Status
{ apiVersion :: T.Text, { apiVersion :: T.Text,
@ -176,6 +178,8 @@ type SearchCards =
:> QueryParam' '[Description "Query string"] "q" T.Text :> QueryParam' '[Description "Query string"] "q" T.Text
:> QueryParam' '[Description "Sorting method"] "sort_by" T.Text :> QueryParam' '[Description "Sorting method"] "sort_by" T.Text
:> QueryParam' '[Description "Search across collection or all cards"] "in_collection" T.Text :> QueryParam' '[Description "Search across collection or all cards"] "in_collection" T.Text
:> QueryParam' '[Description "Pagination limit"] "limit" Int
:> QueryParam' '[Description "Pagination offset"] "offset" Int
:> Get '[JSON] [Card] :> Get '[JSON] [Card]
type TutorAPI = type TutorAPI =
@ -206,9 +210,11 @@ openapi =
tutorServer :: Config -> Server TutorAPI tutorServer :: Config -> Server TutorAPI
tutorServer config = status config :<|> searchCards (tutorDatabase config) tutorServer config = status config :<|> searchCards (tutorDatabase config)
where where
searchCards :: FilePath -> Maybe T.Text -> Maybe T.Text -> Maybe T.Text -> Handler [Card] searchCards :: FilePath -> Maybe T.Text -> Maybe T.Text -> Maybe T.Text -> Maybe Int -> Maybe Int -> Handler [Card]
searchCards dbFile q sortBy inCollection = searchCards dbFile q sortBy inCollection limit offset =
liftIO $ Tutor.Database.searchCards dbFile q sortBy inCollection liftIO $ Pagination.items <$> Tutor.Database.searchCards dbFile q sortBy inCollection pagination
where pagination = Pagination.Pagination (fromMaybe 10 limit) (fromMaybe 0 offset)
docsServer :: Server DocsAPI docsServer :: Server DocsAPI
docsServer = return openapi docsServer = return openapi

View file

@ -14,12 +14,13 @@ import Database.SQLite.Simple.Internal
import Database.SQLite.Simple.Ok import Database.SQLite.Simple.Ok
import Database.SQLite.Simple.QQ import Database.SQLite.Simple.QQ
import Tutor.Card import Tutor.Card
import qualified Tutor.Pagination as Pagination
import qualified Tutor.Search as Search import qualified Tutor.Search as Search
import Tutor.SearchParser import Tutor.SearchParser
import Tutor.Select import Tutor.Select
( Select (..), ( Select (..),
join, join,
limit, limitOffset,
orderBy, orderBy,
parameter, parameter,
selectSimple, selectSimple,
@ -198,14 +199,16 @@ instance FromRow Card where
} }
} }
searchCards :: FilePath -> Maybe T.Text -> Maybe T.Text -> Maybe T.Text -> IO [Card] searchCards :: FilePath -> Maybe T.Text -> Maybe T.Text -> Maybe T.Text -> Pagination.Pagination -> IO (Pagination.Page Card)
searchCards dbFile q sortBy inCollection = searchCards dbFile q sortBy inCollection pagination =
withConnection dbFile $ \conn -> withConnection dbFile $ \conn ->
queryNamed asPage <$> queryNamed
conn conn
(toQuery query) (toQuery query)
(selectParameters query) (selectParameters query)
where where
asPage results =
Pagination.Page Nothing Nothing results
baseQuery = baseQuery =
selectSimple selectSimple
[ "cards.scryfall_id", [ "cards.scryfall_id",
@ -234,7 +237,7 @@ searchCards dbFile q sortBy inCollection =
ELSE cards.color_identity END ASC|] ELSE cards.color_identity END ASC|]
<> orderBy "cards.name ASC" <> orderBy "cards.name ASC"
<> parameter ":last_update_key" ("last_update" :: T.Text) <> parameter ":last_update_key" ("last_update" :: T.Text)
<> limit 10 <> limitOffset (Pagination.limit pagination) (Pagination.offset pagination)
query = query =
mconcat $ mconcat $
catMaybes catMaybes

12
src/Tutor/Pagination.hs Normal file
View file

@ -0,0 +1,12 @@
module Tutor.Pagination (Pagination(..), Page(..)) where
data Pagination = Pagination
{ limit :: Int
, offset :: Int
}
data Page a = Page
{ previous :: Maybe Pagination
, next :: Maybe Pagination
, items :: [a]
}

View file

@ -96,7 +96,7 @@ toQuery select =
[] -> Nothing [] -> Nothing
xs -> Just $ "ORDER BY " <> sqlJoin ", " xs xs -> Just $ "ORDER BY " <> sqlJoin ", " xs
sqlLimitOffset = case (selectLimit select, selectOffset select) of sqlLimitOffset = case (selectLimit select, selectOffset select) of
(Just l, Just o) -> Just "LIMIT :__limit, :__offset" (Just l, Just o) -> Just "LIMIT :__limit OFFSET :__offset"
(Just l, Nothing) -> Just "LIMIT :__limit" (Just l, Nothing) -> Just "LIMIT :__limit"
_ -> Nothing _ -> Nothing