Module

Droplet.Language.Internal.Syntax

Package
purescript-droplet
Repository
easafe/purescript-droplet

This module defines the entire SQL eDSL, mostly because it'd be a pain to split it

Do not import this module directly, it will break your code and make it not type safe. Use the sanitized Droplet.Language instead

#SortFieldsSource Source

class SortFieldsSource :: Type -> Row Type -> Type -> Row Type -> Row Type -> Constraintclass SortFieldsSource (s :: Type) (projection :: Row Type) (f :: Type) (fields :: Row Type) (available :: Row Type) | s -> available

Fields available for sorting this query

N.B: SELECT DISTINCT queries can only be sorted by fields in the projection

Instances

#IncludeColumn Source

class IncludeColumn :: Symbol -> Type -> RowList Symbol -> RowList Type -> Constraintclass IncludeColumn (name :: Symbol) (t :: Type) (aliases :: SymbolList) (included :: RowList Type) | name -> included

Build a RowList of the given name and type qualified with each alias

Instances

#UnwrapAll Source

class UnwrapAll :: RowList Type -> Row Type -> Constraintclass UnwrapAll (list :: RowList Type) (projection :: Row Type) | list -> projection

Recursively remove source field wrappers

Instances

#Resume Source

class Resume a b c | a -> b, a b -> c where

Most SQL statement constructors accept a rest type parameter that refers to next statements

Such parameter is initially filled with E, meaning that the query ends there

This type class replaces the (nested) final E for the next statement

Members

Instances

#StarProjection Source

class StarProjection :: RowList Type -> Row Type -> RowList Symbol -> Row Type -> Constraintclass StarProjection (list :: RowList Type) (fields :: Row Type) (aliases :: SymbolList) (projection :: Row Type) | list -> projection

SELECT * FROM should:

  • Display column unqualified if it appear both as qualified and unqualified
  • Display column qualified if is projected with Path

Instances

#SymbolListSingleton Source

class SymbolListSingleton :: Symbol -> RowList Symbol -> Constraintclass SymbolListSingleton (alias :: Symbol) (list :: SymbolList) | alias -> list

Creates a SymbolList single with a single entry

Instances

#SourceAlias Source

class SourceAlias :: Type -> Symbol -> Constraintclass SourceAlias (f :: Type) (alias :: Symbol) | f -> alias

Table/subquery alias or Empty

Instances

#ToPath Source

class ToPath :: Symbol -> Symbol -> Constraintclass ToPath (alias :: Symbol) (path :: Symbol) | alias -> path

Optionally add source field alias

Instances

#QueryMustBeAliased Source

class QueryMustBeAliased :: Type -> Symbol -> Constraintclass QueryMustBeAliased (q :: Type) (alias :: Symbol) | q -> alias

Find this query's alias, or fail at compile time if query is not aliased

Instances

#UniqueSources Source

class UniqueSources :: Row Type -> Row Type -> Constraintclass UniqueSources (some :: Row Type) (more :: Row Type) 

Joined tables should not be the same

Instances

#OuterScopeAlias Source

class OuterScopeAlias :: RowList Symbol -> RowList Symbol -> Boolean -> Constraintclass OuterScopeAlias (all :: SymbolList) (unique :: SymbolList) (y :: Boolean) | all unique -> y

Is this column present in the current field source?

Instances

#OnCondition Source

class OnCondition :: Type -> Row Type -> RowList Symbol -> Constraintclass OnCondition (c :: Type) (fields :: Row Type) (aliases :: SymbolList) 

Comparision logic for ON statements

Instances

#QueryOptionallyAliased Source

class QueryOptionallyAliased :: Type -> Symbol -> Symbol -> Constraintclass QueryOptionallyAliased (q :: Type) (name :: Symbol) (alias :: Symbol) | q -> name alias

If this query is in the form of (SELECT ...) AS alias, return alias, otherwise keep name

Instances

#ToJoin Source

class ToJoin :: Type -> Row Type -> RowList Symbol -> Constraintclass ToJoin (q :: Type) (fields :: Row Type) (aliases :: SymbolList) | q -> fields aliases

Given a source q, compute its joined (non and qualified) fields

Instances

#QualifiedColumn Source

class QualifiedColumn :: Boolean -> Symbol -> Row Type -> Type -> Constraintclass QualifiedColumn (unscoped :: Boolean) (fullPath :: Symbol) (fields :: Row Type) (t :: Type) | unscoped -> fullPath fields t

The type of a qualified column

Instances

#OnComparision Source

