module Persistence.Category ( count , list , listAll , create , edit , delete ) where import qualified Data.Maybe as Maybe import Data.Text (Text) import Data.Time.Clock (getCurrentTime) import Database.SQLite.Simple (FromRow (fromRow), Only (Only)) import qualified Database.SQLite.Simple as SQLite import Prelude hiding (id) import Common.Model (Category (..), CategoryId) import Model.Query (Query (Query)) newtype Row = Row Category instance FromRow Row where fromRow = Row <$> (Category <$> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field) data CountRow = CountRow Int instance FromRow CountRow where fromRow = CountRow <$> SQLite.field count :: Query Int count = Query (\conn -> (Maybe.fromMaybe 0 . fmap (\(CountRow n) -> n) . Maybe.listToMaybe) <$> SQLite.query_ conn "SELECT COUNT(*) FROM category WHERE deleted_at IS NULL" ) list :: Int -> Int -> Query [Category] list page perPage = Query (\conn -> map (\(Row c) -> c) <$> SQLite.query conn "SELECT * FROM category WHERE deleted_at IS NULL ORDER BY edited_at, created_at DESC LIMIT ? OFFSET ?" (perPage, (page - 1) * perPage) ) listAll :: Query [Category] listAll = Query (\conn -> map (\(Row c) -> c) <$> SQLite.query_ conn "SELECT * FROM category WHERE deleted_at IS NULL" ) create :: Text -> Text -> Query () create categoryName categoryColor = Query (\conn -> do now <- getCurrentTime SQLite.execute conn "INSERT INTO category (name, color, created_at) VALUES (?, ?, ?)" (categoryName, categoryColor, now) ) edit :: CategoryId -> Text -> Text -> Query Bool edit categoryId categoryName categoryColor = Query (\conn -> do mbCategory <- fmap (\(Row c) -> c) . Maybe.listToMaybe <$> (SQLite.query conn "SELECT * FROM category WHERE id = ?" (Only categoryId)) if Maybe.isJust mbCategory then do now <- getCurrentTime SQLite.execute conn "UPDATE category SET edited_at = ?, name = ?, color = ? WHERE id = ?" (now, categoryName, categoryColor, categoryId) return True else return False ) delete :: CategoryId -> Query Bool delete categoryId = Query (\conn -> do mbCategory <- fmap (\(Row c) -> c) . Maybe.listToMaybe <$> (SQLite.query conn "SELECT * FROM category WHERE id = ?" (Only categoryId)) if Maybe.isJust mbCategory then do now <- getCurrentTime SQLite.execute conn "UPDATE category SET deleted_at = ? WHERE id = ?" (now, categoryId) return True else return False )