2{-# language NamedFieldPuns #-}
3{-# language ScopedTypeVariables #-}
4{-# language StandaloneKindSignatures #-}
5{-# language TypeApplications #-}
7module Rel8.Statement.Update
14import Control.Exception ( throwIO )
15import Data.Kind ( Type )
19import Hasql.Connection ( Connection )
20import qualified Hasql.Decoders as Hasql
21import qualified Hasql.Encoders as Hasql
22import qualified Hasql.Session as Hasql
23import qualified Hasql.Statement as Hasql
26import qualified Opaleye.Internal.Manipulation as Opaleye
29import Data.Profunctor ( lmap )
32import Rel8.Expr ( Expr )
33import Rel8.Expr.Opaleye ( toColumn, toPrimExpr )
34import Rel8.Schema.Name ( Selects )
35import Rel8.Schema.Table ( TableSchema )
36import Rel8.Statement.Returning ( Returning( Projection, NumberOfRowsAffected ) )
37import Rel8.Table ( fromColumns, toColumns )
38import Rel8.Table.Insert ( toInsert )
39import Rel8.Table.Opaleye ( castTable, table, unpackspec )
40import Rel8.Table.Serialize ( Serializable, parse )
43import qualified Data.Text as Text
44import Data.Text.Encoding ( encodeUtf8 )
47-- | The constituent parts of an @UPDATE@ statement.
48type Update :: Type -> Type
50 Update :: Selects names exprs =>
51 { target :: TableSchema names
52 -- ^ Which table to update.
53 , set :: exprs -> exprs
54 -- ^ How to update each selected row.
55 , updateWhere :: exprs -> Expr Bool
56 -- ^ Which rows to select for update.
57 , returning :: Returning names a
58 -- ^ What to return from the @UPDATE@ statement.
63-- | Run an @UPDATE@ statement.
64update :: Connection -> Update a -> IO a
65update c Update {target, set, updateWhere, returning} =
67 NumberOfRowsAffected -> Hasql.run session c >>= either throwIO pure
69 session = Hasql.statement () statement
70 statement = Hasql.Statement bytes params decode prepare
71 bytes = encodeUtf8 $ Text.pack sql
72 params = Hasql.noParams
73 decode = Hasql.rowsAffected
75 sql = Opaleye.arrangeUpdateSql target' set' where'
77 target' = lmap toInsert $ table $ toColumns <$> target
78 set' = toColumns . set . fromColumns
79 where' = toColumn . toPrimExpr . updateWhere . fromColumns
81 Projection project -> Hasql.run session c >>= either throwIO pure
83 session = Hasql.statement () statement
84 statement = Hasql.Statement bytes params decode prepare
85 bytes = encodeUtf8 $ Text.pack sql
86 params = Hasql.noParams
87 decode = decoder project
90 Opaleye.arrangeUpdateReturningSql
97 target' = lmap toInsert $ table $ toColumns <$> target
98 set' = toColumns . set . fromColumns
99 where' = toColumn . toPrimExpr . updateWhere . fromColumns
100 project' = castTable . toColumns . project . fromColumns
103 decoder :: forall exprs projection a. Serializable projection a
104 => (exprs -> projection) -> Hasql.Result [a]
105 decoder _ = Hasql.rowList (parse @projection @a)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list