bdcs-0.1.0: src/BDCS/Sources.hs
{-# LANGUAGE RecordWildCards #-}
-- |
-- Module: BDCS.Sources
-- Copyright: (c) 2016-2017 Red Hat, Inc.
-- License: LGPL
--
-- Maintainer: https://github.com/weldr
-- Stability: alpha
-- Portability: portable
--
-- Manage 'Sources' records in the database. This record keeps track of a single
-- software release of a single project. A single project can make many releases,
-- each of which will require a separate 'Sources' record.
module BDCS.Sources(findSource,
getSource,
insertSource,
insertSourceKeyValue)
where
import Control.Monad.IO.Class(MonadIO)
import qualified Data.Text as T
import Database.Esqueleto
import BDCS.DB
import BDCS.KeyType
import BDCS.KeyValue(findKeyValue)
-- | Given a version number and a key to a 'Projects' record, find a matching software
-- source in the database. If it exists, the database key is returned.
findSource :: MonadIO m => T.Text -> Key Projects -> SqlPersistT m (Maybe (Key Sources))
findSource version projectId = firstKeyResult $
-- FIXME: Is (project_id, version) unique in Sources?
select $ from $ \src -> do
where_ $ src ^. SourcesProject_id ==. val projectId &&.
src ^. SourcesVersion ==. val version
limit 1
return $ src ^. SourcesId
-- | Given a key to a 'Sources' record in the database, return that record. This function
-- is suitable for using on the result of 'findSource'.
getSource :: MonadIO m => Key Sources -> SqlPersistT m (Maybe Sources)
getSource key = firstEntityResult $
select $ from $ \source -> do
where_ $ source ^. SourcesId ==. val key
limit 1
return source
-- | Conditionally add a new 'Sources' record to the database. If the record already exists,
-- return its key. Otherwise, insert the record and return the new key.
insertSource :: MonadIO m => Sources -> SqlPersistT m (Key Sources)
insertSource source@Sources{..} =
findSource sourcesVersion sourcesProject_id `orInsert` source
-- | Conditionally add a new 'KeyVal' record to the database and associate a 'Sources'
-- record with it. If the 'KeyVal' record already exists, it is reused in creating the
-- association. They database key of the association is returned.
--
-- A single source can potentially have zero or more 'KeyVal' paris associated with it.
-- On the other hand, a single 'KeyVal' pair can apply to many sources.
insertSourceKeyValue :: MonadIO m =>
KeyType -- ^ Type of the 'KeyVal'
-> T.Text -- ^ Value of the 'KeyVal'
-> Maybe T.Text -- ^ Extended value of the 'KeyVal'
-> Key Sources -- ^ Source to be associated with the 'KeyVal'
-> SqlPersistT m (Key SourceKeyValues)
insertSourceKeyValue k v e sourceId = do
kvId <- findKeyValue k (Just v) e `orInsert` KeyVal k (Just v) e
insert $ SourceKeyValues sourceId kvId