chore: version bumps

This commit is contained in:
Gregor Kleen 2021-01-11 14:16:39 +01:00
parent c38ef39938
commit ae3f2aa703
46 changed files with 195 additions and 182 deletions

View File

@ -42,7 +42,7 @@ AllocationCourse
AllocationUser AllocationUser
allocation AllocationId allocation AllocationId
user UserId user UserId
totalCourses Natural -- number of total allocated courses for this user must be <= than this number totalCourses Word64 -- number of total allocated courses for this user must be <= than this number
priority AllocationPriority Maybe priority AllocationPriority Maybe
UniqueAllocationUser allocation user UniqueAllocationUser allocation user
deriving Eq Ord Show deriving Eq Ord Show

View File

@ -7,7 +7,7 @@ CourseApplication
ratingPoints ExamGrade Maybe ratingPoints ExamGrade Maybe
ratingComment Text Maybe ratingComment Text Maybe
allocation AllocationId Maybe allocation AllocationId Maybe
allocationPriority Natural Maybe allocationPriority Word64 Maybe
time UTCTime default=now() time UTCTime default=now()
ratingTime UTCTime Maybe ratingTime UTCTime Maybe

View File

@ -33,7 +33,7 @@ ExamOccurrence
name ExamOccurrenceName name ExamOccurrenceName
room RoomReference Maybe room RoomReference Maybe
roomHidden Bool default=false roomHidden Bool default=false
capacity Natural capacity Word64
start UTCTime start UTCTime
end UTCTime Maybe end UTCTime Maybe
description StoredMarkup Maybe description StoredMarkup Maybe

View File

@ -1,6 +1,6 @@
FileContentEntry FileContentEntry
hash FileContentReference hash FileContentReference
ix Natural ix Word64
chunkHash FileContentChunkId chunkHash FileContentChunkId
UniqueFileContentEntry hash ix UniqueFileContentEntry hash ix

View File

@ -6,7 +6,7 @@ SystemMessage
newsOnly Bool default=false newsOnly Bool default=false
authenticatedOnly Bool -- Show message to all users upon visiting the site or only upon login? authenticatedOnly Bool -- Show message to all users upon visiting the site or only upon login?
severity MessageStatus -- Success, Warning, Error, Info, ... severity MessageStatus -- Success, Warning, Error, Info, ...
manualPriority Natural Maybe manualPriority Word64 Maybe
created UTCTime default=now() created UTCTime default=now()
lastChanged UTCTime default=now() lastChanged UTCTime default=now()
lastUnhide UTCTime default=now() lastUnhide UTCTime default=now()

View File

@ -267,7 +267,7 @@ executables:
- condition: flag(library-only) - condition: flag(library-only)
buildable: false buildable: false
ghc-options: ghc-options:
- -threaded -rtsopts "-with-rtsopts=-N -T" # Nonblocking GC causes segfaults in production as of 2020-08-19 - -threaded -rtsopts "-with-rtsopts=-N -T --nonmoving-gc"
uniworxdb: uniworxdb:
main: Database.hs main: Database.hs
ghc-options: ghc-options:

View File

@ -6,7 +6,7 @@ module Data.CaseInsensitive.Instances
( (
) where ) where
import ClassyPrelude.Yesod hiding (lift) import ClassyPrelude.Yesod hiding (lift, Proxy(..))
import Data.CaseInsensitive (CI) import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
@ -28,16 +28,19 @@ import Web.HttpApiData
import qualified Data.Csv as Csv import qualified Data.Csv as Csv
import Utils.Persist
import Data.Proxy
instance PersistField (CI Text) where instance PersistField (CI Text) where
toPersistValue ciText = PersistDbSpecific . Text.encodeUtf8 $ CI.original ciText toPersistValue ciText = PersistLiteralEscaped . Text.encodeUtf8 $ CI.original ciText
fromPersistValue (PersistDbSpecific bs) = Right . CI.mk $ Text.decodeUtf8 bs fromPersistValue (PersistLiteralEscaped bs) = Right . CI.mk $ Text.decodeUtf8 bs
fromPersistValue x = Left . pack $ "Expected PersistDbSpecific, received: " ++ show x fromPersistValue x = Left $ fromPersistValueErrorSql (Proxy @(CI Text)) x
instance PersistField (CI String) where instance PersistField (CI String) where
toPersistValue ciText = PersistDbSpecific . Text.encodeUtf8 . pack $ CI.original ciText toPersistValue ciText = PersistLiteralEscaped . Text.encodeUtf8 . pack $ CI.original ciText
fromPersistValue (PersistDbSpecific bs) = Right . CI.mk . unpack $ Text.decodeUtf8 bs fromPersistValue (PersistLiteralEscaped bs) = Right . CI.mk . unpack $ Text.decodeUtf8 bs
fromPersistValue x = Left . pack $ "Expected PersistDbSpecific, received: " ++ show x fromPersistValue x = Left $ fromPersistValueErrorSql (Proxy @(CI String)) x
instance PersistFieldSql (CI Text) where instance PersistFieldSql (CI Text) where
sqlType _ = SqlOther "citext" sqlType _ = SqlOther "citext"

View File

@ -18,7 +18,9 @@ deriving instance Lift Day
instance Hashable Day where instance Hashable Day where
hashWithSalt s (ModifiedJulianDay jDay) = s `hashWithSalt` hash (typeRep @Day) `hashWithSalt` jDay hashWithSalt s (ModifiedJulianDay jDay) = s `hashWithSalt` hash (typeRep @Day) `hashWithSalt` jDay
deriving instance Ord DayOfWeek -- -- Available since time-1.11
-- deriving instance Ord DayOfWeek
instance Universe DayOfWeek where instance Universe DayOfWeek where
universe = [Monday .. Sunday] universe = [Monday .. Sunday]
instance Finite DayOfWeek instance Finite DayOfWeek

View File

@ -3,11 +3,13 @@
module Data.UUID.Instances module Data.UUID.Instances
() where () where
import ClassyPrelude.Yesod import ClassyPrelude.Yesod hiding (Proxy(..))
import Data.UUID (UUID) import Data.UUID (UUID)
import qualified Data.UUID as UUID import qualified Data.UUID as UUID
import Database.Persist.Sql import Database.Persist.Sql
import Utils.Persist
import Data.Proxy
import Text.Blaze (ToMarkup(..)) import Text.Blaze (ToMarkup(..))
@ -17,12 +19,12 @@ instance PathPiece UUID where
toPathPiece = pack . UUID.toString toPathPiece = pack . UUID.toString
instance PersistField UUID where instance PersistField UUID where
toPersistValue = PersistDbSpecific . UUID.toASCIIBytes toPersistValue = PersistLiteralEscaped . UUID.toASCIIBytes
fromPersistValue (PersistText t) = maybe (Left "Failed to parse UUID") Right $ UUID.fromText t fromPersistValue (PersistText t) = maybe (Left "Failed to parse UUID") Right $ UUID.fromText t
fromPersistValue (PersistByteString bs) = maybe (Left "Failed to parse UUID") Right $ UUID.fromASCIIBytes bs fromPersistValue (PersistByteString bs) = maybe (Left "Failed to parse UUID") Right $ UUID.fromASCIIBytes bs
fromPersistValue (PersistDbSpecific bs) = maybe (Left "Failed to parse UUID") Right $ UUID.fromASCIIBytes bs fromPersistValue (PersistLiteralEscaped bs) = maybe (Left "Failed to parse UUID") Right $ UUID.fromASCIIBytes bs
fromPersistValue x = Left $ "Expected UUID, received: " <> tshow x fromPersistValue x = Left $ fromPersistValueErrorSql (Proxy @UUID) x
instance PersistFieldSql UUID where instance PersistFieldSql UUID where
sqlType _ = SqlOther "uuid" sqlType _ = SqlOther "uuid"

View File

@ -10,7 +10,7 @@ module Database.Esqueleto.Utils.TH
import ClassyPrelude import ClassyPrelude
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect) import qualified Database.Esqueleto.Internal.Internal as E (SqlSelect)
import Database.Persist (PersistField) import Database.Persist (PersistField)

View File