class OnComparision :: Type -> Row Type -> RowList Symbol -> Type -> Constraintclass OnComparision (a :: Type) (fields :: Row Type) (aliases :: SymbolList) (t :: Type) | a -> t

Instances

#Join Source

data Join :: Side -> Row Type -> Type -> Type -> RowList Symbol -> Type -> Typedata Join (k :: Side) (fields :: Row Type) q r (aliases :: SymbolList) rest

Constructors

Instances

#Inclusion Source

data Inclusion

Constructors

#Side Source

data Side

Kind for OUTER and INNER joins

#Inner Source

data Inner :: Side

Instances

#Outer Source

data Outer :: Side

Instances

#SymbolList Source

type SymbolList = RowList Symbol

A RowList of Symbols

#join Source

join :: forall r l aliases unique las ras right rf lf left all source fields. ToJoin l left las => ToJoin r right ras => UniqueSources left right => RowListAppend las ras aliases => RowListNub aliases unique => UniqueAliases aliases unique => Union right left all => Nub all source => Union left lf source => Union right rf source => Union lf rf fields => l -> r -> Join Inner fields l r aliases E

INNER JOIN statement

JOIN sources are the same as FROM

#leftJoin Source

leftJoin :: forall r l las ras list out aliases unique rf lf right left all fields source. ToJoin l left las => ToJoin r right ras => UniqueSources left right => RowListAppend las ras aliases => RowListNub aliases unique => UniqueAliases aliases unique => Union left right all => Nub all source => Union left lf source => Union right rf source => RowToList lf list => ToOuterFields list out => Union rf out fields => l -> r -> Join Outer fields l r aliases E

LEFT OUTER JOIN statement

JOIN sources are the same as FROM

#ValidGroupByProjection Source

class ValidGroupByProjection :: Type -> Row Type -> Constraintclass ValidGroupByProjection (s :: Type) (grouped :: Row Type) | s -> grouped

Asserts that a SELECT ... GROUP BY projection contains only grouped columns or aggregate functions

Instances

#GroupByFields Source

class GroupByFields :: Type -> Row Type -> Row Type -> Constraintclass GroupByFields (f :: Type) (fields :: Row Type) (grouped :: Row Type) | f -> fields grouped

Instances

#ToGroupBy Source

class ToGroupBy :: Type -> Type -> Row Type -> Constraintclass ToGroupBy (q :: Type) (s :: Type) (fields :: Row Type) | q -> s fields

GROUP BY can only follow FROM or WHERE

Instances

#ToOuterFields Source

class ToOuterFields :: RowList Type -> Row Type -> Constraintclass ToOuterFields (list :: RowList Type) (fields :: Row Type) | list -> fields

OUTER JOINs make one side nullable, as a corresponding record may not be found

For ease of use, this class marks the nullable side fields with Joined, later on ToProjection will flatten it to Maybe

Instances

#ToUnion Source

class ToUnion (q :: Type) (r :: Type) 

Instances

#RequiredFields Source

class RequiredFields :: RowList Type -> Row Type -> Constraintclass RequiredFields (fieldList :: RowList Type) (required :: Row Type) | fieldList -> required

Instances

#ToAs Source

class ToAs :: Type -> Symbol -> Constraintclass ToAs (q :: Type) (alias :: Symbol) | q -> alias

Acceptable alias targets

Instances

#exists Source

exists :: forall s projection f fields rest. Select s projection (From f fields rest) -> Op Exists (Select s projection (From f fields rest))

#ToFrom Source

class ToFrom :: Type -> Type -> Row Type -> Constraintclass ToFrom (f :: Type) (q :: Type) (fields :: Row Type) | q f -> fields

Acceptable sources for FROM statements

Instances

#GroupBySource Source

class GroupBySource :: Type -> Row Type -> Constraintclass GroupBySource (f :: Type) (fields :: Row Type) | f -> fields

Instances

#InsertList Source

class InsertList :: Row Type -> Type -> Row Type -> Constraintclass InsertList (fields :: Row Type) (fieldNames :: Type) (inserted :: Row Type) | fieldNames -> fields inserted

Instances

#InsertValues Source

class InsertValues :: Row Type -> Type -> Type -> Constraintclass InsertValues (fields :: Row Type) (fieldNames :: Type) (t :: Type) 

Instances

#ToPrepare Source

class ToPrepare (q :: Type) 

Only complete statements are accepted by PREPARE

Instances

#ToProjection Source

class ToProjection :: Type -> Row Type -> RowList Symbol -> Row Type -> Constraintclass ToProjection (s :: Type) (fields :: Row Type) (aliases :: SymbolList) (projection :: Row Type) | s -> fields projection

