2module TutorialD.Interpreter.DatabaseContextExpr where
4import TutorialD.Interpreter.Base
5import qualified Data.Text as T
6import TutorialD.Interpreter.RelationalExpr
7import TutorialD.Interpreter.Types
8import qualified Data.Map as M
9import Control.Monad.State
10import ProjectM36.StaticOptimizer
11import qualified ProjectM36.Error as PM36E
12import ProjectM36.Error
13import qualified ProjectM36.RelationalExpression as RE
15import ProjectM36.FunctionalDependency
16#if __GLASGOW_HASKELL__ < 804
21--parsers which create "database expressions" which modify the database context (such as relvar assignment)
22databaseContextExprP :: Parser DatabaseContextExpr
23databaseContextExprP = choice [insertP,
36 removeTypeConstructorP,
38 executeDatabaseContextFunctionP,
39 removeDatabaseContextFunctionP,
42nothingP :: Parser DatabaseContextExpr
43nothingP = spaceConsumer >> pure NoOperation
45assignP :: Parser DatabaseContextExpr
47 relVarName <- try $ do
48 relVarName <- relVarNameP
51 Assign relVarName <$> relExprP
53multilineSep :: Parser T.Text
54multilineSep = newline >> pure "\n"
56multipleDatabaseContextExprP :: Parser DatabaseContextExpr
57multipleDatabaseContextExprP =
58 MultipleExpr <$> sepBy1 databaseContextExprP semi
60insertP :: Parser DatabaseContextExpr
64 Insert relvar <$> relExprP
66defineP :: Parser DatabaseContextExpr
68 relVarName <- try $ do
69 relVarName <- relVarNameP
72 Define relVarName <$> makeAttributeExprsP
74undefineP :: Parser DatabaseContextExpr
77 Undefine <$> relVarNameP
79deleteP :: Parser DatabaseContextExpr
82 Delete <$> relVarNameP <*> option TruePredicate (reservedOp "where" *> restrictionPredicateP)
84updateP :: Parser DatabaseContextExpr
87 relVarName <- relVarNameP
88 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP <* spaceConsumer)
89 attributeAssignments <- M.fromList <$> parens (sepBy attributeAssignmentP comma)
90 return $ Update relVarName attributeAssignments predicate
92data IncDepOp = SubsetOp | EqualityOp
94addConstraintP :: Parser DatabaseContextExpr
96 reservedOp "constraint" <|> reservedOp "foreign key"
97 constraintName <- identifier
99 op <- (reservedOp "in" $> SubsetOp) <|> (reservedOp "equals" $> EqualityOp)
101 let subsetA = incDepSet constraintName subset superset
102 subsetB = incDepSet (constraintName <> "_eqInvert") superset subset --inverted args for equality constraint
103 incDepSet nam a b = AddInclusionDependency nam (InclusionDependency a b)
105 SubsetOp -> pure subsetA
106 EqualityOp -> pure (MultipleExpr [subsetA, subsetB])
108deleteConstraintP :: Parser DatabaseContextExpr
109deleteConstraintP = do
110 reserved "deleteconstraint"
111 RemoveInclusionDependency <$> identifier
113-- key <constraint name> {<uniqueness attributes>} <uniqueness relexpr>
114keyP :: Parser DatabaseContextExpr
117 keyName <- identifier
118 uniquenessAttrNames <- braces attributeListP
119 uniquenessExpr <- relExprP
120 let newIncDep = inclusionDependencyForKey uniquenessAttrNames uniquenessExpr
121 pure $ AddInclusionDependency keyName newIncDep
123funcDepP :: Parser DatabaseContextExpr
126 keyName <- identifier
127 source <- parens attributeListP
129 dependents <- parens attributeListP
131 let newIncDeps = inclusionDependenciesForFunctionalDependency funcDep
132 funcDep = FunctionalDependency source dependents expr
133 nameA = keyName <> "_A"
134 nameB = keyName <> "_B"
135 pure (MultipleExpr [AddInclusionDependency nameA (fst newIncDeps),
136 AddInclusionDependency nameB (snd newIncDeps)])
138attributeAssignmentP :: Parser (AttributeName, AtomExpr)
139attributeAssignmentP = do
140 attrName <- identifier
142 atomExpr <- atomExprP
143 pure (attrName, atomExpr)
145addNotificationP :: Parser DatabaseContextExpr
148 notName <- identifier
149 triggerExpr <- relExprP
150 resultOldExpr <- relExprP
151 AddNotification notName triggerExpr resultOldExpr <$> relExprP
153removeNotificationP :: Parser DatabaseContextExpr
154removeNotificationP = do
156 RemoveNotification <$> identifier
158-- | data Hair = Bald | Color Text
159addTypeConstructorP :: Parser DatabaseContextExpr
160addTypeConstructorP = do
162 typeConstructorDef <- typeConstructorDefP
164 dataConstructorDefs <- sepBy1 dataConstructorDefP pipe
165 pure (AddTypeConstructor typeConstructorDef dataConstructorDefs)
167removeTypeConstructorP :: Parser DatabaseContextExpr
168removeTypeConstructorP = do
170 RemoveTypeConstructor <$> typeConstructorNameP
172removeAtomFunctionP :: Parser DatabaseContextExpr
173removeAtomFunctionP = do
174 reserved "removeatomfunction"
175 RemoveAtomFunction <$> quotedString
177removeDatabaseContextFunctionP :: Parser DatabaseContextExpr
178removeDatabaseContextFunctionP = do
179 reserved "removedatabasecontextfunction"
180 RemoveDatabaseContextFunction <$> quotedString
182functionNameP :: Parser AtomFunctionName
183functionNameP = uncapitalizedIdentifier
185executeDatabaseContextFunctionP :: Parser DatabaseContextExpr
186executeDatabaseContextFunctionP = do
188 funcName <- functionNameP
189 args <- parens (sepBy atomExprP comma)
190 pure (ExecuteDatabaseContextFunction funcName args)
192databaseExprOpP :: Parser DatabaseContextExpr
193databaseExprOpP = multipleDatabaseContextExprP
195evalDatabaseContextExpr :: Bool -> DatabaseContext -> DatabaseContextExpr -> Either RelationalError DatabaseContext
196evalDatabaseContextExpr useOptimizer context expr = do
197 optimizedExpr <- evalState (applyStaticDatabaseOptimization expr) (RE.freshDatabaseState context)
198 case runState (RE.evalDatabaseContextExpr (if useOptimizer then optimizedExpr else expr)) (RE.freshDatabaseState context) of
199 (Right (), (context',_, _)) -> Right context'
200 (Left err, _) -> Left err
203interpretDatabaseContextExpr :: DatabaseContext -> T.Text -> Either RelationalError DatabaseContext
204interpretDatabaseContextExpr context tutdstring = case parse databaseExprOpP "" tutdstring of
205 Left err -> Left $ PM36E.ParseError (T.pack (show err))
207 evalDatabaseContextExpr True context parsed
211interpretNO :: DatabaseContext -> String -> (Maybe RelationalError, DatabaseContext)
212interpretNO context tutdstring = case parseString tutdstring of
213 Left err -> (Just err, context)
214 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