@ -165,6 +165,8 @@ instance RenderMessage UniWorX Integer where
renderMessage f ls = renderMessage f ls . tshow renderMessage f ls = renderMessage f ls . tshow
instance RenderMessage UniWorX Natural where instance RenderMessage UniWorX Natural where
renderMessage f ls = renderMessage f ls . tshow renderMessage f ls = renderMessage f ls . tshow
instance RenderMessage UniWorX Word64 where
renderMessage f ls = renderMessage f ls . tshow
instance HasResolution a => RenderMessage UniWorX (Fixed a) where instance HasResolution a => RenderMessage UniWorX (Fixed a) where
renderMessage f ls = renderMessage f ls . showFixed True renderMessage f ls = renderMessage f ls . showFixed True
@ -342,6 +344,7 @@ instance RenderMessage UniWorX ExamCloseMode where
mr = renderMessage foundation ls mr = renderMessage foundation ls
-- ToMessage instances for converting raw numbers to Text (no internationalization) -- ToMessage instances for converting raw numbers to Text (no internationalization)
-- FIXME: Use RenderMessage always
instance ToMessage Int where instance ToMessage Int where
toMessage = tshow toMessage = tshow
@ -351,6 +354,8 @@ instance ToMessage Integer where
toMessage = tshow toMessage = tshow
instance ToMessage Natural where instance ToMessage Natural where
toMessage = tshow toMessage = tshow
instance ToMessage Word64 where
toMessage = tshow
instance HasResolution a => ToMessage (Fixed a) where instance HasResolution a => ToMessage (Fixed a) where
toMessage = toMessage . showFixed True toMessage = toMessage . showFixed True

View File

@ -16,7 +16,7 @@ import qualified Database.Esqueleto as E
data AllocationAddUserForm = AllocationAddUserForm data AllocationAddUserForm = AllocationAddUserForm
{ aauUser :: UserId { aauUser :: UserId
, aauTotalCourses :: Natural , aauTotalCourses :: Word64
, aauPriority :: Maybe AllocationPriority , aauPriority :: Maybe AllocationPriority
, aauApplications :: Map CourseId ApplicationForm , aauApplications :: Map CourseId ApplicationForm
} }

View File

@ -49,7 +49,7 @@ data ApplicationFormView = ApplicationFormView
} }
data ApplicationForm = ApplicationForm data ApplicationForm = ApplicationForm
{ afPriority :: Maybe Natural { afPriority :: Maybe Word64
, afText :: Maybe Text , afText :: Maybe Text
, afFiles :: Maybe FileUploads , afFiles :: Maybe FileUploads
, afRatingVeto :: Bool , afRatingVeto :: Bool
@ -90,19 +90,19 @@ applicationForm maId@(is _Just -> isAlloc) cid muid ApplicationFormMode{..} mcsr
MsgRenderer mr <- getMsgRenderer MsgRenderer mr <- getMsgRenderer
let let
oldPrio :: Maybe Natural oldPrio :: Maybe Word64
oldPrio = mApp >>= courseApplicationAllocationPriority . entityVal oldPrio = mApp >>= courseApplicationAllocationPriority . entityVal
coursesNum' = succ maxPrio `max` coursesNum coursesNum' = succ maxPrio `max` coursesNum
mkPrioOption :: Natural -> Option Natural mkPrioOption :: Word64 -> Option Word64
mkPrioOption i = Option mkPrioOption i = Option
{ optionDisplay = mr . MsgAllocationCoursePriority $ coursesNum' - i { optionDisplay = mr . MsgAllocationCoursePriority . fromIntegral $ coursesNum' - i
, optionInternalValue = i , optionInternalValue = i
, optionExternalValue = tshow i , optionExternalValue = tshow i
} }
prioOptions :: OptionList Natural prioOptions :: OptionList Word64
prioOptions = OptionList prioOptions = OptionList
{ olOptions = sortOn (Down . optionInternalValue) . map mkPrioOption $ [0 .. pred coursesNum'] { olOptions = sortOn (Down . optionInternalValue) . map mkPrioOption $ [0 .. pred coursesNum']
, olReadExternal = readMay , olReadExternal = readMay

View File

@ -37,10 +37,10 @@ countCourses muid ata now addWhere allocation = E.subSelectCount . E.from $ \all
) E.&&. addWhere allocationCourse ) E.&&. addWhere allocationCourse
queryAvailable :: Maybe UserId -> AuthTagActive -> UTCTime queryAvailable :: Maybe UserId -> AuthTagActive -> UTCTime
-> Getter AllocationTableExpr (E.SqlExpr (E.Value Natural)) -> Getter AllocationTableExpr (E.SqlExpr (E.Value Word64))
queryAvailable muid ata now = queryAllocation . to (countCourses muid ata now $ const E.true) queryAvailable muid ata now = queryAllocation . to (countCourses muid ata now $ const E.true)
queryApplied :: AuthTagActive -> UTCTime -> UserId -> Getter AllocationTableExpr (E.SqlExpr (E.Value Natural)) queryApplied :: AuthTagActive -> UTCTime -> UserId -> Getter AllocationTableExpr (E.SqlExpr (E.Value Word64))
queryApplied ata now uid = queryAllocation . to (\allocation -> countCourses (Just uid) ata now (addWhere allocation) allocation) queryApplied ata now uid = queryAllocation . to (\allocation -> countCourses (Just uid) ata now (addWhere allocation) allocation)
where where
addWhere allocation allocationCourse addWhere allocation allocationCourse
@ -78,7 +78,7 @@ getAllocationListR = do
<*> view (maybe (to . const $ E.val 0) (queryApplied ata now) muid) <*> view (maybe (to . const $ E.val 0) (queryApplied ata now) muid)
dbtProj :: DBRow _ -> DB AllocationTableData dbtProj :: DBRow _ -> DB AllocationTableData
dbtProj = return . over (_dbrOutput . _2) E.unValue . over (_dbrOutput . _3) E.unValue dbtProj = return . over (_dbrOutput . _2) (fromIntegral . E.unValue) . over (_dbrOutput . _3) (fromIntegral . E.unValue)
dbtRowKey = view $ queryAllocation . to (E.^. AllocationId) dbtRowKey = view $ queryAllocation . to (E.^. AllocationId)

View File

@ -14,7 +14,7 @@ import Handler.Utils.Form
data AllocationRegisterForm = AllocationRegisterForm data AllocationRegisterForm = AllocationRegisterForm
{ arfTotalCourses :: Natural { arfTotalCourses :: Word64
} }
allocationRegisterForm :: Maybe AllocationRegisterForm -> AForm Handler AllocationRegisterForm allocationRegisterForm :: Maybe AllocationRegisterForm -> AForm Handler AllocationRegisterForm

View File

