@@ -17,7 +17,7 @@ import qualified Data.List as L
17import Control.Applicative (liftA, (<*), (*>))
17import Control.Applicative (liftA, (<*), (*>))
18import Control.Monad.State
18import Control.Monad.State
19import System.Console.Readline
19import System.Console.Readline
22lexer :: Token.TokenParser ()
22lexer :: Token.TokenParser ()
23lexer = Token.makeTokenParser tutD
23lexer = Token.makeTokenParser tutD
@@ -184,9 +184,9 @@ updateP :: Parser DatabaseExpr
184updateP = do
184updateP = do
185 reservedOp "update"
185 reservedOp "update"
186 relVarName <- identifier
186 relVarName <- identifier
187− -- where clause
187+ predicate <- option TruePredicate (reservedOp "where" *> restrictionPredicateP <* spaces)
188 attributeAssignments <- liftM M.fromList $ parens (sepBy attributeAssignment comma)
188 attributeAssignments <- liftM M.fromList $ parens (sepBy attributeAssignment comma)
189− return $ Update relVarName attributeAssignments
189+ return $ Update relVarName attributeAssignments predicate
191constraintP :: Parser DatabaseExpr
191constraintP :: Parser DatabaseExpr
192constraintP = do
192constraintP = do
@@ -197,12 +197,12 @@ constraintP = do
197 superset <- relExpr
197 superset <- relExpr
198 return $ AddInclusionDependency (InclusionDependency constraintName subset superset)
198 return $ AddInclusionDependency (InclusionDependency constraintName subset superset)
200−attributeAssignment :: Parser (String, RelationalExpr)
200+attributeAssignment :: Parser (String, Atom)
201attributeAssignment = do
201attributeAssignment = do
202 attrName <- identifier
202 attrName <- identifier
203 reservedOp ":="
203 reservedOp ":="
204− relExpr <- relExpr
204+ atom <- stringAtomP <|> intAtomP
205− return $ (attrName, relExpr)
205+ return $ (attrName, atom)
207parseString :: String -> Either RelationalError DatabaseExpr
207parseString :: String -> Either RelationalError DatabaseExpr
208parseString str = case parse multipleDatabaseExpr "" str of
208parseString str = case parse multipleDatabaseExpr "" str of
@@ -213,6 +213,7 @@ data TutorialDOperator where
213 ShowRelation :: RelationalExpr -> TutorialDOperator
213 ShowRelation :: RelationalExpr -> TutorialDOperator
214 ShowRelationType :: RelationalExpr -> TutorialDOperator
214 ShowRelationType :: RelationalExpr -> TutorialDOperator
215 ShowConstraint :: String -> TutorialDOperator
215 ShowConstraint :: String -> TutorialDOperator
216+ Quit :: TutorialDOperator
216 deriving (Show)
217 deriving (Show)
218typeP :: Parser TutorialDOperator
219typeP :: Parser TutorialDOperator
@@ -227,6 +228,11 @@ showRelP = do
227 expr <- relExpr
228 expr <- relExpr
228 return $ ShowRelation expr
229 return $ ShowRelation expr
231+quitP :: Parser TutorialDOperator
230showConstraintsP :: Parser TutorialDOperator
236showConstraintsP :: Parser TutorialDOperator
231showConstraintsP = do
237showConstraintsP = do
232 reservedOp ":c"
238 reservedOp ":c"
@@ -237,6 +243,7 @@ interpreterOps :: Parser TutorialDOperator
237interpreterOps = typeP
243interpreterOps = typeP
238 <|> showRelP
244 <|> showRelP
239 <|> showConstraintsP
245 <|> showConstraintsP
241showRelationAttributes :: Relation -> String
248showRelationAttributes :: Relation -> String
242showRelationAttributes rel = "{" ++ concat (L.intersperse ", " $ map showAttribute attrs) ++ "}"
249showRelationAttributes rel = "{" ++ concat (L.intersperse ", " $ map showAttribute attrs) ++ "}"
@@ -247,23 +254,30 @@ showRelationAttributes rel = "{" ++ concat (L.intersperse ", " $ map showAttribu
247 attrs = values (attributes rel)
254 attrs = values (attributes rel)
248 values m = map snd (M.toAscList m)
255 values m = map snd (M.toAscList m)
257+data TutorialDOperatorResult = QuitResult |
258+ DisplayResult String |
259+ DisplayErrorResult String |
250−evalTutorialDOp :: DatabaseContext -> TutorialDOperator -> String
262+evalTutorialDOp :: DatabaseContext -> TutorialDOperator -> TutorialDOperatorResult
251evalTutorialDOp context (ShowRelationType expr) = case runState (typeForRelationalExpr expr) context of
263evalTutorialDOp context (ShowRelationType expr) = case runState (typeForRelationalExpr expr) context of
252− (Right rel, _) -> showRelationAttributes rel
264+ (Right rel, _) -> DisplayResult $ showRelationAttributes rel
253− (Left err, _) -> show err
265+ (Left err, _) -> DisplayErrorResult $ show err
255evalTutorialDOp context (ShowRelation expr) = do
267evalTutorialDOp context (ShowRelation expr) = do
256 case runState (evalRelationalExpr expr) context of
268 case runState (evalRelationalExpr expr) context of
257− (Left err, _) -> show err
269+ (Left err, _) -> DisplayErrorResult $ show err
258− (Right rel, _) -> showRelation rel
270+ (Right rel, _) -> DisplayResult $ showRelation rel
260evalTutorialDOp context (ShowConstraint name) = do
272evalTutorialDOp context (ShowConstraint name) = do
261− show filteredDeps
273+ DisplayResult $ show filteredDeps
263 deps = inclusionDependencies context
275 deps = inclusionDependencies context
264 filteredDeps = case name of
276 filteredDeps = case name of
265 "" -> deps
277 "" -> deps
266 name -> HS.filter (\(InclusionDependency n _ _) -> n == name) deps
278 name -> HS.filter (\(InclusionDependency n _ _) -> n == name) deps
280+evalTutorialDOp context (Quit) = QuitResult
268example1 = "relA {a,b, c}"
282example1 = "relA {a,b, c}"
269example2 = "relA join relB"
283example2 = "relA join relB"
@@ -281,10 +295,10 @@ interpret context tutdstring = case parseString tutdstring of
281 Right parsed -> runState (evalContextExpr parsed) context
295 Right parsed -> runState (evalContextExpr parsed) context
283-- for interpreter-specific operations
297-- for interpreter-specific operations
284−interpretOps :: DatabaseContext -> String -> Maybe String
298+interpretOps :: DatabaseContext -> String -> TutorialDOperatorResult
285interpretOps context instring = case parse interpreterOps "" instring of
299interpretOps context instring = case parse interpreterOps "" instring of
286− Left err -> Nothing
300+ Left err -> NoActionResult
287− Right ops -> Just $ evalTutorialDOp context ops
301+ Right ops -> evalTutorialDOp context ops
289reprLoop :: DatabaseContext -> IO ()
303reprLoop :: DatabaseContext -> IO ()
290reprLoop context = do
304reprLoop context = do
@@ -295,28 +309,31 @@ reprLoop context = do
295 addHistory line
309 addHistory line
297 case interpretOps context line of
311 case interpretOps context line of
298− Just out -> do
312+ QuitResult -> return ()
313+ DisplayErrorResult err -> hPutStrLn stderr ("ERR: " ++ err)
314+ DisplayResult out -> do
299 putStrLn out
315 putStrLn out
300 reprLoop context
316 reprLoop context
301− Nothing -> return ()
317+ NoActionResult -> do
303− let (value, contextup) = interpret context line
318+ let (value, contextup) = interpret context line
304− case value of
319+ case value of
305− Nothing -> reprLoop contextup
320+ Nothing -> reprLoop contextup
306− (Just err) -> do
321+ (Just err) -> do
307− putStrLn $ show err
322+ hPutStrLn stderr ("ERR:" ++ show err)
308− reprLoop context
323+ reprLoop context
310restrictionPredicateP :: Parser RestrictionPredicateExpr
325restrictionPredicateP :: Parser RestrictionPredicateExpr
311restrictionPredicateP = buildExpressionParser predicateOperators predicateTerm
326restrictionPredicateP = buildExpressionParser predicateOperators predicateTerm
313 predicateOperators = [
328 predicateOperators = [
329+ [Prefix (reservedOp "not" >> return NotPredicate)],
314 [Infix (reservedOp "and" >> return AndPredicate) AssocLeft],
330 [Infix (reservedOp "and" >> return AndPredicate) AssocLeft],
315 [Infix (reservedOp "or" >> return OrPredicate) AssocLeft]
331 [Infix (reservedOp "or" >> return OrPredicate) AssocLeft]
317 predicateTerm = parens restrictionPredicateP
333 predicateTerm = parens restrictionPredicateP
318 <|> try restrictionAttributeEqualityP
334 <|> try restrictionAttributeEqualityP
319− <|> relationalBooleanExpr
335+ <|> try relationalBooleanExpr
321relationalBooleanExpr :: Parser RestrictionPredicateExpr
338relationalBooleanExpr :: Parser RestrictionPredicateExpr
322relationalBooleanExpr = do
339relationalBooleanExpr = do