@@ -19,21 +19,24 @@
1919module Backend where
2020
2121import Common.Api
22+import Common.Schema
2223import Backend.Schema
2324import Common.Route
24−import Data.Text (Text)
2525import Data.Map.Monoidal (MonoidalMap (..))
26+import qualified Data.Map.Monoidal as Map
2627import Data.Pool
28+import Data.Semigroup
2729import Obelisk.Backend
2830import Obelisk.Route
2931import Obelisk.Api
3032import Obelisk.Db
3133import Obelisk.Postgres.LogicalDecoding.Plugins.TestDecoding
32−import qualified Data.Map as Map
34+import qualified Data.Map as OldMap
3335import Data.Sequence (Seq)
3436
3537import Database.Beam
3638import Database.Beam.Postgres
39+import Database.Beam.Postgres.Full (PgInsertReturning, returning, runPgInsertReturningList)
3740import Database.Beam.Postgres.Migrate
3841import Database.Beam.Migrate.Simple
3942import Database.Beam.Schema.Tables
@@ -55,27 +58,23 @@ backend = Backend
5558 withConnectionPool dbUri $ \pool -> do
5659 withResource pool $ \conn -> do
5760 runBeamPostgres conn $ autoMigrate migrationBackend checkedDb
58− let onNotify :: forall a. VS Int Text a -> Transaction -> ReadDb (V Int Text a)
59− onNotify (VS _) txn = do
60− traceM $ show txn
61− traceM $ show $ decodeTransaction txn
61+ let onNotify :: forall a. VS (Id Task) Task a -> Transaction -> ReadDb (V (Id Task) Task a)
62+ onNotify (VS requested) txn = do
6263 tasks <- runSelectReturningList' $ select $ all_ $ _db_tasks db
63− traceM $ show tasks
64− pure $ V $ MonoidalMap mempty
65− onSubscribe :: forall a. VS Int Text a -> ReadDb (V Int Text a)
66− onSubscribe (VS _) = do
64+ pure $ V $ Map.intersectionWith (,) requested $ Map.fromList $ fmap (\x -> (TaskId $ _task_id x, First $ Just x)) tasks
65+ onSubscribe :: forall a. VS (Id Task) Task a -> ReadDb (V (Id Task) Task a)
66+ onSubscribe (VS requested) = do
6767 tasks <- runSelectReturningList' $ select $ all_ $ _db_tasks db
68− traceM $ show tasks
69− pure $ V $ MonoidalMap mempty
68+ pure $ V $ Map.intersectionWith (,) requested $ Map.fromList $ fmap (\x -> (TaskId $ _task_id x, First $ Just x)) tasks
7069 onRequest :: forall a. MyRequest a -> WriteDb a
7170 onRequest = \case
72− MyRequest_Echo a -> do
73− runInsert' $ insert (_db_tasks db) $ insertExpressions $ (:[]) $ Task
71+ MyRequest_Add a -> do
72+ [taskId] <- runInsertReturningList' $ flip returning _task_id $ insert (_db_tasks db) $ insertExpressions $ (:[]) $ Task
7473 { _task_id = default_
7574 , _task_description = val_ a
7675 , _task_completed = val_ False
7776 }
78− pure a
77+ pure $ TaskId taskId
7978 withApiHandler dbUri onRequest onNotify onSubscribe $ \handler -> do
8079 serve $ \case
8180 BackendRoute_Api :/ () -> handler
@@ -107,11 +106,13 @@ instance MonadBeamRead ReadDb where
107106
108107class MonadBeamWrite m where
109108 runInsert' :: SqlInsert Postgres table -> m ()
109+ runInsertReturningList' :: FromBackendRow Postgres a => PgInsertReturning a -> m [a]
110110 runUpdate' :: SqlUpdate Postgres table -> m ()
111111 runDelete' :: SqlDelete Postgres table -> m ()
112112
113113instance MonadBeamWrite WriteDb where
114114 runInsert' = unsafeRunPgWriteDb . runInsert
115+ runInsertReturningList' = unsafeRunPgWriteDb . runPgInsertReturningList
115116 runUpdate' = unsafeRunPgWriteDb . runUpdate
116117 runDelete' = unsafeRunPgWriteDb . runDelete
117118
@@ -122,4 +123,4 @@ decodeTransaction (_, tableChanges) = runIdentity $ zipTables (Proxy :: Proxy Po
122123 f (DatabaseEntity descriptor) _ = pure $ Const $
123124 let n = view dbEntityName descriptor
124125 s = Just "public" -- view dbEntitySchema descriptor --TODO: Beam has 'Nothing' while the replication connection reports 'Just "public"'
125− in trace (show (s, n)) $ Map.findWithDefault mempty (QualifiedIdentifier s n) tableChanges
126+ in trace (show (s, n)) $ OldMap.findWithDefault mempty (QualifiedIdentifier s n) tableChanges