@ -198,7 +198,7 @@ postAUsersR tid ssh ash = do
[ pure $ colUserDisplayName (resultUser . _entityVal . $(multifocusL 2) _userDisplayName _userSurname) [ pure $ colUserDisplayName (resultUser . _entityVal . $(multifocusL 2) _userDisplayName _userSurname)
, pure $ colUserMatriculation (resultUser . _entityVal . _userMatrikelnummer) , pure $ colUserMatriculation (resultUser . _entityVal . _userMatrikelnummer)
, pure $ colStudyFeatures resultStudyFeatures , pure $ colStudyFeatures resultStudyFeatures
, pure $ colAllocationRequested (resultAllocationUser . _entityVal . _allocationUserTotalCourses) , pure $ colAllocationRequested (resultAllocationUser . _entityVal . _allocationUserTotalCourses . _Integral)
, pure . coursesModalApplied $ colAllocationApplied resultAppliedCourses , pure . coursesModalApplied $ colAllocationApplied resultAppliedCourses
, pure . coursesModalVetoed $ colAllocationVetoed resultVetoedCourses , pure . coursesModalVetoed $ colAllocationVetoed resultVetoedCourses
, guardOn resultsDone . coursesModalAssigned . bool id (assignedHeated $ view resultAssignedCourses) resultsDone $ colAllocationAssigned resultAssignedCourses , guardOn resultsDone . coursesModalAssigned . bool id (assignedHeated $ view resultAssignedCourses) resultsDone $ colAllocationAssigned resultAssignedCourses
@ -305,10 +305,10 @@ postAUsersR tid ssh ash = do
<*> view (resultUser . _entityVal . _userDisplayName) <*> view (resultUser . _entityVal . _userDisplayName)
<*> view (resultUser . _entityVal . _userMatrikelnummer) <*> view (resultUser . _entityVal . _userMatrikelnummer)
<*> view resultStudyFeatures <*> view resultStudyFeatures
<*> view (resultAllocationUser . _entityVal . _allocationUserTotalCourses) <*> view (resultAllocationUser . _entityVal . _allocationUserTotalCourses . _Integral)
<*> view (resultAppliedCourses . to fromIntegral) <*> view (resultAppliedCourses . _Integral)
<*> view (resultVetoedCourses . to fromIntegral) <*> view (resultVetoedCourses . _Integral)
<*> view (resultAssignedCourses . to fromIntegral) <*> view (resultAssignedCourses . _Integral)
<*> views (resultUser . _entityKey) (\uid -> maybe 0 (fromIntegral . olength) . Map.lookup uid <$> allocMatching) <*> views (resultUser . _entityKey) (\uid -> maybe 0 (fromIntegral . olength) . Map.lookup uid <$> allocMatching)
<*> view (resultAllocationUser . _entityVal . _allocationUserPriority) <*> view (resultAllocationUser . _entityVal . _allocationUserPriority)
, dbtCsvName = unpack csvName , dbtCsvName = unpack csvName

View File

@ -113,7 +113,7 @@ postEAutoOccurrenceR tid ssh csh examn = do
let participants' = Map.fromList $ do let participants' = Map.fromList $ do
(Entity uid userRec, Entity _ ExamRegistration{..}) <- participants (Entity uid userRec, Entity _ ExamRegistration{..}) <- participants
return (uid, (userRec, examRegistrationOccurrence)) return (uid, (userRec, examRegistrationOccurrence))
occurrences' = Map.fromList $ map (\(Entity eoId ExamOccurrence{..}) -> (eoId, examOccurrenceCapacity)) occurrences occurrences' = Map.fromList $ map (\(Entity eoId ExamOccurrence{..}) -> (eoId, fromIntegral examOccurrenceCapacity)) occurrences
(eaofMapping, eaofAssignment) = examAutoOccurrence eId examOccurrenceRule eaofConfig occurrences' participants' (eaofMapping, eaofAssignment) = examAutoOccurrence eId examOccurrenceRule eaofConfig occurrences' participants'
return $ Just ExamAutoOccurrenceAcceptForm{..} return $ Just ExamAutoOccurrenceAcceptForm{..}

View File

@ -56,7 +56,7 @@ data ExamOccurrenceForm = ExamOccurrenceForm
, eofName :: ExamOccurrenceName , eofName :: ExamOccurrenceName
, eofRoom :: Maybe RoomReference , eofRoom :: Maybe RoomReference
, eofRoomHidden :: Bool , eofRoomHidden :: Bool
, eofCapacity :: Natural , eofCapacity :: Word64
, eofStart :: UTCTime , eofStart :: UTCTime
, eofEnd :: Maybe UTCTime , eofEnd :: Maybe UTCTime
, eofDescription :: Maybe StoredMarkup , eofDescription :: Maybe StoredMarkup

View File

@ -38,7 +38,7 @@ querySchool = to $ $(E.sqlIJproj 3 3) . $(E.sqlFOJproj 2 1)
queryExternalExam :: Getter ExamsTableExpr (E.SqlExpr (Maybe (Entity ExternalExam))) queryExternalExam :: Getter ExamsTableExpr (E.SqlExpr (Maybe (Entity ExternalExam)))
queryExternalExam = to $(E.sqlFOJproj 2 2) queryExternalExam = to $(E.sqlFOJproj 2 2)
querySynchronised :: E.SqlExpr (E.Value UserId) -> Getter ExamsTableExpr (E.SqlExpr (E.Value Natural)) querySynchronised :: E.SqlExpr (E.Value UserId) -> Getter ExamsTableExpr (E.SqlExpr (E.Value Word64))
querySynchronised office = to . runReader $ do querySynchronised office = to . runReader $ do
exam' <- view queryExam exam' <- view queryExam
externalExam' <- view queryExternalExam externalExam' <- view queryExternalExam
@ -53,7 +53,7 @@ querySynchronised office = to . runReader $ do
E.where_ $ ExternalExam.resultIsSynced office externalExamResult E.where_ $ ExternalExam.resultIsSynced office externalExamResult
return $ E.maybe (E.val 0) examSynchronised (exam' E.?. ExamId) E.+. E.maybe (E.val 0) externalExamSynchronised (externalExam' E.?. ExternalExamId) return $ E.maybe (E.val 0) examSynchronised (exam' E.?. ExamId) E.+. E.maybe (E.val 0) externalExamSynchronised (externalExam' E.?. ExternalExamId)
queryResults :: E.SqlExpr (E.Value UserId) -> Getter ExamsTableExpr (E.SqlExpr (E.Value Natural)) queryResults :: E.SqlExpr (E.Value UserId) -> Getter ExamsTableExpr (E.SqlExpr (E.Value Word64))
queryResults office = to . runReader $ do queryResults office = to . runReader $ do
exam' <- view queryExam exam' <- view queryExam
externalExam' <- view queryExternalExam externalExam' <- view queryExternalExam
@ -164,9 +164,9 @@ getEOExamsR = do
case (exam, course, school, externalExam) of case (exam, course, school, externalExam) of
(Just exam', Just course', Just school', Nothing) -> (Just exam', Just course', Just school', Nothing) ->
(Right (exam', course', school'),,) <$> view (_5 . _Value) <*> view (_6 . _Value) (Right (exam', course', school'),,) <$> view (_5 . _Value . _Integral) <*> view (_6 . _Value . _Integral)
(Nothing, Nothing, Nothing, Just externalExam') -> (Nothing, Nothing, Nothing, Just externalExam') ->
(Left externalExam',,) <$> view (_5 . _Value) <*> view (_6 . _Value) (Left externalExam',,) <$> view (_5 . _Value . _Integral) <*> view (_6 . _Value . _Integral)
_other -> return $ error "Got exam & externalExam in same result" _other -> return $ error "Got exam & externalExam in same result"

View File

@ -16,7 +16,7 @@ import Data.Maybe (fromJust)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import qualified Database.Esqueleto.Internal.Sql as E (unsafeSqlFunction) import qualified Database.Esqueleto.Internal.Internal as E (unsafeSqlFunction)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map ((!), (!?)) import Data.Map ((!), (!?))

View File

@ -28,7 +28,7 @@ import qualified Data.CaseInsensitive as CI
import Database.Esqueleto.Utils.TH import Database.Esqueleto.Utils.TH
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import qualified Database.Esqueleto.Internal.Language (From) import qualified Database.Esqueleto.Internal.Internal as IE (From)
import Text.Hamlet (ihamletFile) import Text.Hamlet (ihamletFile)
@ -49,7 +49,7 @@ correctionsTableQuery whereClause returnStatement t@((course `E.InnerJoin` sheet
E.where_ $ whereClause t E.where_ $ whereClause t
return $ returnStatement t return $ returnStatement t
lastEditQuery :: Database.Esqueleto.Internal.Language.From (E.SqlExpr (Entity SubmissionEdit)) lastEditQuery :: IE.From (E.SqlExpr (Entity SubmissionEdit))
=> E.SqlExpr (Entity Submission) -> E.SqlExpr (E.Value (Maybe UTCTime)) => E.SqlExpr (Entity Submission) -> E.SqlExpr (E.Value (Maybe UTCTime))
lastEditQuery submission = E.subSelectMaybe $ E.from $ \edit -> do lastEditQuery submission = E.subSelectMaybe $ E.from $ \edit -> do
E.where_ $ edit E.^. SubmissionEditSubmission E.==. submission E.^. SubmissionId E.where_ $ edit E.^. SubmissionEditSubmission E.==. submission E.^. SubmissionId

View File

@ -141,7 +141,7 @@ computeAllocation (Entity allocId Allocation{allocationMatchingSeed}) cRestr = d
return (user, ((allocated, totalCourses - allocated), priority)) return (user, ((allocated, totalCourses - allocated), priority))
) )
& Map.fromList & Map.fromList
cloneCounts = Map.map (view _1) users'' cloneCounts = Map.map (views _1 $ bimap fromIntegral fromIntegral) users''
allocationPrio = view _2 . (Map.!) users'' allocationPrio = view _2 . (Map.!) users''
courses' <- E.select . E.from $ \(allocationCourse `E.InnerJoin` course) -> do courses' <- E.select . E.from $ \(allocationCourse `E.InnerJoin` course) -> do

View File

@ -26,7 +26,7 @@ import qualified Data.CaseInsensitive as CI
import Data.Char (isAlphaNum) import Data.Char (isAlphaNum)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect) import qualified Database.Esqueleto.Internal.Internal as E (SqlSelect)
import Jobs.Queue import Jobs.Queue

View File

@ -21,7 +21,7 @@ import Import
import Database.Persist.Sql (SqlBackendCanRead) import Database.Persist.Sql (SqlBackendCanRead)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import qualified Database.Esqueleto.Internal.Sql as E import qualified Database.Esqueleto.Internal.Internal as E
import Database.Esqueleto.Utils.TH import Database.Esqueleto.Utils.TH
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C

View File

@ -165,9 +165,9 @@ respondFileConditional representationLastModified cType FileReference{..} = do
ByteRangeSpecification f (Just t) -> (min (pred iLength) f, min (pred iLength) t) ByteRangeSpecification f (Just t) -> (min (pred iLength) f, min (pred iLength) t)
ByteRangeSuffixSpecification s -> (iLength - min (pred iLength) s, pred iLength) ByteRangeSuffixSpecification s -> (iLength - min (pred iLength) s, pred iLength)
relevantChunks = view _2 $ foldl' go (0, []) dbManifest'' relevantChunks = view _2 $ foldl' go (0, []) dbManifest''
where go :: (Natural, [(FileContentChunkReference, Natural, Natural)]) where go :: (Word64, [(FileContentChunkReference, Word64, Word64)])
-> (FileContentChunkReference, Natural) -> (FileContentChunkReference, Word64)
-> (Natural, [(FileContentChunkReference, Natural, Natural)]) -> (Word64, [(FileContentChunkReference, Word64, Word64)])
go (lengthBefore, acc) (cChunk, cLength) go (lengthBefore, acc) (cChunk, cLength)
= ( lengthBefore + cLength = ( lengthBefore + cLength
, if , if

View File

@ -3,7 +3,7 @@ module Handler.Utils.Sheet where
import Import import Import
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Internal.Sql as E import qualified Database.Esqueleto.Internal.Internal as E
-- | Map sheet file types to their visibily dates of a given sheet, for convenience -- | Map sheet file types to their visibily dates of a given sheet, for convenience

View File

@ -16,7 +16,7 @@ import Import hiding (link)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E hiding ((->.)) import qualified Database.Esqueleto.Utils as E hiding ((->.))
import qualified Database.Esqueleto.PostgreSQL.JSON as E (JSONBExpr, (->.)) import qualified Database.Esqueleto.PostgreSQL.JSON as E (JSONBExpr, (->.))
import qualified Database.Esqueleto.Internal.Sql as IE import qualified Database.Esqueleto.Internal.Internal as IE
import Database.Esqueleto.Utils (mkExactFilter, mkExactFilterWith, mkContainsFilter, mkContainsFilterWith, anyFilter) import Database.Esqueleto.Utils (mkExactFilter, mkExactFilterWith, mkContainsFilter, mkContainsFilterWith, anyFilter)
import Handler.Utils.Table.Cells import Handler.Utils.Table.Cells

View File

@ -65,7 +65,7 @@ import qualified Yesod.Form.Functions as Yesod
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect,unsafeSqlValue) import qualified Database.Esqueleto.Internal.Internal as E (SqlSelect,unsafeSqlValue)
import qualified Network.Wai as Wai import qualified Network.Wai as Wai

View File

@ -23,7 +23,7 @@ import qualified Data.Map as Map
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Internal.Sql as E import qualified Database.Esqueleto.Internal.Internal as E
{-# ANN module ("HLint: ignore Use newtype instead of data"::String) #-} {-# ANN module ("HLint: ignore Use newtype instead of data"::String) #-}

View File

@ -9,7 +9,7 @@ import Import
import Database.Persist.Sql (SqlBackendCanRead) import Database.Persist.Sql (SqlBackendCanRead)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import qualified Database.Esqueleto.Internal.Sql as E import qualified Database.Esqueleto.Internal.Internal as E
import Database.Esqueleto.Utils.TH import Database.Esqueleto.Utils.TH

View File

@ -10,7 +10,7 @@ import ClassyPrelude.Yesod as Import
, getMessages, addMessage, addMessageI , getMessages, addMessage, addMessageI
, (.=) , (.=)
, MForm , MForm
, Proxy , Proxy(..)
, foldlM , foldlM
, static , static
, boolField, identifyForm, addClass , boolField, identifyForm, addClass

View File

@ -93,7 +93,7 @@ dispatchNotificationAllocationAllocation (otoList -> nAllocations) jRecipient =
dispatchNotificationAllocationUnratedApplications :: Set AllocationId -> UserId -> Handler () dispatchNotificationAllocationUnratedApplications :: Set AllocationId -> UserId -> Handler ()
dispatchNotificationAllocationUnratedApplications (otoList -> nAllocations) jRecipient = do dispatchNotificationAllocationUnratedApplications (otoList -> nAllocations) jRecipient = do
courses <- fmap (nubOn (views _2 entityKey) . over (traverse . _3) E.unValue) . runDB . E.select . E.from $ \(course `E.InnerJoin` allocationCourse `E.InnerJoin` allocation `E.InnerJoin` lecturer) -> do courses <- fmap (nubOn (views _2 entityKey) . over (traverse . _3) (fromIntegral . E.unValue)) . runDB . E.select . E.from $ \(course `E.InnerJoin` allocationCourse `E.InnerJoin` allocation `E.InnerJoin` lecturer) -> do
E.on $ lecturer E.^. LecturerCourse E.==. course E.^. CourseId E.on $ lecturer E.^. LecturerCourse E.==. course E.^. CourseId
E.on $ allocation E.^. AllocationId E.==. allocationCourse E.^. AllocationCourseAllocation E.on $ allocation E.^. AllocationId E.==. allocationCourse E.^. AllocationCourseAllocation
E.on $ allocationCourse E.^. AllocationCourseCourse E.==. course E.^. CourseId E.on $ allocationCourse E.^. AllocationCourseCourse E.==. course E.^. CourseId
@ -102,7 +102,7 @@ dispatchNotificationAllocationUnratedApplications (otoList -> nAllocations) jRec
E.where_ $ allocation E.^. AllocationId `E.in_` E.valList nAllocations E.where_ $ allocation E.^. AllocationId `E.in_` E.valList nAllocations
let let
unratedAppCount :: E.SqlExpr (E.Value Natural) unratedAppCount :: E.SqlExpr (E.Value Word64)
unratedAppCount = E.subSelectCount . E.from $ \application -> unratedAppCount = E.subSelectCount . E.from $ \application ->
E.where_ $ application E.^. CourseApplicationCourse E.==. course E.^. CourseId E.where_ $ application E.^. CourseApplicationCourse E.==. course E.^. CourseId
E.&&. application E.^. CourseApplicationAllocation E.==. E.just (allocation E.^. AllocationId) E.&&. application E.^. CourseApplicationAllocation E.==. E.just (allocation E.^. AllocationId)

View File

@ -44,6 +44,8 @@ deriving newtype instance FromJSONKey UserId
deriving newtype instance ToJSONKey ExamOccurrenceId deriving newtype instance ToJSONKey ExamOccurrenceId
deriving newtype instance FromJSONKey ExamOccurrenceId deriving newtype instance FromJSONKey ExamOccurrenceId
deriving instance Show (Unique ExamPart)
-- ToMarkup and ToMessage instances for displaying selected database primary keys -- ToMarkup and ToMessage instances for displaying selected database primary keys
instance ToMarkup (Key School) where instance ToMarkup (Key School) where

View File

@ -20,7 +20,7 @@ import qualified Data.Map.Strict as Map
import Crypto.Hash (SHAKE128) import Crypto.Hash (SHAKE128)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Internal.Sql as E import qualified Database.Esqueleto.Internal.Internal as E
import qualified Database.Esqueleto.PostgreSQL.JSON as E import qualified Database.Esqueleto.PostgreSQL.JSON as E
import qualified Data.Text as Text import qualified Data.Text as Text

View File

@ -122,12 +122,12 @@ instance Csv.FromField StoredMarkup where
parseField = fmap htmlToStoredMarkup . Csv.parseField parseField = fmap htmlToStoredMarkup . Csv.parseField
instance PersistField StoredMarkup where instance PersistField StoredMarkup where
fromPersistValue (PersistDbSpecific bs) = first pack $ Aeson.eitherDecodeStrict' bs fromPersistValue (PersistLiteralEscaped bs) = first pack $ Aeson.eitherDecodeStrict' bs
fromPersistValue (PersistByteString bs) = first pack $ Aeson.eitherDecodeStrict' bs fromPersistValue (PersistByteString bs) = first pack $ Aeson.eitherDecodeStrict' bs
<|> bimap show preEscapedToStoredMarkup (decodeUtf8' bs) <|> bimap show preEscapedToStoredMarkup (decodeUtf8' bs)
fromPersistValue (PersistText t) = first pack $ Aeson.eitherDecodeStrict' (encodeUtf8 t) fromPersistValue (PersistText t) = first pack $ Aeson.eitherDecodeStrict' (encodeUtf8 t)
<|> return (preEscapedToStoredMarkup t) <|> return (preEscapedToStoredMarkup t)
fromPersistValue _ = Left "StoredMarkup values must be converted from PersistDbSpecific, PersistText, or PersistByteString" fromPersistValue x = Left $ fromPersistValueErrorSql (Proxy @StoredMarkup) x
toPersistValue = PersistDbSpecific . LBS.toStrict . Aeson.encode toPersistValue = PersistLiteralEscaped . LBS.toStrict . Aeson.encode
instance PersistFieldSql StoredMarkup where instance PersistFieldSql StoredMarkup where
sqlType _ = SqlOther "jsonb" sqlType _ = SqlOther "jsonb"

View File

@ -1,6 +1,6 @@
module Model.Types.TH.JSON where module Model.Types.TH.JSON where
import ClassyPrelude.Yesod hiding (derivePersistFieldJSON, toPersistValueJSON, fromPersistValueJSON) import ClassyPrelude.Yesod hiding (derivePersistFieldJSON, toPersistValueJSON, fromPersistValueJSON, Proxy(..))
import Data.List (foldl) import Data.List (foldl)
import Database.Persist.Sql hiding (toPersistValueJSON, fromPersistValueJSON) import Database.Persist.Sql hiding (toPersistValueJSON, fromPersistValueJSON)
@ -14,16 +14,19 @@ import Language.Haskell.TH.Datatype
import Utils.PathPiece import Utils.PathPiece
import Utils.Persist
import Data.Proxy
toPersistValueJSON :: ToJSON a => a -> PersistValue toPersistValueJSON :: ToJSON a => a -> PersistValue
toPersistValueJSON = PersistDbSpecific . LBS.toStrict . JSON.encode toPersistValueJSON = PersistLiteralEscaped . LBS.toStrict . JSON.encode
fromPersistValueJSON :: FromJSON a => PersistValue -> Either Text a fromPersistValueJSON :: forall a. (FromJSON a, PersistFieldSql a, Typeable a) => PersistValue -> Either Text a
fromPersistValueJSON = \case fromPersistValueJSON = \case
PersistDbSpecific bs -> decodeBS bs PersistLiteralEscaped bs -> decodeBS bs
PersistByteString bs -> decodeBS bs PersistByteString bs -> decodeBS bs
PersistText text -> decodeBS $ Text.encodeUtf8 text PersistText text -> decodeBS $ Text.encodeUtf8 text
_other -> Left "JSON values must be converted from PersistDbSpecific, PersistText, or PersistByteString" x -> Left $ fromPersistValueErrorSql (Proxy @a) x
where decodeBS = first pack . JSON.eitherDecodeStrict' where decodeBS = first pack . JSON.eitherDecodeStrict'
{-# SCC fromPersistValueJSON #-} {-# SCC fromPersistValueJSON #-}
@ -38,7 +41,7 @@ derivePersistFieldJSON tName = do
let t = foldl (\t' n' -> t' `appT` varT n') (conT tName) vars let t = foldl (\t' n' -> t' `appT` varT n') (conT tName) vars
iCxt iCxt
| null vars = cxt [] | null vars = cxt []
| otherwise = cxt [[t|ToJSON|] `appT` t, [t|FromJSON|] `appT` t] | otherwise = cxt [[t|ToJSON|] `appT` t, [t|FromJSON|] `appT` t, [t|Typeable|] `appT` t]
sqlCxt sqlCxt
| null vars = cxt [] | null vars = cxt []
| otherwise = cxt [[t|PersistField|] `appT` t] | otherwise = cxt [[t|PersistField|] `appT` t]

View File

@ -38,11 +38,11 @@ derivePersistFieldPathPiece' sType tName = do
clause [[p|PersistByteString $(varP bs)|]] (normalB [e|maybe (Left "Could not decode PathPiece from PersistByteString") Right $ fromPathPiece =<< either (const Nothing) Just (Text.decodeUtf8' $(varE bs))|]) [] clause [[p|PersistByteString $(varP bs)|]] (normalB [e|maybe (Left "Could not decode PathPiece from PersistByteString") Right $ fromPathPiece =<< either (const Nothing) Just (Text.decodeUtf8' $(varE bs))|]) []
, do , do
bs <- newName "bs" bs <- newName "bs"
clause [[p|PersistDbSpecific $(varP bs)|]] (normalB [e|maybe (Left "Could not decode PathPiece from PersistDbSpecific") Right $ fromPathPiece =<< either (const Nothing) Just (Text.decodeUtf8' $(varE bs))|]) [] clause [[p|PersistLiteralEscaped $(varP bs)|]] (normalB [e|maybe (Left "Could not decode PathPiece from PersistLiteralEscaped") Right $ fromPathPiece =<< either (const Nothing) Just (Text.decodeUtf8' $(varE bs))|]) []
, do , do
text <- newName "text" text <- newName "text"
clause [[p|PersistText $(varP text)|]] (normalB [e|maybe (Left "Could not decode PathPiece from PersistText") Right $ fromPathPiece $(varE text)|]) [] clause [[p|PersistText $(varP text)|]] (normalB [e|maybe (Left "Could not decode PathPiece from PersistText") Right $ fromPathPiece $(varE text)|]) []
, clause [wildP] (normalB [e|Left "PathPiece values must be converted from PersistText, PersistByteString, or PersistDbSpecific"|]) [] , clause [wildP] (normalB [e|Left "PathPiece values must be converted from PersistText, PersistByteString, or PersistLiteralEscaped"|]) []
] ]
] ]
, instanceD sqlCxt ([t|PersistFieldSql|] `appT` t) , instanceD sqlCxt ([t|PersistFieldSql|] `appT` t)

