@@ -4,12 +4,12 @@ module Relation where
44import qualified Data.Map as M
55import qualified Data.Set as S
66import qualified Data.HashSet as HS
7−import qualified Control.Monad.Error as Err
87
98import RelationType
109import RelationTuple
1110import RelationAttribute
1211import RelationTupleSet
12+import RelationalError
1313
1414testTuple1 = mkRelationTuple (S.fromList ["hair"]) (M.fromList [("hair", StringAtom "brown")])
1515
@@ -39,18 +39,16 @@ atomValueType (StringAtom _) = StringAtomType
3939atomValueType (IntAtom _) = IntAtomType
4040atomValueType (RelationAtom rel) = RelationAtomType (attributes rel)
4141
42−instance Err.Error RelationalError where
43−
4442mkRelation :: Attributes -> RelationTupleSet -> Either RelationalError Relation
4543mkRelation attrs tupleSet =
4644 --check that all tuples have the same keys
4745 --check that all tuples have keys (1-N) where N is the attribute count
4846 if differentTupleCounts
49− then Left $ RelationalError 1 "Tuple attribute count mismatch"
47+ then Left $ TupleAttributeCountMismatchError 0
5048 else if not (fst (verifyRelationTupleSet tupleSet))
51− then Left $ RelationalError 1 "Tuple values not of the same type for same keys"
49+ then Left $ TupleAttributeTypeMismatchError 0
5250 else if attrCountMismatch
53− then Left $ RelationalError 1 "Attribute count mismatch"
51+ then Left $ AttributeCountMismatchError 0
5452 else
5553 Right $ Relation attrs tupleSet
5654 where
@@ -70,7 +68,7 @@ madeFalse = mkRelation M.empty emptyTupleSet
7068union :: Relation -> Relation -> Either RelationalError Relation
7169union (Relation attrs1 tupSet1) (Relation attrs2 tupSet2) =
7270 if not (attrs1 == attrs2)
73− then Left $ RelationalError 1 ("Attribute mismatch " ++ show attrs1 ++ show attrs2)
71+ then Left $ AttributeNameMismatchError (show attrs1 ++ show attrs2)
7472 else
7573 Right $ Relation attrs1 newtuples
7674 where
@@ -79,7 +77,7 @@ union (Relation attrs1 tupSet1) (Relation attrs2 tupSet2) =
7977project :: S.Set AttributeName -> Relation -> Either RelationalError Relation
8078project projectionAttrNames rel@(Relation oldattrs rtuples) =
8179 if not $ attributeNamesContained projectionAttrNames (attributeNames rel)
82− then Left $ RelationalError 1 "Attributes mismatch"
80+ then Left $ AttributeNameMismatchError ""
8381 else
8482 relFold folder (Right $ Relation newAttrs HS.empty) rel
8583 where
@@ -98,9 +96,9 @@ tupleProject projectAttrs tupleIn@(RelationTuple tupleInMap) = RelationTuple $ M
9896rename :: AttributeName -> AttributeName -> Relation -> Either RelationalError Relation
9997rename oldAttrName newAttrName rel@(Relation oldAttrs oldTupSet) =
10098 if not attributeValid
101− then Left $ RelationalError 1 "No such attribute"
99+ then Left $ AttributeNameMismatchError ""
102100 else if newAttributeInUse
103− then Left $ RelationalError 1 ("Attribute \"" ++ newAttrName ++ "\" already in use.")
101+ then Left $ AttributeNameInUseError newAttrName
104102 else
105103 mkRelation newAttrs newTupSet
106104 where
@@ -194,7 +192,7 @@ tupleUngroup relvalAttrName newAttrs tuple@(RelationTuple tupMap) = case (tupMap
194192 where
195193 unsafeRelValFromAtom :: Atom -> Relation
196194 unsafeRelValFromAtom (RelationAtom rel) = rel
197− _ -> Left $ RelationalError 1 "Attribute is not relation-valued."
195+ _ -> Left $ AttributeIsNotRelationValuedError relvalAttrName
198196
199197--this is a hack needed because the relation attributes are untyped so we must dig into the relval to get the attribute names
200198attributesForRelval :: AttributeName -> Relation -> Attributes