@@ -12,6 +12,7 @@ module ProjectM36.Client
1212 executeDatabaseContextExpr,
1313 executeDatabaseContextIOExpr,
1414 executeGraphExpr,
15+ executeSchemaExpr,
1516 executeTransGraphRelationalExpr,
1617 commit,
1718 rollback,
@@ -19,6 +20,8 @@ module ProjectM36.Client
1920 inclusionDependencies,
2021 planForDatabaseContextExpr,
2122 processPersistence,
23+ currentSchemaName,
24+ setCurrentSchemaName,
2225 transactionGraphAsRelation,
2326 relationVariablesAsRelation,
2427 headName,
@@ -60,18 +63,19 @@ import ProjectM36.Base hiding (inclusionDependencies) --defined in this module a
6063import qualified ProjectM36.Base as B
6164import ProjectM36.Error
6265import ProjectM36.StaticOptimizer
66+import qualified ProjectM36.IsomorphicSchema as Schema
6367import Control.Monad.State
6468import qualified ProjectM36.RelationalExpression as RE
6569import ProjectM36.DatabaseContext (basicDatabaseContext)
6670import ProjectM36.TransactionGraph
6771import qualified ProjectM36.Transaction as Trans
68−import qualified ProjectM36.DisconnectedTransaction as DTrans
6972import ProjectM36.TransactionGraph.Persist
7073import ProjectM36.Attribute hiding (atomTypes)
7174import ProjectM36.TransGraphRelationalExpression (TransGraphRelationalExpr, evalTransGraphRelationalExpr)
7275import ProjectM36.Persist (DiskSync(..))
7376import ProjectM36.Notifications
7477import ProjectM36.Server.RemoteCallTypes
78+import qualified ProjectM36.DisconnectedTransaction as Discon
7579import ProjectM36.Relation (typesAsRelation)
7680import ProjectM36.AtomFunctionBody (initScriptSession, ScriptSession)
7781import qualified ProjectM36.Relation as R
@@ -287,7 +291,7 @@ createSessionAtCommit_ commitId newSessionId (InProcessConnection _ _ sessions g
287291 case keyDuplication of
288292 Just _ -> pure $ Left (SessionIdInUseError newSessionId)
289293 Nothing -> do
290− STMMap.insert (Session freshDiscon) newSessionId sessions
294+ STMMap.insert (Session freshDiscon defaultSchemaName) newSessionId sessions
291295 pure $ Right newSessionId
292296createSessionAtCommit_ _ _ (RemoteProcessConnection _ _) = error "createSessionAtCommit_ called on remote connection"
293297
@@ -357,6 +361,24 @@ sessionForSessionId :: SessionId -> Sessions -> STM (Either RelationalError Sess
357361sessionForSessionId sessionId sessions = do
358362 maybeSession <- STMMap.lookup sessionId sessions
359363 pure $ maybe (Left $ NoSuchSessionError sessionId) Right maybeSession
364+
365+currentSchemaName :: SessionId -> Connection -> IO (Maybe SchemaName)
366+currentSchemaName sessionId (InProcessConnection _ _ sessions _ _) = atomically $ do
367+ eSession <- sessionForSessionId sessionId sessions
368+ case eSession of
369+ Left _ -> pure Nothing
370+ Right session -> pure (Just (Sess.schemaName session))
371+currentSchemaName sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (RetrieveCurrentSchemaName sessionId)
372+
373+setCurrentSchemaName :: SessionId -> Connection -> SchemaName -> IO (Maybe RelationalError)
374+setCurrentSchemaName sessionId (InProcessConnection _ _ sessions _ _) sname = atomically $ do
375+ eSession <- sessionForSessionId sessionId sessions
376+ case eSession of
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)
360382
361383-- | Execute a relational expression in the context of the session and connection. Relational expressions are queries and therefore cannot alter the database.
362384executeRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
@@ -364,7 +386,7 @@ executeRelationalExpr sessionId (InProcessConnection _ _ sessions _ _) expr = ex
364386 eSession <- sessionForSessionId sessionId sessions
365387 case eSession of
366388 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
368390 Left err -> pure (Left err)
369391 Right rel -> pure (force (Right rel)) -- this is necessary so that any undefined/error exceptions are spit out here
370392executeRelationalExpr sessionId conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteRelationalExpr sessionId relExpr)
@@ -381,7 +403,7 @@ executeDatabaseContextExpr sessionId (InProcessConnection _ _ sessions _ _) expr
381403 (Nothing, context') -> do
382404 let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas
383405 newSchemas = Schemas context' (Sess.subschemas session)
384− newSession = Session newDiscon
406+ newSession = Session newDiscon (Sess.schemaName session)
385407 STMMap.insert newSession sessionId sessions
386408 pure Nothing
387409
@@ -401,7 +423,7 @@ executeDatabaseContextIOExpr sessionId (InProcessConnection _ _ sessions _ scrip
401423 Right context' -> do
402424 let newDiscon = DisconnectedTransaction (Sess.parentId session) newSchemas
403425 newSchemas = Schemas context' (Sess.subschemas session)
404− newSession = Session newDiscon
426+ newSession = Session newDiscon (Sess.schemaName session)
405427 atomically $ STMMap.insert newSession sessionId sessions
406428 pure Nothing
407429executeDatabaseContextIOExpr sessionId conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (ExecuteDatabaseContextIOExpr sessionId dbExpr)
@@ -412,11 +434,11 @@ executeGraphExprSTM_ freshId sessionId sessions graphExpr graphTvar = do
412434 eSession <- sessionForSessionId sessionId sessions
413435 case eSession of
414436 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
416438 Left err -> pure $ Left err
417439 Right (discon', graph') -> do
418440 writeTVar graphTvar graph'
419− let newSession = Session discon'
441+ let newSession = Session discon' (Sess.schemaName session)
420442 STMMap.insert newSession sessionId sessions
421443 pure $ Right graph'
422444
@@ -483,6 +505,24 @@ executeTransGraphRelationalExpr _ (InProcessConnection _ _ _ graphTvar _) tgraph
483505 Right rel -> pure (force (Right rel))
484506executeTransGraphRelationalExpr sessionId conn@(RemoteProcessConnection _ _) tgraphExpr = remoteCall conn (ExecuteTransGraphRelationalExpr sessionId tgraphExpr)
485507
508+executeSchemaExpr :: SessionId -> Connection -> Schema.SchemaExpr -> IO (Maybe RelationalError)
509+executeSchemaExpr sessionId (InProcessConnection _ _ sessions _ _) schemaExpr = atomically $ do
510+ eSession <- sessionForSessionId sessionId sessions
511+ case eSession of
512+ Left err -> pure (Just err)
513+ Right session -> do
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
523+ pure Nothing
524+executeSchemaExpr sessionId conn@(RemoteProcessConnection _ _) schemaExpr = remoteCall conn (ExecuteSchemaExpr sessionId schemaExpr)
525+
486526-- | 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.
487527commit :: SessionId -> Connection -> IO (Maybe RelationalError)
488528commit sessionId conn@(InProcessConnection _ _ _ _ _) = executeGraphExpr sessionId conn Commit
@@ -553,9 +593,9 @@ transactionGraphAsRelation sessionId (InProcessConnection _ _ sessions tvar _) =
553593 eSession <- sessionForSessionId sessionId sessions
554594 case eSession of
555595 Left err -> pure $ Left err
556− Right (Session discon) -> do
596+ Right session -> do
557597 graph <- readTVar tvar
558− pure $ graphAsRelation discon graph
598+ pure $ graphAsRelation (Sess.disconnectedTransaction session) graph
559599
560600transactionGraphAsRelation sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (RetrieveTransactionGraph sessionId)
561601