| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
IHP.TypedSql
Synopsis
- typedSql :: QuasiQuoter
- typedSqlStar :: QuasiQuoter
- data QueryCardinality
- data QueryExecResult
- data TypedQuery (cardinality :: QueryCardinality) (execResult :: QueryExecResult) result = TypedQuery {
- tqSnippet :: !Snippet
- tqResultDecoder :: !(Row result)
- type family TypedQueryResult (cardinality :: QueryCardinality) result where ...
- type family SqlExecTypedResult (execResult :: QueryExecResult) where ...
- class DecodeTypedQuery (cardinality :: QueryCardinality)
- class RunTypedExec (execResult :: QueryExecResult)
- sqlQueryTyped :: forall (cardinality :: QueryCardinality) result. (?modelContext :: ModelContext, DecodeTypedQuery cardinality) => TypedQuery cardinality 'ReturnsRows result -> IO (TypedQueryResult cardinality result)
- sqlQueryTypedRows :: (?modelContext :: ModelContext) => TypedQuery 'ManyRows 'ReturnsRows result -> IO [result]
- sqlQueryTypedOneOrNothing :: (?modelContext :: ModelContext) => TypedQuery 'AtMostOneRow 'ReturnsRows result -> IO (Maybe result)
- sqlQueryTypedSingle :: (?modelContext :: ModelContext) => TypedQuery 'ExactlyOneRow 'ReturnsRows result -> IO result
- sqlQueryTypedMaybeColumn :: (?modelContext :: ModelContext) => TypedQuery 'AtMostOneRow 'ReturnsRows (Maybe result) -> IO (Maybe result)
- sqlQueryTypedPipelined :: forall (cardinality :: QueryCardinality) result. DecodeTypedQuery cardinality => TypedQuery cardinality 'ReturnsRows result -> Pipeline (TypedQueryResult cardinality result)
- sqlQueryTypedMaybeColumnPipelined :: TypedQuery 'AtMostOneRow 'ReturnsRows (Maybe result) -> Pipeline (Maybe result)
- sqlExecTyped :: forall (cardinality :: QueryCardinality) (execResult :: QueryExecResult) result. (?modelContext :: ModelContext, RunTypedExec execResult) => TypedQuery cardinality execResult result -> IO (SqlExecTypedResult execResult)
Documentation
typedSql :: QuasiQuoter Source #
QuasiQuoter entry point for typed SQL.
Disallows SELECT * and SELECT table.* by default to prevent production errors
when the schema changes. Use typedSqlStar to opt in to star selects.
typedSqlStar :: QuasiQuoter Source #
Like typedSql but allows SELECT * and SELECT table.* patterns.
Use this when you understand that star selects can break at runtime if the
schema changes between compilation and deployment.
data QueryCardinality Source #
What the SQL parser can prove about how many rows a query returns.
Constructors
| ManyRows | |
| AtMostOneRow | |
| ExactlyOneRow |
Instances
| Show QueryCardinality Source # | |
Defined in IHP.TypedSql.Types Methods showsPrec :: Int -> QueryCardinality -> ShowS # show :: QueryCardinality -> String # showList :: [QueryCardinality] -> ShowS # | |
| Eq QueryCardinality Source # | |
Defined in IHP.TypedSql.Types Methods (==) :: QueryCardinality -> QueryCardinality -> Bool # (/=) :: QueryCardinality -> QueryCardinality -> Bool # | |
data QueryExecResult Source #
What kind of result an SQL statement has.
This marker is separate from QueryCardinality because statements without
result columns can still have different execution results: DML statements
report affected rows, while utility statements such as SET CONSTRAINTS do
not report a row count.
Constructors
| ReturnsRows | |
| ReturnsAffectedRows | |
| ReturnsNoResult |
Instances
| Show QueryExecResult Source # | |
Defined in IHP.TypedSql.Types Methods showsPrec :: Int -> QueryExecResult -> ShowS # show :: QueryExecResult -> String # showList :: [QueryExecResult] -> ShowS # | |
| Eq QueryExecResult Source # | |
Defined in IHP.TypedSql.Types Methods (==) :: QueryExecResult -> QueryExecResult -> Bool # (/=) :: QueryExecResult -> QueryExecResult -> Bool # | |
data TypedQuery (cardinality :: QueryCardinality) (execResult :: QueryExecResult) result Source #
Prepared query with a custom row parser. High-level: this is the runtime value produced by the typed SQL quasiquoter.
Constructors
| TypedQuery | |
Fields
| |
type family TypedQueryResult (cardinality :: QueryCardinality) result where ... Source #
The result shape returned by sqlQueryTyped.
Equations
| TypedQueryResult 'ManyRows result = [result] | |
| TypedQueryResult 'AtMostOneRow result = Maybe result | |
| TypedQueryResult 'ExactlyOneRow result = result |
type family SqlExecTypedResult (execResult :: QueryExecResult) where ... Source #
The result returned by sqlExecTyped.
Equations
| SqlExecTypedResult 'ReturnsAffectedRows = Int64 | |
| SqlExecTypedResult 'ReturnsNoResult = () | |
| SqlExecTypedResult 'ReturnsRows = TypeError ('Text "sqlExecTyped cannot run SQL statements that return rows. Use sqlQueryTyped instead.") :: Type |
class DecodeTypedQuery (cardinality :: QueryCardinality) Source #
Minimal complete definition
typedQueryResultDecoder
Instances
| DecodeTypedQuery 'AtMostOneRow Source # | |
Defined in IHP.TypedSql Methods typedQueryResultDecoder :: Proxy 'AtMostOneRow -> Row result -> Result (TypedQueryResult 'AtMostOneRow result) | |
| DecodeTypedQuery 'ExactlyOneRow Source # | |
Defined in IHP.TypedSql Methods typedQueryResultDecoder :: Proxy 'ExactlyOneRow -> Row result -> Result (TypedQueryResult 'ExactlyOneRow result) | |
| DecodeTypedQuery 'ManyRows Source # | |
Defined in IHP.TypedSql Methods typedQueryResultDecoder :: Proxy 'ManyRows -> Row result -> Result (TypedQueryResult 'ManyRows result) | |
class RunTypedExec (execResult :: QueryExecResult) Source #
Minimal complete definition
runTypedExec
Instances
| RunTypedExec 'ReturnsAffectedRows Source # | |
Defined in IHP.TypedSql Methods runTypedExec :: Proxy 'ReturnsAffectedRows -> ModelContext -> Snippet -> IO (SqlExecTypedResult 'ReturnsAffectedRows) | |
| RunTypedExec 'ReturnsNoResult Source # | |
Defined in IHP.TypedSql Methods runTypedExec :: Proxy 'ReturnsNoResult -> ModelContext -> Snippet -> IO (SqlExecTypedResult 'ReturnsNoResult) | |
| (TypeError ('Text "sqlExecTyped cannot run SQL statements that return rows. Use sqlQueryTyped instead.") :: Constraint) => RunTypedExec 'ReturnsRows Source # | |
Defined in IHP.TypedSql Methods runTypedExec :: Proxy 'ReturnsRows -> ModelContext -> Snippet -> IO (SqlExecTypedResult 'ReturnsRows) | |
sqlQueryTyped :: forall (cardinality :: QueryCardinality) result. (?modelContext :: ModelContext, DecodeTypedQuery cardinality) => TypedQuery cardinality 'ReturnsRows result -> IO (TypedQueryResult cardinality result) Source #
Run a typed SELECT query.
Also works with INSERT/UPDATE/DELETE ... RETURNING statements that return rows.
The return type is inferred from the query cardinality:
- many rows:
[result] - at most one row:
Maybe result - exactly one row:
result
users <- sqlQueryTyped [typedSql| SELECT name FROM users |] -- IO [Text] total <- sqlQueryTyped [typedSql| SELECT count(*) FROM users |] -- IO Int64
sqlQueryTypedRows :: (?modelContext :: ModelContext) => TypedQuery 'ManyRows 'ReturnsRows result -> IO [result] Source #
Run a typed query that can return many rows.
This is equivalent to sqlQueryTyped, but fixes the expected cardinality in
the function name. It can make type errors easier to read when migrating code
from the old list-shaped sqlQueryTyped result.
sqlQueryTypedOneOrNothing :: (?modelContext :: ModelContext) => TypedQuery 'AtMostOneRow 'ReturnsRows result -> IO (Maybe result) Source #
Run a typed query that can return at most one row.
This is equivalent to sqlQueryTyped, but fixes the expected cardinality in
the function name.
sqlQueryTypedSingle :: (?modelContext :: ModelContext) => TypedQuery 'ExactlyOneRow 'ReturnsRows result -> IO result Source #
Run a typed query that must return exactly one row.
This is equivalent to sqlQueryTyped, but fixes the expected cardinality in
the function name.
sqlQueryTypedMaybeColumn :: (?modelContext :: ModelContext) => TypedQuery 'AtMostOneRow 'ReturnsRows (Maybe result) -> IO (Maybe result) Source #
Run an at-most-one-row query selecting a nullable single column and flatten
the two independent failure modes into one Maybe.
Useful for queries like:
email <- sqlQueryTypedMaybeColumn [typedSql|
SELECT optional_email FROM users WHERE id = ${userId}
|]Without this helper, the precise sqlQueryTyped result is
Maybe (Maybe Text): the outer Maybe is "no row", the inner Maybe is
"the selected column was NULL".
sqlQueryTypedPipelined :: forall (cardinality :: QueryCardinality) result. DecodeTypedQuery cardinality => TypedQuery cardinality 'ReturnsRows result -> Pipeline (TypedQueryResult cardinality result) Source #
Pipeline variant of sqlQueryTyped.
Compose this with pipeline to run independent typed SQL
queries in one PostgreSQL pipeline batch.
sqlQueryTypedMaybeColumnPipelined :: TypedQuery 'AtMostOneRow 'ReturnsRows (Maybe result) -> Pipeline (Maybe result) Source #
Pipeline variant of sqlQueryTypedMaybeColumn.
sqlExecTyped :: forall (cardinality :: QueryCardinality) (execResult :: QueryExecResult) result. (?modelContext :: ModelContext, RunTypedExec execResult) => TypedQuery cardinality execResult result -> IO (SqlExecTypedResult execResult) Source #
Run a typed statement.
Use sqlQueryTyped instead if your statement has a RETURNING clause.
Known utility statements without a row-count result, such as
SET CONSTRAINTS, are run with Hasql's no-result decoder and return ().
rowsAffected <- sqlExecTyped [typedSql| DELETE FROM items WHERE id = ${itemId} |]
sqlExecTyped [typedSql| SET CONSTRAINTS ALL DEFERRED |] -- IO ()