on master help sign in
WIP: more client-server stability changes
ff20471AgentM
ProjectM36/Client.hs+29−22
@@ -16,7 +16,6 @@ module ProjectM36.Client
16 typeForRelationalExpr,
16 typeForRelationalExpr,
17 inclusionDependencies,
17 inclusionDependencies,
18 planForDatabaseContextExpr,
18 planForDatabaseContextExpr,
19− attributesForRelationalExpr,
20 processPersistence,
19 processPersistence,
21 transactionGraphAsRelation,
20 transactionGraphAsRelation,
22 headName,
21 headName,
@@ -37,7 +36,6 @@ module ProjectM36.Client
37import ProjectM36.Base hiding (inclusionDependencies) --defined in this module as well
36import ProjectM36.Base hiding (inclusionDependencies) --defined in this module as well
38import qualified ProjectM36.Base as B
37import qualified ProjectM36.Base as B
39import ProjectM36.Error
38import ProjectM36.Error
40−import ProjectM36.Relation
41import ProjectM36.StaticOptimizer
39import ProjectM36.StaticOptimizer
42import Control.Monad.State
40import Control.Monad.State
43import ProjectM36.Transaction
41import ProjectM36.Transaction
@@ -50,17 +48,19 @@ import ProjectM36.Daemon.RemoteCallTypes (RemoteExecution(..))
50import Network.Transport.TCP (createTransport, defaultTCPParameters, encodeEndPointAddress)
48import Network.Transport.TCP (createTransport, defaultTCPParameters, encodeEndPointAddress)
51import Control.Distributed.Process.Node (newLocalNode, initRemoteTable, runProcess, LocalNode)
49import Control.Distributed.Process.Node (newLocalNode, initRemoteTable, runProcess, LocalNode)
52import Control.Distributed.Process.Extras.Internal.Types (whereisRemote)
50import Control.Distributed.Process.Extras.Internal.Types (whereisRemote)
53−import Control.Distributed.Process.ManagedProcess.Client (call)
51+import Control.Distributed.Process.ManagedProcess.Client (call, safeCall)
54import Control.Distributed.Process (NodeId(..))
52import Control.Distributed.Process (NodeId(..))
55
53
56import Data.UUID (UUID)
54import Data.UUID (UUID)
57import Data.UUID.V4 (nextRandom)
55import Data.UUID.V4 (nextRandom)
58import Control.Concurrent.STM
56import Control.Concurrent.STM
59import Data.Word
57import Data.Word
60−import Control.Distributed.Process (ProcessId, Process)
58+import Control.Distributed.Process (ProcessId, Process, getSelfPid)
61import Control.Exception (IOException)
59import Control.Exception (IOException)
62import Control.Concurrent.MVar
60import Control.Concurrent.MVar
63import qualified Data.Map as M
61import qualified Data.Map as M
62+import Control.Distributed.Process.Serializable (Serializable)
63+--import Control.Distributed.Process.Debug
64
64
65type Hostname = String
65type Hostname = String
66
66
@@ -165,13 +165,21 @@ runProcessResult localNode proc = do
165 liftIO $ putMVar ret val
165 liftIO $ putMVar ret val
166 takeMVar ret
166 takeMVar ret
167
167
168+remoteCall :: (Serializable a, Serializable b) => Connection -> a -> IO b
169+remoteCall (InProcessConnection _ _) _ = error "remoteCall called on local connection"
170+remoteCall (RemoteProcessConnection localNode serverProcessId) arg = runProcessResult localNode $ do
171+ pid <- getSelfPid
172+ liftIO $ putStrLn (show serverProcessId)
173+ ret <- safeCall serverProcessId arg
174+ case ret of
175+ Left err -> error (show err)
176+ Right ret' -> pure ret'
177+
168executeRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
178executeRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
169executeRelationalExpr (InProcessConnection _ tvar) expr = atomically $ do
179executeRelationalExpr (InProcessConnection _ tvar) expr = atomically $ do
170 ((DisconnectedTransaction _ context), _) <- readTVar tvar
180 ((DisconnectedTransaction _ context), _) <- readTVar tvar
171 return $ evalState (RE.evalRelationalExpr expr) context
181 return $ evalState (RE.evalRelationalExpr expr) context
172−executeRelationalExpr (RemoteProcessConnection localNode serverProcessId) relExpr = do
182+executeRelationalExpr conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteRelationalExpr relExpr)
173− runProcessResult localNode $ do
174− call serverProcessId (ExecuteRelationalExpr relExpr)
175
183
176executeDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Maybe RelationalError)
184executeDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Maybe RelationalError)
177executeDatabaseContextExpr (InProcessConnection _ tvar) expr = atomically $ do
185executeDatabaseContextExpr (InProcessConnection _ tvar) expr = atomically $ do
@@ -182,8 +190,7 @@ executeDatabaseContextExpr (InProcessConnection _ tvar) expr = atomically $ do
182 let newDiscon = DisconnectedTransaction parentUUID context'
190 let newDiscon = DisconnectedTransaction parentUUID context'
183 writeTVar tvar (newDiscon, graph)
191 writeTVar tvar (newDiscon, graph)
184 return Nothing
192 return Nothing
185−executeDatabaseContextExpr (RemoteProcessConnection localNode serverProcessId) dbExpr = do
193+executeDatabaseContextExpr conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (ExecuteDatabaseContextExpr dbExpr)
186− runProcessResult localNode $ call serverProcessId (ExecuteDatabaseContextExpr dbExpr)
187
194
188executeGraphExpr :: Connection -> TransactionGraphOperator -> IO (Maybe RelationalError)
195executeGraphExpr :: Connection -> TransactionGraphOperator -> IO (Maybe RelationalError)
189executeGraphExpr (InProcessConnection strat tvar) graphExpr = do
196executeGraphExpr (InProcessConnection strat tvar) graphExpr = do
@@ -202,15 +209,15 @@ executeGraphExpr (InProcessConnection strat tvar) graphExpr = do
202 --this should really grab a lock at the beginning of the method to be threadsafe
209 --this should really grab a lock at the beginning of the method to be threadsafe
203 processPersistence strat newGraph
210 processPersistence strat newGraph
204 return Nothing
211 return Nothing
205−executeGraphExpr (RemoteProcessConnection localNode serverProcessId) graphExpr = do
212+executeGraphExpr conn@(RemoteProcessConnection _ _) graphExpr = remoteCall conn (ExecuteGraphExpr graphExpr)
206− runProcessResult localNode $ do
207− call serverProcessId (ExecuteGraphExpr graphExpr)
208
213
209commit :: Connection -> IO (Maybe RelationalError)
214commit :: Connection -> IO (Maybe RelationalError)
210−commit conn = executeGraphExpr conn Commit
215+commit conn@(InProcessConnection _ _) = executeGraphExpr conn Commit
216+commit conn@(RemoteProcessConnection _ _) = remoteCall conn (ExecuteGraphExpr Commit)
211
217
212rollback :: Connection -> IO (Maybe RelationalError)
218rollback :: Connection -> IO (Maybe RelationalError)
213−rollback conn = executeGraphExpr conn Rollback
219+rollback conn@(InProcessConnection _ _) = executeGraphExpr conn Rollback
220+rollback conn@(RemoteProcessConnection _ _) = remoteCall conn (ExecuteGraphExpr Rollback)
214
221
215processPersistence :: PersistenceStrategy -> TransactionGraph -> IO ()
222processPersistence :: PersistenceStrategy -> TransactionGraph -> IO ()
216processPersistence NoPersistence _ = return ()
223processPersistence NoPersistence _ = return ()
@@ -219,43 +226,43 @@ processPersistence (CrashSafePersistence dbdir) graph = transactionGraphPersist
219
226
220typeForRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
227typeForRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
221typeForRelationalExpr conn@(InProcessConnection _ _) relExpr = atomically $ typeForRelationalExprSTM conn relExpr
228typeForRelationalExpr conn@(InProcessConnection _ _) relExpr = atomically $ typeForRelationalExprSTM conn relExpr
229+typeForRelationalExpr conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteTypeForRelationalExpr relExpr)
222
230
223typeForRelationalExprSTM :: Connection -> RelationalExpr -> STM (Either RelationalError Relation)
231typeForRelationalExprSTM :: Connection -> RelationalExpr -> STM (Either RelationalError Relation)
224typeForRelationalExprSTM (InProcessConnection _ tvar) relExpr = do
232typeForRelationalExprSTM (InProcessConnection _ tvar) relExpr = do
225 (DisconnectedTransaction _ context, _) <- readTVar tvar
233 (DisconnectedTransaction _ context, _) <- readTVar tvar
226 pure $ evalState (RE.typeForRelationalExpr relExpr) context
234 pure $ evalState (RE.typeForRelationalExpr relExpr) context
235+typeForRelationalExprSTM _ _ = error "typeForRelationalExprSTM called on non-local connection"
227
236
228inclusionDependencies :: Connection -> IO (M.Map IncDepName InclusionDependency)
237inclusionDependencies :: Connection -> IO (M.Map IncDepName InclusionDependency)
229inclusionDependencies (InProcessConnection _ tvar) = do
238inclusionDependencies (InProcessConnection _ tvar) = do
230 atomically $ do
239 atomically $ do
231 ((DisconnectedTransaction _ context), _) <- readTVar tvar
240 ((DisconnectedTransaction _ context), _) <- readTVar tvar
232 pure (B.inclusionDependencies context)
241 pure (B.inclusionDependencies context)
242+inclusionDependencies conn@(RemoteProcessConnection _ _) = remoteCall conn RetrieveInclusionDependencies
243+
233
244
234planForDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Either RelationalError DatabaseExpr)
245planForDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Either RelationalError DatabaseExpr)
235planForDatabaseContextExpr (InProcessConnection _ tvar) dbExpr = do
246planForDatabaseContextExpr (InProcessConnection _ tvar) dbExpr = do
236 atomically $ do
247 atomically $ do
237 ((DisconnectedTransaction _ context), _) <- readTVar tvar
248 ((DisconnectedTransaction _ context), _) <- readTVar tvar
238 pure $ evalState (applyStaticDatabaseOptimization dbExpr) context
249 pure $ evalState (applyStaticDatabaseOptimization dbExpr) context
250+planForDatabaseContextExpr conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (RetrievePlanForDatabaseContextExpr dbExpr)
239
251
240transactionGraphAsRelation :: Connection -> IO (Either RelationalError Relation)
252transactionGraphAsRelation :: Connection -> IO (Either RelationalError Relation)
241transactionGraphAsRelation (InProcessConnection _ tvar) = do
253transactionGraphAsRelation (InProcessConnection _ tvar) = do
242 atomically $ do
254 atomically $ do
243 (discon, graph) <- readTVar tvar
255 (discon, graph) <- readTVar tvar
244 pure $ graphAsRelation discon graph
256 pure $ graphAsRelation discon graph
245−
257+transactionGraphAsRelation conn@(RemoteProcessConnection _ _) = remoteCall conn RetrieveTransactionGraph
246−attributesForRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Attributes)
258+
247−attributesForRelationalExpr conn relExpr = atomically $ do
248− eRelType <- typeForRelationalExprSTM conn relExpr
249− pure $ case eRelType of
250− Left err -> Left err
251− Right relType -> Right $ attributes relType
252−
253-- | Returns the UUID for the connection's disconnected transaction committed parent transaction.
259-- | Returns the UUID for the connection's disconnected transaction committed parent transaction.
254headTransactionUUID :: Connection -> IO (UUID)
260headTransactionUUID :: Connection -> IO (UUID)
255headTransactionUUID (InProcessConnection _ tvar) = do
261headTransactionUUID (InProcessConnection _ tvar) = do
256 atomically $ do
262 atomically $ do
257 (DisconnectedTransaction parentUUID _, _) <- readTVar tvar
263 (DisconnectedTransaction parentUUID _, _) <- readTVar tvar
258 pure parentUUID
264 pure parentUUID
265+headTransactionUUID conn@(RemoteProcessConnection _ _) = remoteCall conn RetrieveHeadTransactionUUID
259
266
260-- | Returns Just the name of the head of the current disconnected transaction or Nothing.
267-- | Returns Just the name of the head of the current disconnected transaction or Nothing.
261headName :: Connection -> IO (Maybe HeadName)
268headName :: Connection -> IO (Maybe HeadName)
ProjectM36/Daemon/EntryPoints.hs+28−1
@@ -1,11 +1,13 @@
1module ProjectM36.Daemon.EntryPoints where
1module ProjectM36.Daemon.EntryPoints where
2−import ProjectM36.Base
2+import ProjectM36.Base hiding (inclusionDependencies)
3import ProjectM36.Client
3import ProjectM36.Client
4import ProjectM36.Error
4import ProjectM36.Error
5import Control.Distributed.Process (Process)
5import Control.Distributed.Process (Process)
6import Control.Distributed.Process.ManagedProcess (ProcessReply)
6import Control.Distributed.Process.ManagedProcess (ProcessReply)
7import Control.Distributed.Process.ManagedProcess.Server (reply)
7import Control.Distributed.Process.ManagedProcess.Server (reply)
8import Control.Monad.IO.Class (liftIO)
8import Control.Monad.IO.Class (liftIO)
9+import Data.Map
10+import Data.UUID (UUID)
9
11
10handleExecuteRelationalExpr :: Connection -> RelationalExpr -> Process (ProcessReply (Either RelationalError Relation) Connection)
12handleExecuteRelationalExpr :: Connection -> RelationalExpr -> Process (ProcessReply (Either RelationalError Relation) Connection)
11handleExecuteRelationalExpr conn expr = do
13handleExecuteRelationalExpr conn expr = do
@@ -28,4 +30,29 @@ handleLogin conn = reply True conn
28handleExecuteGraphExpr :: Connection -> TransactionGraphOperator -> Process (ProcessReply (Maybe RelationalError) Connection)
30handleExecuteGraphExpr :: Connection -> TransactionGraphOperator -> Process (ProcessReply (Maybe RelationalError) Connection)
29handleExecuteGraphExpr conn graphExpr = do
31handleExecuteGraphExpr conn graphExpr = do
30 ret <- liftIO $ executeGraphExpr conn graphExpr
32 ret <- liftIO $ executeGraphExpr conn graphExpr
33+ reply ret conn
34+
35+handleExecuteTypeForRelationalExpr :: Connection -> RelationalExpr -> Process (ProcessReply (Either RelationalError Relation) Connection)
36+handleExecuteTypeForRelationalExpr conn relExpr = do
37+ ret <- liftIO $ typeForRelationalExpr conn relExpr
38+ reply ret conn
39+
40+handleRetrieveInclusionDependencies :: Connection -> Process (ProcessReply (Map IncDepName InclusionDependency) Connection)
41+handleRetrieveInclusionDependencies conn = do
42+ ret <- liftIO $ inclusionDependencies conn
43+ reply ret conn
44+
45+handleRetrievePlanForDatabaseContextExpr :: Connection -> DatabaseExpr -> Process (ProcessReply (Either RelationalError DatabaseExpr) Connection)
46+handleRetrievePlanForDatabaseContextExpr conn dbExpr = do
47+ ret <- liftIO $ planForDatabaseContextExpr conn dbExpr
48+ reply ret conn
49+
50+handleRetrieveTransactionGraph :: Connection -> Process (ProcessReply (Either RelationalError Relation) Connection)
51+handleRetrieveTransactionGraph conn = do
52+ ret <- liftIO $ transactionGraphAsRelation conn
53+ reply ret conn
54+
55+handleRetrieveHeadTransactionUUID :: Connection -> Process (ProcessReply UUID Connection)
56+handleRetrieveHeadTransactionUUID conn = do
57+ ret <- liftIO $ headTransactionUUID conn
31 reply ret conn
58 reply ret conn
ProjectM36/Daemon/Main.hs+21−12
@@ -1,7 +1,7 @@
1{-# LANGUAGE ScopedTypeVariables #-}
1{-# LANGUAGE ScopedTypeVariables #-}
2import ProjectM36.Client
2import ProjectM36.Client
3import ProjectM36.Daemon.ParseArgs (parseConfig, persistenceStrategy, databaseName)
3import ProjectM36.Daemon.ParseArgs (parseConfig, persistenceStrategy, databaseName)
4−import ProjectM36.Daemon.EntryPoints (handleExecuteRelationalExpr, handleExecuteDatabaseContextExpr, handleLogin, handleExecuteHeadName, handleExecuteGraphExpr)
4+import ProjectM36.Daemon.EntryPoints (handleExecuteRelationalExpr, handleExecuteDatabaseContextExpr, handleLogin, handleExecuteHeadName, handleExecuteGraphExpr, handleExecuteTypeForRelationalExpr, handleRetrieveInclusionDependencies,handleRetrievePlanForDatabaseContextExpr, handleRetrieveTransactionGraph, handleRetrieveHeadTransactionUUID)
5import ProjectM36.Daemon.RemoteCallTypes (RemoteExecution(..))
5import ProjectM36.Daemon.RemoteCallTypes (RemoteExecution(..))
6
6
7import System.Exit (exitFailure, exitSuccess)
7import System.Exit (exitFailure, exitSuccess)
@@ -10,7 +10,7 @@ import Control.Monad.IO.Class (liftIO)
10import Network.Transport.TCP (createTransport, defaultTCPParameters)
10import Network.Transport.TCP (createTransport, defaultTCPParameters)
11import Control.Distributed.Process.Node (initRemoteTable, runProcess, newLocalNode)
11import Control.Distributed.Process.Node (initRemoteTable, runProcess, newLocalNode)
12import Control.Distributed.Process.Extras.Time (Delay(..))
12import Control.Distributed.Process.Extras.Time (Delay(..))
13−import Control.Distributed.Process (ProcessId, spawnLocal, Process, register, RemoteTable)
13+import Control.Distributed.Process (Process, register, RemoteTable, getSelfPid)
14import Control.Distributed.Process.ManagedProcess (defaultProcess, UnhandledMessagePolicy(..), ProcessDefinition(..), handleCall, serve, InitHandler, InitResult(..))
14import Control.Distributed.Process.ManagedProcess (defaultProcess, UnhandledMessagePolicy(..), ProcessDefinition(..), handleCall, serve, InitHandler, InitResult(..))
15import Control.Monad (forever)
15import Control.Monad (forever)
16import System.IO (hPutStrLn, stderr)
16import System.IO (hPutStrLn, stderr)
@@ -22,19 +22,30 @@ serverDefinition = defaultProcess {
22 handleCall (\conn ExecuteHeadName -> handleExecuteHeadName conn),
22 handleCall (\conn ExecuteHeadName -> handleExecuteHeadName conn),
23 handleCall (\conn (ExecuteRelationalExpr expr) -> handleExecuteRelationalExpr conn expr),
23 handleCall (\conn (ExecuteRelationalExpr expr) -> handleExecuteRelationalExpr conn expr),
24 handleCall (\conn (ExecuteDatabaseContextExpr expr) -> handleExecuteDatabaseContextExpr conn expr),
24 handleCall (\conn (ExecuteDatabaseContextExpr expr) -> handleExecuteDatabaseContextExpr conn expr),
25− handleCall (\conn (ExecuteGraphExpr expr) -> handleExecuteGraphExpr conn expr)
25+ handleCall (\conn (ExecuteGraphExpr expr) -> handleExecuteGraphExpr conn expr),
26+ handleCall (\conn (ExecuteTypeForRelationalExpr expr) -> handleExecuteTypeForRelationalExpr conn expr),
27+ handleCall (\conn RetrieveInclusionDependencies -> handleRetrieveInclusionDependencies conn),
28+ handleCall (\conn (RetrievePlanForDatabaseContextExpr dbExpr) -> handleRetrievePlanForDatabaseContextExpr conn dbExpr),
29+ handleCall (\conn RetrieveHeadTransactionUUID -> handleRetrieveHeadTransactionUUID conn),
30+ handleCall (\conn RetrieveTransactionGraph -> handleRetrieveTransactionGraph conn)
26 ],
31 ],
27 unhandledMessagePolicy = Log
32 unhandledMessagePolicy = Log
28 }
33 }
29
34
30−initServer :: InitHandler Connection Connection
35+initServer :: InitHandler (Connection, DatabaseName) Connection
36+initServer (conn, dbname) = do
37+ registerDB dbname
31−initServer conn = return $ InitOk conn Infinity
38+ pure $ InitOk conn Infinity
32−
33−launchServer :: Connection -> Process ProcessId
34−launchServer conn = spawnLocal (serve conn initServer serverDefinition)
35
39
36remoteTable :: RemoteTable
40remoteTable :: RemoteTable
37remoteTable = DIT.__remoteTable initRemoteTable
41remoteTable = DIT.__remoteTable initRemoteTable
42+
43+registerDB :: DatabaseName -> Process ()
44+registerDB dbname = do
45+ self <- getSelfPid
46+ let dbname' = remoteDBLookupName dbname
47+ register dbname' self
48+ liftIO $ putStrLn $ "registered " ++ (show self) ++ " " ++ dbname'
38
49
39main :: IO ()
50main :: IO ()
40main = do
51main = do
@@ -51,10 +62,8 @@ main = do
51 Right transport -> do
62 Right transport -> do
52 localTCPNode <- newLocalNode transport remoteTable
63 localTCPNode <- newLocalNode transport remoteTable
53 runProcess localTCPNode $ do
64 runProcess localTCPNode $ do
54− serverPid <- launchServer conn
55− let dbname = remoteDBLookupName (databaseName daemonConfig)
65+ serve (conn, databaseName daemonConfig) initServer serverDefinition
56− register dbname serverPid
57− liftIO $ putStrLn $ show serverPid ++ " " ++ dbname
66+ liftIO $ putStrLn "serve returned"
58 _ <- forever $ threadDelay 1000000
67 _ <- forever $ threadDelay 1000000
59 putStrLn "Server Exit."
68 putStrLn "Server Exit."
60 exitSuccess
69 exitSuccess
ProjectM36/Daemon/ParseArgs.hs+1−1
@@ -26,7 +26,7 @@ parsePersistenceStrategy = CrashSafePersistence <$> (dbdirOpt <* fsyncOpt) <|>
26
26
27parseDatabaseName :: Parser DatabaseName
27parseDatabaseName :: Parser DatabaseName
28parseDatabaseName = strOption (short 'n' <>
28parseDatabaseName = strOption (short 'n' <>
29− long "dbname" <>
29+ long "database" <>
30 metavar "DATABASE NAME")
30 metavar "DATABASE NAME")
31
31
32parseConfig :: IO DaemonConfig
32parseConfig :: IO DaemonConfig
ProjectM36/Daemon/RemoteCallTypes.hs+6−1
@@ -10,5 +10,10 @@ data RemoteExecution = Login |
10 ExecuteRelationalExpr RelationalExpr |
10 ExecuteRelationalExpr RelationalExpr |
11 ExecuteDatabaseContextExpr DatabaseExpr |
11 ExecuteDatabaseContextExpr DatabaseExpr |
12 ExecuteGraphExpr TransactionGraphOperator |
12 ExecuteGraphExpr TransactionGraphOperator |
13− ExecuteHeadName
13+ ExecuteHeadName |
14+ ExecuteTypeForRelationalExpr RelationalExpr |
15+ RetrieveInclusionDependencies |
16+ RetrievePlanForDatabaseContextExpr DatabaseExpr |
17+ RetrieveTransactionGraph |
18+ RetrieveHeadTransactionUUID
14 deriving (Binary, Generic)
19 deriving (Binary, Generic)
ProjectM36/Error.hs+2−1
@@ -8,6 +8,7 @@ import Control.DeepSeq.Generics (genericRnf)
8import GHC.Generics (Generic)
8import GHC.Generics (Generic)
9import qualified Data.Text as T
9import qualified Data.Text as T
10import Data.Binary
10import Data.Binary
11+import Data.Typeable
11
12
12data RelationalError = NoSuchAttributeNamesError (S.Set AttributeName)
13data RelationalError = NoSuchAttributeNamesError (S.Set AttributeName)
13 | TupleAttributeCountMismatchError Int --attribute name
14 | TupleAttributeCountMismatchError Int --attribute name
@@ -38,7 +39,7 @@ data RelationalError = NoSuchAttributeNamesError (S.Set AttributeName)
38 | RelationValuedAttributesNotSupportedError [AttributeName]
39 | RelationValuedAttributesNotSupportedError [AttributeName]
39 | ImportError T.Text -- really? This should be broken out into some other error type- this has nothing to do with relational algebra
40 | ImportError T.Text -- really? This should be broken out into some other error type- this has nothing to do with relational algebra
40 | ExportError T.Text
41 | ExportError T.Text
41− deriving (Show,Eq,Generic,Binary)
42+ deriving (Show,Eq,Generic,Binary,Typeable)
42
43
43instance NFData RelationalError where rnf = genericRnf
44instance NFData RelationalError where rnf = genericRnf
44
45
TutorialD/Interpreter.hs+6−4
@@ -16,6 +16,8 @@ import ProjectM36.Base
16import ProjectM36.Relation.Show.Term
16import ProjectM36.Relation.Show.Term
17import ProjectM36.TransactionGraph
17import ProjectM36.TransactionGraph
18import qualified ProjectM36.Client as C
18import qualified ProjectM36.Client as C
19+import ProjectM36.Relation (attributes)
20+
19import Text.Parsec
21import Text.Parsec
20import Text.Parsec.String
22import Text.Parsec.String
21import Control.Monad.State
23import Control.Monad.State
@@ -84,11 +86,11 @@ evalTutorialD conn expr = case expr of
84 (ImportRelVarOp execOp@(RelVarDataImportOperator relVarName _ _)) -> do
86 (ImportRelVarOp execOp@(RelVarDataImportOperator relVarName _ _)) -> do
85 -- collect attributes from relvar name
87 -- collect attributes from relvar name
86 -- is there a race condition here? The attributes of the relvar may have since changed, no?
88 -- is there a race condition here? The attributes of the relvar may have since changed, no?
87− eImportAttributes <- C.attributesForRelationalExpr conn (RelationVariable relVarName)
89+ eImportType <- C.typeForRelationalExpr conn (RelationVariable relVarName)
88− case eImportAttributes of
90+ case eImportType of
89 Left err -> barf err
91 Left err -> barf err
90− Right importAttributes -> do
92+ Right importType -> do
91− exprErr <- evalRelVarDataImportOperator execOp importAttributes
93+ exprErr <- evalRelVarDataImportOperator execOp (attributes importType)
92 case exprErr of
94 case exprErr of
93 Left err -> barf err
95 Left err -> barf err
94 Right dbexpr -> evalTutorialD conn (DatabaseExprOp dbexpr)
96 Right dbexpr -> evalTutorialD conn (DatabaseExprOp dbexpr)