{- | Module : Web.RBB.Blog.Query Description : Utlities for creating search queries Copyright : (c) Sebastian Witte License : BSD3 Maintainer : woozletoff@gmail.com Stability : experimental This module provides some functions and data types that can be used to manage search and query data for a list of 'Entry' values. -} module Web.RBB.Blog.Query ( EntryQuery(..), -- * Sorting SortMethod(..), SortOrder(..), sortMethodToComparator, ) where import Data.Default import Web.RBB.Types import Web.RBB.Util -- | Simple enum that provides Show and read instances so that a parser can -- convert the sting directly to a value of this type. data SortMethod = Update | Identifier | Author deriving (Show, Read, Eq, Ord, Enum) data SortOrder = Ascending | Descending deriving (Show, Read, Eq, Ord, Enum) -- | Convert a 'SortMethod' value to a sorting function that can be used in -- confunction with functions 'sortBy' from "Data.List". sortMethodToComparator :: SortMethod -> SortOrder -> (Entry -> Entry -> Ordering) sortMethodToComparator m o | o == Ascending = cmp | otherwise = flip cmp where cmp = case m of Update -> compare `on` view lastUpdate Identifier -> compare `on` view entryId Author -> compare `on` view author -- | The request data provided inside a URL. -- -- Example: @?id=42&sortBy=Identifier@ -- -- Example backend implementation using the Happstack package: -- -- > import Happstack.Server (look, HasRqData, ServerPartT) -- > -- > maybeLookAndRead :: (Monad m, Read a, Alternative m, HasRqData m) -- > => a -> String -> m a -- > maybeLookAndRead a qry = do -- > l <- optional $ look qry -- > return $ fromMaybe a (maybe (Just a) readMaybe l) -- > -- > -- | Parse the supported request data and present it in a data type. -- > parseQueryRqData :: ServerPartT IO EntryQuery -- > parseQueryRqData = EntryQuery -- > <$> (sortMethodToComparator -- > <$> maybeLookAndRead Update "sortBy" -- > <*> maybeLookAndRead Descending "sortOrder") -- > data EntryQuery = EntryQuery { eqSortBy :: Entry -> Entry -> Ordering -- ^ The method entries are sorted by. } -- | The 'Default' instance for an 'EntryQuery' type contains a function that -- sorts the entries descending by the last update to the entry. instance Default EntryQuery where def = EntryQuery (sortMethodToComparator Update Descending)