View File

@ -966,11 +966,13 @@ instance ( ToJSON fileid, ToJSON userid
instance ( ToJSON termid, ToJSON schoolid, ToJSON courseid instance ( ToJSON termid, ToJSON schoolid, ToJSON courseid
, FromJSON termid, FromJSON schoolid, FromJSON courseid , FromJSON termid, FromJSON schoolid, FromJSON courseid
, Typeable termid, Typeable schoolid, Typeable courseid
) => PersistField (WorkflowScope termid schoolid courseid) where ) => PersistField (WorkflowScope termid schoolid courseid) where
toPersistValue = toPersistValueJSON toPersistValue = toPersistValueJSON
fromPersistValue = fromPersistValueJSON fromPersistValue = fromPersistValueJSON
instance ( ToJSON termid, ToJSON schoolid, ToJSON courseid instance ( ToJSON termid, ToJSON schoolid, ToJSON courseid
, FromJSON termid, FromJSON schoolid, FromJSON courseid , FromJSON termid, FromJSON schoolid, FromJSON courseid
, Typeable termid, Typeable schoolid, Typeable courseid
) => PersistFieldSql (WorkflowScope termid schoolid courseid) where ) => PersistFieldSql (WorkflowScope termid schoolid courseid) where
sqlType _ = sqlTypeJSON sqlType _ = sqlTypeJSON

View File

@ -14,13 +14,16 @@ import Database.Persist.Sql
import qualified Data.Text.Encoding as Text import qualified Data.Text.Encoding as Text
import Utils.Persist
import Data.Proxy
instance PersistField IP where instance PersistField IP where
toPersistValue = PersistDbSpecific . Textual.toUtf8 toPersistValue = PersistLiteralEscaped . Textual.toUtf8
fromPersistValue (PersistDbSpecific bs) = first tshow (Text.decodeUtf8' bs) >>= maybe (Left "Could not parse IP-address") Right . Textual.fromText fromPersistValue (PersistLiteralEscaped bs) = first tshow (Text.decodeUtf8' bs) >>= maybe (Left "Could not parse IP-address") Right . Textual.fromText
fromPersistValue (PersistByteString bs) = first tshow (Text.decodeUtf8' bs) >>= maybe (Left "Could not parse IP-address") Right . Textual.fromText fromPersistValue (PersistByteString bs) = first tshow (Text.decodeUtf8' bs) >>= maybe (Left "Could not parse IP-address") Right . Textual.fromText
fromPersistValue (PersistText t) = maybe (Left "Could not parse IP-address") Right $ Textual.fromText t fromPersistValue (PersistText t) = maybe (Left "Could not parse IP-address") Right $ Textual.fromText t
fromPersistValue _ = Left "IP-address values must be converted from PersistDbSpecific, PersistText, or PersistByteString" fromPersistValue x = Left $ fromPersistValueErrorSql (Proxy @IP) x
instance PersistFieldSql IP where instance PersistFieldSql IP where
sqlType _ = SqlOther "inet" sqlType _ = SqlOther "inet"

View File

@ -34,6 +34,7 @@ import Utils.Csv as Utils
import Utils.I18n as Utils import Utils.I18n as Utils
import Utils.NTop as Utils import Utils.NTop as Utils
import Utils.HttpConditional as Utils import Utils.HttpConditional as Utils
import Utils.Persist as Utils
import Text.Blaze (Markup, ToMarkup) import Text.Blaze (Markup, ToMarkup)

View File

@ -60,9 +60,10 @@ existsKey :: (PersistRecordBackend record backend, PersistQueryRead backend, Mon
=> Key record -> ReaderT backend m Bool => Key record -> ReaderT backend m Bool
existsKey = exists . pure . (persistIdField ==.) existsKey = exists . pure . (persistIdField ==.)
exists :: (PersistRecordBackend record backend, PersistQueryRead backend, MonadIO m) -- -- Available in persistent since 2.11.0.0
=> [Filter record] -> ReaderT backend m Bool -- exists :: (PersistRecordBackend record backend, PersistQueryRead backend, MonadIO m)
exists = fmap (not . null) . flip selectKeysList [LimitTo 1] -- => [Filter record] -> ReaderT backend m Bool
-- exists = fmap (not . null) . flip selectKeysList [LimitTo 1]
exists404 :: (PersistRecordBackend record backend, PersistQueryRead backend, MonadHandler m) exists404 :: (PersistRecordBackend record backend, PersistQueryRead backend, MonadHandler m)
=> [Filter record] -> ReaderT backend m () => [Filter record] -> ReaderT backend m ()

View File

@ -26,7 +26,6 @@ import Web.HttpApiData
import qualified Data.Attoparsec.Text as A import qualified Data.Attoparsec.Text as A
import Data.Char (chr, ord) import Data.Char (chr, ord)
import Numeric.Natural
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.CaseInsensitive (CI) import Data.CaseInsensitive (CI)
@ -77,11 +76,11 @@ newtype ByteRangesSpecifier = ByteRangesSpecifier (NonNull (Set ByteRangeSpecifi
deriving (Eq, Ord, Read, Show, Generic, Typeable) deriving (Eq, Ord, Read, Show, Generic, Typeable)
data ByteRangeSpecification data ByteRangeSpecification
= ByteRangeSpecification = ByteRangeSpecification
{ byteRangeSpecFirstPosition :: Natural { byteRangeSpecFirstPosition :: Word64
, byteRangeSpecLastPosition :: Maybe Natural , byteRangeSpecLastPosition :: Maybe Word64
} }
| ByteRangeSuffixSpecification | ByteRangeSuffixSpecification
{ byteRangeSpecSuffixLength :: Natural { byteRangeSpecSuffixLength :: Word64
} }
deriving (Eq, Ord, Read, Show, Generic, Typeable) deriving (Eq, Ord, Read, Show, Generic, Typeable)
@ -106,12 +105,12 @@ instance FromHttpApiData ByteRangesSpecifier where
data ByteContentRangeSpecification data ByteContentRangeSpecification
= ByteContentRangeSpecification = ByteContentRangeSpecification
{ byteRangeResponse :: Maybe ByteRangeResponseSpecification { byteRangeResponse :: Maybe ByteRangeResponseSpecification
, byteRangeInstanceLength :: Maybe Natural , byteRangeInstanceLength :: Maybe Word64
} deriving (Eq, Ord, Read, Show, Generic, Typeable) } deriving (Eq, Ord, Read, Show, Generic, Typeable)
data ByteRangeResponseSpecification data ByteRangeResponseSpecification
= ByteRangeResponseSpecification = ByteRangeResponseSpecification
{ byteRangeResponseSpecFirstPosition { byteRangeResponseSpecFirstPosition
, byteRangeResponseSpecLastPosition :: Natural , byteRangeResponseSpecLastPosition :: Word64
} deriving (Eq, Ord, Read, Show, Generic, Typeable) } deriving (Eq, Ord, Read, Show, Generic, Typeable)
instance ToHttpApiData ByteContentRangeSpecification where instance ToHttpApiData ByteContentRangeSpecification where
@ -129,7 +128,7 @@ class (FromHttpApiData req, ToHttpApiData resp, Ord (SingularRangeSpecification
default _RangeSpecifications :: Coercible req (NonNull (Set (SingularRangeSpecification req))) default _RangeSpecifications :: Coercible req (NonNull (Set (SingularRangeSpecification req)))
=> Iso' req (NonNull (Set (SingularRangeSpecification req))) => Iso' req (NonNull (Set (SingularRangeSpecification req)))
_RangeSpecifications = coerced _RangeSpecifications = coerced
rangeInstanceLength :: resp -> Maybe Natural rangeInstanceLength :: resp -> Maybe Word64
rangeInstanceLength _ = Nothing rangeInstanceLength _ = Nothing
instance IsRangeUnit ByteRangesSpecifier ByteContentRangeSpecification where instance IsRangeUnit ByteRangesSpecifier ByteContentRangeSpecification where

View File

@ -78,6 +78,9 @@ _SqlKey' = iso fromSqlKey toSqlKey
_SqlKey :: ToBackendKey SqlBackend record => Iso' (Key record) SqlBackendKey _SqlKey :: ToBackendKey SqlBackend record => Iso' (Key record) SqlBackendKey
_SqlKey = _SqlKey' . _Unwrapped _SqlKey = _SqlKey' . _Unwrapped
_Integral :: (Integral a, Integral b) => Iso' a b
_Integral = iso fromIntegral fromIntegral
----------------------------------- -----------------------------------
-- Lens Definitions for our Types -- Lens Definitions for our Types

35
src/Utils/Persist.hs Normal file
View File

@ -0,0 +1,35 @@
module Utils.Persist
( fromPersistValueError
, fromPersistValueErrorSql
) where
import ClassyPrelude
import Database.Persist
import Database.Persist.Sql
import Data.Proxy
import Type.Reflection (typeRep)
fromPersistValueError :: Text -- ^ Haskell type
-> Text -- ^ Database type
-> PersistValue -- ^ Incorrect value
-> Text -- ^ Error Message
fromPersistValueError hType dbType received = mconcat
[ "Failed to parse Haskell type `"
, hType
, "`; expected "
, dbType
, " from database, but received: "
, tshow received
, "."
]
fromPersistValueErrorSql :: forall p a.
( PersistFieldSql a
, Typeable a
)
=> p a
-> PersistValue
-> Text
fromPersistValueErrorSql _ = fromPersistValueError (tshow $ typeRep @a) (tshow $ sqlType (Proxy @a))

View File

@ -62,28 +62,22 @@ extra-deps:
- git: git@gitlab2.rz.ifi.lmu.de:uni2work/zip-stream.git - git: git@gitlab2.rz.ifi.lmu.de:uni2work/zip-stream.git
commit: 843683d024f767de236f74d24a3348f69181a720 commit: 843683d024f767de236f74d24a3348f69181a720
- classy-prelude-yesod-1.5.0@sha256:8f7e183bdfd6d2ea9674284c4f285294ab086aff60d9be4e5d7d2f3c1a2b05b7,1330
- acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207 - acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207
- commonmark-0.1.0.2@sha256:fbff7a2ade0ce7d699964a87f765e503a3a9e22542c05f0f02ba7aad64e38af4,3278 - commonmark-0.1.1.2@sha256:c06ab05f0f224ab7982502a96e17952823a9b6dae8505fb35194b0baa9e2a975,3278
- commonmark-extensions-0.2.0.1@sha256:647aa8dba5fd46984ddedc15c3693c9c4d9655503d42006576bd8f0dadf8cd39,3176 - commonmark-extensions-0.2.0.4@sha256:6a437bcfa3c757af4262b71336513619990eafb5cfdc33e57a499c93ad225608,3184
- commonmark-pandoc-0.2.0.0@sha256:84a9f6846d4fe33e9f0dcd938ef1c83162fb4fe81cca66315249e86414aac226,1167 - commonmark-pandoc-0.2.0.1@sha256:529c6e2c6cabf61558b66a28123eafc1d90d3324be29819f59f024e430312c1f,1105
- hlibsass-0.1.10.1@sha256:08db56c633e9a83a642d8ea57dffa93112b092d05bf8f3b07491cfee9ee0dfa5,2565
- hlint-test-0.1.0.0@sha256:e427c0593433205fc629fb05b74c6b1deb1de72d1571f26142de008f0d5ee7a9,1814
- hsass-0.8.0@sha256:05fb3d435dbdf9f66a98db4e1ee57a313170a677e52ab3a5a05ced1fc42b0834,2899
- normaldistribution-1.1.0.3@sha256:2615b784c4112cbf6ffa0e2b55b76790290a9b9dff18a05d8c89aa374b213477,2160 - normaldistribution-1.1.0.3@sha256:2615b784c4112cbf6ffa0e2b55b76790290a9b9dff18a05d8c89aa374b213477,2160
- pandoc-2.10.1@sha256:23d7ec480c7cb86740475a419d6ca4819987b6dd23bbae9b50bc3d42a7ed2f9f,36933 - pandoc-2.11.1.1@sha256:33a2092e86dc6c8cb9041b5b9bb12faa08c8508954815c79f1a4dfe240f5b499,39390
- citeproc-0.1.1.1@sha256:c03ab98aeceda7770eec3eb76f5e95a98e4908ba7c1cb3b43ff482e876b17456,5395
- pkcs7-1.0.0.1@sha256:b26e5181868667abbde3ce17f9a61cf705eb695da073cdf82e1f9dfd6cc11176,3594 - pkcs7-1.0.0.1@sha256:b26e5181868667abbde3ce17f9a61cf705eb695da073cdf82e1f9dfd6cc11176,3594
- prometheus-metrics-ghc-1.0.1.1@sha256:d378a7186a967140fe0e09d325fe5e3bfd7b77a1123934b40f81fdfed2eacbdc,1233 - prometheus-metrics-ghc-1.0.1.1@sha256:d378a7186a967140fe0e09d325fe5e3bfd7b77a1123934b40f81fdfed2eacbdc,1233
- system-locale-0.3.0.0@sha256:13b3982403d8ac8cc6138e68802be8d8e7cf7ebc4cbc7e47e99e3c0dd1be066a,1529 - system-locale-0.3.0.0@sha256:13b3982403d8ac8cc6138e68802be8d8e7cf7ebc4cbc7e47e99e3c0dd1be066a,1529
- token-bucket-0.1.0.1@sha256:d8e85f2fc373939975e7ace7907baee177531ab6e43df94e330a2357e64a2d11,1899 - token-bucket-0.1.0.1@sha256:d8e85f2fc373939975e7ace7907baee177531ab6e43df94e330a2357e64a2d11,1899
- tz-0.1.3.4@sha256:bd311e202b8bdd15bcd6a4ca182e69794949d3b3b9f4aa835e9ccff011284979,5086 - tz-0.1.3.5@sha256:fb17ca50a7d943e511c0ca70342dc83f66aa2532de2745632f1f5f9b1ad783c4,5086
- unidecode-0.1.0.4@sha256:99581ee1ea334a4596a09ae3642e007808457c66893b587e965b31f15cbf8c4d,1144 - unidecode-0.1.0.4@sha256:99581ee1ea334a4596a09ae3642e007808457c66893b587e965b31f15cbf8c4d,1144
- wai-middleware-prometheus-1.0.0@sha256:1625792914fb2139f005685be8ce519111451cfb854816e430fbf54af46238b4,1314 - wai-middleware-prometheus-1.0.0@sha256:1625792914fb2139f005685be8ce519111451cfb854816e430fbf54af46238b4,1314
- primitive-0.7.1.0@sha256:6a237bb338bcc43193077ff8e8c0f0ce2de14c652231496a15672e8b563a07e2,2604
- aeson-1.5.3.0@sha256:05496710de6ae694e55dc77dbdaf7503f56c24e4aecc06045e42e75a02df8bc4,6906
- data-fix-0.3.0@sha256:058a266d1e658500e0ffb8babe68195b0ce06a081dcfc3814afc784b083fd9a5,1645
- strict-0.4@sha256:1b50c7c9c636c3a1bbc7f8873b9be48f6ca0faca4df6eec6a014de6208fb1c0e,4200
- network-arbitrary-0.6.0.0@sha256:a7034d63295dfc41cf559ee705fc95cac9a9a01b4715300f590eaa237b5ffd48,2506
resolver: nightly-2020-08-08 resolver: nightly-2021-01-11
compiler: ghc-8.10.2 compiler: ghc-8.10.3
allow-newer: true allow-newer: true

View File

@ -233,6 +233,13 @@ packages:
original: original:
git: git@gitlab2.rz.ifi.lmu.de:uni2work/zip-stream.git git: git@gitlab2.rz.ifi.lmu.de:uni2work/zip-stream.git
commit: 843683d024f767de236f74d24a3348f69181a720 commit: 843683d024f767de236f74d24a3348f69181a720
- completed:
hackage: classy-prelude-yesod-1.5.0@sha256:8f7e183bdfd6d2ea9674284c4f285294ab086aff60d9be4e5d7d2f3c1a2b05b7,1330
pantry-tree:
size: 330
sha256: ae84d4cc0e1daf985db6cdcf2ac92319531b8e60f547183cc46480d00aafbe20
original:
hackage: classy-prelude-yesod-1.5.0@sha256:8f7e183bdfd6d2ea9674284c4f285294ab086aff60d9be4e5d7d2f3c1a2b05b7,1330
- completed: - completed:
hackage: acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207 hackage: acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207
pantry-tree: pantry-tree:
@ -241,47 +248,26 @@ packages:
original: original:
hackage: acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207 hackage: acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207
- completed: - completed:
hackage: commonmark-0.1.0.2@sha256:fbff7a2ade0ce7d699964a87f765e503a3a9e22542c05f0f02ba7aad64e38af4,3278 hackage: commonmark-0.1.1.2@sha256:c06ab05f0f224ab7982502a96e17952823a9b6dae8505fb35194b0baa9e2a975,3278
pantry-tree: pantry-tree:
size: 1346 size: 1346
sha256: 991da6da60804286b9ea23a1522e18ceeabddfdf416787231db9fd047c163f53 sha256: 6a187bbbfaf61b4b1bf87ee5027e7edb5b7157ad3380982b07b876e9a60cd63d
original: original:
hackage: commonmark-0.1.0.2@sha256:fbff7a2ade0ce7d699964a87f765e503a3a9e22542c05f0f02ba7aad64e38af4,3278 hackage: commonmark-0.1.1.2@sha256:c06ab05f0f224ab7982502a96e17952823a9b6dae8505fb35194b0baa9e2a975,3278
- completed: - completed:
hackage: commonmark-extensions-0.2.0.1@sha256:647aa8dba5fd46984ddedc15c3693c9c4d9655503d42006576bd8f0dadf8cd39,3176 hackage: commonmark-extensions-0.2.0.4@sha256:6a437bcfa3c757af4262b71336513619990eafb5cfdc33e57a499c93ad225608,3184
pantry-tree: pantry-tree:
size: 2927 size: 2928
sha256: 89e1ee05938d558834c397a3a22cdacc755a1941c144f4c1f3daf8a1ede943ce sha256: ac8993e356edabc65a40d6c6909696c5f2dfe2a5298089da820c29ca75852360
original: original:
hackage: commonmark-extensions-0.2.0.1@sha256:647aa8dba5fd46984ddedc15c3693c9c4d9655503d42006576bd8f0dadf8cd39,3176 hackage: commonmark-extensions-0.2.0.4@sha256:6a437bcfa3c757af4262b71336513619990eafb5cfdc33e57a499c93ad225608,3184
- completed: - completed:
hackage: commonmark-pandoc-0.2.0.0@sha256:84a9f6846d4fe33e9f0dcd938ef1c83162fb4fe81cca66315249e86414aac226,1167 hackage: commonmark-pandoc-0.2.0.1@sha256:529c6e2c6cabf61558b66a28123eafc1d90d3324be29819f59f024e430312c1f,1105
pantry-tree: pantry-tree:
size: 326 size: 326
sha256: aa88fb10bd382b8d942b51b2ad0b94f52a72a4e37c8085abc5c380964c7eeb7c sha256: d9954a15f73c8fe55a5097e1cc0957fa626d340ef36e2beefb8caae66008c3dc
original: original:
hackage: commonmark-pandoc-0.2.0.0@sha256:84a9f6846d4fe33e9f0dcd938ef1c83162fb4fe81cca66315249e86414aac226,1167 hackage: commonmark-pandoc-0.2.0.1@sha256:529c6e2c6cabf61558b66a28123eafc1d90d3324be29819f59f024e430312c1f,1105
- completed:
hackage: hlibsass-0.1.10.1@sha256:08db56c633e9a83a642d8ea57dffa93112b092d05bf8f3b07491cfee9ee0dfa5,2565
pantry-tree:
size: 11229
sha256: 39b62f1f3f30c5a9e12f9c6a040d6863edb5ce81951452e649152a18145ee1bc
original:
hackage: hlibsass-0.1.10.1@sha256:08db56c633e9a83a642d8ea57dffa93112b092d05bf8f3b07491cfee9ee0dfa5,2565
- completed:
hackage: hlint-test-0.1.0.0@sha256:e427c0593433205fc629fb05b74c6b1deb1de72d1571f26142de008f0d5ee7a9,1814
pantry-tree:
size: 442
sha256: 347eac6c8a3c02fc0101444d6526b57b3c27785809149b12f90d8db57c721fea
original:
hackage: hlint-test-0.1.0.0@sha256:e427c0593433205fc629fb05b74c6b1deb1de72d1571f26142de008f0d5ee7a9,1814
- completed:
hackage: hsass-0.8.0@sha256:05fb3d435dbdf9f66a98db4e1ee57a313170a677e52ab3a5a05ced1fc42b0834,2899
pantry-tree:
size: 1448
sha256: b25aeb947cb4e0b550f8a6f226d06503ef0edcb54712ad9cdd4fb2b05bf16c7c
original:
hackage: hsass-0.8.0@sha256:05fb3d435dbdf9f66a98db4e1ee57a313170a677e52ab3a5a05ced1fc42b0834,2899
- completed: - completed:
hackage: normaldistribution-1.1.0.3@sha256:2615b784c4112cbf6ffa0e2b55b76790290a9b9dff18a05d8c89aa374b213477,2160 hackage: normaldistribution-1.1.0.3@sha256:2615b784c4112cbf6ffa0e2b55b76790290a9b9dff18a05d8c89aa374b213477,2160
pantry-tree: pantry-tree:
@ -290,12 +276,19 @@ packages:
original: original:
hackage: normaldistribution-1.1.0.3@sha256:2615b784c4112cbf6ffa0e2b55b76790290a9b9dff18a05d8c89aa374b213477,2160 hackage: normaldistribution-1.1.0.3@sha256:2615b784c4112cbf6ffa0e2b55b76790290a9b9dff18a05d8c89aa374b213477,2160
- completed: - completed:
hackage: pandoc-2.10.1@sha256:23d7ec480c7cb86740475a419d6ca4819987b6dd23bbae9b50bc3d42a7ed2f9f,36933 hackage: pandoc-2.11.1.1@sha256:33a2092e86dc6c8cb9041b5b9bb12faa08c8508954815c79f1a4dfe240f5b499,39390
pantry-tree: pantry-tree:
size: 89646 size: 114305
sha256: 08c8b20356152b9ee8161bacafda2dc1bed13d7db4cbf38ab040c1977b2d28d5 sha256: e905129cec9cabaace47ce95a7bbdc6553bf61931f99c76df0e1fef6bbe9973d
original: original:
hackage: pandoc-2.10.1@sha256:23d7ec480c7cb86740475a419d6ca4819987b6dd23bbae9b50bc3d42a7ed2f9f,36933 hackage: pandoc-2.11.1.1@sha256:33a2092e86dc6c8cb9041b5b9bb12faa08c8508954815c79f1a4dfe240f5b499,39390
- completed:
hackage: citeproc-0.1.1.1@sha256:c03ab98aeceda7770eec3eb76f5e95a98e4908ba7c1cb3b43ff482e876b17456,5395
pantry-tree:
size: 78399
sha256: 306f732ddb5aae7c87f459108c9ecbfd7622a9a7156264d6a3da7ce75b0db56b
original:
hackage: citeproc-0.1.1.1@sha256:c03ab98aeceda7770eec3eb76f5e95a98e4908ba7c1cb3b43ff482e876b17456,5395
- completed: - completed:
hackage: pkcs7-1.0.0.1@sha256:b26e5181868667abbde3ce17f9a61cf705eb695da073cdf82e1f9dfd6cc11176,3594 hackage: pkcs7-1.0.0.1@sha256:b26e5181868667abbde3ce17f9a61cf705eb695da073cdf82e1f9dfd6cc11176,3594
pantry-tree: pantry-tree:
@ -325,12 +318,12 @@ packages:
original: original:
hackage: token-bucket-0.1.0.1@sha256:d8e85f2fc373939975e7ace7907baee177531ab6e43df94e330a2357e64a2d11,1899 hackage: token-bucket-0.1.0.1@sha256:d8e85f2fc373939975e7ace7907baee177531ab6e43df94e330a2357e64a2d11,1899
- completed: - completed:
hackage: tz-0.1.3.4@sha256:bd311e202b8bdd15bcd6a4ca182e69794949d3b3b9f4aa835e9ccff011284979,5086 hackage: tz-0.1.3.5@sha256:fb17ca50a7d943e511c0ca70342dc83f66aa2532de2745632f1f5f9b1ad783c4,5086
pantry-tree: pantry-tree:
size: 1179 size: 1179
sha256: f6b8517eaaf3588afd1b3025fe6874a1ffff611001a803a26094c9cb40bc33f6 sha256: 6482698ea1b1a93bd684fca35836b35e8cdf53fe51b0fa6b215afa7da1f983a6
original: original:
hackage: tz-0.1.3.4@sha256:bd311e202b8bdd15bcd6a4ca182e69794949d3b3b9f4aa835e9ccff011284979,5086 hackage: tz-0.1.3.5@sha256:fb17ca50a7d943e511c0ca70342dc83f66aa2532de2745632f1f5f9b1ad783c4,5086
- completed: - completed:
hackage: unidecode-0.1.0.4@sha256:99581ee1ea334a4596a09ae3642e007808457c66893b587e965b31f15cbf8c4d,1144 hackage: unidecode-0.1.0.4@sha256:99581ee1ea334a4596a09ae3642e007808457c66893b587e965b31f15cbf8c4d,1144
pantry-tree: pantry-tree:
@ -345,44 +338,9 @@ packages:
sha256: 6d64803c639ed4c7204ea6fab0536b97d3ee16cdecb9b4a883cd8e56d3c61402 sha256: 6d64803c639ed4c7204ea6fab0536b97d3ee16cdecb9b4a883cd8e56d3c61402
original: original:
hackage: wai-middleware-prometheus-1.0.0@sha256:1625792914fb2139f005685be8ce519111451cfb854816e430fbf54af46238b4,1314 hackage: wai-middleware-prometheus-1.0.0@sha256:1625792914fb2139f005685be8ce519111451cfb854816e430fbf54af46238b4,1314
- completed:
hackage: primitive-0.7.1.0@sha256:6a237bb338bcc43193077ff8e8c0f0ce2de14c652231496a15672e8b563a07e2,2604
pantry-tree:
size: 1376
sha256: 924e88629b493abb6b2f3c3029cef076554a2b627091e3bb6887ec03487a707d
original:
hackage: primitive-0.7.1.0@sha256:6a237bb338bcc43193077ff8e8c0f0ce2de14c652231496a15672e8b563a07e2,2604
- completed:
hackage: aeson-1.5.3.0@sha256:05496710de6ae694e55dc77dbdaf7503f56c24e4aecc06045e42e75a02df8bc4,6906
pantry-tree:
size: 39759
sha256: 6290ffac2ea3e52b57d869306d12dbf32c07d17099f695f035ff7f756677831d
original:
hackage: aeson-1.5.3.0@sha256:05496710de6ae694e55dc77dbdaf7503f56c24e4aecc06045e42e75a02df8bc4,6906
- completed:
hackage: data-fix-0.3.0@sha256:058a266d1e658500e0ffb8babe68195b0ce06a081dcfc3814afc784b083fd9a5,1645
pantry-tree:
size: 261
sha256: 6cf43af344624e087dbe2f1e96e985de6142e85bb02db8449df6d72bee3c1013
original:
hackage: data-fix-0.3.0@sha256:058a266d1e658500e0ffb8babe68195b0ce06a081dcfc3814afc784b083fd9a5,1645
- completed:
hackage: strict-0.4@sha256:1b50c7c9c636c3a1bbc7f8873b9be48f6ca0faca4df6eec6a014de6208fb1c0e,4200
pantry-tree:
size: 654
sha256: fdf523b8990567d69277b999d68d492ed0b3a98a89b1acdfb3087e3b95eb9908
original:
hackage: strict-0.4@sha256:1b50c7c9c636c3a1bbc7f8873b9be48f6ca0faca4df6eec6a014de6208fb1c0e,4200
- completed:
hackage: network-arbitrary-0.6.0.0@sha256:a7034d63295dfc41cf559ee705fc95cac9a9a01b4715300f590eaa237b5ffd48,2506
pantry-tree:
size: 915
sha256: 97b797944cf068eb5fde620e005e253818f03068b2c20e9cfdd3aaa6cafcb678
original:
hackage: network-arbitrary-0.6.0.0@sha256:a7034d63295dfc41cf559ee705fc95cac9a9a01b4715300f590eaa237b5ffd48,2506
snapshots: snapshots:
- completed: - completed:
size: 524392 size: 562265
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2020/8/8.yaml url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2021/1/11.yaml
sha256: 21b78cd42414558e6e381666a51ab92b405f969ab1d675137fd55ef557edc9a4 sha256: fbfadbcb74451699985d24e0f5bb56bac60b1fe05db553f09d94c724623fc826
original: nightly-2020-08-08 original: nightly-2021-01-11