on master help sign in
add feature: createarbitraryrelation. Usage: createarbitraryrelation rvname {name Text, number Integer} 10-20
commit8285a5811b9ae6a14612f2462fe2e133bb231df5 authorJohnny Liao <dycan0716@gmail.com> dateMon 21 May 2018, 15:46 (8 years ago) parent6c82550
6 files changed+142−9
src/bin/TutorialD/Interpreter/DatabaseContextIOOperator.hs+13−1 src/bin/TutorialD/tutd.hs+3 src/lib/ProjectM36/Attribute.hs+2−2 src/lib/ProjectM36/Base.hs+22−4 src/lib/ProjectM36/MyTest.hs+83 src/lib/ProjectM36/RelationalExpression.hs+19−2
src/bin/TutorialD/Interpreter/DatabaseContextIOOperator.hs+13−1
@@ -4,6 +4,7 @@ import ProjectM36.Base
44
55import TutorialD.Interpreter.Base
66import TutorialD.Interpreter.Types
7+import TutorialD.Interpreter.RelationalExpr
78import Text.Megaparsec
89import Text.Megaparsec.Text
910import Data.Text
@@ -13,6 +14,16 @@ addAtomFunctionExprP = dbioexprP "addatomfunction" AddAtomFunction
1314
1415addDatabaseContextFunctionExprP :: Parser DatabaseContextIOExpr
1516addDatabaseContextFunctionExprP = dbioexprP "adddatabasecontextfunction" AddDatabaseContextFunction
17+
18+createArbitraryRelationP :: Parser DatabaseContextIOExpr
19+createArbitraryRelationP = do
20+ reserved "createarbitraryrelation"
21+ relVarName <- identifier
22+ attrExprs <- makeAttributeExprsP :: Parser [AttributeExpr]
23+ min <- fromInteger <$> integer
24+ symbol "-"
25+ max <- fromInteger <$> integer
26+ pure $ CreateArbitraryRelation relVarName attrExprs (min,max)
1627
1728dbioexprP :: String -> (Text -> [TypeConstructor] -> Text -> DatabaseContextIOExpr) -> Parser DatabaseContextIOExpr
1829dbioexprP res adt = do
@@ -29,7 +40,8 @@ dbContextIOExprP :: Parser DatabaseContextIOExpr
2940dbContextIOExprP = addAtomFunctionExprP <|>
3041 addDatabaseContextFunctionExprP <|>
3142 loadAtomFunctionsP <|>
32− loadDatabaseContextFunctionsP
43+ loadDatabaseContextFunctionsP <|>
44+ createArbitraryRelationP
3345
3446loadAtomFunctionsP :: Parser DatabaseContextIOExpr
3547loadAtomFunctionsP = do
src/bin/TutorialD/tutd.hs+3
@@ -82,6 +82,9 @@ printWelcome = do
8282
8383main :: IO ()
8484main = do
85+ hSetEncoding stdin utf8
86+ hSetEncoding stdout utf8
87+ hSetEncoding stderr utf8
8588 interpreterConfig <- execParser opts
8689 let connInfo = connectionInfoForConfig interpreterConfig
8790 fscheck <- checkFSType (checkFSForConfig interpreterConfig) (fromMaybe NoPersistence (persistenceStrategyForConfig interpreterConfig))
src/lib/ProjectM36/Attribute.hs+2−2
@@ -135,7 +135,7 @@ verifyAttributes attrs = if collapsedAttrs /= attrs then
135135 collapsedAttrs = vectorUniqueify attrs
136136
137137attributesEqual :: Attributes -> Attributes -> Bool
138−attributesEqual attrs1 attrs2 = V.null (attributesDifference attrs1 attrs2)
138+attributesEqual attrs1 attrs2 = V.null (attributesDifference attrs1 attrs2)
139139
140140attributesAsMap :: Attributes -> M.Map AttributeName Attribute
141141attributesAsMap attrs = (M.fromList . V.toList) (V.map (\attr -> (attributeName attr, attr)) attrs)
@@ -149,4 +149,4 @@ union attrsA attrsB = V.fromList (M.elems unioned)
149149intersection :: Attributes -> Attributes -> Attributes
150150intersection attrsA attrsB = V.fromList (M.elems intersected)
151151 where
152− intersected = M.intersection (attributesAsMap attrsA) (attributesAsMap attrsB)
152+ intersected = M.intersection (attributesAsMap attrsA) (attributesAsMap attrsB)
src/lib/ProjectM36/Base.hs+22−4
@@ -344,12 +344,13 @@ data DatabaseContextExpr =
344344
345345type ObjModuleName = StringType
346346type ObjFunctionName = StringType
347−
347+type Range = (Int,Int)
348348-- | Adding an atom function should be nominally a DatabaseExpr except for the fact that it cannot be performed purely. Thus, we create the DatabaseContextIOExpr.
349349data DatabaseContextIOExpr = AddAtomFunction AtomFunctionName [TypeConstructor] AtomFunctionBodyScript |
350350 LoadAtomFunctions ObjModuleName ObjFunctionName FilePath |
351351 AddDatabaseContextFunction DatabaseContextFunctionName [TypeConstructor] DatabaseContextFunctionBodyScript |
352− LoadDatabaseContextFunctions ObjModuleName ObjFunctionName FilePath
352+ LoadDatabaseContextFunctions ObjModuleName ObjFunctionName FilePath |
353+ CreateArbitraryRelation RelVarName [AttributeExpr] Range
353354 deriving (Show, Eq, Generic, Binary)
354355
355356type RestrictionPredicateExpr = RestrictionPredicateExprBase ()
@@ -540,9 +541,8 @@ instance Eq DatabaseContextFunction where
540541
541542
542543-- for creating arbitrary tuples
543−
544544instance Arbitrary Text where
545− arbitrary = pack <$> elements ["Mary", "Johnny", "Sunny", "Ted"] --(arbitrary :: Gen String)
545+ arbitrary = pack <$> elements ["Mary", "Johnny", "Sunny", "Ted"]
546546
547547instance Arbitrary Day where
548548 arbitrary = ModifiedJulianDay <$> (arbitrary :: Gen Integer)
@@ -583,6 +583,15 @@ instance Arbitrary Relation where
583583 list <- listOf (arbitrary :: Gen RelationTuple)
584584 return $ Relation defAttributes (RelationTupleSet list)
585585
586+arbitraryRelationTuple attris = do
587+ let attrisG = V.fromList <$> mapM (arbitrary'.getAtomType) (V.toList attris)
588+ RelationTuple attris <$> attrisG
589+
590+arbitraryRel attris bound@(min,max) = do
591+ num <- choose (min,max)
592+ let tupleListG = vectorOf num (arbitraryRelationTuple attris)
593+ Relation attris <$> (RelationTupleSet <$> tupleListG)
594+
586595instance Arbitrary AtomType where
587596 arbitrary = genericArbitrary
588597
@@ -591,4 +600,13 @@ instance Arbitrary Atom where
591600
592601instance ToADTArbitrary Atom
593602
603+arbitrary' :: AtomType -> Gen Atom
604+arbitrary' IntAtomType = IntAtom <$> (arbitrary :: Gen Int)
605+arbitrary' IntegerAtomType = IntegerAtom <$> (arbitrary :: Gen Integer)
606+arbitrary' TextAtomType = TextAtom <$> (arbitrary :: Gen Text)
607+arbitrary' DayAtomType = DayAtom <$> (arbitrary :: Gen Day)
608+arbitrary' BoolAtomType = BoolAtom <$> (arbitrary :: Gen Bool)
609+arbitrary' _ = undefined
594610
611+getAtomType :: Attribute -> AtomType
612+getAtomType (Attribute _ atomType) = atomType
src/lib/ProjectM36/MyTest.hsnew file+83
@@ -0,0 +1,83 @@
1+{-# Language TypeSynonymInstances,FlexibleInstances,OverloadedStrings #-}
2+module ProjectM36.MyTest where
3+import ProjectM36.Base
4+import Test.QuickCheck
5+import Test.QuickCheck.Gen
6+import Test.QuickCheck.Random
7+import Test.QuickCheck.Arbitrary.ADT
8+import qualified Data.Text as T
9+import qualified Data.ByteString.Char8 as B
10+import Data.Time
11+import Data.Time.Clock
12+import qualified Data.Vector as V
13+import qualified Data.Map as M
14+
15+{-
16+instance Arbitrary Atom where
17+ arbitrary = IntAtom <$> int
18+ where int = (arbitrary :: Gen Int)
19+
20+genAtom :: IO Atom
21+genAtom = do
22+ seed <- newQCGen
23+ return $ unGen (arbitrary :: Gen Atom) seed (2^29-1)
24+-}
25+
26+instance Arbitrary T.Text where
27+ arbitrary = T.pack <$> elements ["Mary", "Johnny", "Sunny", "Ted"] --(arbitrary :: Gen String)
28+
29+instance Arbitrary Day where
30+ arbitrary = ModifiedJulianDay <$> (arbitrary :: Gen Integer)
31+
32+instance Arbitrary Attribute where
33+ arbitrary = genericArbitrary
34+
35+instance (Arbitrary a) => Arbitrary (V.Vector a) where
36+ arbitrary = do
37+ maxbound <- choose (0,5)
38+ V.fromList <$> vectorOf maxbound arbitrary
39+
40+instance {-# OVERLAPPING #-} Arbitrary TypeVarMap where
41+ arbitrary = undefined
42+
43+instance Arbitrary UTCTime where
44+ arbitrary = UTCTime <$> arbitrary <*> (secondsToDiffTime <$> arbitrary)
45+
46+instance Arbitrary B.ByteString where
47+ arbitrary = B.pack <$> (arbitrary :: Gen String)
48+
49+-- arbitrary attributes seems to involve dependant-type techniques and seems unneccsary for a dud example.
50+attributeNames = ["Number","People","Time","Thing"]
51+atomtypes = [IntAtomType, TextAtomType, DayAtomType, TextAtomType]
52+attributes = V.fromList $ zipWith Attribute attributeNames atomtypes
53+
54+instance Arbitrary RelationTuple where
55+ arbitrary = do
56+ a <- IntAtom <$> (arbitrary :: Gen Int)
57+ b <- TextAtom <$> (arbitrary :: Gen T.Text)
58+ c <- DayAtom <$> (arbitrary :: Gen Day)
59+ d <- TextAtom <$> (arbitrary :: Gen T.Text)
60+ let sample = V.fromList [a,b,c,d]
61+ return $ RelationTuple attributes sample
62+
63+instance Arbitrary Relation where
64+ arbitrary = do
65+ list <- listOf (arbitrary :: Gen RelationTuple)
66+ return $ Relation attributes (RelationTupleSet list)
67+
68+
69+instance Arbitrary AtomType where
70+ arbitrary = genericArbitrary
71+
72+instance Arbitrary Atom where
73+ arbitrary = genericArbitrary
74+
75+instance ToADTArbitrary Atom
76+
77+
78+--three parts
79+-- s# generation
80+-- expr -> Relation
81+-- keyword arbitrary
82+-- database context: seed + expr
83+--
src/lib/ProjectM36/RelationalExpression.hs+19−2
@@ -25,7 +25,7 @@ import qualified Data.Vector as V
2525import qualified ProjectM36.TypeConstructorDef as TCD
2626import Control.Monad.Trans.Except
2727import Control.Monad.Trans.Reader
28−
28+import Test.QuickCheck
2929import GHC
3030import GHC.Paths
3131
@@ -575,7 +575,24 @@ evalDatabaseContextIOExpr _ currentContext (LoadDatabaseContextFunctions modName
575575 Right dbcListFunc -> let newContext = currentContext { dbcFunctions = mergedFuncs }
576576 mergedFuncs = HS.union (dbcFunctions currentContext) (HS.fromList dbcListFunc)
577577 in pure (Right newContext)
578−
578+
579+evalDatabaseContextIOExpr _ currentContext (CreateArbitraryRelation relVarName attrExprs range) = do
580+ --Define
581+ case runState ( evalDatabaseContextExpr (Define relVarName attrExprs)) (freshDatabaseState currentContext) of
582+ (Left err,_) -> pure (Left err)
583+ (Right (), elems@(ctx,_,_)) -> do
584+ --Assign
585+ let existingRelVar = M.lookup relVarName relVarTable
586+ relVarTable = relationVariables ctx
587+ case existingRelVar of
588+ Nothing -> pure $ Left (RelVarNotDefinedError relVarName)
589+ Just existingRel -> do
590+ let expectedAttributes = attributes existingRel
591+ rel <- generate $ arbitraryRel expectedAttributes range
592+ case runState (setRelVar relVarName rel) elems of
593+ (Left err,_) -> pure (Left err)
594+ (Right (), (ctx',_,_)) -> pure $ Right ctx'
595+
579596updateTupleWithAtomExprs :: M.Map AttributeName AtomExpr -> DatabaseContext -> RelationTuple -> Either RelationalError RelationTuple
580597updateTupleWithAtomExprs exprMap context tupIn = do
581598 --resolve all atom exprs