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 ProjectM36.StaticOptimizer
10import qualified ProjectM36.Error as PM36E
11import ProjectM36.Error
12import qualified ProjectM36.RelationalExpression as RE
14import ProjectM36.FunctionalDependency
15#if __GLASGOW_HASKELL__ < 804
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 <- relVarNameP
50 Assign relVarName <$> relExprP
52multilineSep :: Parser T.Text
53multilineSep = newline >> pure "\n"
55multipleDatabaseContextExprP :: Parser DatabaseContextExpr
56multipleDatabaseContextExprP =
57 MultipleExpr <$> sepBy1 databaseContextExprP semi
59insertP :: Parser DatabaseContextExpr
63 Insert relvar <$> relExprP
65defineP :: Parser DatabaseContextExpr
67 relVarName <- try $ do
68 relVarName <- relVarNameP
71 Define relVarName <$> makeAttributeExprsP
73undefineP :: Parser DatabaseContextExpr
76 Undefine <$> relVarNameP
78deleteP :: Parser DatabaseContextExpr
81 Delete <$> relVarNameP <*> option TruePredicate (reservedOp "where" *> restrictionPredicateP)
83updateP :: Parser DatabaseContextExpr
86 relVarName <- relVarNameP
87 predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP <* spaceConsumer)
88 attributeAssignments <- M.fromList <$> parens (sepBy attributeAssignmentP comma)
89 return $ Update relVarName attributeAssignments predicate
91data IncDepOp = SubsetOp | EqualityOp
93addConstraintP :: Parser DatabaseContextExpr
95 reservedOp "constraint" <|> reservedOp "foreign key"
96 constraintName <- identifier
98 op <- (reservedOp "in" $> SubsetOp) <|> (reservedOp "equals" $> EqualityOp)
100 let subsetA = incDepSet constraintName subset superset
101 subsetB = incDepSet (constraintName <> "_eqInvert") superset subset --inverted args for equality constraint
102 incDepSet nam a b = AddInclusionDependency nam (InclusionDependency a b)
104 SubsetOp -> pure subsetA
105 EqualityOp -> pure (MultipleExpr [subsetA, subsetB])
107deleteConstraintP :: Parser DatabaseContextExpr
108deleteConstraintP = do
109 reserved "deleteconstraint"
110 RemoveInclusionDependency <$> identifier
112-- key <constraint name> {<uniqueness attributes>} <uniqueness relexpr>
113keyP :: Parser DatabaseContextExpr
116 keyName <- identifier
117 uniquenessAttrNames <- braces attributeListP
118 uniquenessExpr <- relExprP
119 let newIncDep = inclusionDependencyForKey uniquenessAttrNames uniquenessExpr
120 pure $ AddInclusionDependency keyName newIncDep
122funcDepP :: Parser DatabaseContextExpr
125 keyName <- identifier
126 source <- parens attributeListP
128 dependents <- parens attributeListP
130 let newIncDeps = inclusionDependenciesForFunctionalDependency funcDep
131 funcDep = FunctionalDependency source dependents expr
132 nameA = keyName <> "_A"
133 nameB = keyName <> "_B"
134 pure (MultipleExpr [AddInclusionDependency nameA (fst newIncDeps),
135 AddInclusionDependency nameB (snd newIncDeps)])
137attributeAssignmentP :: Parser (AttributeName, AtomExpr)
138attributeAssignmentP = do
139 attrName <- identifier
141 atomExpr <- atomExprP
142 pure (attrName, atomExpr)
144addNotificationP :: Parser DatabaseContextExpr
147 notName <- identifier
148 triggerExpr <- relExprP
149 resultOldExpr <- relExprP
150 AddNotification notName triggerExpr resultOldExpr <$> relExprP
152removeNotificationP :: Parser DatabaseContextExpr
153removeNotificationP = do
155 RemoveNotification <$> identifier
157-- | data Hair = Bald | Color Text
158addTypeConstructorP :: Parser DatabaseContextExpr
159addTypeConstructorP = do
161 typeConstructorDef <- typeConstructorDefP
163 dataConstructorDefs <- sepBy1 dataConstructorDefP pipe
164 pure (AddTypeConstructor typeConstructorDef dataConstructorDefs)
166removeTypeConstructorP :: Parser DatabaseContextExpr
167removeTypeConstructorP = do
169 RemoveTypeConstructor <$> typeConstructorNameP
171removeAtomFunctionP :: Parser DatabaseContextExpr
172removeAtomFunctionP = do
173 reserved "removeatomfunction"
174 RemoveAtomFunction <$> quotedString
176removeDatabaseContextFunctionP :: Parser DatabaseContextExpr
177removeDatabaseContextFunctionP = do
178 reserved "removedatabasecontextfunction"
179 RemoveDatabaseContextFunction <$> quotedString
181functionNameP :: Parser AtomFunctionName
182functionNameP = uncapitalizedIdentifier
184executeDatabaseContextFunctionP :: Parser DatabaseContextExpr
185executeDatabaseContextFunctionP = do
187 funcName <- functionNameP
188 args <- parens (sepBy atomExprP comma)
189 pure (ExecuteDatabaseContextFunction funcName args)
191databaseExprOpP :: Parser DatabaseContextExpr
192databaseExprOpP = 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 -> TransactionId -> TransactionGraph -> T.Text -> Either RelationalError DatabaseContext
204interpretDatabaseContextExpr context transId graph tutdstring =
205 case parse databaseExprOpP "" tutdstring of
206 Left err -> Left $ PM36E.ParseError (T.pack (show err))
208 let env = RE.mkDatabaseContextEvalEnv transId graph
209 RE.dbc_context <$> RE.runDatabaseContextEvalMonad context env (optimizeAndEvalDatabaseContextExpr True parsed)
213interpretNO :: DatabaseContext -> String -> (Maybe RelationalError, DatabaseContext)
214interpretNO context tutdstring = case parseString tutdstring of
215 Left err -> (Just err, context)
216 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