@@ -19,21 +19,24 @@
19module Backend where
19module Backend where
21import Common.Api
21import Common.Api
22import Backend.Schema
23import Backend.Schema
23import Common.Route
24import Common.Route
24−import Data.Text (Text)
25import Data.Map.Monoidal (MonoidalMap (..))
25import Data.Map.Monoidal (MonoidalMap (..))
26+import qualified Data.Map.Monoidal as Map
26import Data.Pool
27import Data.Pool
27import Obelisk.Backend
29import Obelisk.Backend
28import Obelisk.Route
30import Obelisk.Route
29import Obelisk.Api
31import Obelisk.Api
30import Obelisk.Db
32import Obelisk.Db
31import Obelisk.Postgres.LogicalDecoding.Plugins.TestDecoding
33import Obelisk.Postgres.LogicalDecoding.Plugins.TestDecoding
32−import qualified Data.Map as Map
34+import qualified Data.Map as OldMap
33import Data.Sequence (Seq)
35import Data.Sequence (Seq)
35import Database.Beam
37import Database.Beam
36import Database.Beam.Postgres
38import Database.Beam.Postgres
39+import Database.Beam.Postgres.Full (PgInsertReturning, returning, runPgInsertReturningList)
37import Database.Beam.Postgres.Migrate
40import Database.Beam.Postgres.Migrate
38import Database.Beam.Migrate.Simple
41import Database.Beam.Migrate.Simple
39import Database.Beam.Schema.Tables
42import Database.Beam.Schema.Tables
@@ -55,27 +58,23 @@ backend = Backend
55 withConnectionPool dbUri $ \pool -> do
58 withConnectionPool dbUri $ \pool -> do
56 withResource pool $ \conn -> do
59 withResource pool $ \conn -> do
57 runBeamPostgres conn $ autoMigrate migrationBackend checkedDb
60 runBeamPostgres conn $ autoMigrate migrationBackend checkedDb
58− let onNotify :: forall a. VS Int Text a -> Transaction -> ReadDb (V Int Text a)
61+ let onNotify :: forall a. VS (Id Task) Task a -> Transaction -> ReadDb (V (Id Task) Task a)
59− onNotify (VS _) txn = do
62+ onNotify (VS requested) txn = do
61− traceM $ show $ decodeTransaction txn
62 tasks <- runSelectReturningList' $ select $ all_ $ _db_tasks db
63 tasks <- runSelectReturningList' $ select $ all_ $ _db_tasks db
63− traceM $ show tasks
64+ pure $ V $ Map.intersectionWith (,) requested $ Map.fromList $ fmap (\x -> (TaskId $ _task_id x, First $ Just x)) tasks
64− pure $ V $ MonoidalMap mempty
65− onSubscribe :: forall a. VS Int Text a -> ReadDb (V Int Text a)
65+ onSubscribe :: forall a. VS (Id Task) Task a -> ReadDb (V (Id Task) Task a)
66− onSubscribe (VS _) = do
66+ onSubscribe (VS requested) = do
67 tasks <- runSelectReturningList' $ select $ all_ $ _db_tasks db
67 tasks <- runSelectReturningList' $ select $ all_ $ _db_tasks db
68− traceM $ show tasks
68+ pure $ V $ Map.intersectionWith (,) requested $ Map.fromList $ fmap (\x -> (TaskId $ _task_id x, First $ Just x)) tasks
69− pure $ V $ MonoidalMap mempty
70 onRequest :: forall a. MyRequest a -> WriteDb a
69 onRequest :: forall a. MyRequest a -> WriteDb a
71 onRequest = \case
70 onRequest = \case
72− MyRequest_Echo a -> do
71+ MyRequest_Add a -> do
73− runInsert' $ insert (_db_tasks db) $ insertExpressions $ (:[]) $ Task
72+ [taskId] <- runInsertReturningList' $ flip returning _task_id $ insert (_db_tasks db) $ insertExpressions $ (:[]) $ Task
74 { _task_id = default_
73 { _task_id = default_
75 , _task_description = val_ a
74 , _task_description = val_ a
76 , _task_completed = val_ False
75 , _task_completed = val_ False
78− pure a
77+ pure $ TaskId taskId
79 withApiHandler dbUri onRequest onNotify onSubscribe $ \handler -> do
78 withApiHandler dbUri onRequest onNotify onSubscribe $ \handler -> do
80 serve $ \case
79 serve $ \case
81 BackendRoute_Api :/ () -> handler
80 BackendRoute_Api :/ () -> handler
@@ -107,11 +106,13 @@ instance MonadBeamRead ReadDb where
108class MonadBeamWrite m where
107class MonadBeamWrite m where
109 runInsert' :: SqlInsert Postgres table -> m ()
108 runInsert' :: SqlInsert Postgres table -> m ()
109+ runInsertReturningList' :: FromBackendRow Postgres a => PgInsertReturning a -> m [a]
110 runUpdate' :: SqlUpdate Postgres table -> m ()
110 runUpdate' :: SqlUpdate Postgres table -> m ()
111 runDelete' :: SqlDelete Postgres table -> m ()
111 runDelete' :: SqlDelete Postgres table -> m ()
113instance MonadBeamWrite WriteDb where
113instance MonadBeamWrite WriteDb where
114 runInsert' = unsafeRunPgWriteDb . runInsert
114 runInsert' = unsafeRunPgWriteDb . runInsert
115+ runInsertReturningList' = unsafeRunPgWriteDb . runPgInsertReturningList
115 runUpdate' = unsafeRunPgWriteDb . runUpdate
116 runUpdate' = unsafeRunPgWriteDb . runUpdate
116 runDelete' = unsafeRunPgWriteDb . runDelete
117 runDelete' = unsafeRunPgWriteDb . runDelete
@@ -122,4 +123,4 @@ decodeTransaction (_, tableChanges) = runIdentity $ zipTables (Proxy :: Proxy Po
122 f (DatabaseEntity descriptor) _ = pure $ Const $
123 f (DatabaseEntity descriptor) _ = pure $ Const $
123 let n = view dbEntityName descriptor
124 let n = view dbEntityName descriptor
124 s = Just "public" -- view dbEntitySchema descriptor --TODO: Beam has 'Nothing' while the replication connection reports 'Just "public"'
125 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