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 qualified ProjectM36.RelationalExpression as RE
16import ProjectM36.FunctionalDependency
20--parsers which create "database expressions" which modify the database context (such as relvar assignment)
21databaseContextExprP :: Parser DatabaseContextExpr
22databaseContextExprP = choice [insertP,
35 removeTypeConstructorP,
37 executeDatabaseContextFunctionP,
38 removeDatabaseContextFunctionP,
41nothingP :: Parser DatabaseContextExpr
42nothingP = spaceConsumer >> pure NoOperation
44assignP :: Parser DatabaseContextExpr
46 relVarName <- try $ do
47 relVarName <- identifier
51 pure $ Assign relVarName expr
53multilineSep :: Parser T.Text
54multilineSep = newline >> pure "\n"
56multipleDatabaseContextExprP :: Parser DatabaseContextExpr
57multipleDatabaseContextExprP = do
58 exprs <- sepBy1 databaseContextExprP semi
59 pure $ MultipleExpr exprs
61insertP :: Parser DatabaseContextExpr
66 pure $ Insert relvar expr
68defineP :: Parser DatabaseContextExpr
70 relVarName <- try $ do
71 relVarName <- identifier
74 attributeSet <- makeAttributeExprsP
75 pure $ Define relVarName attributeSet
77undefineP :: Parser DatabaseContextExpr
80 Undefine <$> identifier
82deleteP :: Parser DatabaseContextExpr
85 Delete <$> identifier <*> option TruePredicate (reservedOp "where" *> restrictionPredicateP)
87updateP :: Parser DatabaseContextExpr
90 relVarName <- identifier
91 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP <* spaceConsumer)
92 attributeAssignments <- 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" $> SubsetOp) <|> (reservedOp "equals" $> 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
127funcDepP :: Parser DatabaseContextExpr
130 keyName <- identifier
131 source <- parens attributeListP
133 dependents <- parens attributeListP
135 let newIncDeps = inclusionDependenciesForFunctionalDependency funcDep
136 funcDep = FunctionalDependency source dependents expr
137 nameA = keyName <> "_A"
138 nameB = keyName <> "_B"
139 pure (MultipleExpr [AddInclusionDependency nameA (fst newIncDeps),
140 AddInclusionDependency nameB (snd newIncDeps)])
142attributeAssignmentP :: Parser (AttributeName, AtomExpr)
143attributeAssignmentP = do
144 attrName <- identifier
146 atomExpr <- atomExprP
147 pure (attrName, atomExpr)
149addNotificationP :: Parser DatabaseContextExpr
152 notName <- identifier
153 triggerExpr <- relExprP
154 resultOldExpr <- relExprP
155 resultNewExpr <- relExprP
156 pure $ AddNotification notName triggerExpr resultOldExpr resultNewExpr
158removeNotificationP :: Parser DatabaseContextExpr
159removeNotificationP = do
161 notName <- identifier
162 pure $ RemoveNotification notName
164-- | data Hair = Bald | Color Text
165addTypeConstructorP :: Parser DatabaseContextExpr
166addTypeConstructorP = do
168 typeConstructorDef <- typeConstructorDefP
170 dataConstructorDefs <- sepBy1 dataConstructorDefP pipe
171 pure (AddTypeConstructor typeConstructorDef dataConstructorDefs)
173removeTypeConstructorP :: Parser DatabaseContextExpr
174removeTypeConstructorP = do
176 RemoveTypeConstructor <$> identifier
178removeAtomFunctionP :: Parser DatabaseContextExpr
179removeAtomFunctionP = do
180 reserved "removeatomfunction"
181 RemoveAtomFunction <$> quotedString
183removeDatabaseContextFunctionP :: Parser DatabaseContextExpr
184removeDatabaseContextFunctionP = do
185 reserved "removedatabasecontextfunction"
186 RemoveDatabaseContextFunction <$> quotedString
188executeDatabaseContextFunctionP :: Parser DatabaseContextExpr
189executeDatabaseContextFunctionP = do
191 funcName <- identifier
192 args <- parens (sepBy atomExprP comma)
193 pure (ExecuteDatabaseContextFunction funcName args)
195databaseExprOpP :: Parser DatabaseContextExpr
196databaseExprOpP = multipleDatabaseContextExprP
198evalDatabaseContextExpr :: Bool -> DatabaseContext -> DatabaseContextExpr -> Either RelationalError DatabaseContext
199evalDatabaseContextExpr useOptimizer context expr = do
200 optimizedExpr <- evalState (applyStaticDatabaseOptimization expr) (RE.freshDatabaseState context)
201 case runState (RE.evalDatabaseContextExpr (if useOptimizer then optimizedExpr else expr)) (RE.freshDatabaseState context) of
202 (Right (), (context',_, _)) -> Right context'
203 (Left err, _) -> Left err
206interpretDatabaseContextExpr :: DatabaseContext -> T.Text -> Either RelationalError DatabaseContext
207interpretDatabaseContextExpr context tutdstring = case parse databaseExprOpP "" tutdstring of
208 Left err -> Left $ PM36E.ParseError (T.pack (show err))
210 evalDatabaseContextExpr True context parsed
214interpretNO :: DatabaseContext -> String -> (Maybe RelationalError, DatabaseContext)
215interpretNO context tutdstring = case parseString tutdstring of
216 Left err -> (Just err, context)
217 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