Computes SELECT projection as a Row Type

Instances

#ToSelect Source

class ToSelect (s :: Type) 

Acceptable column type for SELECT statements

Instances

#ToSingleColumn Source

class ToSingleColumn :: RowList Type -> Symbol -> Type -> Constraintclass ToSingleColumn (fields :: RowList Type) (name :: Symbol) (t :: Type) | fields -> name t

Instances

#ToSubExpression Source

class ToSubExpression (s :: Type) 

Only single columns can be projected by subqueries

Note: column subqueries may not return a value, thus their projection will be Maybe unless the original column type is already Maybe

Instances

#IncludeAllColumns Source

class IncludeAllColumns :: RowList Type -> RowList Symbol -> RowList Type -> Constraintclass IncludeAllColumns (list :: RowList Type) (aliases :: SymbolList) (all :: RowList Type) | list -> all

Recursively call IncludeColumn on the given list

Instances

#SourceFields Source

class SourceFields :: Type -> Row Type -> RowList Symbol -> Constraintclass SourceFields (f :: Type) (fields :: Row Type) (aliases :: SymbolList) | f -> fields aliases

Given a source f, compute its (non and qualified) fields

Instances

#ToUpdatePairs Source

class ToUpdatePairs :: Row Type -> Type -> Constraintclass ToUpdatePairs (fields :: Row Type) (pairs :: Type) 

Instances

#ToReturning Source

class ToReturning (f :: Type) (q :: Type) | q -> f

Instances

#ToReturningFields Source

class ToReturningFields :: Type -> Row Type -> Constraintclass ToReturningFields (f :: Type) (fields :: Row Type) | f -> fields

Instances

#UniqueAliases Source

class UniqueAliases :: RowList Symbol -> RowList Symbol -> Constraintclass UniqueAliases (some :: SymbolList) (more :: SymbolList) 

Joined tables should not repeat table aliases

Instances

#QualifiedFields Source

class QualifiedFields :: RowList Type -> Symbol -> Row Type -> Constraintclass QualifiedFields (list :: RowList Type) (alias :: Symbol) (fields :: Row Type) | list alias -> fields

Computes all source fields with their alias

Instances

#on Source

on :: forall k l r c fields aliases. OnCondition c fields aliases => c -> Join k fields l r aliases E -> Join k fields l r aliases (On c E)

JOIN ... ON statement

#On Source

data On c rest

Constructors

Instances

#ToWhere Source

class ToWhere (c :: Type) (q :: Type) 

WHERE can only follow FROM, UPDATE and DELETE

Instances

#JoinedToMaybe Source

class JoinedToMaybe (t :: Type) (v :: Type) | t -> v

Joined fields appear as Maybe in projections

Instances

#CompatibleProjection Source

class CompatibleProjection :: RowList Type -> RowList Type -> Constraintclass CompatibleProjection (pro :: RowList Type) (jection :: RowList Type) 

Instances

#Union Source

data Union q r

Constructors

Instances

#union Source

union :: forall q r. ToUnion q r => q -> r -> Union q r

#UniqueColumnNames Source

class UniqueColumnNames :: Row Type -> Row Type -> Constraintclass UniqueColumnNames (some :: Row Type) (more :: Row Type) 

Query projections should not repeat column names

Instances

#As Source

newtype As :: Symbol -> Type -> Typenewtype As (alias :: Symbol) rest

Constructors

Instances

#Delete Source

newtype Delete rest

Constructors

Instances

#From Source

data From :: Type -> Row Type -> Type -> Typedata From f (fields :: Row Type) rest

Constructors

Instances

#Insert Source

newtype Insert rest

Constructors

Instances

#OrderBy Source

data OrderBy f rest

Constructors

Instances

#ToOrderBy Source

class ToOrderBy (f :: Type) (q :: Type) 

ORDER BY must be last statement

Instances

#SortFields Source

class SortFields :: Type -> Row Type -> Constraintclass SortFields (f :: Type) (fields :: Row Type) | f -> fields

Instances

#ToLimit Source

class ToLimit (q :: Type) 

Instances

#Limit Source

data Limit rest

Constructors

Instances

#groupBy Source

groupBy :: forall f s q sql grouped fields. ToGroupBy q s fields => GroupByFields f fields grouped => ValidGroupByProjection s grouped => Resume q (GroupBy f E) sql => f -> q -> sql

GROUP BY statement

#GroupBy Source

data GroupBy f rest

Constructors

Instances

#unionAll Source

