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
16import ProjectM36.FunctionalDependency
19--parsers which create "database expressions" which modify the database context (such as relvar assignment)
20databaseContextExprP :: Parser DatabaseContextExpr
21databaseContextExprP = choice [insertP,
34 removeTypeConstructorP,
37nothingP :: Parser DatabaseContextExpr
38nothingP = spaceConsumer >> pure NoOperation
40assignP :: Parser DatabaseContextExpr
42 relVarName <- try $ do
43 relVarName <- identifier
47 pure $ Assign relVarName expr
49multilineSep :: Parser T.Text
50multilineSep = newline >> pure "\n"
52multipleDatabaseContextExprP :: Parser DatabaseContextExpr
53multipleDatabaseContextExprP = do
54 exprs <- sepBy1 databaseContextExprP semi
55 pure $ MultipleExpr exprs
57insertP :: Parser DatabaseContextExpr
62 pure $ Insert relvar expr
64defineP :: Parser DatabaseContextExpr
66 relVarName <- try $ do
67 relVarName <- identifier
70 attributeSet <- makeAttributeExprsP
71 pure $ Define relVarName attributeSet
73undefineP :: Parser DatabaseContextExpr
76 relVarName <- identifier
77 return $ Undefine relVarName
79deleteP :: Parser DatabaseContextExpr
82 relVarName <- identifier
83 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP)
84 return $ Delete relVarName predicate
86updateP :: Parser DatabaseContextExpr
89 relVarName <- identifier
90 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP <* spaceConsumer)
91 attributeAssignments <- liftM M.fromList $ parens (sepBy attributeAssignmentP comma)
92 return $ Update relVarName attributeAssignments predicate
94data IncDepOp = SubsetOp | EqualityOp
96addConstraintP :: Parser DatabaseContextExpr
98 reservedOp "constraint" <|> reservedOp "foreign key"
99 constraintName <- identifier
101 op <- (reservedOp "in" *> pure SubsetOp) <|> (reservedOp "equals" *> pure EqualityOp)
103 let subsetA = incDepSet constraintName subset superset
104 subsetB = incDepSet (constraintName <> "_eqInvert") superset subset --inverted args for equality constraint
105 incDepSet nam a b = AddInclusionDependency nam (InclusionDependency a b)
107 SubsetOp -> pure subsetA
108 EqualityOp -> pure (MultipleExpr [subsetA, subsetB])
110deleteConstraintP :: Parser DatabaseContextExpr
111deleteConstraintP = do
112 reserved "deleteconstraint"
113 constraintName <- identifier
114 pure $ RemoveInclusionDependency constraintName
116-- key <constraint name> {<uniqueness attributes>} <uniqueness relexpr>
117keyP :: Parser DatabaseContextExpr
120 keyName <- identifier
121 uniquenessAttrNames <- braces attributeListP
122 uniquenessExpr <- relExprP
123 let newIncDep = inclusionDependencyForKey uniquenessAttrNames uniquenessExpr
124 pure $ AddInclusionDependency keyName newIncDep
126funcDepP :: Parser DatabaseContextExpr
129 keyName <- identifier
130 source <- parens attributeListP
132 dependents <- parens attributeListP
134 let newIncDeps = inclusionDependenciesForFunctionalDependency funcDep
135 funcDep = FunctionalDependency source dependents expr
136 nameA = keyName <> "_A"
137 nameB = keyName <> "_B"
138 pure (MultipleExpr [AddInclusionDependency nameA (fst newIncDeps),
139 AddInclusionDependency nameB (snd newIncDeps)])
141attributeAssignmentP :: Parser (AttributeName, AtomExpr)
142attributeAssignmentP = do
143 attrName <- identifier
145 atomExpr <- atomExprP
146 pure $ (attrName, atomExpr)
148addNotificationP :: Parser DatabaseContextExpr
151 notName <- identifier
152 triggerExpr <- relExprP
153 resultExpr <- relExprP
154 pure $ AddNotification notName triggerExpr resultExpr
156removeNotificationP :: Parser DatabaseContextExpr
157removeNotificationP = do
159 notName <- identifier
160 pure $ RemoveNotification notName
162-- | data Hair = Bald | Color Text
163addTypeConstructorP :: Parser DatabaseContextExpr
164addTypeConstructorP = do
166 typeConstructorDef <- typeConstructorDefP
168 dataConstructorDefs <- sepBy1 dataConstructorDefP pipe
169 pure (AddTypeConstructor typeConstructorDef dataConstructorDefs)
171removeTypeConstructorP :: Parser DatabaseContextExpr
172removeTypeConstructorP = do
174 RemoveTypeConstructor <$> identifier
176removeAtomFunctionP :: Parser DatabaseContextExpr
177removeAtomFunctionP = do
178 reserved "removeatomfunction"
179 RemoveAtomFunction <$> quotedString
181databaseExprOpP :: Parser DatabaseContextExpr
182databaseExprOpP = multipleDatabaseContextExprP
184evalDatabaseContextExpr :: Bool -> DatabaseContext -> DatabaseContextExpr -> Either RelationalError DatabaseContext
185evalDatabaseContextExpr useOptimizer context expr = do
186 optimizedExpr <- evalState (applyStaticDatabaseOptimization expr) context
187 case runState (evalContextExpr (if useOptimizer then optimizedExpr else expr)) context of
188 (Nothing, context') -> Right context'
189 (Just err, _) -> Left err
192interpretDatabaseContextExpr :: DatabaseContext -> T.Text -> Either RelationalError DatabaseContext
193interpretDatabaseContextExpr context tutdstring = case parse databaseExprOpP "" tutdstring of
194 Left err -> Left $ PM36E.ParseError (T.pack (show err))
195 Right parsed -> evalDatabaseContextExpr True context parsed
199interpretNO :: DatabaseContext -> String -> (Maybe RelationalError, DatabaseContext)
200interpretNO context tutdstring = case parseString tutdstring of
201 Left err -> (Just err, context)
202 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