@@ -3,11 +3,13 @@ import TutorialD.Interpreter.DatabaseExpr
33import TutorialD.Interpreter
44import TutorialD.Interpreter.Base
55import Test.HUnit
6−import ProjectM36.RelationalExpression
76import ProjectM36.Relation
87import ProjectM36.Tuple
98import ProjectM36.TupleSet
109import ProjectM36.Error
10+import ProjectM36.DatabaseContext
11+import ProjectM36.DataTypes.Primitive
12+import ProjectM36.DateExamples
1113import ProjectM36.Base hiding (Finite)
1214import qualified ProjectM36.Base as Base
1315import ProjectM36.TransactionGraph
@@ -22,9 +24,6 @@ import qualified Data.Vector as V
2224import Data.Text.Encoding as TE
2325import Data.Typeable (Proxy(..))
2426import Data.Text (Text)
25−import Data.Time.Clock (UTCTime(..))
26−import Data.Time.Calendar (fromGregorian)
27−import Data.Interval (interval, Interval, Extended(Finite))
2827import Control.Concurrent.STM
2928import Control.Concurrent
3029import qualified STMContainers.Map as STMMap
@@ -39,13 +38,13 @@ main = do
3938 ("x:=false", Right relationFalse),
4039 ("x:=true union false", Right relationTrue),
4140 ("x:=true; x:=false", Right relationFalse),
42− ("x:=relation{a int}", mkRelation simpleAAttributes emptyTupleSet),
43− ("x:=relation{c int} rename {c as d}", mkRelation simpleBAttributes emptyTupleSet),
44− ("y:=relation{b int, c int}; x:=y{c}", mkRelation simpleProjectionAttributes emptyTupleSet),
45− ("x:=relation{tuple{a \"spam\", b 5}}", mkRelation simpleCAttributes $ RelationTupleSet [(RelationTuple simpleCAttributes) (V.fromList [stringAtom "spam", intAtom 5])]),
41+ ("x:=relation{a Int}{}", mkRelation simpleAAttributes emptyTupleSet),
42+ ("x:=relation{c Int}{} rename {c as d}", mkRelation simpleBAttributes emptyTupleSet),
43+ ("y:=relation{b Int, c Int}{}; x:=y{c}", mkRelation simpleProjectionAttributes emptyTupleSet),
44+ ("x:=relation{tuple{a \"spam\", b 5}}", mkRelation simpleCAttributes $ RelationTupleSet [(RelationTuple simpleCAttributes) (V.fromList [textAtom "spam", intAtom 5])]),
4645 ("constraint failc true in false; x:=true", Left $ InclusionDependencyCheckError "failc"),
4746 ("x:=y; x:=true", Left $ RelVarNotDefinedError "y"),
48− ("x:=relation{}", Right relationFalse),
47+ ("x:=relation{}{}", Right relationFalse),
4948 ("x:=relation{tuple{}}", Right relationTrue),
5049 ("x:=true where true", Right relationTrue),
5150 ("x:=true where false", Right relationFalse),
@@ -56,50 +55,49 @@ main = do
5655 ("x:=true=true", Right relationTrue),
5756 ("x:=true=false", Right relationFalse),
5857 ("x:=true; undefine x", Left (RelVarNotDefinedError "x")),
59− ("x:=relation {b int, a char}; insert x relation{tuple{b 5, a \"spam\"}}", mkRelationFromTuples simpleCAttributes [RelationTuple simpleCAttributes $ V.fromList[stringAtom "spam", intAtom 5]]),
58+ ("x:=relation {b Int, a Text}{}; insert x relation{tuple{b 5, a \"spam\"}}", mkRelationFromTuples simpleCAttributes [RelationTuple simpleCAttributes $ V.fromList[textAtom "spam", intAtom 5]]),
6059 -- test nested relation constructor
6160 ("x:=relation{tuple{a 5, b relation{tuple{a 6}}}}", mkRelation nestedRelationAttributes $ RelationTupleSet [RelationTuple nestedRelationAttributes (V.fromList [intAtom 5, Atom (Relation simpleAAttributes $ RelationTupleSet [RelationTuple simpleAAttributes $ V.fromList [intAtom 6]])])]),
62− ("x:=relation{tuple{b 5,a \"spam\"},tuple{b 6,a \"sam\"}}; delete x where b=6", mkRelation simpleCAttributes $ RelationTupleSet [RelationTuple simpleCAttributes (V.fromList [stringAtom "spam", intAtom 5])]),
61+ ("x:=relation{tuple{b 5,a \"spam\"},tuple{b 6,a \"sam\"}}; delete x where b=6", mkRelation simpleCAttributes $ RelationTupleSet [RelationTuple simpleCAttributes (V.fromList [textAtom "spam", intAtom 5])]),
6362 ("x:=relation{tuple{a 5}} : {b:=@a}", mkRelation simpleDAttributes $ RelationTupleSet [RelationTuple simpleDAttributes (V.fromList [intAtom 5, intAtom 5])]),
6463 ("x:=relation{tuple{a 5}} : {b:=6}", mkRelationFromTuples simpleDAttributes [RelationTuple simpleDAttributes (V.fromList [intAtom 5, intAtom 6])]),
6564 ("x:=relation{tuple{a 5}} : {b:=add(@a,5)}", mkRelationFromTuples simpleDAttributes [RelationTuple simpleDAttributes (V.fromList [intAtom 5, intAtom 10])]),
66− ("x:=relation{tuple{a 5}} : {b:=add(@a,\"spam\")}", Left (AtomFunctionTypeError "add" 2 intAtomType stringAtomType)),
65+ ("x:=relation{tuple{a 5}} : {b:=add(@a,\"spam\")}", Left (AtomFunctionTypeError "add" 2 intAtomType textAtomType)),
6766 ("x:=relation{tuple{a 5}} : {b:=add(add(@a,2),5)}", mkRelationFromTuples simpleDAttributes [RelationTuple simpleDAttributes (V.fromList [intAtom 5, intAtom 12])])
6867 ]
6968 simpleAAttributes = A.attributesFromList [Attribute "a" intAtomType]
7069 simpleBAttributes = A.attributesFromList [Attribute "d" intAtomType]
71− simpleCAttributes = A.attributesFromList [Attribute "a" stringAtomType, Attribute "b" intAtomType]
70+ simpleCAttributes = A.attributesFromList [Attribute "a" textAtomType, Attribute "b" intAtomType]
7271 simpleDAttributes = A.attributesFromList [Attribute "a" intAtomType, Attribute "b" intAtomType]
7372 simpleMaybeTextAttributes = A.attributesFromList [Attribute "a" $ atomTypeForProxy (Proxy :: Proxy (Maybe Text))]
7473 simpleMaybeIntAttributes = A.attributesFromList [Attribute "a" $ atomTypeForProxy (Proxy :: Proxy (Maybe Int))]
75− simpleIntervalDateTimeAttributes = A.attributesFromList [Attribute "a" $ atomTypeForProxy (Proxy :: Proxy (Interval UTCTime))]
7674 simpleProjectionAttributes = A.attributesFromList [Attribute "c" intAtomType]
7775 nestedRelationAttributes = A.attributesFromList [Attribute "a" intAtomType, Attribute "b" (RelationAtomType $ A.attributesFromList [Attribute "a" intAtomType])]
7876 extendTestAttributes = A.attributesFromList [Attribute "a" intAtomType, Attribute "b" $ RelationAtomType (attributes suppliersRel)]
7977 byteStringAttributes = A.attributesFromList [Attribute "y" byteStringAtomType]
8078 groupCountAttrs = A.attributesFromList [Attribute "z" intAtomType]
81− minMaxAttrs = A.attributesFromList [Attribute "S#" stringAtomType, Attribute "z" intAtomType]
79+ minMaxAttrs = A.attributesFromList [Attribute "S#" textAtomType, Attribute "z" intAtomType]
8280 dateExampleRelTests = [("x:=S where true", Right suppliersRel),
83− ("x:=S where CITY = \"London\"", restrict (\tuple -> atomForAttributeName "CITY" tuple == (Right $ stringAtom "London")) suppliersRel),
81+ ("x:=S where CITY = \"London\"", restrict (\tuple -> atomForAttributeName "CITY" tuple == (Right $ textAtom "London")) suppliersRel),
8482 ("x:=S where false", Right $ Relation (attributes suppliersRel) emptyTupleSet),
85− ("x:=P where COLOR=\"Blue\" and CITY=\"Paris\"", mkRelationFromList (attributes productsRel) [[stringAtom "P5", stringAtom "Cam", stringAtom "Blue", intAtom 12, stringAtom "Paris"]]),
83+ ("x:=P where COLOR=\"Blue\" and CITY=\"Paris\"", mkRelationFromList (attributes productsRel) [[textAtom "P5", textAtom "Cam", textAtom "Blue", intAtom 12, textAtom "Paris"]]),
8684 ("a:=S; update a (STATUS:=50); x:=a{STATUS}", mkRelation (A.attributesFromList [Attribute "STATUS" intAtomType]) (RelationTupleSet [mkRelationTuple (A.attributesFromList [Attribute "STATUS" intAtomType]) (V.fromList [intAtom 50])])),
8785 --atom function tests
8886 ("x:=((S : {STATUS2 := add(10,@STATUS)}) where STATUS2=add(10,@STATUS)){CITY,S#,SNAME,STATUS}", Right suppliersRel),
89− ("x:=S; update x where SNAME=\"Blake\" (CITY:=\"Boston\")", relMap (\tuple -> if atomForAttributeName "SNAME" tuple == (Right $ stringAtom "Blake") then updateTuple (M.singleton "CITY" (stringAtom "Boston")) tuple else tuple) suppliersRel),
87+ ("x:=S; update x where SNAME=\"Blake\" (CITY:=\"Boston\")", relMap (\tuple -> if atomForAttributeName "SNAME" tuple == (Right $ textAtom "Blake") then updateTuple (M.singleton "CITY" (textAtom "Boston")) tuple else tuple) suppliersRel),
9088 ("x:=relation{tuple{a 5}} : {b:=S}", mkRelation extendTestAttributes (RelationTupleSet [mkRelationTuple extendTestAttributes (V.fromList [intAtom 5, Atom suppliersRel])])),
9189 --relatom function tests
9290 ("x:=((S group ({CITY} as y)):{z:=count(@y)}){z}", mkRelation groupCountAttrs (RelationTupleSet [mkRelationTuple groupCountAttrs (V.singleton $ intAtom 1)])),
9391 ("x:=(SP group ({S#} as y)) ungroup y", Right supplierProductsRel),
94− ("x:=((SP{S#,QTY}) group ({QTY} as x):{z:=max(@x)}){S#,z}", mkRelationFromList minMaxAttrs (map (\(s,i) -> [stringAtom s,intAtom i]) [("S1", 400), ("S2", 400), ("S3", 200), ("S4", 400)])),
95− ("x:=((SP{S#,QTY}) group ({QTY} as x):{z:=min(@x)}){S#,z}", mkRelationFromList minMaxAttrs (map (\(s,i) -> [stringAtom s,intAtom i]) [("S1", 100), ("S2", 300), ("S3", 200), ("S4", 200)])),
96− ("x:=((SP{S#,QTY}) group ({QTY} as x):{z:=sum(@x)}){S#,z}", mkRelationFromList minMaxAttrs (map (\(s,i) -> [stringAtom s,intAtom i]) [("S1", 1000), ("S2", 700), ("S3", 200), ("S4", 900)])),
92+ ("x:=((SP{S#,QTY}) group ({QTY} as x):{z:=max(@x)}){S#,z}", mkRelationFromList minMaxAttrs (map (\(s,i) -> [textAtom s,intAtom i]) [("S1", 400), ("S2", 400), ("S3", 200), ("S4", 400)])),
93+ ("x:=((SP{S#,QTY}) group ({QTY} as x):{z:=min(@x)}){S#,z}", mkRelationFromList minMaxAttrs (map (\(s,i) -> [textAtom s,intAtom i]) [("S1", 100), ("S2", 300), ("S3", 200), ("S4", 200)])),
94+ ("x:=((SP{S#,QTY}) group ({QTY} as x):{z:=sum(@x)}){S#,z}", mkRelationFromList minMaxAttrs (map (\(s,i) -> [textAtom s,intAtom i]) [("S1", 1000), ("S2", 700), ("S3", 200), ("S4", 900)])),
9795 --boolean function restriction
98− ("x:=S where ^lt(@STATUS,20)", mkRelationFromList (attributes suppliersRel) [[stringAtom "S2", stringAtom "Jones", intAtom 10, stringAtom "Paris"]]),
99− ("x:=S where ^gt(@STATUS,20)", mkRelationFromList (attributes suppliersRel) [[stringAtom "S3", stringAtom "Blake", intAtom 30, stringAtom "Paris"],
100− [stringAtom "S5", stringAtom "Adams", intAtom 30, stringAtom "Athens"]]),
96+ ("x:=S where ^lt(@STATUS,20)", mkRelationFromList (attributes suppliersRel) [[textAtom "S2", textAtom "Jones", intAtom 10, textAtom "Paris"]]),
97+ ("x:=S where ^gt(@STATUS,20)", mkRelationFromList (attributes suppliersRel) [[textAtom "S3", textAtom "Blake", intAtom 30, textAtom "Paris"],
98+ [textAtom "S5", textAtom "Adams", intAtom 30, textAtom "Athens"]]),
10199 ("x:=S where ^sum(@STATUS)", Left $ AtomTypeMismatchError intAtomType boolAtomType),
102− ("x:=S where ^not(gte(@STATUS,20))", mkRelationFromList (attributes suppliersRel) [[stringAtom "S2", stringAtom "Jones", intAtom 10, stringAtom "Paris"]]),
100+ ("x:=S where ^not(gte(@STATUS,20))", mkRelationFromList (attributes suppliersRel) [[textAtom "S2", textAtom "Jones", intAtom 10, textAtom "Paris"]]),
103101 --test "all but" attribute inversion syntax
104102 ("x:=S{all but S#} = S{CITY,SNAME,STATUS}", Right $ relationTrue),
105103 --test key syntax
@@ -108,14 +106,9 @@ main = do
108106 --test binary bytestring data type
109107 ("x:=relation{tuple{y \"dGVzdGRhdGE=\"::bytestring}}", mkRelationFromList byteStringAttributes [[Atom (TE.encodeUtf8 "testdata")]]),
110108 --test Maybe Text
111− ("x:=relation{tuple{a Just \"spam\"::maybe char}}", mkRelationFromList simpleMaybeTextAttributes [[Atom (Just "spam" :: Maybe Text)]]),
109+ ("x:=relation{tuple{a Just \"spam\"}}", mkRelationFromList simpleMaybeTextAttributes [[ConstructedAtom "Just" (ConstructedAtomType "Maybe" (M.singleton "a" textAtomType)) [textAtom "spam"]]]),
112110 --test Maybe Int
113− ("x:=relation{tuple{a Just 3::maybe int}}", mkRelationFromList simpleMaybeIntAttributes [[Atom (Just 3 :: Maybe Int)]]),
114− --test datetime interval
115− ("x:=relation{tuple{a interval_datetime((\"2015-01-01 00:00:00\",\"2016-01-01 00:00:00\"])}}", mkRelationFromList simpleIntervalDateTimeAttributes [
116− [Atom $ interval (Finite (UTCTime (fromGregorian 2015 1 1) 0), False)
117− (Finite (UTCTime (fromGregorian 2016 1 1) 0), True)]
118− ])
111+ ("x:=relation{tuple{a Just 3}}", mkRelationFromList simpleMaybeIntAttributes [[Atom (Just 3 :: Maybe Int)]])
119112 ]
120113
121114assertTutdEqual :: DatabaseContext -> Either RelationalError Relation -> String -> Assertion
@@ -205,24 +198,24 @@ transactionBranchTest = TestCase $ do
205198simpleJoinTest :: Test
206199simpleJoinTest = TestCase $ assertTutdEqual dateExamples joinedRel "x:=S join SP"
207200 where
208− attrs = A.attributesFromList [Attribute "CITY" stringAtomType,
201+ attrs = A.attributesFromList [Attribute "CITY" textAtomType,
209202 Attribute "QTY" intAtomType,
210− Attribute "P#" stringAtomType,
211− Attribute "S#" stringAtomType,
212− Attribute "SNAME" stringAtomType,
203+ Attribute "P#" textAtomType,
204+ Attribute "S#" textAtomType,
205+ Attribute "SNAME" textAtomType,
213206 Attribute "STATUS" intAtomType]
214− joinedRel = mkRelationFromList attrs [[stringAtom "London", intAtom 100, stringAtom "P6", stringAtom "S1", stringAtom "Smith", intAtom 20],
215− [stringAtom "London", intAtom 400, stringAtom "P3", stringAtom "S1", stringAtom "Smith", intAtom 20],
216− [stringAtom "London", intAtom 400, stringAtom "P5", stringAtom "S4", stringAtom "Clark", intAtom 20],
217− [stringAtom "London", intAtom 300, stringAtom "P1", stringAtom "S1", stringAtom "Smith", intAtom 20],
218− [stringAtom "Paris", intAtom 200, stringAtom "P2", stringAtom "S3", stringAtom "Blake", intAtom 30],
219− [stringAtom "Paris", intAtom 300, stringAtom "P1", stringAtom "S2", stringAtom "Jones", intAtom 10],
220− [stringAtom "London", intAtom 100, stringAtom "P5", stringAtom "S1", stringAtom "Smith", intAtom 20],
221− [stringAtom "London", intAtom 300, stringAtom "P4", stringAtom "S4", stringAtom "Clark", intAtom 20],
222− [stringAtom "Paris", intAtom 400, stringAtom "P2", stringAtom "S2", stringAtom "Jones", intAtom 10],
223− [stringAtom "London", intAtom 200, stringAtom "P2", stringAtom "S1", stringAtom "Smith", intAtom 20],
224− [stringAtom "London", intAtom 200, stringAtom "P4", stringAtom "S1", stringAtom "Smith", intAtom 20],
225− [stringAtom "London", intAtom 200, stringAtom "P2", stringAtom "S4", stringAtom "Clark", intAtom 20]
207+ joinedRel = mkRelationFromList attrs [[textAtom "London", intAtom 100, textAtom "P6", textAtom "S1", textAtom "Smith", intAtom 20],
208+ [textAtom "London", intAtom 400, textAtom "P3", textAtom "S1", textAtom "Smith", intAtom 20],
209+ [textAtom "London", intAtom 400, textAtom "P5", textAtom "S4", textAtom "Clark", intAtom 20],
210+ [textAtom "London", intAtom 300, textAtom "P1", textAtom "S1", textAtom "Smith", intAtom 20],
211+ [textAtom "Paris", intAtom 200, textAtom "P2", textAtom "S3", textAtom "Blake", intAtom 30],
212+ [textAtom "Paris", intAtom 300, textAtom "P1", textAtom "S2", textAtom "Jones", intAtom 10],
213+ [textAtom "London", intAtom 100, textAtom "P5", textAtom "S1", textAtom "Smith", intAtom 20],
214+ [textAtom "London", intAtom 300, textAtom "P4", textAtom "S4", textAtom "Clark", intAtom 20],
215+ [textAtom "Paris", intAtom 400, textAtom "P2", textAtom "S2", textAtom "Jones", intAtom 10],
216+ [textAtom "London", intAtom 200, textAtom "P2", textAtom "S1", textAtom "Smith", intAtom 20],
217+ [textAtom "London", intAtom 200, textAtom "P4", textAtom "S1", textAtom "Smith", intAtom 20],
218+ [textAtom "London", intAtom 200, textAtom "P2", textAtom "S4", textAtom "Clark", intAtom 20]
226219 ]
227220transactionGraph :: Connection -> IO TransactionGraph
228221transactionGraph (InProcessConnection _ _ _ tvar) = atomically $ readTVar tvar