1module TutorialD.Interpreter.DatabaseContextExpr where
3import TutorialD.Interpreter.Base
4import qualified Data.Text as T
5import TutorialD.Interpreter.RelationalExpr
6import TutorialD.Interpreter.Types
7import qualified Data.Map as M
8import Control.Monad.State
9import ProjectM36.StaticOptimizer
10import qualified ProjectM36.Error as PM36E
11import ProjectM36.Error
12import qualified ProjectM36.RelationalExpression as RE
14import ProjectM36.FunctionalDependency
18--parsers which create "database expressions" which modify the database context (such as relvar assignment)
19databaseContextExprP :: Parser DatabaseContextExpr
20databaseContextExprP = choice [insertP,
33 removeTypeConstructorP,
35 executeDatabaseContextFunctionP,
36 removeDatabaseContextFunctionP,
39nothingP :: Parser DatabaseContextExpr
40nothingP = spaceConsumer >> pure NoOperation
42assignP :: Parser DatabaseContextExpr
44 relVarName <- try $ do
45 relVarName <- identifier
48 Assign relVarName <$> relExprP
50multilineSep :: Parser T.Text
51multilineSep = newline >> pure "\n"
53multipleDatabaseContextExprP :: Parser DatabaseContextExpr
54multipleDatabaseContextExprP =
55 MultipleExpr <$> sepBy1 databaseContextExprP semi
57insertP :: Parser DatabaseContextExpr
61 Insert relvar <$> relExprP
63defineP :: Parser DatabaseContextExpr
65 relVarName <- try $ do
66 relVarName <- identifier
69 Define relVarName <$> makeAttributeExprsP
71undefineP :: Parser DatabaseContextExpr
74 Undefine <$> identifier
76deleteP :: Parser DatabaseContextExpr
79 Delete <$> identifier <*> option TruePredicate (reservedOp "where" *> restrictionPredicateP)
81updateP :: Parser DatabaseContextExpr
84 relVarName <- identifier
85 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP <* spaceConsumer)
86 attributeAssignments <- M.fromList <$> parens (sepBy attributeAssignmentP comma)
87 return $ Update relVarName attributeAssignments predicate
89data IncDepOp = SubsetOp | EqualityOp
91addConstraintP :: Parser DatabaseContextExpr
93 reservedOp "constraint" <|> reservedOp "foreign key"
94 constraintName <- identifier
96 op <- (reservedOp "in" $> SubsetOp) <|> (reservedOp "equals" $> EqualityOp)
98 let subsetA = incDepSet constraintName subset superset
99 subsetB = incDepSet (constraintName <> "_eqInvert") superset subset --inverted args for equality constraint
100 incDepSet nam a b = AddInclusionDependency nam (InclusionDependency a b)
102 SubsetOp -> pure subsetA
103 EqualityOp -> pure (MultipleExpr [subsetA, subsetB])
105deleteConstraintP :: Parser DatabaseContextExpr
106deleteConstraintP = do
107 reserved "deleteconstraint"
108 RemoveInclusionDependency <$> identifier
110-- key <constraint name> {<uniqueness attributes>} <uniqueness relexpr>
111keyP :: Parser DatabaseContextExpr
114 keyName <- identifier
115 uniquenessAttrNames <- braces attributeListP
116 uniquenessExpr <- relExprP
117 let newIncDep = inclusionDependencyForKey uniquenessAttrNames uniquenessExpr
118 pure $ AddInclusionDependency keyName newIncDep
120funcDepP :: Parser DatabaseContextExpr
123 keyName <- identifier
124 source <- parens attributeListP
126 dependents <- parens attributeListP
128 let newIncDeps = inclusionDependenciesForFunctionalDependency funcDep
129 funcDep = FunctionalDependency source dependents expr
130 nameA = keyName <> "_A"
131 nameB = keyName <> "_B"
132 pure (MultipleExpr [AddInclusionDependency nameA (fst newIncDeps),
133 AddInclusionDependency nameB (snd newIncDeps)])
135attributeAssignmentP :: Parser (AttributeName, AtomExpr)
136attributeAssignmentP = do
137 attrName <- identifier
139 atomExpr <- atomExprP
140 pure (attrName, atomExpr)
142addNotificationP :: Parser DatabaseContextExpr
145 notName <- identifier
146 triggerExpr <- relExprP
147 resultOldExpr <- relExprP
148 AddNotification notName triggerExpr resultOldExpr <$> relExprP
150removeNotificationP :: Parser DatabaseContextExpr
151removeNotificationP = do
153 RemoveNotification <$> identifier
155-- | data Hair = Bald | Color Text
156addTypeConstructorP :: Parser DatabaseContextExpr
157addTypeConstructorP = do
159 typeConstructorDef <- typeConstructorDefP
161 dataConstructorDefs <- sepBy1 dataConstructorDefP pipe
162 pure (AddTypeConstructor typeConstructorDef dataConstructorDefs)
164removeTypeConstructorP :: Parser DatabaseContextExpr
165removeTypeConstructorP = do
167 RemoveTypeConstructor <$> identifier
169removeAtomFunctionP :: Parser DatabaseContextExpr
170removeAtomFunctionP = do
171 reserved "removeatomfunction"
172 RemoveAtomFunction <$> quotedString
174removeDatabaseContextFunctionP :: Parser DatabaseContextExpr
175removeDatabaseContextFunctionP = do
176 reserved "removedatabasecontextfunction"
177 RemoveDatabaseContextFunction <$> quotedString
179executeDatabaseContextFunctionP :: Parser DatabaseContextExpr
180executeDatabaseContextFunctionP = do
182 funcName <- identifier
183 args <- parens (sepBy atomExprP comma)
184 pure (ExecuteDatabaseContextFunction funcName args)
186databaseExprOpP :: Parser DatabaseContextExpr
187databaseExprOpP = multipleDatabaseContextExprP
189evalDatabaseContextExpr :: Bool -> DatabaseContext -> DatabaseContextExpr -> Either RelationalError DatabaseContext
190evalDatabaseContextExpr useOptimizer context expr = do
191 optimizedExpr <- evalState (applyStaticDatabaseOptimization expr) (RE.freshDatabaseState context)
192 case runState (RE.evalDatabaseContextExpr (if useOptimizer then optimizedExpr else expr)) (RE.freshDatabaseState context) of
193 (Right (), (context',_, _)) -> Right context'
194 (Left err, _) -> Left err
197interpretDatabaseContextExpr :: DatabaseContext -> T.Text -> Either RelationalError DatabaseContext
198interpretDatabaseContextExpr context tutdstring = case parse databaseExprOpP "" tutdstring of
199 Left err -> Left $ PM36E.ParseError (T.pack (show err))
201 evalDatabaseContextExpr True context parsed
205interpretNO :: DatabaseContext -> String -> (Maybe RelationalError, DatabaseContext)
206interpretNO context tutdstring = case parseString tutdstring of
207 Left err -> (Just err, context)
208 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