unionAll :: forall q r. ToUnion q r => q -> r -> Union q r

#orderBy Source

orderBy :: forall f q sql. ToOrderBy f q => Resume q (OrderBy f E) sql => f -> q -> sql

ORDER BY statement

#Into Source

data Into :: Symbol -> Row Type -> Type -> Type -> Typedata Into (name :: Symbol) (fields :: Row Type) fieldNames rest

Constructors

  • Into fieldNames rest

Instances

#Plan Source

newtype Plan

Name of this prepared statement

Constructors

#Distinct Source

newtype Distinct s

Constructors

Instances

#distinct Source

distinct :: forall s. ToSelect s => s -> Distinct s

#Prepare Source

data Prepare q

Constructors

#Select Source

data Select :: Type -> Row Type -> Type -> Typedata Select s (projection :: Row Type) rest

SELECT representation. projection refers to the final output of this statement

Constructors

Instances

#Returning Source

newtype Returning f

Constructors

#Set Source

data Set pairs rest

Constructors

Instances

#Update Source

newtype Update :: Symbol -> Row Type -> Type -> Typenewtype Update (name :: Symbol) (fields :: Row Type) rest

Constructors

Instances

#Values Source

data Values fieldValues rest

Constructors

Instances

#Offset Source

data Offset rest

Constructors

Instances

#ToOffset Source

class ToOffset (q :: Type) 

Instances

#offset Source

offset :: forall q sql. ToOffset q => Resume q (Offset E) sql => Int -> q -> sql

OFFSET statement

Note: OFFSET must always follow after LIMIT or ORDER BY

#Where Source

data Where c rest

Constructors

Instances

#as Source

as :: forall q alias sql. ToAs q alias => Resume q (As alias E) sql => Proxy alias -> q -> sql

AS statement

#asc Source

asc :: forall name. name -> Sort name

ASC

#desc Source

desc :: forall name. name -> Sort name

DESC

#Sort Source

data Sort (f :: Type)

Constructors

Instances

#from Source

from :: forall f q fields sql. ToFrom f q fields => Resume q (From f fields E) sql => f -> q -> sql

FROM accepts the following sources

  • Tables
  • Inner and outer joins
  • Aliased tables
  • Aliased SELECT statements

Due to how SQL binding works, joins and subqueries require brackets to be parsed correctly. For example:

  • SELECT column FROM (SELECT column FROM table) AS alias should be select column # from (select column # from table # as alias))
  • SELECT column FROM table alias JOIN other_table other_alias should be select column # from ((table # as alias)join(other_table # as other_alias)))

To aid composition, SELECT projections are only validated on FROM

#limit Source

limit :: forall q sql. ToLimit q => Resume q (Limit E) sql => Int -> q -> sql

LIMIT statement

Note: LIMIT must always follow after ORDER BY

#into Source

into :: forall tableName fields fieldNames fieldList required e inserted. RowToList fields fieldList => RequiredFields fieldList required => InsertList fields fieldNames inserted => Union required e inserted => Table tableName fields -> fieldNames -> Insert E -> Insert (Into tableName fields fieldNames E)

#prepare Source

prepare :: forall q. ToPrepare q => Plan -> q -> Prepare q

https://www.postgresql.org/docs/current/sql-prepare.html

PREPARE statements can be employed to reuse execution plans, and thus optimize performance

Note: droplet always creates server-side parameters for literal values in queries. In the case of PREPARE, however, literals will be be parsed as statement parameters

#select Source

select :: forall s projection. ToSelect s => s -> Select s projection E

SELECT can project literals, columns and subqueries with the following considerations:

  • Multiple columns are represented by tuples. Data.Tuple.Nested./\ is convenient for this
  • Literal values (e.g., numbers) must be aliased (with AS)
  • Columns names in projections must be unique, or referenced by different table aliases (e.g., u.name, t.name)
  • Subqueries must return a single column

#set Source

set :: forall name fields pairs. ToUpdatePairs fields pairs => pairs -> Update name fields E -> Update name fields (Set pairs E)

#update Source

update :: forall name fields. Table name fields -> Update name fields E

#values Source

values :: forall tableName fields fieldNames fieldValues. InsertValues fields fieldNames fieldValues => fieldValues -> Insert (Into tableName fields fieldNames E) -> Insert (Into tableName fields fieldNames (Values fieldValues E))

#returning Source

returning :: forall f q sql. ToReturning f q => Resume q (Returning f) sql => f -> q -> sql

#wher Source

wher :: forall c q sql. ToWhere c q => Resume q (Where c E) sql => c -> q -> sql

WHERE statement