1{-# language DeriveTraversable #-}
2{-# language DerivingStrategies #-}
3{-# language FlexibleContexts #-}
4{-# language MonoLocalBinds #-}
5{-# language ScopedTypeVariables #-}
6{-# language TypeApplications #-}
8module Rel8.Statement.Select
18import Control.Exception ( throwIO )
19import Data.Void ( Void )
23import Hasql.Connection ( Connection )
24import qualified Hasql.Decoders as Hasql
25import qualified Hasql.Encoders as Hasql
26import qualified Hasql.Session as Hasql
27import qualified Hasql.Statement as Hasql
30import qualified Opaleye.Internal.HaskellDB.Sql as Opaleye
31import qualified Opaleye.Internal.PrimQuery as Opaleye
32import qualified Opaleye.Internal.Print as Opaleye
33import qualified Opaleye.Internal.Optimize as Opaleye
34import qualified Opaleye.Internal.QueryArr as Opaleye hiding ( Select )
35import qualified Opaleye.Internal.Sql as Opaleye
38import Text.PrettyPrint ( Doc )
41import Rel8.Expr ( Expr )
42import Rel8.Query ( Query )
43import Rel8.Query.Opaleye ( toOpaleye )
44import Rel8.Schema.Name ( Selects )
45import Rel8.Table ( Table )
46import Rel8.Table.Cols ( toCols )
47import Rel8.Table.Name ( namesFromLabels )
48import Rel8.Table.Opaleye ( castTable, exprsWithNames )
49import Rel8.Table.Serialize ( Serializable, parse )
52import qualified Data.Text as Text
53import Data.Text.Encoding ( encodeUtf8 )
56-- | Run a @SELECT@ statement, returning all rows.
57select :: forall exprs a. Serializable exprs a
58 => Connection -> Query exprs -> IO [a]
59select c query = case ppSelect query of
61 Just doc -> Hasql.run session c >>= either throwIO pure
63 session = Hasql.statement () statement
64 statement = Hasql.Statement bytes params decode prepare
65 bytes = encodeUtf8 (Text.pack sql)
66 params = Hasql.noParams
67 decode = Hasql.rowList (parse @exprs @a)
72ppSelect :: Table Expr a => Query a -> Maybe Doc
74 primQuery' <- case optimize primQuery of
76 Unit -> Just Opaleye.Unit
77 Optimized primQuery' -> Just primQuery'
78 pure $ Opaleye.ppSql $ primSelectWith names (toCols exprs) primQuery'
80 names = namesFromLabels
81 (exprs, primQuery, _) =
82 Opaleye.runSimpleQueryArrStart (toOpaleye query) ()
85ppPrimSelect :: Query a -> (Optimized Doc, a)
87 (Opaleye.ppSql . primSelect <$> optimize primQuery, a)
90 Opaleye.runSimpleQueryArrStart (toOpaleye query) ()
93data Optimized a = Empty | Unit | Optimized a
94 deriving stock (Functor, Foldable, Traversable)
97optimize :: Opaleye.PrimQuery' a -> Optimized (Opaleye.PrimQuery' Void)
98optimize query = case Opaleye.removeEmpty (Opaleye.optimize query) of
100 Just Opaleye.Unit -> Unit
101 Just query' -> Optimized query'
104primSelect :: Opaleye.PrimQuery' Void -> Opaleye.Select
105primSelect = Opaleye.foldPrimQuery Opaleye.sqlQueryGenerator
108primSelectWith :: Selects names exprs
109 => names -> exprs -> Opaleye.PrimQuery' Void -> Opaleye.Select
110primSelectWith names exprs query =
111 Opaleye.SelectFrom $ Opaleye.newSelect
112 { Opaleye.attrs = Opaleye.SelectAttrs attrs
113 , Opaleye.tables = Opaleye.oneTable (primSelect query)
116 attrs = makeAttr <$> exprsWithNames names (castTable exprs)
118 makeAttr (label, expr) =
119 (Opaleye.sqlExpr expr, Just (Opaleye.SqlColumn label))
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