@@ -12,6 +12,7 @@ module ProjectM36.Client
12 executeDatabaseContextExpr,
12 executeDatabaseContextExpr,
13 executeDatabaseContextIOExpr,
13 executeDatabaseContextIOExpr,
14 executeGraphExpr,
14 executeGraphExpr,
15 executeTransGraphRelationalExpr,
16 executeTransGraphRelationalExpr,
@@ -19,6 +20,8 @@ module ProjectM36.Client
19 inclusionDependencies,
20 inclusionDependencies,
20 planForDatabaseContextExpr,
21 planForDatabaseContextExpr,
21 processPersistence,
22 processPersistence,
24+ setCurrentSchemaName,
22 transactionGraphAsRelation,
25 transactionGraphAsRelation,
23 relationVariablesAsRelation,
26 relationVariablesAsRelation,
@@ -60,18 +63,19 @@ import ProjectM36.Base hiding (inclusionDependencies) --defined in this module a
60import qualified ProjectM36.Base as B
63import qualified ProjectM36.Base as B
61import ProjectM36.Error
64import ProjectM36.Error
62import ProjectM36.StaticOptimizer
65import ProjectM36.StaticOptimizer
66+import qualified ProjectM36.IsomorphicSchema as Schema
63import Control.Monad.State
67import Control.Monad.State
64import qualified ProjectM36.RelationalExpression as RE
68import qualified ProjectM36.RelationalExpression as RE
65import ProjectM36.DatabaseContext (basicDatabaseContext)
69import ProjectM36.DatabaseContext (basicDatabaseContext)
66import ProjectM36.TransactionGraph
70import ProjectM36.TransactionGraph
67import qualified ProjectM36.Transaction as Trans
71import qualified ProjectM36.Transaction as Trans
68−import qualified ProjectM36.DisconnectedTransaction as DTrans
69import ProjectM36.TransactionGraph.Persist
72import ProjectM36.TransactionGraph.Persist
70import ProjectM36.Attribute hiding (atomTypes)
73import ProjectM36.Attribute hiding (atomTypes)
71import ProjectM36.TransGraphRelationalExpression (TransGraphRelationalExpr, evalTransGraphRelationalExpr)
74import ProjectM36.TransGraphRelationalExpression (TransGraphRelationalExpr, evalTransGraphRelationalExpr)
72import ProjectM36.Persist (DiskSync(..))
75import ProjectM36.Persist (DiskSync(..))
73import ProjectM36.Notifications
76import ProjectM36.Notifications
74import ProjectM36.Server.RemoteCallTypes
77import ProjectM36.Server.RemoteCallTypes
78+import qualified ProjectM36.DisconnectedTransaction as Discon
75import ProjectM36.Relation (typesAsRelation)
79import ProjectM36.Relation (typesAsRelation)
76import ProjectM36.AtomFunctionBody (initScriptSession, ScriptSession)
80import ProjectM36.AtomFunctionBody (initScriptSession, ScriptSession)
77import qualified ProjectM36.Relation as R
81import qualified ProjectM36.Relation as R
@@ -287,7 +291,7 @@ createSessionAtCommit_ commitId newSessionId (InProcessConnection _ _ sessions g
287 case keyDuplication of
291 case keyDuplication of
288 Just _ -> pure $ Left (SessionIdInUseError newSessionId)
292 Just _ -> pure $ Left (SessionIdInUseError newSessionId)
289 Nothing -> do
293 Nothing -> do
290− STMMap.insert (Session freshDiscon) newSessionId sessions
294+ STMMap.insert (Session freshDiscon defaultSchemaName) newSessionId sessions
291 pure $ Right newSessionId
295 pure $ Right newSessionId
292createSessionAtCommit_ _ _ (RemoteProcessConnection _ _) = error "createSessionAtCommit_ called on remote connection"
296createSessionAtCommit_ _ _ (RemoteProcessConnection _ _) = error "createSessionAtCommit_ called on remote connection"
@@ -357,6 +361,24 @@ sessionForSessionId :: SessionId -> Sessions -> STM (Either RelationalError Sess
357sessionForSessionId sessionId sessions = do
361sessionForSessionId sessionId sessions = do
358 maybeSession <- STMMap.lookup sessionId sessions
362 maybeSession <- STMMap.lookup sessionId sessions
359 pure $ maybe (Left $ NoSuchSessionError sessionId) Right maybeSession
363 pure $ maybe (Left $ NoSuchSessionError sessionId) Right maybeSession
365+currentSchemaName :: SessionId -> Connection -> IO (Maybe SchemaName)
366+currentSchemaName sessionId (InProcessConnection _ _ sessions _ _) = atomically $ do
367+ eSession <- sessionForSessionId sessionId sessions
369+ Left _ -> pure Nothing
370+ Right session -> pure (Just (Sess.schemaName session))
371+currentSchemaName sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (RetrieveCurrentSchemaName sessionId)
373+setCurrentSchemaName :: SessionId -> Connection -> SchemaName -> IO (Maybe RelationalError)
374+setCurrentSchemaName sessionId (InProcessConnection _ _ sessions _ _) sname = atomically $ do
375+ eSession <- sessionForSessionId sessionId sessions
377+ Left _ -> pure Nothing
378+ Right session -> case Sess.setSchemaName sname session of
379+ Left err -> pure (Just err)
380+ Right newSession -> STMMap.insert newSession sessionId sessions >> pure Nothing
381+setCurrentSchemaName sessionId conn@(RemoteProcessConnection _ _) sname = remoteCall conn (ExecuteSetCurrentSchema sessionId sname)
361-- | Execute a relational expression in the context of the session and connection. Relational expressions are queries and therefore cannot alter the database.
383-- | Execute a relational expression in the context of the session and connection. Relational expressions are queries and therefore cannot alter the database.
362executeRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
384executeRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
@@ -364,7 +386,7 @@ executeRelationalExpr sessionId (InProcessConnection _ _ sessions _ _) expr = ex
364 eSession <- sessionForSessionId sessionId sessions
386 eSession <- sessionForSessionId sessionId sessions
365 case eSession of
387 case eSession of
366 Left err -> pure $ Left err
388 Left err -> pure $ Left err
367− Right (Session discon) -> case evalState (RE.evalRelationalExpr expr) (DTrans.concreteDatabaseContext discon) of
389+ Right session -> case evalState (RE.evalRelationalExpr expr) (Sess.concreteDatabaseContext session) of
368 Left err -> pure (Left err)
390 Left err -> pure (Left err)
369 Right rel -> pure (force (Right rel)) -- this is necessary so that any undefined/error exceptions are spit out here
391 Right rel -> pure (force (Right rel)) -- this is necessary so that any undefined/error exceptions are spit out here
370executeRelationalExpr sessionId conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteRelationalExpr sessionId relExpr)
392executeRelationalExpr sessionId conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteRelationalExpr sessionId relExpr)
@@ -381,7 +403,7 @@ executeDatabaseContextExpr sessionId (InProcessConnection _ _ sessions _ _) expr
381 (Nothing, context') -> do
403 (Nothing, context') -> do
382 let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas
404 let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas
383 newSchemas = Schemas context' (Sess.subschemas session)
405 newSchemas = Schemas context' (Sess.subschemas session)
384− newSession = Session newDiscon
406+ newSession = Session newDiscon (Sess.schemaName session)
385 STMMap.insert newSession sessionId sessions
407 STMMap.insert newSession sessionId sessions
386 pure Nothing
408 pure Nothing
@@ -401,7 +423,7 @@ executeDatabaseContextIOExpr sessionId (InProcessConnection _ _ sessions _ scrip
401 Right context' -> do
423 Right context' -> do
402 let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas
424 let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas
403 newSchemas = Schemas context' (Sess.subschemas session)
425 newSchemas = Schemas context' (Sess.subschemas session)
404− newSession = Session newDiscon
426+ newSession = Session newDiscon (Sess.schemaName session)
405 atomically $ STMMap.insert newSession sessionId sessions
427 atomically $ STMMap.insert newSession sessionId sessions
406 pure Nothing
428 pure Nothing
407executeDatabaseContextIOExpr sessionId conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (ExecuteDatabaseContextIOExpr sessionId dbExpr)
429executeDatabaseContextIOExpr sessionId conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (ExecuteDatabaseContextIOExpr sessionId dbExpr)
@@ -412,11 +434,11 @@ executeGraphExprSTM_ freshId sessionId sessions graphExpr graphTvar = do
412 eSession <- sessionForSessionId sessionId sessions
434 eSession <- sessionForSessionId sessionId sessions
413 case eSession of
435 case eSession of
414 Left err -> pure $ Left err
436 Left err -> pure $ Left err
415− Right (Session discon) -> case evalGraphOp freshId discon graph graphExpr of
437+ Right session -> case evalGraphOp freshId (Sess.disconnectedTransaction session) graph graphExpr of
416 Left err -> pure $ Left err
438 Left err -> pure $ Left err
417 Right (discon', graph') -> do
439 Right (discon', graph') -> do
418 writeTVar graphTvar graph'
440 writeTVar graphTvar graph'
419− let newSession = Session discon'
441+ let newSession = Session discon' (Sess.schemaName session)
420 STMMap.insert newSession sessionId sessions
442 STMMap.insert newSession sessionId sessions
421 pure $ Right graph'
443 pure $ Right graph'
@@ -483,6 +505,24 @@ executeTransGraphRelationalExpr _ (InProcessConnection _ _ _ graphTvar _) tgraph
483 Right rel -> pure (force (Right rel))
505 Right rel -> pure (force (Right rel))
484executeTransGraphRelationalExpr sessionId conn@(RemoteProcessConnection _ _) tgraphExpr = remoteCall conn (ExecuteTransGraphRelationalExpr sessionId tgraphExpr)
506executeTransGraphRelationalExpr sessionId conn@(RemoteProcessConnection _ _) tgraphExpr = remoteCall conn (ExecuteTransGraphRelationalExpr sessionId tgraphExpr)
508+executeSchemaExpr :: SessionId -> Connection -> Schema.SchemaExpr -> IO (Maybe RelationalError)
509+executeSchemaExpr sessionId (InProcessConnection _ _ sessions _ _) schemaExpr = atomically $ do
510+ eSession <- sessionForSessionId sessionId sessions
512+ Left err -> pure (Just err)
514+ let subschemas' = subschemas session
515+ case Schema.evalSchemaExpr schemaExpr subschemas' of
516+ Left err -> pure (Just err)
517+ Right newSubschemas -> do
518+ --hm- maybe we should start using lenses
519+ let discon = Sess.disconnectedTransaction session
520+ newSchemas = Schemas (Sess.concreteDatabaseContext session) newSubschemas
521+ newSession = Session (DisconnectedTransaction (Discon.parentId discon) newSchemas) (Sess.schemaName session)
522+ STMMap.insert newSession sessionId sessions
524+executeSchemaExpr sessionId conn@(RemoteProcessConnection _ _) schemaExpr = remoteCall conn (ExecuteSchemaExpr sessionId schemaExpr)
486-- | After modifying a session, 'commit' the transaction to the transaction graph at the head which the session is referencing. This will also trigger checks for any notifications which need to be propagated.
526-- | After modifying a session, 'commit' the transaction to the transaction graph at the head which the session is referencing. This will also trigger checks for any notifications which need to be propagated.
487commit :: SessionId -> Connection -> IO (Maybe RelationalError)
527commit :: SessionId -> Connection -> IO (Maybe RelationalError)
488commit sessionId conn@(InProcessConnection _ _ _ _ _) = executeGraphExpr sessionId conn Commit
528commit sessionId conn@(InProcessConnection _ _ _ _ _) = executeGraphExpr sessionId conn Commit
@@ -553,9 +593,9 @@ transactionGraphAsRelation sessionId (InProcessConnection _ _ sessions tvar _) =
553 eSession <- sessionForSessionId sessionId sessions
593 eSession <- sessionForSessionId sessionId sessions
554 case eSession of
594 case eSession of
555 Left err -> pure $ Left err
595 Left err -> pure $ Left err
556− Right (Session discon) -> do
596+ Right session -> do
557 graph <- readTVar tvar
597 graph <- readTVar tvar
558− pure $ graphAsRelation discon graph
598+ pure $ graphAsRelation (Sess.disconnectedTransaction session) graph
560transactionGraphAsRelation sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (RetrieveTransactionGraph sessionId)
600transactionGraphAsRelation sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (RetrieveTransactionGraph sessionId)