1{-# language DuplicateRecordFields #-}
2{-# language FlexibleContexts #-}
4{-# language NamedFieldPuns #-}
5{-# language ScopedTypeVariables #-}
6{-# language StandaloneKindSignatures #-}
7{-# language TypeApplications #-}
9module Rel8.Statement.Insert
17import Control.Exception ( throwIO )
18import Control.Monad ( (>=>) )
19import Data.Kind ( Type )
20import Data.List.NonEmpty ( NonEmpty( (:|) ) )
24import Hasql.Connection ( Connection )
25import qualified Hasql.Decoders as Hasql
26import qualified Hasql.Encoders as Hasql
27import qualified Hasql.Session as Hasql
28import qualified Hasql.Statement as Hasql
31import qualified Opaleye.Internal.Manipulation as Opaleye
32import qualified Opaleye.Manipulation as Opaleye
33import Rel8.Schema.Table ( TableSchema )
34import Rel8.Statement.Returning ( Returning( Projection, NumberOfRowsAffected ) )
35import Rel8.Table ( fromColumns, toColumns )
36import Rel8.Table.Opaleye ( table, unpackspec )
37import Rel8.Table.Recontextualize ( Inserts, Selects )
38import Rel8.Table.Serialize ( Serializable, parse )
41import qualified Data.Text as Text ( pack )
42import Data.Text.Encoding ( encodeUtf8 )
45type Insert :: Type -> Type
47 Insert :: (Selects names exprs, Inserts exprs inserts) =>
48 { into :: TableSchema names
50 , onConflict :: OnConflict
51 , returning :: Returning names a
56data OnConflict = Abort | DoNothing
59insert :: Insert a -> Connection -> IO a
60insert Insert {into, rows, onConflict, returning} =
61 case (rows, returning) of
62 ([], NumberOfRowsAffected) -> const $ pure 0
63 ([], Projection _) -> const $ pure []
65 (x:xs, NumberOfRowsAffected) -> Hasql.run session >=> either throwIO pure
67 session = Hasql.statement () statement
68 statement = Hasql.Statement bytes params decode prepare
69 bytes = encodeUtf8 $ Text.pack sql
70 params = Hasql.noParams
71 decode = Hasql.rowsAffected
73 sql = Opaleye.arrangeInsertManySql into' rows' onConflict'
75 into' = table $ toColumns <$> into
76 rows' = toColumns <$> x :| xs
78 (x:xs, Projection project) -> Hasql.run session >=> either throwIO pure
80 session = Hasql.statement () statement
81 statement = Hasql.Statement bytes params decode prepare
82 bytes = encodeUtf8 $ Text.pack sql
83 params = Hasql.noParams
84 decode = decoder project
87 Opaleye.arrangeInsertManyReturningSql
94 into' = table $ toColumns <$> into
95 rows' = toColumns <$> x :| xs
96 project' = toColumns . project . fromColumns
101 DoNothing -> Just Opaleye.DoNothing
104 decoder :: forall exprs projection a. Serializable projection a
105 => (exprs -> projection) -> Hasql.Result [a]
106 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