{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}

module U.Codebase.Sqlite.ProjectReflog
  ( Entry (..),
    project_,
    branch_,
    projectAndBranch_,
  )
where

import Control.Lens
import Data.Text (Text)
import Data.Time (UTCTime)
import U.Codebase.Sqlite.DbId (CausalHashId, ProjectBranchId, ProjectId)
import Unison.Sqlite (FromRow (..), ToRow (..), field)

data Entry project branch causal = Entry
  { forall project branch causal.
Entry project branch causal -> project
project :: project,
    forall project branch causal. Entry project branch causal -> branch
branch :: branch,
    forall project branch causal.
Entry project branch causal -> UTCTime
time :: UTCTime,
    forall project branch causal.
Entry project branch causal -> Maybe causal
fromRootCausalHash :: Maybe causal,
    forall project branch causal. Entry project branch causal -> causal
toRootCausalHash :: causal,
    forall project branch causal. Entry project branch causal -> Text
reason :: Text
  }
  deriving stock (Entry project branch causal -> Entry project branch causal -> Bool
(Entry project branch causal
 -> Entry project branch causal -> Bool)
-> (Entry project branch causal
    -> Entry project branch causal -> Bool)
-> Eq (Entry project branch causal)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall project branch causal.
(Eq project, Eq branch, Eq causal) =>
Entry project branch causal -> Entry project branch causal -> Bool
$c== :: forall project branch causal.
(Eq project, Eq branch, Eq causal) =>
Entry project branch causal -> Entry project branch causal -> Bool
== :: Entry project branch causal -> Entry project branch causal -> Bool
$c/= :: forall project branch causal.
(Eq project, Eq branch, Eq causal) =>
Entry project branch causal -> Entry project branch causal -> Bool
/= :: Entry project branch causal -> Entry project branch causal -> Bool
Eq, Int -> Entry project branch causal -> ShowS
[Entry project branch causal] -> ShowS
Entry project branch causal -> String
(Int -> Entry project branch causal -> ShowS)
-> (Entry project branch causal -> String)
-> ([Entry project branch causal] -> ShowS)
-> Show (Entry project branch causal)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall project branch causal.
(Show project, Show branch, Show causal) =>
Int -> Entry project branch causal -> ShowS
forall project branch causal.
(Show project, Show branch, Show causal) =>
[Entry project branch causal] -> ShowS
forall project branch causal.
(Show project, Show branch, Show causal) =>
Entry project branch causal -> String
$cshowsPrec :: forall project branch causal.
(Show project, Show branch, Show causal) =>
Int -> Entry project branch causal -> ShowS
showsPrec :: Int -> Entry project branch causal -> ShowS
$cshow :: forall project branch causal.
(Show project, Show branch, Show causal) =>
Entry project branch causal -> String
show :: Entry project branch causal -> String
$cshowList :: forall project branch causal.
(Show project, Show branch, Show causal) =>
[Entry project branch causal] -> ShowS
showList :: [Entry project branch causal] -> ShowS
Show, (forall a b.
 (a -> b) -> Entry project branch a -> Entry project branch b)
-> (forall a b.
    a -> Entry project branch b -> Entry project branch a)
-> Functor (Entry project branch)
forall a b. a -> Entry project branch b -> Entry project branch a
forall a b.
(a -> b) -> Entry project branch a -> Entry project branch b
forall project branch a b.
a -> Entry project branch b -> Entry project branch a
forall project branch a b.
(a -> b) -> Entry project branch a -> Entry project branch b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall project branch a b.
(a -> b) -> Entry project branch a -> Entry project branch b
fmap :: forall a b.
(a -> b) -> Entry project branch a -> Entry project branch b
$c<$ :: forall project branch a b.
a -> Entry project branch b -> Entry project branch a
<$ :: forall a b. a -> Entry project branch b -> Entry project branch a
Functor, (forall m. Monoid m => Entry project branch m -> m)
-> (forall m a.
    Monoid m =>
    (a -> m) -> Entry project branch a -> m)
-> (forall m a.
    Monoid m =>
    (a -> m) -> Entry project branch a -> m)
-> (forall a b. (a -> b -> b) -> b -> Entry project branch a -> b)
-> (forall a b. (a -> b -> b) -> b -> Entry project branch a -> b)
-> (forall b a. (b -> a -> b) -> b -> Entry project branch a -> b)
-> (forall b a. (b -> a -> b) -> b -> Entry project branch a -> b)
-> (forall a. (a -> a -> a) -> Entry project branch a -> a)
-> (forall a. (a -> a -> a) -> Entry project branch a -> a)
-> (forall a. Entry project branch a -> [a])
-> (forall a. Entry project branch a -> Bool)
-> (forall a. Entry project branch a -> Int)
-> (forall a. Eq a => a -> Entry project branch a -> Bool)
-> (forall a. Ord a => Entry project branch a -> a)
-> (forall a. Ord a => Entry project branch a -> a)
-> (forall a. Num a => Entry project branch a -> a)
-> (forall a. Num a => Entry project branch a -> a)
-> Foldable (Entry project branch)
forall a. Eq a => a -> Entry project branch a -> Bool
forall a. Num a => Entry project branch a -> a
forall a. Ord a => Entry project branch a -> a
forall m. Monoid m => Entry project branch m -> m
forall a. Entry project branch a -> Bool
forall a. Entry project branch a -> Int
forall a. Entry project branch a -> [a]
forall a. (a -> a -> a) -> Entry project branch a -> a
forall m a. Monoid m => (a -> m) -> Entry project branch a -> m
forall b a. (b -> a -> b) -> b -> Entry project branch a -> b
forall a b. (a -> b -> b) -> b -> Entry project branch a -> b
forall project branch a.
Eq a =>
a -> Entry project branch a -> Bool
forall project branch a. Num a => Entry project branch a -> a
forall project branch a. Ord a => Entry project branch a -> a
forall project branch m. Monoid m => Entry project branch m -> m
forall project branch a. Entry project branch a -> Bool
forall project branch a. Entry project branch a -> Int
forall project branch a. Entry project branch a -> [a]
forall project branch a.
(a -> a -> a) -> Entry project branch a -> a
forall project branch m a.
Monoid m =>
(a -> m) -> Entry project branch a -> m
forall project branch b a.
(b -> a -> b) -> b -> Entry project branch a -> b
forall project branch a b.
(a -> b -> b) -> b -> Entry project branch a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall project branch m. Monoid m => Entry project branch m -> m
fold :: forall m. Monoid m => Entry project branch m -> m
$cfoldMap :: forall project branch m a.
Monoid m =>
(a -> m) -> Entry project branch a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Entry project branch a -> m
$cfoldMap' :: forall project branch m a.
Monoid m =>
(a -> m) -> Entry project branch a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Entry project branch a -> m
$cfoldr :: forall project branch a b.
(a -> b -> b) -> b -> Entry project branch a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Entry project branch a -> b
$cfoldr' :: forall project branch a b.
(a -> b -> b) -> b -> Entry project branch a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Entry project branch a -> b
$cfoldl :: forall project branch b a.
(b -> a -> b) -> b -> Entry project branch a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Entry project branch a -> b
$cfoldl' :: forall project branch b a.
(b -> a -> b) -> b -> Entry project branch a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Entry project branch a -> b
$cfoldr1 :: forall project branch a.
(a -> a -> a) -> Entry project branch a -> a
foldr1 :: forall a. (a -> a -> a) -> Entry project branch a -> a
$cfoldl1 :: forall project branch a.
(a -> a -> a) -> Entry project branch a -> a
foldl1 :: forall a. (a -> a -> a) -> Entry project branch a -> a
$ctoList :: forall project branch a. Entry project branch a -> [a]
toList :: forall a. Entry project branch a -> [a]
$cnull :: forall project branch a. Entry project branch a -> Bool
null :: forall a. Entry project branch a -> Bool
$clength :: forall project branch a. Entry project branch a -> Int
length :: forall a. Entry project branch a -> Int
$celem :: forall project branch a.
Eq a =>
a -> Entry project branch a -> Bool
elem :: forall a. Eq a => a -> Entry project branch a -> Bool
$cmaximum :: forall project branch a. Ord a => Entry project branch a -> a
maximum :: forall a. Ord a => Entry project branch a -> a
$cminimum :: forall project branch a. Ord a => Entry project branch a -> a
minimum :: forall a. Ord a => Entry project branch a -> a
$csum :: forall project branch a. Num a => Entry project branch a -> a
sum :: forall a. Num a => Entry project branch a -> a
$cproduct :: forall project branch a. Num a => Entry project branch a -> a
product :: forall a. Num a => Entry project branch a -> a
Foldable, Functor (Entry project branch)
Foldable (Entry project branch)
(Functor (Entry project branch),
 Foldable (Entry project branch)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Entry project branch a -> f (Entry project branch b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Entry project branch (f a) -> f (Entry project branch a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Entry project branch a -> m (Entry project branch b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Entry project branch (m a) -> m (Entry project branch a))
-> Traversable (Entry project branch)
forall project branch. Functor (Entry project branch)
forall project branch. Foldable (Entry project branch)
forall project branch (m :: * -> *) a.
Monad m =>
Entry project branch (m a) -> m (Entry project branch a)
forall project branch (f :: * -> *) a.
Applicative f =>
Entry project branch (f a) -> f (Entry project branch a)
forall project branch (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Entry project branch a -> m (Entry project branch b)
forall project branch (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Entry project branch a -> f (Entry project branch b)
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
Entry project branch (m a) -> m (Entry project branch a)
forall (f :: * -> *) a.
Applicative f =>
Entry project branch (f a) -> f (Entry project branch a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Entry project branch a -> m (Entry project branch b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Entry project branch a -> f (Entry project branch b)
$ctraverse :: forall project branch (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Entry project branch a -> f (Entry project branch b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Entry project branch a -> f (Entry project branch b)
$csequenceA :: forall project branch (f :: * -> *) a.
Applicative f =>
Entry project branch (f a) -> f (Entry project branch a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Entry project branch (f a) -> f (Entry project branch a)
$cmapM :: forall project branch (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Entry project branch a -> m (Entry project branch b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Entry project branch a -> m (Entry project branch b)
$csequence :: forall project branch (m :: * -> *) a.
Monad m =>
Entry project branch (m a) -> m (Entry project branch a)
sequence :: forall (m :: * -> *) a.
Monad m =>
Entry project branch (m a) -> m (Entry project branch a)
Traversable)

project_ :: Lens (Entry project branch causal) (Entry project' branch causal) project project'
project_ :: forall project branch causal project' (f :: * -> *).
Functor f =>
(project -> f project')
-> Entry project branch causal -> f (Entry project' branch causal)
project_ = (Entry project branch causal -> project)
-> (Entry project branch causal
    -> project' -> Entry project' branch causal)
-> Lens
     (Entry project branch causal)
     (Entry project' branch causal)
     project
     project'
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Entry project branch causal -> project
forall project branch causal.
Entry project branch causal -> project
project (\Entry project branch causal
e project'
p -> Entry project branch causal
e {project = p})

branch_ :: Lens (Entry project branch causal) (Entry project branch' causal) branch branch'
branch_ :: forall project branch causal branch' (f :: * -> *).
Functor f =>
(branch -> f branch')
-> Entry project branch causal -> f (Entry project branch' causal)
branch_ = (Entry project branch causal -> branch)
-> (Entry project branch causal
    -> branch' -> Entry project branch' causal)
-> Lens
     (Entry project branch causal)
     (Entry project branch' causal)
     branch
     branch'
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Entry project branch causal -> branch
forall project branch causal. Entry project branch causal -> branch
branch (\Entry project branch causal
e branch'
b -> Entry project branch causal
e {branch = b})

-- | Both Project and Branch Ids are required to load a branch, so this is often more useful.
projectAndBranch_ :: Lens (Entry project branch causal) (Entry project' branch' causal) (project, branch) (project', branch')
projectAndBranch_ :: forall project branch causal project' branch' (f :: * -> *).
Functor f =>
((project, branch) -> f (project', branch'))
-> Entry project branch causal -> f (Entry project' branch' causal)
projectAndBranch_ = (Entry project branch causal -> (project, branch))
-> (Entry project branch causal
    -> (project', branch') -> Entry project' branch' causal)
-> Lens
     (Entry project branch causal)
     (Entry project' branch' causal)
     (project, branch)
     (project', branch')
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (\Entry {project
branch
causal
Maybe causal
Text
UTCTime
$sel:project:Entry :: forall project branch causal.
Entry project branch causal -> project
$sel:branch:Entry :: forall project branch causal. Entry project branch causal -> branch
$sel:time:Entry :: forall project branch causal.
Entry project branch causal -> UTCTime
$sel:fromRootCausalHash:Entry :: forall project branch causal.
Entry project branch causal -> Maybe causal
$sel:toRootCausalHash:Entry :: forall project branch causal. Entry project branch causal -> causal
$sel:reason:Entry :: forall project branch causal. Entry project branch causal -> Text
project :: project
branch :: branch
time :: UTCTime
fromRootCausalHash :: Maybe causal
toRootCausalHash :: causal
reason :: Text
..} -> (project
project, branch
branch)) (\Entry project branch causal
e (project'
project, branch'
branch) -> Entry project branch causal
e {project = project, branch = branch})

instance ToRow (Entry ProjectId ProjectBranchId CausalHashId) where
  toRow :: Entry ProjectId ProjectBranchId CausalHashId -> [SQLData]
toRow (Entry ProjectId
proj ProjectBranchId
branch UTCTime
time Maybe CausalHashId
fromRootCausalHash CausalHashId
toRootCausalHash Text
reason) =
    (ProjectId, ProjectBranchId, UTCTime, Maybe CausalHashId,
 CausalHashId, Text)
-> [SQLData]
forall a. ToRow a => a -> [SQLData]
toRow (ProjectId
proj, ProjectBranchId
branch, UTCTime
time, Maybe CausalHashId
fromRootCausalHash, CausalHashId
toRootCausalHash, Text
reason)

instance FromRow (Entry ProjectId ProjectBranchId CausalHashId) where
  fromRow :: RowParser (Entry ProjectId ProjectBranchId CausalHashId)
fromRow = do
    ProjectId
project <- RowParser ProjectId
forall a. FromField a => RowParser a
field
    ProjectBranchId
branch <- RowParser ProjectBranchId
forall a. FromField a => RowParser a
field
    UTCTime
time <- RowParser UTCTime
forall a. FromField a => RowParser a
field
    Maybe CausalHashId
fromRootCausalHash <- RowParser (Maybe CausalHashId)
forall a. FromField a => RowParser a
field
    CausalHashId
toRootCausalHash <- RowParser CausalHashId
forall a. FromField a => RowParser a
field
    Text
reason <- RowParser Text
forall a. FromField a => RowParser a
field
    pure $ Entry {Maybe CausalHashId
Text
UTCTime
ProjectId
ProjectBranchId
CausalHashId
$sel:project:Entry :: ProjectId
$sel:branch:Entry :: ProjectBranchId
$sel:time:Entry :: UTCTime
$sel:fromRootCausalHash:Entry :: Maybe CausalHashId
$sel:toRootCausalHash:Entry :: CausalHashId
$sel:reason:Entry :: Text
project :: ProjectId
branch :: ProjectBranchId
time :: UTCTime
fromRootCausalHash :: Maybe CausalHashId
toRootCausalHash :: CausalHashId
reason :: Text
..}