1{-# language DuplicateRecordFields #-}
2{-# language FlexibleContexts #-}
4{-# language NamedFieldPuns #-}
5{-# language RecordWildCards #-}
6{-# language StandaloneKindSignatures #-}
7{-# language StrictData #-}
9module Rel8.Statement.Insert
18import Control.Exception ( throwIO )
19import Data.Foldable ( toList )
20import Data.Kind ( Type )
24import Hasql.Connection ( Connection )
25import qualified Hasql.Encoders as Hasql
26import qualified Hasql.Session as Hasql
27import qualified Hasql.Statement as Hasql
30import qualified Opaleye.Internal.HaskellDB.Sql.Print as Opaleye
33import Text.PrettyPrint ( Doc, (<+>), ($$), parens, text )
36import Rel8.Query ( Query )
37import Rel8.Schema.Name ( Name, Selects, ppColumn )
38import Rel8.Schema.Table ( TableSchema(..), ppTable )
39import Rel8.Statement.OnConflict ( OnConflict, ppOnConflict )
40import Rel8.Statement.Returning
42 , decodeReturning, emptyReturning, ppReturning
44import Rel8.Statement.Select ( ppSelect )
45import Rel8.Table ( Table )
46import Rel8.Table.Name ( showNames )
49import qualified Data.Text as Text ( pack )
50import Data.Text.Encoding ( encodeUtf8 )
53-- | The constituent parts of a SQL @INSERT@ statement.
54type Insert :: Type -> Type
56 Insert :: Selects names exprs =>
57 { into :: TableSchema names
58 -- ^ Which table to insert into.
60 -- ^ The rows to insert. This can be an arbitrary query — use
61 -- 'Rel8.values' insert a static list of rows.
62 , onConflict :: OnConflict names
63 -- ^ What to do if the inserted rows conflict with data already in the
65 , returning :: Returning names a
66 -- ^ What information to return on completion.
71ppInsert :: Insert a -> Maybe Doc
72ppInsert Insert {..} = do
73 rows' <- ppSelect rows
74 pure $ text "INSERT INTO" <+> ppInto into
76 $$ ppOnConflict into onConflict
77 $$ ppReturning into returning
80ppInto :: Table Name a => TableSchema a -> Doc
81ppInto table@TableSchema {columns} =
83 parens (Opaleye.commaV ppColumn (toList (showNames columns)))
86-- | Run an 'Insert' statement.
87insert :: Connection -> Insert a -> IO a
88insert connection i@Insert {returning} =
89 case show <$> ppInsert i of
90 Nothing -> pure (emptyReturning returning)
92 Hasql.run session connection >>= either throwIO pure
94 session = Hasql.statement () statement
95 statement = Hasql.Statement bytes params decode prepare
96 bytes = encodeUtf8 $ Text.pack sql
97 params = Hasql.noParams
98 decode = decodeReturning returning
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