{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} module Handler.Api where import Import import Database.Persist.Sql (rawSql) import Data.Time.Clock.POSIX (posixSecondsToUTCTime, utcTimeToPOSIXSeconds) import qualified Data.Text as Text getApiR :: Int -> Handler TypedContent getApiR time = do -- TODO: use only one runDB userId <- getUserId -- We get all groups no matter what, since else we can't know which groups have been deleted groups <- getGroups userId let utcTime = posixSecondsToUTCTime (fromIntegral time) let sqlLists = "select ?? from todolist join group_user on todolist.group_id = group_user.group_id and group_user.user = ? join \"group\" on todolist.group_id = \"group\".id and \"group\".last_modified > ?;" lists <- runDB $ rawSql sqlLists [toPersistValue userId, toPersistValue utcTime] let a = lists :: [Entity Todolist] let sqlItems = "select ?? from todolist join group_user on todolist.group_id = group_user.group_id and group_user.user = ? join \"group\" on todolist.group_id = \"group\".id and \"group\".last_modified > ? join todolist_item on todolist_item.todolist_id = todolist.id;" items <- runDB $ rawSql sqlItems [toPersistValue userId, toPersistValue utcTime] let t = unlines $ map groupToCSV groups <> map todolistToCSV lists <> map todolistItemToCSV items return $ TypedContent typePlain $ toContent t todolistItemToCSV :: Entity TodolistItem -> Text todolistItemToCSV item = "i," <> fieldToText item todolistToCSV :: Entity Todolist -> Text todolistToCSV list = "l," <> fieldToText list groupToCSV :: Entity Group -> Text groupToCSV group = "g," <> fieldToText group -- TODO: error management ? (maybe use Either Text Text and then propagate left to handler and send error ?) fieldToText :: PersistEntity record => Entity record -> Text fieldToText field = Text.intercalate "," (map persistValueToText $ entityValues field) persistValueToText :: PersistValue -> Text persistValueToText (PersistText s) = s persistValueToText (PersistInt64 i) = Text.pack $ show i persistValueToText (PersistUTCTime d) = Text.pack $ show $ floor (utcTimeToPOSIXSeconds d) persistValueToText (PersistBool b) = if b then "T" else "F" persistValueToText _ = error "Wrong input type" getText :: Text getText = do -- GET EVERY GROUP THAT HAS BEEN MODIFIED SINCE TIMESTAMP FROM USER -- GET EVERY TODOLIST THAT HAS BEEN MODIFIED SINCE TIMESTAMP -- GET EVERY ITEM FROM THESE TODOLISTS -- ENCODE ALL OF THEM IN THE TEXTFILE -- SEND IT ! -- DONE :) error "not done yet"