@@ -10,6 +10,7 @@ import qualified Data.ByteString.Lazy as BS
1010import System.Exit
1111import Data.Word
1212import ProjectM36.RelationalExpression
13+import qualified ProjectM36.DisconnectedTransaction as Discon
1314import qualified Data.UUID as U
1415import qualified Data.Set as S
1516import qualified Data.Map as M
@@ -37,6 +38,10 @@ root 1
3738|--- branchA aaaa
3839|--- branchB bbbb
3940-}
41+
42+createTrans :: TransactionId -> TransactionInfo -> DatabaseContext -> Transaction
43+createTrans tid info ctx = Transaction tid info (Schemas ctx M.empty)
44+
4045basicTransactionGraph :: IO TransactionGraph
4146basicTransactionGraph = do
4247 let bsGraph = bootstrapTransactionGraph uuidRoot DBC.empty --dateExamples
@@ -46,9 +51,9 @@ basicTransactionGraph = do
4651 uuidA = fakeUUID 10
4752 uuidB = fakeUUID 11
4853 uuidRoot = fakeUUID 1
49− rootContext = transactionContext rootTrans
50− (_, bsGraph') <- addTransaction "branchA" (Transaction uuidA (TransactionInfo uuidRoot S.empty) rootContext) bsGraph
51− (_, bsGraph'') <- addTransaction "branchB" (Transaction uuidB (TransactionInfo uuidRoot S.empty) rootContext) bsGraph'
54+ rootContext = concreteDatabaseContext rootTrans
55+ (_, bsGraph') <- addTransaction "branchA" (createTrans uuidA (TransactionInfo uuidRoot S.empty) rootContext) bsGraph
56+ (_, bsGraph'') <- addTransaction "branchB" (createTrans uuidB (TransactionInfo uuidRoot S.empty) rootContext) bsGraph'
5257 pure bsGraph''
5358
5459addTransaction :: HeadName -> Transaction -> TransactionGraph -> IO (Transaction, TransactionGraph)
@@ -85,7 +90,8 @@ testSubGraphToFirstAncestorBasic = TestCase $ do
8590 transA <- assertMaybe (transactionForHead "branchA" graph) "failed to get branchA"
8691 transB <- assertMaybe (transactionForHead "branchB" graph) "failed to get branchB"
8792 subgraph <- assertEither $ subGraphOfFirstCommonAncestor graph (transactionHeadsForGraph graph) transA transB S.empty
88− assertEqual "no graph changes" subgraph graph
93+ let graphEq graphArg = S.map transactionId (transactionsForGraph graphArg)
94+ assertEqual "no graph changes" (graphEq subgraph) (graphEq graph)
8995
9096-- | Test that a branch anchored at the root transaction is removed when using the first ancestor function.
9197testSubGraphToFirstAncestorSnipBranch :: Test
@@ -93,10 +99,11 @@ testSubGraphToFirstAncestorSnipBranch = TestCase $ do
9399 baseGraph <- basicTransactionGraph
94100 transA <- assertMaybe (transactionForHead "branchA" baseGraph) "failed to get branchA"
95101 transB <- assertMaybe (transactionForHead "branchB" baseGraph) "failed to get branchB"
96− (_, graph) <- addTransaction "branchC" (Transaction (fakeUUID 12) (TransactionInfo (fakeUUID 1) S.empty) (transactionContext transA)) baseGraph
102+ (_, graph) <- addTransaction "branchC" (createTrans (fakeUUID 12) (TransactionInfo (fakeUUID 1) S.empty) (concreteDatabaseContext transA)) baseGraph
97103 subgraph <- assertEither $ subGraphOfFirstCommonAncestor graph (transactionHeadsForGraph baseGraph) transA transB S.empty
98104 assertGraph subgraph
99− assertEqual "failed to snip branch" baseGraph subgraph
105+ let graphEq graphArg = S.map transactionId (transactionsForGraph graphArg)
106+ assertEqual "failed to snip branch" (graphEq baseGraph) (graphEq subgraph)
100107
101108-- | Test that the subgraph function recurses properly through multiple parent transactions.
102109testSubGraphToFirstAncestorMoreTransactions :: Test
@@ -106,16 +113,16 @@ testSubGraphToFirstAncestorMoreTransactions = TestCase $ do
106113
107114 -- add another relvar to branchB
108115 branchBTrans <- assertMaybe (transactionForHead "branchB" graph) "failed to get branchB head"
109− updatedBranchBContext <- case runState (evalContextExpr (Assign "branchBOnlyRelvar" (ExistingRelation relationTrue))) (transactionContext branchBTrans) of
116+ updatedBranchBContext <- case runState (evalContextExpr (Assign "branchBOnlyRelvar" (ExistingRelation relationTrue))) (concreteDatabaseContext branchBTrans) of
110117 (Just err, _) -> assertFailure (show err) >> undefined
111118 (Nothing, context) -> pure context
112− (_, graph') <- addTransaction "branchB" (Transaction (fakeUUID 3) (TransactionInfo (transactionId branchBTrans) S.empty) updatedBranchBContext) graph
119+ (_, graph') <- addTransaction "branchB" (createTrans (fakeUUID 3) (TransactionInfo (transactionId branchBTrans) S.empty) updatedBranchBContext) graph
113120 branchBTrans' <- assertMaybe (transactionForHead "branchB" graph') "failed to get branchB head"
114121 assertEqual "branchB id 3" (fakeUUID 3) (transactionId branchBTrans')
115122
116123 -- add another transaction to branchA
117124 branchATrans <- assertMaybe (transactionForHead "branchA" graph) "failed to get branchA head"
118− (_, graph'') <- addTransaction "branchA" (Transaction (fakeUUID 4) (TransactionInfo (transactionId branchATrans) S.empty) (transactionContext branchATrans)) graph'
125+ (_, graph'') <- addTransaction "branchA" (createTrans (fakeUUID 4) (TransactionInfo (transactionId branchATrans) S.empty) (concreteDatabaseContext branchATrans)) graph'
119126 branchATrans' <- assertMaybe (transactionForHead "branchA" graph'') "failed to get branchA head"
120127 assertEqual "branchA id 4" (fakeUUID 4) (transactionId branchATrans')
121128
@@ -133,10 +140,10 @@ testSelectedBranchMerge = TestCase $ do
133140
134141 -- add another relvar to branchB
135142 branchBTrans <- assertMaybe (transactionForHead "branchB" graph) "failed to get branchB head"
136− updatedBranchBContext <- case runState (evalContextExpr (Assign "branchBOnlyRelvar" (ExistingRelation relationTrue))) (transactionContext branchBTrans) of
143+ updatedBranchBContext <- case runState (evalContextExpr (Assign "branchBOnlyRelvar" (ExistingRelation relationTrue))) (concreteDatabaseContext branchBTrans) of
137144 (Just err, _) -> assertFailure (show err) >> undefined
138145 (Nothing, context) -> pure context
139− (_, graph') <- addTransaction "branchB" (Transaction (fakeUUID 3) (TransactionInfo (transactionId branchBTrans) S.empty) updatedBranchBContext) graph
146+ (_, graph') <- addTransaction "branchB" (createTrans (fakeUUID 3) (TransactionInfo (transactionId branchBTrans) S.empty) updatedBranchBContext) graph
140147 --create the merge transaction in the graph
141148 let eGraph' = mergeTransactions (fakeUUID 4) (fakeUUID 10) (SelectedBranchMergeStrategy "branchA") ("branchA", "branchB") graph'
142149
@@ -149,7 +156,7 @@ testSelectedBranchMerge = TestCase $ do
149156
150157 --validate that the branchB relvar does *not* appear in the merge because branchA was selected
151158 mergeTrans <- assertEither (transactionForId (fakeUUID 4) graph'')
152− assertBool "branchOnlyRelvar is present in merge" (M.notMember "branchBOnlyRelvar" (relationVariables (transactionContext mergeTrans)))
159+ assertBool "branchOnlyRelvar is present in merge" (M.notMember "branchBOnlyRelvar" (relationVariables (concreteDatabaseContext mergeTrans)))
153160
154161-- try various individual component conflicts and check for resolution
155162testUnionPreferMergeStrategy :: Test
@@ -159,19 +166,19 @@ testUnionPreferMergeStrategy = TestCase $ do
159166 branchATrans <- assertMaybe (transactionForHead "branchA" graph) "branchATrans"
160167 branchBTrans <- assertMaybe (transactionForHead "branchB" graph) "branchBTrans"
161168 branchBRelVar <- assertEither $ mkRelationFromList (attributesFromList [Attribute "conflict" IntAtomType]) []
162− let branchAContext = (transactionContext branchATrans) {relationVariables = M.insert conflictRelVarName branchARelVar (relationVariables (transactionContext branchATrans))}
169+ let branchAContext = (concreteDatabaseContext branchATrans) {relationVariables = M.insert conflictRelVarName branchARelVar (relationVariables (concreteDatabaseContext branchATrans))}
163170 branchARelVar = relationTrue
164− branchBContext = (transactionContext branchBTrans) {relationVariables = M.insert conflictRelVarName branchBRelVar (relationVariables (transactionContext branchBTrans))}
171+ branchBContext = (concreteDatabaseContext branchBTrans) {relationVariables = M.insert conflictRelVarName branchBRelVar (relationVariables (concreteDatabaseContext branchBTrans))}
165172 conflictRelVarName = "conflictRelVar"
166173
167− (_, graph') <- addTransaction "branchA" (Transaction (fakeUUID 3) (TransactionInfo (transactionId branchATrans) S.empty) branchAContext) graph
168− (_, graph'') <- addTransaction "branchB" (Transaction (fakeUUID 4) (TransactionInfo (transactionId branchBTrans) S.empty) branchBContext) graph'
174+ (_, graph') <- addTransaction "branchA" (createTrans (fakeUUID 3) (TransactionInfo (transactionId branchATrans) S.empty) branchAContext) graph
175+ (_, graph'') <- addTransaction "branchB" (createTrans (fakeUUID 4) (TransactionInfo (transactionId branchBTrans) S.empty) branchBContext) graph'
169176 -- validate that the conflict is hidden because we preferred a branch
170177 let merged = mergeTransactions (fakeUUID 5) (fakeUUID 3) (UnionPreferMergeStrategy "branchB") ("branchA", "branchB") graph''
171178 case merged of
172179 Left err -> assertFailure ("expected merge success: " ++ show err)
173− Right (DisconnectedTransaction _ mergeContext, _) -> do
174− assertEqual "branchB relvar preferred in conflict" (Just branchBRelVar) (M.lookup conflictRelVarName (relationVariables mergeContext))
180+ Right (discon, _) -> do
181+ assertEqual "branchB relvar preferred in conflict" (Just branchBRelVar) (M.lookup conflictRelVarName (relationVariables (Discon.concreteDatabaseContext discon)))
175182
176183-- try various individual component conflicts and check for merge failure
177184testUnionMergeStrategy :: Test
@@ -184,23 +191,23 @@ testUnionMergeStrategy = TestCase $ do
184191 -- add another relvar to branchB - branchBOnlyRelvar should appear in the merge
185192 -- add inclusion dependency in branchA
186193
187− let updatedBranchBContext = (transactionContext branchBTrans) {relationVariables = M.insert branchBOnlyRelVarName branchBOnlyRelVar (relationVariables (transactionContext branchBTrans)) }
188− updatedBranchAContext = (transactionContext branchATrans) {inclusionDependencies = M.insert branchAOnlyIncDepName branchAOnlyIncDep (inclusionDependencies (transactionContext branchATrans)) }
194+ let updatedBranchBContext = (concreteDatabaseContext branchBTrans) {relationVariables = M.insert branchBOnlyRelVarName branchBOnlyRelVar (relationVariables (concreteDatabaseContext branchBTrans)) }
195+ updatedBranchAContext = (concreteDatabaseContext branchATrans) {inclusionDependencies = M.insert branchAOnlyIncDepName branchAOnlyIncDep (inclusionDependencies (concreteDatabaseContext branchATrans)) }
189196 branchBOnlyRelVar = relationTrue
190197 branchAOnlyIncDepName = "branchAOnlyIncDep"
191198 branchBOnlyRelVarName = "branchBOnlyRelVar"
192199 branchAOnlyIncDep = InclusionDependency (ExistingRelation relationTrue) (ExistingRelation relationTrue)
193− (_, graph') <- addTransaction "branchB" (Transaction (fakeUUID 3) (TransactionInfo (transactionId branchBTrans) S.empty) updatedBranchBContext) graph
194− ((DisconnectedTransaction _ mergeContext1), _) <- assertEither $ mergeTransactions (fakeUUID 5) (fakeUUID 10) UnionMergeStrategy ("branchA", "branchB") graph'
195− assertEqual "branchBOnlyRelVar should appear in the merge" (M.lookup branchBOnlyRelVarName (relationVariables mergeContext1)) (Just relationTrue)
196− (_, graph'') <- addTransaction "branchA" (Transaction (fakeUUID 4) (TransactionInfo (transactionId branchATrans) S.empty) updatedBranchAContext) graph'
200+ (_, graph') <- addTransaction "branchB" (createTrans (fakeUUID 3) (TransactionInfo (transactionId branchBTrans) S.empty) updatedBranchBContext) graph
201+ (discon, _) <- assertEither $ mergeTransactions (fakeUUID 5) (fakeUUID 10) UnionMergeStrategy ("branchA", "branchB") graph'
202+ assertEqual "branchBOnlyRelVar should appear in the merge" (M.lookup branchBOnlyRelVarName (relationVariables (Discon.concreteDatabaseContext discon))) (Just relationTrue)
203+ (_, graph'') <- addTransaction "branchA" (createTrans (fakeUUID 4) (TransactionInfo (transactionId branchATrans) S.empty) updatedBranchAContext) graph'
197204 let eMergeGraph = mergeTransactions (fakeUUID 5) (fakeUUID 3) UnionMergeStrategy ("branchA", "branchB") graph''
198205 case eMergeGraph of
199206 Left err -> assertFailure ("expected merge success: " ++ show err)
200207 Right (_, mergeGraph) -> do
201208 -- check that the new merge transaction has the correct parents
202209 mergeTrans <- assertEither $ transactionForId (fakeUUID 5) mergeGraph
203− let mergeContext = transactionContext mergeTrans
210+ let mergeContext = concreteDatabaseContext mergeTrans
204211 assertEqual "merge transaction parents" (transactionParentIds mergeTrans) (S.fromList [fakeUUID 3, fakeUUID 4])
205212 -- check that the new merge tranasction has elements from both A and B branches
206213 assertEqual "merge transaction relvars" (Just relationTrue) (M.lookup branchBOnlyRelVarName (relationVariables mergeContext))
@@ -209,7 +216,7 @@ testUnionMergeStrategy = TestCase $ do
209216 conflictRelVar <- assertEither $ mkRelationFromList (attributesFromList [Attribute "conflict" IntAtomType]) []
210217 let conflictContextA = updatedBranchAContext {relationVariables = M.insert branchBOnlyRelVarName conflictRelVar (relationVariables updatedBranchAContext) }
211218 conflictBranchATrans <- assertMaybe (transactionForHead "branchA" graph'') "retrieving head transaction for expected conflict"
212− (_, graph''') <- addTransaction "branchA" (Transaction (fakeUUID 6) (TransactionInfo (transactionId conflictBranchATrans) S.empty) conflictContextA) graph''
219+ (_, graph''') <- addTransaction "branchA" (createTrans (fakeUUID 6) (TransactionInfo (transactionId conflictBranchATrans) S.empty) conflictContextA) graph''
213220 let failingMerge = mergeTransactions (fakeUUID 5) (fakeUUID 3) UnionMergeStrategy ("branchA", "branchB") graph'''
214221 case failingMerge of
215222 Right _ -> assertFailure "expected merge failure"