on master help sign in
WIP compilation checkpoint
commitcfa7253ca23245e47191b931de525a261c556493 authorAgentM <agentm@themactionfaction.com> dateThu 18 Apr 2019, 00:09 (8 years ago) parent3ac630e
19 files changed+158−139
src/lib/ProjectM36/Atom.hs+1−1 src/lib/ProjectM36/Base.hs+11−4 src/lib/ProjectM36/Client.hs+16−15 src/lib/ProjectM36/Client/Simple.hs+2−1 src/lib/ProjectM36/DataFrame.hs+1−1 src/lib/ProjectM36/IsomorphicSchema.hs+1−1 src/lib/ProjectM36/Key.hs+1−1 src/lib/ProjectM36/Relation/Show/HTML.hs+1−1 src/lib/ProjectM36/Relation/Show/Term.hs+1−1 src/lib/ProjectM36/Server/EntryPoints.hs+3−3 src/lib/ProjectM36/Server/ParseArgs.hs+1−1 src/lib/ProjectM36/Sessions.hs−1 src/lib/ProjectM36/TransGraphPlanExpr.hs+5 src/lib/ProjectM36/Transaction.hs+17−23 src/lib/ProjectM36/TransactionDiffs.hs+7−2 src/lib/ProjectM36/TransactionGraph.hs+80−73 src/lib/ProjectM36/TransactionGraph/Persist.hs+6−5 src/lib/ProjectM36/TransactionGraph/Show.hs+3−4 src/lib/ProjectM36/Tupleable.hs+1−1
src/lib/ProjectM36/Atom.hs+1−1
@@ -3,7 +3,7 @@ import ProjectM36.Base
33import ProjectM36.Error
44import ProjectM36.DataTypes.Interval
55import qualified Data.Text as T
6−import Data.Monoid
6+--import Data.Monoid
77
88relationForAtom :: Atom -> Either RelationalError Relation
99relationForAtom (RelationAtom rel) = Right rel
src/lib/ProjectM36/Base.hs+11−4
@@ -24,6 +24,7 @@ import Data.Time.Calendar (Day,toGregorian,fromGregorian)
2424import Data.Hashable.Time ()
2525import Data.Typeable
2626import Data.ByteString (ByteString)
27+import qualified Data.List.NonEmpty as NE
2728type StringType = Text
2829
2930-- | Database atoms are the smallest, undecomposable units of a tuple. Common examples are integers, text, or unique identity keys.
@@ -262,7 +263,7 @@ data DataConstructorDefArg = DataConstructorDefTypeConstructorArg TypeConstructo
262263 deriving (Show, Generic, Binary, Eq, NFData)
263264
264265type InclusionDependencies = M.Map IncDepName InclusionDependency
265−type RelationVariables = M.Map RelVarName Relation
266+type RelationVariables = M.Map RelVarName RelationVariable --change to RelationalExprBase TransactionId
266267
267268type SchemaName = StringType
268269
@@ -374,13 +375,19 @@ type TransactionHeads = M.Map HeadName Transaction
374375data TransactionGraph = TransactionGraph TransactionHeads (S.Set Transaction)
375376
376377-- | Every transaction has context-specific information attached to it.
377−-- The `TransactionDiff`s represent child/edge relationships to subsequent transactions (branches or continuations of the same branch).
378+-- The `TransactionDiff`s represent child/edge relationships to previous transactions (branches or continuations of the same branch).
379+data TransactionInfo = TransactionInfo {
380+ parents :: TransactionDiffs,
381+ stamp :: UTCTime
382+ } deriving (Show, Generic)
383+{-
378384data TransactionInfo = TransactionInfo TransactionId TransactionDiffs UTCTime | -- 1 parent + n children
379385 MergeTransactionInfo TransactionId TransactionId TransactionDiffs UTCTime -- 2 parents, n children
380− deriving(Show, Generic)
386+ deriving (Show, Generic)
387+-}
381388
382389-- | Each child transaction must have a corresponding difference expression.
383−type TransactionDiffs = [(TransactionId, TransactionDiffExpr)]
390+type TransactionDiffs = NE.NonEmpty (TransactionId, TransactionDiffExpr)
384391
385392instance Binary TransactionInfo
386393
src/lib/ProjectM36/Client.hs+16−15
@@ -46,7 +46,8 @@ module ProjectM36.Client
4646 PersistenceStrategy(..),
4747 RelationalExpr,
4848 RelationalExprBase(..),
49− DatabaseContextExpr(..),
49+ DatabaseContextExprBase(..),
50+ DatabaseContextExpr,
5051 DatabaseContextIOExpr(..),
5152 Attribute(..),
5253 MergeStrategy(..),
@@ -152,7 +153,6 @@ import Control.Distributed.Process (ProcessId, Process, receiveWait, send, match
152153import Control.Exception (IOException, handle, AsyncException, throwIO, fromException, Exception)
153154import Control.Concurrent.MVar
154155import qualified Data.Map as M
155−import Control.Distributed.Process.Serializable (Serializable)
156156#if MIN_VERSION_stm_containers(1,0,0)
157157import qualified StmContainers.Map as StmMap
158158import qualified StmContainers.Set as StmSet
@@ -163,12 +163,13 @@ import qualified STMContainers.Set as StmSet
163163import qualified ProjectM36.Session as Sess
164164import ProjectM36.Session
165165import ProjectM36.Sessions
166−import "list-t" ListT
166+--import "list-t" ListT
167167import Data.Binary (Binary)
168168import GHC.Generics (Generic)
169169import Control.DeepSeq (force)
170170import System.IO
171171import Data.Time.Clock
172+import Data.Typeable
172173
173174type Hostname = String
174175
@@ -311,9 +312,9 @@ connectProjectM36 :: ConnectionInfo -> IO (Either ConnectionError Connection)
311312--create a new in-memory database/transaction graph
312313connectProjectM36 (InProcessConnectionInfo strat notificationCallback ghcPkgPaths) = do
313314 freshId <- nextRandom
314− stamp <- getCurrentTime
315+ tstamp <- getCurrentTime
315316 let bootstrapContext = basicDatabaseContext
316− freshGraph = bootstrapTransactionGraph stamp freshId bootstrapContext
317+ freshGraph = bootstrapTransactionGraph tstamp freshId bootstrapContext
317318 case strat of
318319 --create date examples graph for now- probably should be empty context in the future
319320 NoPersistence -> do
@@ -409,7 +410,7 @@ createSessionAtCommit_ commitId newSessionId (InProcessConnection conf) = do
409410 case transactionForId commitId graph of
410411 Left err -> pure (Left err)
411412 Right transaction -> do
412− let freshDiscon = DisconnectedTransaction commitId (Trans.schemas transaction) False
413+ let freshDiscon = DisconnectedTransaction commitId (Trans.schemas transaction) NoOperation
413414 keyDuplication <- StmMap.lookup newSessionId sessions
414415 case keyDuplication of
415416 Just _ -> pure $ Left (SessionIdInUseError newSessionId)
@@ -494,7 +495,7 @@ safeLogin login procId = do
494495 Left (_ :: ServerError) -> pure False
495496 Right val -> pure val
496497
497−remoteCall :: (Serializable a, Serializable b) => Connection -> a -> IO b
498+remoteCall :: (Binary a, Binary b, Typeable a, Typeable b) => Connection -> a -> IO b
498499remoteCall (InProcessConnection _ ) _ = error "remoteCall called on local connection"
499500remoteCall (RemoteProcessConnection conf) arg = runProcessResult localNode $ do
500501 ret <- safeCall serverProcessId arg
@@ -601,7 +602,7 @@ executeDatabaseContextExpr sessionId (InProcessConnection conf) expr = excEither
601602 (Left err,_) -> pure (Left err)
602603 (Right (), (_,_,False)) -> pure (Right ()) --optimization- if nothing was dirtied, nothing to do
603604 (Right (), (!context',_,True)) -> do
604− let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas True
605+ let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas NoOperation
605606 newSubschemas = Schema.processDatabaseContextExprSchemasUpdate (Sess.subschemas session) expr
606607 newSchemas = Schemas context' newSubschemas
607608 newSession = Session newDiscon (Sess.schemaName session)
@@ -616,7 +617,7 @@ autoMergeToHead sessionId (InProcessConnection conf) strat headName' = do
616617 id1 <- nextRandom
617618 id2 <- nextRandom
618619 id3 <- nextRandom
619− stamp <- getCurrentTime
620+ tstamp <- getCurrentTime
620621 commitLock_ sessionId conf $ \graph -> do
621622 eSession <- sessionForSessionId sessionId sessions
622623 case eSession of
@@ -627,10 +628,10 @@ autoMergeToHead sessionId (InProcessConnection conf) strat headName' = do
627628 Just headTrans -> do
628629 --attempt fast-forward commit, if possible
629630 let graphInfo = if Sess.parentId session == transactionId headTrans then do
630− ret <- Graph.evalGraphOp stamp id1 (Sess.disconnectedTransaction session) graph Commit
631+ ret <- Graph.evalGraphOp tstamp id1 (Sess.disconnectedTransaction session) graph Commit
631632 pure (ret, [id1])
632633 else do
633− ret <- Graph.autoMergeToHead stamp (id1, id2, id3) (Sess.disconnectedTransaction session) headName' strat graph
634+ ret <- Graph.autoMergeToHead tstamp (id1, id2, id3) (Sess.disconnectedTransaction session) headName' strat graph
634635 pure (ret, [id1,id2,id3])
635636 case graphInfo of
636637 Left err -> pure (Left err)
@@ -652,7 +653,7 @@ executeDatabaseContextIOExpr sessionId (InProcessConnection conf) expr = excEith
652653 case res of
653654 Left err -> pure (Left err)
654655 Right context' -> do
655− let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas True
656+ let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas NoOperation
656657 newSchemas = Schemas context' (Sess.subschemas session)
657658 newSession = Session newDiscon (Sess.schemaName session)
658659 atomically $ StmMap.insert newSession sessionId sessions
@@ -694,14 +695,14 @@ executeGraphExpr :: SessionId -> Connection -> TransactionGraphOperator -> IO (E
694695executeGraphExpr sessionId (InProcessConnection conf) graphExpr = excEither $ do
695696 let sessions = ipSessions conf
696697 freshId <- nextRandom
697− stamp <- getCurrentTime
698+ tstamp <- getCurrentTime
698699 commitLock_ sessionId conf $ \updatedGraph -> do
699700 eSession <- sessionForSessionId sessionId sessions
700701 case eSession of
701702 Left err -> pure (Left err)
702703 Right session -> do
703704 let discon = Sess.disconnectedTransaction session
704− case evalGraphOp stamp freshId discon updatedGraph graphExpr of
705+ case evalGraphOp tstamp freshId discon updatedGraph graphExpr of
705706 Left err -> pure (Left err)
706707 Right (discon', graph') -> do
707708 --if freshId appears in the graph, then we need to pass it on
@@ -807,7 +808,7 @@ executeSchemaExpr sessionId (InProcessConnection conf) schemaExpr = atomically $
807808 --hm- maybe we should start using lenses
808809 let discon = Sess.disconnectedTransaction session
809810 newSchemas = Schemas newContext newSubschemas
810− newSession = Session (DisconnectedTransaction (Discon.parentId discon) newSchemas True) (Sess.schemaName session)
811+ newSession = Session (DisconnectedTransaction (Discon.parentId discon) newSchemas NoOperation) (Sess.schemaName session)
811812 StmMap.insert newSession sessionId sessions
812813 pure (Right ())
813814executeSchemaExpr sessionId conn@(RemoteProcessConnection _) schemaExpr = remoteCall conn (ExecuteSchemaExpr sessionId schemaExpr)
src/lib/ProjectM36/Client/Simple.hs+2−1
@@ -25,7 +25,8 @@ module ProjectM36.Client.Simple (
2525 C.PersistenceStrategy(..),
2626 C.NotificationCallback,
2727 C.emptyNotificationCallback,
28− C.DatabaseContextExpr(..),
28+ C.DatabaseContextExprBase(..),
29+ C.DatabaseContextExpr,
2930 C.RelationalExprBase(..)
3031 ) where
3132
src/lib/ProjectM36/DataFrame.hs+1−1
@@ -18,7 +18,7 @@ import Data.Maybe
1818import qualified Data.Text as T
1919import Data.Binary
2020import Control.Arrow
21−import Data.Monoid
21+--import Data.Monoid
2222
2323data AttributeOrderExpr = AttributeOrderExpr AttributeName Order deriving (Show, Generic, Binary)
2424data AttributeOrder = AttributeOrder AttributeName Order deriving (Show, Generic, Binary)
src/lib/ProjectM36/IsomorphicSchema.hs+1−1
@@ -14,7 +14,7 @@ import Data.Binary
1414import qualified Data.Map as M
1515import qualified Data.Set as S
1616import qualified Data.List as L
17−import Data.Monoid
17+--import Data.Monoid
1818-- isomorphic schemas offer bi-directional functors between two schemas
1919
2020--TODO: note that renaming a relvar should alter any stored isomorphisms as well
src/lib/ProjectM36/Key.hs+1−1
@@ -2,7 +2,7 @@ module ProjectM36.Key where
22import ProjectM36.Base
33import ProjectM36.Relation
44import qualified Data.Set as S
5−import Data.Monoid
5+--import Data.Monoid
66
77{-
88keys can be implemented using inclusion dependencies as well: the count of the projection of the keys' attributes must be equal to the count of the tuples- p. 120 Database in Depth
src/lib/ProjectM36/Relation/Show/HTML.hs+1−1
@@ -8,7 +8,7 @@ import qualified Data.List as L
88import Data.Text (Text, pack)
99import qualified Data.Text as T
1010import qualified Data.Text.IO as TIO
11−import Data.Monoid
11+--import Data.Monoid
1212import qualified Data.Vector as V
1313
1414attributesAsHTML :: Attributes -> Text
src/lib/ProjectM36/Relation/Show/Term.hs+1−1
@@ -9,7 +9,7 @@ import ProjectM36.Attribute hiding (null)
99import qualified Data.List as L
1010import qualified Data.Text as T
1111import Control.Arrow hiding (left)
12−import Data.Monoid
12+--import Data.Monoid
1313import ProjectM36.WCWidth --guess the width that the character will appear as in the terminal
1414
1515boxV :: StringType
src/lib/ProjectM36/Server/EntryPoints.hs+3−3
@@ -3,17 +3,17 @@ import ProjectM36.Base hiding (inclusionDependencies)
33import ProjectM36.IsomorphicSchema
44import ProjectM36.Client as C
55import ProjectM36.Error
6−import ProjectM36.DataFrame
76import Control.Distributed.Process (Process, ProcessId)
87import Control.Distributed.Process.ManagedProcess (ProcessReply)
98import Control.Distributed.Process.ManagedProcess.Server (reply)
109import Control.Distributed.Process.Async (async, task, waitCancelTimeout, AsyncResult(..))
11−import Control.Distributed.Process.Serializable (Serializable)
1210import Control.Monad.IO.Class (liftIO)
1311import Data.Map
1412import Control.Concurrent (threadDelay)
13+import Data.Typeable
14+import Data.Binary
1515
16−timeoutOrDie :: Serializable a => Timeout -> IO a -> Process (Either ServerError a)
16+timeoutOrDie :: (Binary a, Typeable a) => Timeout -> IO a -> Process (Either ServerError a)
1717timeoutOrDie micros act =
1818 if micros == 0 then
1919 liftIO act >>= \x -> pure (Right x)
src/lib/ProjectM36/Server/ParseArgs.hs+1−1
@@ -3,7 +3,7 @@ import ProjectM36.Base
33import ProjectM36.Client
44import Options.Applicative
55import ProjectM36.Server.Config
6−import Data.Monoid
6+--import Data.Monoid
77
88parseArgsWithDefaults :: ServerConfig -> Parser ServerConfig
99parseArgsWithDefaults defaults = ServerConfig <$>
src/lib/ProjectM36/Sessions.hs−1
@@ -8,7 +8,6 @@ import qualified StmContainers.Set as StmSet
88import qualified STMContainers.Map as StmMap
99import qualified STMContainers.Set as StmSet
1010#endif
11−import "list-t" ListT
1211import ProjectM36.Attribute
1312import ProjectM36.Base
1413import ProjectM36.Session
src/lib/ProjectM36/TransGraphPlanExpr.hsnew file+5
@@ -0,0 +1,5 @@
1+module ProjectM36.TransGraphPlanExpr where
2+import ProjectM36.Base
3+-- used to create an execution plan which can potentially read from the query cache
4+
5+data TransGraphPlanExpr = ExecuteTransGraphRelationalExprPlan TransGraphRelationalExpr
src/lib/ProjectM36/Transaction.hs+17−23
@@ -3,31 +3,20 @@ import ProjectM36.Base
33import qualified Data.Set as S
44import qualified Data.UUID as U
55import Data.Time.Clock
6+import qualified Data.List.NonEmpty as NE
7+import ProjectM36.TransactionDiffs
68
7−transactionTimestamp :: Transaction -> UTCTime
8−transactionTimestamp (Transaction _ (TransactionInfo _ _ stamp) _) = stamp
9−transactionTimestamp (Transaction _ (MergeTransactionInfo _ _ _ stamp) _) = stamp
10−
11−transactionParentIds :: Transaction -> S.Set TransactionId
12−transactionParentIds (Transaction _ (TransactionInfo pId _ _) _) = S.singleton pId
13−transactionParentIds (Transaction _ (MergeTransactionInfo pId1 pId2 _ _) _) = S.fromList [pId1, pId2]
14−
15−transactionChildIds :: Transaction -> S.Set TransactionId
16−transactionChildIds (Transaction _ (TransactionInfo _ children _) _) = S.fromList (map fst children)
17−transactionChildIds (Transaction _ (MergeTransactionInfo _ _ children _) _) = S.fromList (map fst children)
18−
19−-- | Create a new transaction which is identical to the original except that a new set of child transaction ids is added.
20−transactionSetChildren :: Transaction -> TransactionDiffs -> Transaction
21−transactionSetChildren t@(Transaction _ (TransactionInfo pId _ stamp) schemas') diffs' = Transaction (transactionId t) (TransactionInfo pId diffs' stamp) schemas'
22−transactionSetChildren t@(Transaction _ (MergeTransactionInfo pId1 pId2 _ stamp) schemas') diffs' = Transaction (transactionId t) (MergeTransactionInfo pId1 pId2 diffs' stamp) schemas'
9+parentIds :: Transaction -> S.Set TransactionId
10+parentIds (Transaction _ tinfo _) = S.fromList (NE.toList (NE.map fst (parents tinfo)))
2311
2412-- | Return the same transaction but referencing only the specific child transactions. This is useful when traversing a graph and returning a subgraph. This doesn't filter parent transactions because it assumes a head-to-root traversal.
2513filterTransactionInfoTransactions :: S.Set TransactionId -> TransactionInfo -> TransactionInfo
26−filterTransactionInfoTransactions filterIds (TransactionInfo parentId diffs' stamp) = TransactionInfo (filterParent parentId filterIds) (filterDiffs filterIds diffs') stamp
27−filterTransactionInfoTransactions filterIds (MergeTransactionInfo parentIdA parentIdB diffs' stamp) = MergeTransactionInfo (filterParent parentIdA filterIds) (filterParent parentIdB filterIds) (filterDiffs filterIds diffs') stamp
28−
29−filterDiffs :: S.Set TransactionId -> TransactionDiffs -> TransactionDiffs
30−filterDiffs filterIds = filter (\(tid,_) -> S.member tid filterIds)
14+filterTransactionInfoTransactions filterIds tinfo =
15+ TransactionInfo { parents = case
16+ NE.filter (\diff -> S.member (fst diff) filterIds) (parents tinfo) of
17+ [] -> root
18+ xs -> NE.fromList xs,
19+ stamp = stamp tinfo }
3120
3221filterParent :: TransactionId -> S.Set TransactionId -> TransactionId
3322filterParent parentId validIds = if S.member parentId validIds then parentId else U.nil
@@ -49,5 +38,10 @@ subschemas :: Transaction -> Subschemas
4938subschemas (Transaction _ _ (Schemas _ sschemas)) = sschemas
5039
5140diffs :: Transaction -> TransactionDiffs
52−diffs (Transaction _ (TransactionInfo _ diffs' _) _) = diffs'
53−diffs (Transaction _ (MergeTransactionInfo _ _ diffs' _) _) = diffs'
41+diffs (Transaction _ info _) = parents info
42+
43+fresh :: TransactionId -> UTCTime -> Schemas -> Transaction
44+fresh freshId stamp' newSchemas = Transaction freshId (TransactionInfo root stamp') newSchemas
45+
46+timestamp :: Transaction -> UTCTime
47+timestamp (Transaction _ tinfo _) = stamp tinfo
src/lib/ProjectM36/TransactionDiffs.hs+7−2
@@ -1,5 +1,10 @@
11module ProjectM36.TransactionDiffs where
22import ProjectM36.Base
3+import Data.List.NonEmpty
4+import Data.UUID as U
35
4−empty :: TransactionDiffs
5−empty = []
6+root :: TransactionDiffs
7+root = single U.nil NoOperation
8+
9+single :: TransactionId -> TransactionDiffExpr -> TransactionDiffs
10+single tid expr = (tid, expr) :| []
src/lib/ProjectM36/TransactionGraph.hs+80−73
@@ -16,13 +16,14 @@ import qualified ProjectM36.Attribute as A
1616import qualified Data.UUID as U
1717import qualified Data.Set as S
1818import qualified Data.Map as M
19+import qualified Data.List.NonEmpty as NE
1920import Control.Monad
2021import Data.Time.Clock
2122import qualified Data.Text as T
2223import GHC.Generics
2324import Data.Binary
2425import Data.Either (lefts, rights, isRight)
25−import Data.Monoid
26+--import Data.Monoid
2627import Control.Arrow
2728import Data.Maybe
2829
@@ -63,11 +64,11 @@ data ROTransactionGraphOperator = ShowGraph
6364 deriving Show
6465
6566bootstrapTransactionGraph :: UTCTime -> TransactionId -> DatabaseContext -> TransactionGraph
66−bootstrapTransactionGraph stamp freshId context = TransactionGraph bootstrapHeads bootstrapTransactions
67+bootstrapTransactionGraph stamp' freshId context = TransactionGraph bootstrapHeads bootstrapTransactions
6768 where
6869 bootstrapHeads = M.singleton "master" freshTransaction
6970 newSchemas = Schemas context M.empty
70− freshTransaction = Transaction freshId (TransactionInfo U.nil TD.empty stamp) newSchemas
71+ freshTransaction = fresh freshId stamp' newSchemas
7172 bootstrapTransactions = S.singleton freshTransaction
7273
7374emptyTransactionGraph :: TransactionGraph
@@ -108,57 +109,58 @@ transactionsForIds :: S.Set TransactionId -> TransactionGraph -> Either Relation
108109transactionsForIds idSet graph =
109110 S.fromList <$> forM (S.toList idSet) (`transactionForId` graph)
110111
111−isRootTransaction :: Transaction -> TransactionGraph -> Bool
112−isRootTransaction (Transaction _ (TransactionInfo pId _ _) _) _ = U.null pId
113−isRootTransaction (Transaction _ MergeTransactionInfo{} _) _ = False
112+-- | A root transaction terminates a graph and has no parents.
113+isRootTransaction :: Transaction -> Bool
114+isRootTransaction trans = diffs trans == TD.root
114115
115116-- the first transaction has no parent - all other do have parents- merges have two parents
116117parentTransactions :: Transaction -> TransactionGraph -> Either RelationalError (S.Set Transaction)
117−parentTransactions (Transaction _ (TransactionInfo pId _ _) _) graph =
118− S.singleton <$> transactionForId pId graph
119−
120−
121−parentTransactions (Transaction _ (MergeTransactionInfo pId1 pId2 _ _) _ ) graph = transactionsForIds (S.fromList [pId1, pId2]) graph
122−
118+parentTransactions trans graph = transactionsForIds (parentIds trans) graph
123119
124120childTransactions :: Transaction -> TransactionGraph -> Either RelationalError (S.Set Transaction)
125−childTransactions trans = transactionsForIds (transactionChildIds trans)
121+childTransactions trans graph = transactionsForIds childIds graph
122+ where
123+ childIds = S.map transactionId (S.filter filt (transactionsForGraph graph))
124+ filt trans' = S.member (transactionId trans) (parentIds trans')
126125
127126-- create a new commit and add it to the heads
128127-- technically, the new head could be added to an existing commit, but by adding a new commit, the new head is unambiguously linked to a new commit (with a context indentical to its parent)
129128addBranch :: UTCTime -> TransactionId -> HeadName -> TransactionId -> TransactionGraph -> Either RelationalError (Transaction, TransactionGraph)
130−addBranch stamp newId newBranchName branchPointId graph = do
129+addBranch stamp' newId newBranchName branchPointId graph = do
131130 parentTrans <- transactionForId branchPointId graph
132− let newTrans = Transaction newId (TransactionInfo branchPointId TD.empty stamp) (schemas parentTrans)
133− addTransactionToGraph newBranchName newTrans [(newId, NoOperation)] graph
131+ let newTrans = Transaction newId (TransactionInfo {
132+ parents = TD.single branchPointId NoOperation,
133+ stamp = stamp'}) (schemas parentTrans)
134+ addTransactionToGraph newBranchName newTrans graph
134135
135136--adds a disconnected transaction to a transaction graph at some head
136137addDisconnectedTransaction :: UTCTime -> TransactionId -> HeadName -> DisconnectedTransaction -> TransactionGraph -> Either RelationalError (Transaction, TransactionGraph)
137−addDisconnectedTransaction stamp newId headName discon@(DisconnectedTransaction parentId schemas' _) = addTransactionToGraph headName (Transaction newId (TransactionInfo parentId TD.empty stamp) schemas') [(newId, Discon.diffExpr discon)]
138+addDisconnectedTransaction stamp' newId headName discon@(DisconnectedTransaction parentId schemas' _) = addTransactionToGraph headName newTrans
139+ where
140+ newTrans = Transaction newId (TransactionInfo {
141+ parents = TD.single parentId (Discon.diffExpr discon),
142+ stamp = stamp'}) schemas'
138143
139144
140−addTransactionToGraph :: HeadName -> Transaction -> TransactionDiffs -> TransactionGraph -> Either RelationalError (Transaction, TransactionGraph)
141−addTransactionToGraph headName newTrans transDiffs graph = do
142− let parentIds = transactionParentIds newTrans
143− childIds = transactionChildIds newTrans
145+addTransactionToGraph :: HeadName -> Transaction -> TransactionGraph -> Either RelationalError (Transaction, TransactionGraph)
146+addTransactionToGraph headName newTrans graph = do
147+ let parentIds' = parentIds newTrans
144148 newId = transactionId newTrans
145149 validateIds ids = mapM (`transactionForId` graph) (S.toList ids)
146− addChildTransaction trans = transactionSetChildren trans (transDiffs ++ diffs trans)
150+ childTs <- childTransactions newTrans graph
147151 --validate that the parent transactions are in the graph
148− _ <- validateIds parentIds
149− when (S.size parentIds < 1) (Left $ NewTransactionMissingParentError newId)
152+ _ <- validateIds parentIds'
153+ when (S.size parentIds' < 1) (Left $ NewTransactionMissingParentError newId)
150154 --if the headName already exists, ensure that it refers to a parent
151155 case transactionForHead headName graph of
152156 Nothing -> pure () -- any headName is OK
153− Just trans -> when (S.notMember (transactionId trans) parentIds) (Left (HeadNameSwitchingHeadProhibitedError headName))
157+ Just trans -> when (S.notMember (transactionId trans) parentIds') (Left (HeadNameSwitchingHeadProhibitedError headName))
154158 --validate that the transaction has no children
155− unless (S.null childIds) (Left $ NewTransactionMayNotHaveChildrenError newId)
159+ unless (S.null childTs) (Left $ NewTransactionMayNotHaveChildrenError newId)
156160 --validate that the trasaction's id is unique
157161 when (isRight (transactionForId newId graph)) (Left (TransactionIdInUseError newId))
158− --update the parent transactions to point to the new transaction
159− parents <- mapM (`transactionForId` graph) (S.toList parentIds)
160− let updatedParents = S.map addChildTransaction (S.fromList parents)
161− updatedTransSet = S.insert newTrans (S.union updatedParents (transactionsForGraph graph))
162+
163+ let updatedTransSet = S.insert newTrans (transactionsForGraph graph)
162164 updatedHeads = M.insert headName newTrans (transactionHeadsForGraph graph)
163165 pure (newTrans, TransactionGraph updatedHeads updatedTransSet)
164166
@@ -250,15 +252,15 @@ evalGraphOp newId discon@(DisconnectedTransaction parentId disconContext) graph
250252
251253-- create a new commit and add it to the heads
252254-- technically, the new head could be added to an existing commit, but by adding a new commit, the new head is unambiguously linked to a new commit (with a context indentical to its parent)
253−evalGraphOp stamp newId (DisconnectedTransaction parentId schemas' _) graph (Branch newBranchName) = do
255+evalGraphOp stamp' newId (DisconnectedTransaction parentId schemas' _) graph (Branch newBranchName) = do
254256 let newDiscon = Discon.freshTransaction newId schemas'
255− case addBranch stamp newId newBranchName parentId graph of
257+ case addBranch stamp' newId newBranchName parentId graph of
256258 Left err -> Left err
257259 Right (_, newGraph) -> Right (newDiscon, newGraph)
258260
259261-- add the disconnected transaction to the graph
260262-- affects graph and disconnectedtransaction- the new disconnectedtransaction's parent is the freshly committed transaction
261−evalGraphOp stamp newTransId discon@(DisconnectedTransaction parentId schemas' _) graph Commit = case transactionForId parentId graph of
263+evalGraphOp stamp' newTransId discon@(DisconnectedTransaction parentId schemas' _) graph Commit = case transactionForId parentId graph of
262264 Left err -> Left err
263265 Right parentTransaction -> case headNameForTransaction parentTransaction graph of
264266 Nothing -> Left $ TransactionIsNotAHeadError parentId
@@ -267,7 +269,7 @@ evalGraphOp stamp newTransId discon@(DisconnectedTransaction parentId schemas' _
267269 Right (_, updatedGraph) -> Right (newDisconnectedTrans, updatedGraph)
268270 where
269271 newDisconnectedTrans = Discon.freshTransaction newTransId schemas'
270− maybeUpdatedGraph = addDisconnectedTransaction stamp newTransId headName discon graph
272+ maybeUpdatedGraph = addDisconnectedTransaction stamp' newTransId headName discon graph
271273
272274-- refresh the disconnected transaction, return the same graph
273275evalGraphOp _ _ (DisconnectedTransaction parentId _ _) graph Rollback = case transactionForId parentId graph of
@@ -276,7 +278,7 @@ evalGraphOp _ _ (DisconnectedTransaction parentId _ _) graph Rollback = case tra
276278 where
277279 newDiscon = Discon.freshTransaction parentId (schemas parentTransaction)
278280
279−evalGraphOp stamp newId (DisconnectedTransaction parentId _ _) graph (MergeTransactions mergeStrategy headNameA headNameB) = mergeTransactions stamp newId parentId mergeStrategy (headNameA, headNameB) graph
281+evalGraphOp stamp' newId (DisconnectedTransaction parentId _ _) graph (MergeTransactions mergeStrategy headNameA headNameB) = mergeTransactions stamp' newId parentId mergeStrategy (headNameA, headNameB) graph
280282
281283evalGraphOp _ _ discon graph@(TransactionGraph graphHeads transSet) (DeleteBranch branchName) = case transactionForHead branchName graph of
282284 Nothing -> Left (NoSuchHeadNameError branchName)
@@ -298,7 +300,7 @@ graphAsRelation (DisconnectedTransaction parentId _ _) graph@(TransactionGraph _
298300 tupleGenerator transaction = case transactionParentsRelation transaction graph of
299301 Left err -> Left err
300302 Right parentTransRel -> Right [TextAtom $ T.pack $ show (transactionId transaction),
301− DateTimeAtom (transactionTimestamp transaction),
303+ DateTimeAtom (timestamp transaction),
302304 RelationAtom parentTransRel,
303305 BoolAtom $ parentId == transactionId transaction,
304306 TextAtom $ fromMaybe "" (headNameForTransaction transaction graph)
@@ -306,7 +308,7 @@ graphAsRelation (DisconnectedTransaction parentId _ _) graph@(TransactionGraph _
306308
307309transactionParentsRelation :: Transaction -> TransactionGraph -> Either RelationalError Relation
308310transactionParentsRelation trans graph =
309− if isRootTransaction trans graph then
311+ if isRootTransaction trans then
310312 mkRelation attrs emptyTupleSet
311313 else do
312314 parentTransSet <- parentTransactions trans graph
@@ -326,15 +328,18 @@ evalROGraphOp discon graph ShowGraph = do
326328
327329-- | Execute the merge strategy against the transactions, returning a new transaction which can be then added to the transaction graph
328330createMergeTransaction :: UTCTime -> TransactionId -> MergeStrategy -> TransactionGraph -> (Transaction, Transaction) -> Either MergeError Transaction
329−createMergeTransaction stamp newId (SelectedBranchMergeStrategy selectedBranch) graph t2@(trans1, trans2) = do
331+createMergeTransaction stamp' newId (SelectedBranchMergeStrategy selectedBranch) graph t2@(trans1, trans2) = do
330332 let selectedTrans = validateHeadName selectedBranch graph t2
331− Transaction newId (MergeTransactionInfo (transactionId trans1) (transactionId trans2) TD.empty stamp) . schemas <$> selectedTrans
333+ Transaction newId (TransactionInfo {
334+ parents = NE.fromList [(transactionId trans1, undefined),
335+ (transactionId trans2, undefined)],
336+ stamp = stamp' }) . schemas <$> selectedTrans
332337
333338-- merge functions, relvars, individually
334−createMergeTransaction stamp newId strat@UnionMergeStrategy graph t2 = createUnionMergeTransaction stamp newId strat graph t2
339+createMergeTransaction stamp' newId strat@UnionMergeStrategy graph t2 = createUnionMergeTransaction stamp' newId strat graph t2
335340
336341-- merge function, relvars, but, on error, just take the component from the preferred branch
337−createMergeTransaction stamp newId strat@(UnionPreferMergeStrategy _) graph t2 = createUnionMergeTransaction stamp newId strat graph t2
342+createMergeTransaction stamp' newId strat@(UnionPreferMergeStrategy _) graph t2 = createUnionMergeTransaction stamp' newId strat graph t2
338343
339344-- | Returns the correct Transaction for the branch name in the graph and ensures that it is one of the two transaction arguments in the tuple.
340345validateHeadName :: HeadName -> TransactionGraph -> (Transaction, Transaction) -> Either MergeError Transaction
@@ -355,7 +360,7 @@ subGraphOfFirstCommonAncestor origGraph resultHeads currentTrans goalTrans trave
355360 Right (TransactionGraph resultHeads traverseSet) -- add filter
356361 --catch root transaction to improve error?
357362 else do
358− currentTransChildren <- S.fromList <$> mapM (`transactionForId` origGraph) (S.toList (transactionChildIds currentTrans))
363+ currentTransChildren <- childTransactions currentTrans origGraph
359364 let searchChildren = S.difference (S.insert currentTrans traverseSet) currentTransChildren
360365 searchChild start = pathToTransaction origGraph start goalTrans (S.insert currentTrans traverseSet)
361366 childSearches = map searchChild (S.toList searchChildren)
@@ -374,9 +379,8 @@ subGraphOfFirstCommonAncestor origGraph resultHeads currentTrans goalTrans trave
374379 else -- we found a path
375380 Right (TransactionGraph resultHeads (S.unions (traverseSet : pathsFound)))
376381 where
377− oneParent (Transaction _ (TransactionInfo parentId _ _) _) = transactionForId parentId origGraph
378− oneParent (Transaction _ (MergeTransactionInfo parentId _ _ _) _) = transactionForId parentId origGraph
379−
382+ oneParent (Transaction _ tinfo _) = transactionForId (fst (NE.head (parents tinfo))) origGraph
383+
380384-- | Search from a past graph point to all following heads for a specific transaction. If found, return the transaction path, otherwise a RelationalError.
381385pathToTransaction :: TransactionGraph -> Transaction -> Transaction -> S.Set Transaction -> Either RelationalError (S.Set Transaction)
382386pathToTransaction graph currentTransaction targetTransaction accumTransSet = do
@@ -384,11 +388,11 @@ pathToTransaction graph currentTransaction targetTransaction accumTransSet = do
384388 if transactionId targetTransaction == transactionId currentTransaction then
385389 Right accumTransSet
386390 else do
387− currentTransChildren <- mapM (`transactionForId` graph) (S.toList (transactionChildIds currentTransaction))
391+ currentTransChildren <- childTransactions currentTransaction graph
388392 if null currentTransChildren then
389393 Left (FailedToFindTransactionError targetId)
390394 else do
391− let searches = map (\t -> pathToTransaction graph t targetTransaction (S.insert t accumTransSet)) currentTransChildren
395+ let searches = map (\t -> pathToTransaction graph t targetTransaction (S.insert t accumTransSet)) (S.toList currentTransChildren)
392396 let realErrors = filter (/= FailedToFindTransactionError targetId) (lefts searches)
393397 paths = rights searches
394398 if not (null realErrors) then -- found some real errors
@@ -399,7 +403,7 @@ pathToTransaction graph currentTransaction targetTransaction accumTransSet = do
399403 Right (S.unions paths)
400404
401405mergeTransactions :: UTCTime -> TransactionId -> TransactionId -> MergeStrategy -> (HeadName, HeadName) -> TransactionGraph -> Either RelationalError (DisconnectedTransaction, TransactionGraph)
402−mergeTransactions stamp newId parentId mergeStrategy (headNameA, headNameB) graph = do
406+mergeTransactions stamp' newId parentId mergeStrategy (headNameA, headNameB) graph = do
403407 let transactionForHeadErr name = case transactionForHead name graph of
404408 Nothing -> Left (NoSuchHeadNameError name)
405409 Just t -> Right t
@@ -409,16 +413,16 @@ mergeTransactions stamp newId parentId mergeStrategy (headNameA, headNameB) grap
409413 let subHeads = M.filterWithKey (\k _ -> k `elem` [headNameA, headNameB]) (transactionHeadsForGraph graph)
410414 subGraph <- subGraphOfFirstCommonAncestor graph subHeads transA transB S.empty
411415 subGraph' <- filterSubGraph subGraph subHeads
412− case createMergeTransaction stamp newId mergeStrategy subGraph' (transA, transB) of
416+ case createMergeTransaction stamp' newId mergeStrategy subGraph' (transA, transB) of
413417 Left err -> Left (MergeTransactionError err)
414418 Right mergedTrans -> case checkConstraints (concreteDatabaseContext mergedTrans) of
415419 Left err -> Left err
416420 Right _ -> case headNameForTransaction disconParent graph of
417421 Nothing -> Left (TransactionIsNotAHeadError parentId)
418422 Just headName -> do
419− (newTrans, newGraph) <- addTransactionToGraph headName mergedTrans ??? graph
423+ (newTrans, newGraph) <- addTransactionToGraph headName mergedTrans graph
420424 let newGraph' = TransactionGraph (transactionHeadsForGraph newGraph) (transactionsForGraph newGraph)
421− newDiscon = DisconnectedTransaction newId (schemas newTrans) False
425+ newDiscon = Discon.freshTransaction newId (schemas newTrans)
422426 pure (newDiscon, newGraph')
423427
424428--TEMPORARY COPY/PASTE
@@ -426,7 +430,7 @@ showTransactionStructureX :: Transaction -> TransactionGraph -> String
426430showTransactionStructureX trans graph = headInfo ++ " " ++ show (transactionId trans) ++ " " ++ parentTransactionsInfo
427431 where
428432 headInfo = maybe "" show (headNameForTransaction trans graph)
429− parentTransactionsInfo = if isRootTransaction trans graph then "root" else case parentTransactions trans graph of
433+ parentTransactionsInfo = if isRootTransaction trans then "root" else case parentTransactions trans graph of
430434 Left err -> show err
431435 Right parentTransSet -> concat $ S.toList $ S.map (show . transactionId) parentTransSet
432436
@@ -446,7 +450,7 @@ filterSubGraph graph heads = Right $ TransactionGraph newHeads newTransSet
446450
447451--helper function for commonalities in union merge
448452createUnionMergeTransaction :: UTCTime -> TransactionId -> MergeStrategy -> TransactionGraph -> (Transaction, Transaction) -> Either MergeError Transaction
449−createUnionMergeTransaction stamp newId strategy graph (t1,t2) = do
453+createUnionMergeTransaction stamp' newId strategy graph (t1,t2) = do
450454 let contextA = concreteDatabaseContext t1
451455 contextB = concreteDatabaseContext t2
452456
@@ -474,7 +478,10 @@ createUnionMergeTransaction stamp newId strategy graph (t1,t2) = do
474478 typeConstructorMapping = types
475479 }
476480 newSchemas = Schemas newContext (subschemas t1)
477− pure (Transaction newId (MergeTransactionInfo (transactionId t1) (transactionId t2) TD.empty stamp) newSchemas)
481+ pure (Transaction newId (TransactionInfo {
482+ parents = NE.fromList [(transactionId t1, undefined),
483+ (transactionId t2, undefined)],
484+ stamp = stamp'}) newSchemas)
478485
479486lookupTransaction :: TransactionGraph -> TransactionIdLookup -> Either RelationalError Transaction
480487lookupTransaction graph (TransactionIdLookup tid) = transactionForId tid graph
@@ -491,11 +498,11 @@ backtrackGraph :: TransactionGraph -> TransactionId -> TransactionIdHeadBacktrac
491498-- tilde, step back one parent link- if a choice must be made, choose the "first" link arbitrarily
492499backtrackGraph graph currentTid (TransactionIdHeadParentBacktrack steps) = do
493500 trans <- transactionForId currentTid graph
494− let parents = S.toAscList (transactionParentIds trans)
495− if length parents < 1 then
501+ let parentIds' = S.toList (parentIds trans)
502+ if length parentIds' < 1 then
496503 Left RootTransactionTraversalError
497504 else do
498− parentTrans <- transactionForId (head parents) graph
505+ parentTrans <- transactionForId (head parentIds') graph
499506 if steps == 1 then
500507 pure (transactionId parentTrans)
501508 else
@@ -503,44 +510,44 @@ backtrackGraph graph currentTid (TransactionIdHeadParentBacktrack steps) = do
503510
504511backtrackGraph graph currentTid (TransactionIdHeadBranchBacktrack steps) = do
505512 trans <- transactionForId currentTid graph
506− let parents = transactionParentIds trans
507− if S.size parents < 1 then
513+ let parentIds' = parentIds trans
514+ if S.size parentIds' < 1 then
508515 Left RootTransactionTraversalError
509− else if S.size parents < steps then
510− Left (ParentCountTraversalError (S.size parents) steps)
516+ else if S.size parentIds' < steps then
517+ Left (ParentCountTraversalError (S.size parentIds') steps)
511518 else
512− pure (S.elemAt (steps - 1) parents)
519+ pure (S.elemAt (steps - 1) parentIds')
513520
514−backtrackGraph graph currentTid btrack@(TransactionStampHeadBacktrack stamp) = do
521+backtrackGraph graph currentTid btrack@(TransactionStampHeadBacktrack stamp') = do
515522 trans <- transactionForId currentTid graph
516− let parents = transactionParentIds trans
517− if transactionTimestamp trans <= stamp then
523+ let parentIds' = parentIds trans
524+ if timestamp trans <= stamp' then
518525 pure currentTid
519− else if S.null parents then
526+ else if S.null parentIds' then
520527 Left RootTransactionTraversalError
521528 else
522− let arbitraryParent = head (S.toList parents) in
529+ let arbitraryParent = head (S.toList parentIds') in
523530 backtrackGraph graph arbitraryParent btrack
524531
525532-- | Create a temporary branch for commit, merge the result to head, delete the temporary branch. This is useful to atomically commit a transaction, avoiding a TransactionIsNotHeadError but trading it for a potential MergeError.
526533--this is not a GraphOp because it combines multiple graph operations
527534autoMergeToHead :: UTCTime -> (TransactionId, TransactionId, TransactionId) -> DisconnectedTransaction -> HeadName -> MergeStrategy -> TransactionGraph -> Either RelationalError (DisconnectedTransaction, TransactionGraph)
528−autoMergeToHead stamp (tempBranchTransId, tempCommitTransId, mergeTransId) discon mergeToHeadName strat graph = do
535+autoMergeToHead stamp' (tempBranchTransId, tempCommitTransId, mergeTransId) discon mergeToHeadName strat graph = do
529536 let tempBranchName = "mergebranch_" <> U.toText tempBranchTransId
530537 --create the temp branch
531− (discon', graph') <- evalGraphOp stamp tempBranchTransId discon graph (Branch tempBranchName)
538+ (discon', graph') <- evalGraphOp stamp' tempBranchTransId discon graph (Branch tempBranchName)
532539
533540 --commit to the new branch- possible future optimization: don't require fsync for this- create a temp commit type
534− (discon'', graph'') <- evalGraphOp stamp tempCommitTransId discon' graph' Commit
541+ (discon'', graph'') <- evalGraphOp stamp' tempCommitTransId discon' graph' Commit
535542
536543 --jump to merge head
537− (discon''', graph''') <- evalGraphOp stamp tempBranchTransId discon'' graph'' (JumpToHead mergeToHeadName)
544+ (discon''', graph''') <- evalGraphOp stamp' tempBranchTransId discon'' graph'' (JumpToHead mergeToHeadName)
538545
539546 --create the merge
540− (discon'''', graph'''') <- evalGraphOp stamp mergeTransId discon''' graph''' (MergeTransactions strat tempBranchName mergeToHeadName)
547+ (discon'''', graph'''') <- evalGraphOp stamp' mergeTransId discon''' graph''' (MergeTransactions strat tempBranchName mergeToHeadName)
541548
542549 --delete the temp branch
543− (discon''''', graph''''') <- evalGraphOp stamp tempBranchTransId discon'''' graph'''' (DeleteBranch tempBranchName)
550+ (discon''''', graph''''') <- evalGraphOp stamp' tempBranchTransId discon'''' graph'''' (DeleteBranch tempBranchName)
544551 {-
545552 let rel = runReader (evalRelationalExpr (RelationVariable "s" ())) (mkRelationalExprState $ D.concreteDatabaseContext discon'''')
546553 traceShowM rel
src/lib/ProjectM36/TransactionGraph/Persist.hs+6−5
@@ -24,7 +24,7 @@ import Control.Exception.Base
2424import qualified Data.ByteString as BS
2525import qualified Data.Text.Encoding as TE
2626import Data.ByteString (ByteString)
27−import Data.Monoid
27+--import Data.Monoid
2828import qualified Crypto.Hash.SHA256 as SHA256
2929import Control.Arrow
3030import Data.Time.Clock
@@ -192,12 +192,12 @@ writeGraphTransactionIdFile sync destDirectory (TransactionGraph _ transSet) = w
192192 uuidInfo = T.intercalate "\n" graphLines
193193 digest = SHA256.hash (encodeUtf8 uuidInfo)
194194 graphLines = S.toList $ S.map graphLine transSet
195− epochTime = realToFrac . utcTimeToPOSIXSeconds . transactionTimestamp :: Transaction -> Double
195+ epochTime = realToFrac . utcTimeToPOSIXSeconds . timestamp :: Transaction -> Double
196196 graphLine trans = U.toText (transactionId trans)
197197 <> " "
198198 <> T.pack (show (epochTime trans))
199199 <> " "
200− <> T.intercalate " " (S.toList (S.map U.toText $ transactionParentIds trans))
200+ <> T.intercalate " " (S.toList (S.map U.toText $ parentIds trans))
201201
202202readGraphTransactionIdFileDigest :: FilePath -> IO LockFileHash
203203readGraphTransactionIdFileDigest dbdir = do
@@ -207,8 +207,8 @@ readGraphTransactionIdFileDigest dbdir = do
207207readGraphTransactionIdFile :: FilePath -> IO (Either PersistenceError [(TransactionId, UTCTime, [TransactionId])])
208208readGraphTransactionIdFile dbdir = do
209209 --read in all transactions' uuids
210− let grapher line = let tid:epochText:parentIds = T.words line in
211− (readUUID tid, readEpoch epochText, map readUUID parentIds)
210+ let grapher line = let tid:epochText:parentIds' = T.words line in
211+ (readUUID tid, readEpoch epochText, map readUUID parentIds')
212212 readUUID uuidText = fromMaybe (error "failed to read uuid") (U.fromText uuidText)
213213 readEpoch t = posixSecondsToUTCTime (realToFrac (either (error "failed to read epoch") fst (double t)))
214214 Right . map grapher . T.lines <$> readUTF8FileOrError (transactionLogPath dbdir)
@@ -223,3 +223,4 @@ readUTF8FileOrError pathIn = do
223223 case TE.decodeUtf8' fileBytes of
224224 Left err -> error (show err)
225225 Right utf8Bytes -> pure utf8Bytes
226+
src/lib/ProjectM36/TransactionGraph/Show.hs+3−4
@@ -1,17 +1,16 @@
11module ProjectM36.TransactionGraph.Show where
22import ProjectM36.Base
33import ProjectM36.TransactionGraph
4−import ProjectM36.Transaction
54import qualified Data.Set as S
65
76showTransactionStructure :: Transaction -> TransactionGraph -> String
8−showTransactionStructure trans graph = headInfo ++ " " ++ show (transactionId trans) ++ " p" ++ parentTransactionsInfo ++ " c" ++ childTransactionsInfo
7+showTransactionStructure trans graph = headInfo ++ " " ++ show (transactionId trans) ++ " p" ++ parentTransactionsInfo
98 where
109 headInfo = maybe "" show (headNameForTransaction trans graph)
11− parentTransactionsInfo = if isRootTransaction trans graph then "root" else case parentTransactions trans graph of
10+ parentTransactionsInfo = if isRootTransaction trans then "root" else case parentTransactions trans graph of
1211 Left err -> show err
1312 Right parentTransSet -> concat $ S.toList $ S.map (show . transactionId) parentTransSet
14− childTransactionsInfo = show (S.toList (transactionChildIds trans))
13+
1514
1615showGraphStructure :: TransactionGraph -> String
1716showGraphStructure graph@(TransactionGraph _ transSet) = S.foldr folder "" transSet
src/lib/ProjectM36/Tupleable.hs+1−1
@@ -10,7 +10,7 @@ module ProjectM36.Tupleable where
1010import Data.Foldable
1111import Data.List (partition)
1212import qualified Data.Map as Map
13−import Data.Monoid
13+--import Data.Monoid
1414import Data.Proxy
1515import qualified Data.Text as T
1616import qualified Data.Vector as V