1module TutorialD.Interpreter.DatabaseContextExpr where
3import Text.Megaparsec.Text
5import TutorialD.Interpreter.Base
6import qualified Data.Text as T
7import TutorialD.Interpreter.RelationalExpr
8import TutorialD.Interpreter.Types
9import qualified Data.Map as M
10import Control.Monad.State
11import ProjectM36.StaticOptimizer
12import qualified ProjectM36.Error as PM36E
13import ProjectM36.Error
14import ProjectM36.RelationalExpression
18--parsers which create "database expressions" which modify the database context (such as relvar assignment)
19databaseContextExprP :: Parser DatabaseContextExpr
20databaseContextExprP = choice $ map (\p -> p <* optional commentP) [insertP,
32 removeTypeConstructorP,
35commentP :: Parser DatabaseContextExpr
36commentP = reserved "--" >> manyTill anyChar eof >> pure NoOperation
38nothingP :: Parser DatabaseContextExpr
39nothingP = spaceConsumer >> pure NoOperation
41assignP :: Parser DatabaseContextExpr
43 relVarName <- try $ do
44 relVarName <- identifier
48 pure $ Assign relVarName expr
50multilineSep :: Parser T.Text
51multilineSep = newline >> pure "\n"
53multipleDatabaseContextExprP :: Parser DatabaseContextExpr
54multipleDatabaseContextExprP = do
55 exprs <- sepBy1 databaseContextExprP semi
56 pure $ MultipleExpr exprs
58insertP :: Parser DatabaseContextExpr
63 pure $ Insert relvar expr
65defineP :: Parser DatabaseContextExpr
67 relVarName <- try $ do
68 relVarName <- identifier
71 attributeSet <- makeAttributeExprsP
72 pure $ Define relVarName attributeSet
74undefineP :: Parser DatabaseContextExpr
77 relVarName <- identifier
78 return $ Undefine relVarName
80deleteP :: Parser DatabaseContextExpr
83 relVarName <- identifier
84 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP)
85 return $ Delete relVarName predicate
87updateP :: Parser DatabaseContextExpr
90 relVarName <- identifier
91 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP <* spaceConsumer)
92 attributeAssignments <- liftM M.fromList $ parens (sepBy attributeAssignmentP comma)
93 return $ Update relVarName attributeAssignments predicate
95data IncDepOp = SubsetOp | EqualityOp
97addConstraintP :: Parser DatabaseContextExpr
99 reservedOp "constraint" <|> reservedOp "foreign key"
100 constraintName <- identifier
102 op <- (reservedOp "in" *> pure SubsetOp) <|> (reservedOp "equals" *> pure EqualityOp)
104 let subsetA = incDepSet constraintName subset superset
105 subsetB = incDepSet (constraintName <> "_eqInvert") superset subset --inverted args for equality constraint
106 incDepSet nam a b = AddInclusionDependency nam (InclusionDependency a b)
108 SubsetOp -> pure subsetA
109 EqualityOp -> pure (MultipleExpr [subsetA, subsetB])
111deleteConstraintP :: Parser DatabaseContextExpr
112deleteConstraintP = do
113 reserved "deleteconstraint"
114 constraintName <- identifier
115 pure $ RemoveInclusionDependency constraintName
117-- key <constraint name> {<uniqueness attributes>} <uniqueness relexpr>
118keyP :: Parser DatabaseContextExpr
121 keyName <- identifier
122 uniquenessAttrNames <- braces attributeListP
123 uniquenessExpr <- relExprP
124 let newIncDep = inclusionDependencyForKey uniquenessAttrNames uniquenessExpr
125 pure $ AddInclusionDependency keyName newIncDep
127attributeAssignmentP :: Parser (AttributeName, AtomExpr)
128attributeAssignmentP = do
129 attrName <- identifier
131 atomExpr <- atomExprP
132 pure $ (attrName, atomExpr)
134addNotificationP :: Parser DatabaseContextExpr
137 notName <- identifier
138 triggerExpr <- relExprP
139 resultExpr <- relExprP
140 pure $ AddNotification notName triggerExpr resultExpr
142removeNotificationP :: Parser DatabaseContextExpr
143removeNotificationP = do
145 notName <- identifier
146 pure $ RemoveNotification notName
148-- | data Hair = Bald | Color Text
149addTypeConstructorP :: Parser DatabaseContextExpr
150addTypeConstructorP = do
152 typeConstructorDef <- typeConstructorDefP
154 dataConstructorDefs <- sepBy1 dataConstructorDefP pipe
155 pure (AddTypeConstructor typeConstructorDef dataConstructorDefs)
157removeTypeConstructorP :: Parser DatabaseContextExpr
158removeTypeConstructorP = do
160 RemoveTypeConstructor <$> identifier
162removeAtomFunctionP :: Parser DatabaseContextExpr
163removeAtomFunctionP = do
164 reserved "removeatomfunction"
165 RemoveAtomFunction <$> quotedString
167databaseExprOpP :: Parser DatabaseContextExpr
168databaseExprOpP = multipleDatabaseContextExprP
170evalDatabaseContextExpr :: Bool -> DatabaseContext -> DatabaseContextExpr -> Either RelationalError DatabaseContext
171evalDatabaseContextExpr useOptimizer context expr = do
172 optimizedExpr <- evalState (applyStaticDatabaseOptimization expr) context
173 case runState (evalContextExpr (if useOptimizer then optimizedExpr else expr)) context of
174 (Nothing, context') -> Right context'
175 (Just err, _) -> Left err
178interpretDatabaseContextExpr :: DatabaseContext -> T.Text -> Either RelationalError DatabaseContext
179interpretDatabaseContextExpr context tutdstring = case parse databaseExprOpP "" tutdstring of
180 Left err -> Left $ PM36E.ParseError (T.pack (show err))
181 Right parsed -> evalDatabaseContextExpr True context parsed
185interpretNO :: DatabaseContext -> String -> (Maybe RelationalError, DatabaseContext)
186interpretNO context tutdstring = case parseString tutdstring of
187 Left err -> (Just err, context)
188 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