1{-# LANGUAGE OverloadedStrings #-}
2module TutorialD.Interpreter.DatabaseExpr where
4import Text.Parsec.String
6import TutorialD.Interpreter.Base
7import qualified Data.Text as T
8import TutorialD.Interpreter.RelationalExpr
9import TutorialD.Interpreter.Types
10import qualified Data.Map as M
11import Control.Monad.State
12import ProjectM36.StaticOptimizer
13import ProjectM36.Error
14import ProjectM36.RelationalExpression
17--parsers which create "database expressions" which modify the database context (such as relvar assignment)
18databaseExprP :: Parser DatabaseExpr
19databaseExprP = choice $ map (\p -> p <* optional commentP) [insertP,
31 removeTypeConstructorP,
34commentP :: Parser DatabaseExpr
35commentP = reserved "--" >> manyTill anyChar eof >> pure NoOperation
37nothingP :: Parser DatabaseExpr
38nothingP = whiteSpace >> pure NoOperation
40assignP :: Parser DatabaseExpr
42 relVarName <- try $ do
43 relVarName <- identifier
47 return $ Assign (T.pack relVarName) expr
49multipleDatabaseExprP :: Parser DatabaseExpr
50multipleDatabaseExprP = do
51 exprs <- sepBy1 databaseExprP semi
52 return $ MultipleExpr exprs
54insertP :: Parser DatabaseExpr
59 return $ Insert (T.pack relvar) expr
61defineP :: Parser DatabaseExpr
63 relVarName <- try $ do
64 relVarName <- identifier
67 attributeSet <- makeAttributeExprsP
68 return $ Define (T.pack relVarName) attributeSet
70undefineP :: Parser DatabaseExpr
73 relVarName <- identifier
74 return $ Undefine (T.pack relVarName)
76deleteP :: Parser DatabaseExpr
79 relVarName <- identifier
80 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP)
81 return $ Delete (T.pack relVarName) predicate
83updateP :: Parser DatabaseExpr
86 relVarName <- identifier
87 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP <* spaces)
88 attributeAssignments <- liftM M.fromList $ parens (sepBy attributeAssignmentP comma)
89 return $ Update (T.pack relVarName) (M.mapKeys T.pack $ attributeAssignments) predicate
91data IncDepOp = SubsetOp | EqualityOp
93addConstraintP :: Parser DatabaseExpr
95 reservedOp "constraint" <|> reservedOp "foreign key"
96 constraintName <- identifier
98 op <- (reservedOp "in" *> pure SubsetOp) <|> (reservedOp "equals" *> pure EqualityOp)
100 let subsetA = incDepSet constraintName subset superset
101 subsetB = incDepSet (constraintName ++ "_eqInvert") superset subset --inverted args for equality constraint
102 incDepSet nam a b = AddInclusionDependency (T.pack nam) (InclusionDependency a b)
104 SubsetOp -> pure subsetA
105 EqualityOp -> pure (MultipleExpr [subsetA, subsetB])
109deleteConstraintP :: Parser DatabaseExpr
110deleteConstraintP = do
111 reserved "deleteconstraint"
112 constraintName <- identifier
113 return $ RemoveInclusionDependency (T.pack constraintName)
115-- key <constraint name> {<uniqueness attributes>} <uniqueness relexpr>
116keyP :: Parser DatabaseExpr
119 keyName <- identifier
120 uniquenessAttrNames <- braces attributeListP
121 uniquenessExpr <- relExprP
122 let newIncDep = inclusionDependencyForKey uniquenessAttrNames uniquenessExpr
123 return $ AddInclusionDependency (T.pack keyName) newIncDep
125attributeAssignmentP :: Parser (String, Atom)
126attributeAssignmentP = do
127 attrName <- identifier
129 atom <- stringAtomP <|> intAtomP
130 return $ (attrName, atom)
132addNotificationP :: Parser DatabaseExpr
135 notName <- identifier
136 triggerExpr <- relExprP
137 resultExpr <- relExprP
138 return $ AddNotification (T.pack notName) triggerExpr resultExpr
140removeNotificationP :: Parser DatabaseExpr
141removeNotificationP = do
143 notName <- identifier
144 return $ RemoveNotification (T.pack notName)
146-- | data Hair = Bald | Color Text
147addTypeConstructorP :: Parser DatabaseExpr
148addTypeConstructorP = do
150 typeConstructorDef <- typeConstructorDefP
152 dataConstructorDefs <- sepBy1 dataConstructorDefP pipe
153 pure (AddTypeConstructor typeConstructorDef dataConstructorDefs)
155removeTypeConstructorP :: Parser DatabaseExpr
156removeTypeConstructorP = do
158 RemoveTypeConstructor <$> liftM T.pack identifier
160databaseExprOpP :: Parser DatabaseExpr
161databaseExprOpP = multipleDatabaseExprP
163evalDatabaseExpr :: Bool -> DatabaseContext -> DatabaseExpr -> Either RelationalError DatabaseContext
164evalDatabaseExpr useOptimizer context expr = do
165 optimizedExpr <- evalState (applyStaticDatabaseOptimization expr) context
166 case runState (evalContextExpr (if useOptimizer then optimizedExpr else expr)) context of
167 (Nothing, context') -> Right context'
168 (Just err, _) -> Left err
171interpretDatabaseExpr :: DatabaseContext -> String -> Either RelationalError DatabaseContext
172interpretDatabaseExpr context tutdstring = case parse databaseExprOpP "" tutdstring of
173 Left err -> Left $ ParseError (T.pack (show err))
174 Right parsed -> evalDatabaseExpr True context parsed
178interpretNO :: DatabaseContext -> String -> (Maybe RelationalError, DatabaseContext)
179interpretNO context tutdstring = case parseString tutdstring of
180 Left err -> (Just err, context)
181 Right parsed -> runState (evalContextExpr parsed) context
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list