@@ -1,1674 +0,0 @@
1−{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
2−{-# LANGUAGE
3− AllowAmbiguousTypes
4− , DataKinds
5− , DeriveGeneric
6− , DeriveDataTypeable
7− , FlexibleContexts
8− , FlexibleInstances
9− , FunctionalDependencies
10− , GADTs
11− , GeneralizedNewtypeDeriving
12− , LambdaCase
13− , MagicHash
14− , OverloadedStrings
15− , PolyKinds
16− , RankNTypes
17− , ScopedTypeVariables
18− , StandaloneDeriving
19− , TypeApplications
20− , TypeFamilies
21− , TypeInType
22− , TypeOperators
23− , UndecidableInstances
24−#-}
25−
26−module Squeal.PostgreSQL.Statement
27− ( -- * Column Expressions
28− Expression (UnsafeExpression, renderExpression)
29− , HasParameter (param)
30− , HasColumn (getColumn)
31− , Column (Column)
32− , renderColumn
33− -- ** Default
34− , def
35− , unDef
36− -- ** Null
37− , null_
38− , unNull
39− , coalesce
40− , fromNull
41− , isNull
42− , isn'tNull
43− , matchNull
44− , nullIf
45− -- ** Functions
46− , unsafeBinaryOp
47− , unsafeUnaryOp
48− , unsafeFunction
49− , atan2_
50− , cast
51− , div_
52− , mod_
53− , trunc
54− , round_
55− , ceiling_
56− , greatest
57− , least
58− -- ** Conditions
59− , Condition
60− , true
61− , false
62− , not_
63− , (&&*)
64− , (||*)
65− , caseWhenThenElse
66− , ifThenElse
67− , (==*)
68− , (/=*)
69− , (>=*)
70− , (*<)
71− , (*<=)
72− , (>*)
73− -- ** Time
74− , currentDate
75− , currentTime
76− , currentTimestamp
77− , localTime
78− , localTimestamp
79− -- ** Aggregation
80− , unsafeAggregate
81− , unsafeAggregateDistinct
82− , sum_
83− , sumDistinct
84− , PGAvg (avg, avgDistinct)
85− , bitAnd
86− , bitOr
87− , boolAnd
88− , boolOr
89− , countStar
90− , countDistinctStar
91− , count
92− , every
93− , jsonAgg
94− , jsonbAgg
95− , jsonObjectAgg
96− , jsonbObjectAgg
97− , max_
98− , min_
99− -- * Tables
100− , Table (UnsafeTable, renderTable)
101− , HasTable (getTable)
102− -- ** Froms and Joins
103− , FromClause (..)
104− , renderFromClause
105− -- ** Table Expressions
106− , TableExpression (..)
107− , renderTableExpression
108− , from
109− , where_
110− , group
111− , having
112− , orderBy
113− , limit
114− , offset
115− , By (By, By2)
116− , renderBy
117− , GroupByClause (NoGroups, Group)
118− , renderGroupByClause
119− , HavingClause (NoHaving, Having)
120− , renderHavingClause
121− , GroupedBy (getGroup1, getGroup2)
122− , SortExpression (..)
123− , renderSortExpression
124− -- * TypeExpression
125− , TypeExpression (UnsafeTypeExpression, renderTypeExpression)
126− , PGTyped (pgtype)
127− , bool
128− , int2
129− , smallint
130− , int4
131− , int
132− , integer
133− , int8
134− , bigint
135− , numeric
136− , float4
137− , real
138− , float8
139− , doublePrecision
140− , serial2
141− , smallserial
142− , serial4
143− , serial
144− , serial8
145− , bigserial
146− , text
147− , char
148− , character
149− , varchar
150− , characterVarying
151− , bytea
152− , timestamp
153− , timestampWithTimeZone
154− , date
155− , time
156− , timeWithTimeZone
157− , interval
158− , uuid
159− , json
160− , jsonb
161− , notNull
162− , default_
163− -- * Statements
164− -- ** Queries
165− , Query (UnsafeQuery, renderQuery)
166− , select
167− , selectDistinct
168− , selectStar
169− , selectDistinctStar
170− , selectDotStar
171− , selectDistinctDotStar
172− , union
173− , unionAll
174− , intersect
175− , intersectAll
176− , except
177− , exceptAll
178− -- ** Data Definition Language
179− , Definition (UnsafeDefinition, renderDefinition)
180− , createTable
181− , TableConstraint (UnsafeTableConstraint, renderTableConstraint)
182− , check
183− , unique
184− , primaryKey
185− , foreignKey
186− , OnDelete (OnDeleteNoAction, OnDeleteRestrict, OnDeleteCascade)
187− , renderOnDelete
188− , OnUpdate (OnUpdateNoAction, OnUpdateRestrict, OnUpdateCascade)
189− , renderOnUpdate
190− , dropTable
191− , alterTable
192− , alterTableRename
193− , AlterTable (UnsafeAlterTable, renderAlterTable)
194− , addColumnDefault
195− , addColumnNull
196− , dropColumn
197− , renameColumn
198− , alterColumn
199− , AlterColumn (UnsafeAlterColumn, renderAlterColumn)
200− , setDefault
201− , dropDefault
202− , setNotNull
203− , dropNotNull
204− , alterType
205− -- ** Data Manipulation Language
206− , Manipulation (UnsafeManipulation, renderManipulation)
207− , queryStatement
208− , insertInto
209− , ValuesClause (Values, ValuesQuery)
210− , renderValuesClause
211− , ReturningClause (ReturningStar, Returning)
212− , renderReturningClause
213− , ConflictClause (Conflict, OnConflictDoNothing, OnConflictDoUpdate)
214− , renderConflictClause
215− , UpdateExpression (Same, Set)
216− , renderUpdateExpression
217− , update
218− , deleteFrom
219− -- * Re-export
220− , (&)
221− , NP ((:*), Nil)
222− ) where
223−
224−import Control.Category
225−import Control.DeepSeq
226−import Data.ByteString (ByteString)
227−import Data.Data (Data)
228−import Data.Foldable
229−import Data.Function ((&))
230−import Data.Maybe
231−import Data.Monoid hiding (All)
232−import Data.Ratio
233−import Data.String
234−import Data.Word
235−import Generics.SOP hiding (from)
236−import GHC.Exts
237−import GHC.OverloadedLabels
238−import GHC.TypeLits
239−import Prelude hiding (id, (.))
240−
241−import qualified GHC.Generics as GHC
242−import qualified Data.ByteString as ByteString
243−
244−import Squeal.PostgreSQL.Schema
245−
246−{-----------------------------------------
247−column expressions
248−-----------------------------------------}
249−
250−{- | `Expression`s are used in a variety of contexts,
251−such as in the target list of the `select` command,
252−as new column values in `insertInto` or `update`,
253−or in search `Condition`s in a number of commands.
254−
255−The expression syntax allows the calculation of
256−values from primitive expression using arithmetic, logical,
257−and other operations.
258−-}
259−newtype Expression
260− (params :: [ColumnType])
261− (tables :: TablesType)
262− (grouping :: Grouping)
263− (ty :: ColumnType)
264− = UnsafeExpression { renderExpression :: ByteString }
265− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
266−
267−{- | A `HasParameter` constraint is used to indicate a value that is
268−supplied externally to a SQL statement.
269−`Squeal.PostgreSQL.PQ.manipulateParams`,
270−`Squeal.PostgreSQL.PQ.queryParams` and
271−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
272−separately from the SQL command string, in which case `param`s are used to
273−refer to the out-of-line data values.
274−-}
275−class (PGTyped (BaseType ty), KnownNat n)
276− => HasParameter (n :: Nat) params ty | n params -> ty where
277− param :: Expression params tables grouping ty
278− param = UnsafeExpression $ parenthesized $
279− "$" <> renderNat (Proxy @n) <+> "::"
280− <+> renderTypeExpression (pgtype @(BaseType ty))
281−instance {-# OVERLAPPING #-} PGTyped (BaseType ty1)
282− => HasParameter 1 (ty1:tys) ty1
283−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
284− => HasParameter n (ty' : params) ty
285−
286−{- | A `HasColumn` constraint indicates an unqualified column reference.
287−`getColumn` can only be unambiguous when the `TableExpression` the column
288−references is unique, in which case the column may be referenced using
289−@-XOverloadedLabels@. Otherwise, combined with a `HasTable` constraint, the
290−qualified column reference operator `!` may be used.
291−-}
292−class KnownSymbol column => HasColumn column columns ty
293− | column columns -> ty where
294− getColumn
295− :: HasUnique table tables columns
296− => Alias column
297− -> Expression params tables 'Ungrouped ty
298− getColumn column = UnsafeExpression $ renderAlias column
299−instance {-# OVERLAPPING #-} KnownSymbol column
300− => HasColumn column ((column ::: optionality ty) ': tys) ('Required ty)
301−instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
302− => HasColumn column (ty' ': table) ty
303−
304−instance (HasColumn column columns ty, HasUnique table tables columns)
305− => IsLabel column (Expression params tables 'Ungrouped ty) where
306− fromLabel = getColumn (Alias @column)
307−
308−instance (HasTable table tables columns, HasColumn column columns ty)
309− => IsTableColumn table column (Expression params tables 'Ungrouped ty) where
310− table ! column = UnsafeExpression $
311− renderAlias table <> "." <> renderAlias column
312−
313−data Column
314− (columns :: ColumnsType)
315− (columnty :: (Symbol,ColumnType))
316− where
317− Column
318− :: HasColumn column columns ty
319− => Alias column
320− -> Column columns (column ::: ty)
321−deriving instance Show (Column columns columnty)
322−deriving instance Eq (Column columns columnty)
323−deriving instance Ord (Column columns columnty)
324−
325−-- | >>> renderExpression def
326−-- "DEFAULT"
327−def :: Expression params '[] 'Ungrouped ('Optional (nullity ty))
328−def = UnsafeExpression "DEFAULT"
329−
330−-- | >>> renderExpression $ unDef false
331−-- "FALSE"
332−unDef
333− :: Expression params '[] 'Ungrouped ('Required (nullity ty))
334− -> Expression params '[] 'Ungrouped ('Optional (nullity ty))
335−unDef = UnsafeExpression . renderExpression
336−
337−-- | analagous to `Nothing`
338−--
339−-- >>> renderExpression $ null_
340−-- "NULL"
341−null_ :: Expression params tables grouping (optionality ('Null ty))
342−null_ = UnsafeExpression "NULL"
343−
344−-- | analagous to `Just`
345−--
346−-- >>> renderExpression $ unNull true
347−-- "TRUE"
348−unNull
349− :: Expression params tables grouping (optionality ('NotNull ty))
350− -> Expression params tables grouping (optionality ('Null ty))
351−unNull = UnsafeExpression . renderExpression
352−
353−-- | return the leftmost value which is not NULL
354−--
355−-- >>> renderExpression $ coalesce [null_, unNull true] false
356−-- "COALESCE(NULL, TRUE, FALSE)"
357−coalesce
358− :: [Expression params tables grouping ('Required ('Null ty))]
359− -> Expression params tables grouping ('Required ('NotNull ty))
360− -> Expression params tables grouping ('Required ('NotNull ty))
361−coalesce nullxs notNullx = UnsafeExpression $
362− "COALESCE" <> parenthesized (commaSeparated
363− ((renderExpression <$> nullxs) <> [renderExpression notNullx]))
364−
365−-- | analagous to `fromMaybe` using @COALESCE@
366−--
367−-- >>> renderExpression $ fromNull true null_
368−-- "COALESCE(NULL, TRUE)"
369−fromNull
370− :: Expression params tables grouping ('Required ('NotNull ty))
371− -> Expression params tables grouping ('Required ('Null ty))
372− -> Expression params tables grouping ('Required ('NotNull ty))
373−fromNull notNullx nullx = coalesce [nullx] notNullx
374−
375−-- | >>> renderExpression $ null_ & isNull
376−-- "NULL IS NULL"
377−isNull
378− :: Expression params tables grouping ('Required ('Null ty))
379− -> Condition params tables grouping
380−isNull x = UnsafeExpression $ renderExpression x <+> "IS NULL"
381−
382−-- | >>> renderExpression $ null_ & isn'tNull
383−-- "NULL IS NOT NULL"
384−isn'tNull
385− :: Expression params tables grouping ('Required ('Null ty))
386− -> Condition params tables grouping
387−isn'tNull x = UnsafeExpression $ renderExpression x <+> "IS NOT NULL"
388−
389−-- | analagous to `maybe` using @IS NULL@
390−--
391−-- >>> renderExpression $ matchNull true not_ null_
392−-- "CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END"
393−matchNull
394− :: Expression params tables grouping ('Required nullty)
395− -> ( Expression params tables grouping ('Required ('NotNull ty))
396− -> Expression params tables grouping ('Required nullty) )
397− -> Expression params tables grouping ('Required ('Null ty))
398− -> Expression params tables grouping ('Required nullty)
399−matchNull y f x = ifThenElse (isNull x) y
400− (f (UnsafeExpression (renderExpression x)))
401−
402−-- | right inverse to `fromNull`
403−--
404−-- >>> :set -XTypeApplications -XDataKinds
405−-- >>> renderExpression @'[_] $ fromNull false (nullIf false (param @1))
406−-- "COALESCE(NULL IF (FALSE, ($1 :: bool)), FALSE)"
407−nullIf
408− :: Expression params tables grouping ('Required ('NotNull ty))
409− -> Expression params tables grouping ('Required ('NotNull ty))
410− -> Expression params tables grouping ('Required ('Null ty))
411−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
412− (renderExpression x <> ", " <> renderExpression y)
413−
414−-- | >>> renderExpression @'[_] $ greatest currentTimestamp [param @1]
415−-- "GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))"
416−greatest
417− :: Expression params tables grouping ('Required nullty)
418− -> [Expression params tables grouping ('Required nullty)]
419− -> Expression params table grouping ('Required nullty)
420−greatest x xs = UnsafeExpression $ "GREATEST("
421− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
422−
423−-- | >>> renderExpression $ least currentTimestamp [null_]
424−-- "LEAST(CURRENT_TIMESTAMP, NULL)"
425−least
426− :: Expression params tables grouping ('Required nullty)
427− -> [Expression params tables grouping ('Required nullty)]
428− -> Expression params table grouping ('Required nullty)
429−least x xs = UnsafeExpression $ "LEAST("
430− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
431−
432−unsafeBinaryOp
433− :: ByteString
434− -> Expression params tables grouping ('Required ty0)
435− -> Expression params tables grouping ('Required ty1)
436− -> Expression params tables grouping ('Required ty2)
437−unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
438− renderExpression x <+> op <+> renderExpression y
439−
440−unsafeUnaryOp
441− :: ByteString
442− -> Expression params tables grouping ('Required ty0)
443− -> Expression params tables grouping ('Required ty1)
444−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
445− op <+> renderExpression x
446−
447−unsafeFunction
448− :: ByteString
449− -> Expression params tables grouping ('Required xty)
450− -> Expression params tables grouping ('Required yty)
451−unsafeFunction fun x = UnsafeExpression $
452− fun <> parenthesized (renderExpression x)
453−
454−instance PGNum ty
455− => Num (Expression params tables grouping ('Required (nullity ty))) where
456− (+) = unsafeBinaryOp "+"
457− (-) = unsafeBinaryOp "-"
458− (*) = unsafeBinaryOp "*"
459− abs = unsafeFunction "abs"
460− signum = unsafeFunction "sign"
461− fromInteger
462− = UnsafeExpression
463− . fromString
464− . show
465−
466−instance (PGNum ty, PGFloating ty) => Fractional
467− (Expression params tables grouping ('Required (nullity ty))) where
468− (/) = unsafeBinaryOp "/"
469− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
470−
471−instance (PGNum ty, PGFloating ty) => Floating
472− (Expression params tables grouping ('Required (nullity ty))) where
473− pi = UnsafeExpression "pi()"
474− exp = unsafeFunction "exp"
475− log = unsafeFunction "ln"
476− sqrt = unsafeFunction "sqrt"
477− b ** x = UnsafeExpression $
478− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
479− logBase b y = log y / log b
480− sin = unsafeFunction "sin"
481− cos = unsafeFunction "cos"
482− tan = unsafeFunction "tan"
483− asin = unsafeFunction "asin"
484− acos = unsafeFunction "acos"
485− atan = unsafeFunction "atan"
486− sinh x = (exp x - exp (-x)) / 2
487− cosh x = (exp x + exp (-x)) / 2
488− tanh x = sinh x / cosh x
489− asinh x = log (x + sqrt (x*x + 1))
490− acosh x = log (x + sqrt (x*x - 1))
491− atanh x = log ((1 + x) / (1 - x)) / 2
492−
493−atan2_
494− :: PGFloating float
495− => Expression params tables grouping ('Required (nullity float))
496− -> Expression params tables grouping ('Required (nullity float))
497− -> Expression params tables grouping ('Required (nullity float))
498−atan2_ y x = UnsafeExpression $
499− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
500−
501−cast
502− :: TypeExpression ('Required ('Null ty1))
503− -> Expression params tables grouping ('Required (nullity ty0))
504− -> Expression params tables grouping ('Required (nullity ty1))
505−cast ty x = UnsafeExpression $ parenthesized $
506− renderExpression x <+> "::" <+> renderTypeExpression ty
507−
508−div_
509− :: PGIntegral int
510− => Expression params tables grouping ('Required (nullity int))
511− -> Expression params tables grouping ('Required (nullity int))
512− -> Expression params tables grouping ('Required (nullity int))
513−div_ = unsafeBinaryOp "/"
514−
515−mod_
516− :: PGIntegral int
517− => Expression params tables grouping ('Required (nullity int))
518− -> Expression params tables grouping ('Required (nullity int))
519− -> Expression params tables grouping ('Required (nullity int))
520−mod_ = unsafeBinaryOp "%"
521−
522−trunc
523− :: PGFloating frac
524− => Expression params tables grouping ('Required (nullity frac))
525− -> Expression params tables grouping ('Required (nullity frac))
526−trunc = unsafeFunction "trunc"
527−
528−round_
529− :: PGFloating frac
530− => Expression params tables grouping ('Required (nullity frac))
531− -> Expression params tables grouping ('Required (nullity frac))
532−round_ = unsafeFunction "round"
533−
534−ceiling_
535− :: PGFloating frac
536− => Expression params tables grouping ('Required (nullity frac))
537− -> Expression params tables grouping ('Required (nullity frac))
538−ceiling_ = unsafeFunction "ceiling"
539−
540−instance IsString
541− (Expression params tables grouping ('Required (nullity 'PGtext))) where
542− fromString str = UnsafeExpression $
543− "E\'" <> fromString (escape =<< str) <> "\'"
544− where
545− escape = \case
546− '\NUL' -> "\\0"
547− '\'' -> "''"
548− '"' -> "\\\""
549− '\b' -> "\\b"
550− '\n' -> "\\n"
551− '\r' -> "\\r"
552− '\t' -> "\\t"
553− '\\' -> "\\\\"
554− c -> [c]
555−
556−type Condition params tables grouping =
557− Expression params tables grouping ('Required ('NotNull 'PGbool))
558−
559−true :: Condition params tables grouping
560−true = UnsafeExpression "TRUE"
561−
562−false :: Condition params tables grouping
563−false = UnsafeExpression "FALSE"
564−
565−not_
566− :: Condition params tables grouping
567− -> Condition params tables grouping
568−not_ = unsafeUnaryOp "NOT"
569−
570−(&&*)
571− :: Condition params tables grouping
572− -> Condition params tables grouping
573− -> Condition params tables grouping
574−(&&*) = unsafeBinaryOp "AND"
575−
576−(||*)
577− :: Condition params tables grouping
578− -> Condition params tables grouping
579− -> Condition params tables grouping
580−(||*) = unsafeBinaryOp "OR"
581−
582−caseWhenThenElse
583− :: [ ( Condition params tables grouping
584− , Expression params tables grouping ('Required ty)
585− ) ]
586− -> Expression params tables grouping ('Required ty)
587− -> Expression params tables grouping ('Required ty)
588−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
589− [ "CASE"
590− , mconcat
591− [ mconcat
592− [ " WHEN ", renderExpression when_
593− , " THEN ", renderExpression then_
594− ]
595− | (when_,then_) <- whenThens
596− ]
597− , " ELSE ", renderExpression else_
598− , " END"
599− ]
600−
601−ifThenElse
602− :: Condition params tables grouping
603− -> Expression params tables grouping ('Required ty)
604− -> Expression params tables grouping ('Required ty)
605− -> Expression params tables grouping ('Required ty)
606−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
607−
608−(==*)
609− :: Expression params tables grouping ('Required (nullity ty))
610− -> Expression params tables grouping ('Required (nullity ty))
611− -> Expression params tables grouping ('Required (nullity 'PGbool))
612−(==*) = unsafeBinaryOp "="
613−infix 4 ==*
614−
615−(/=*)
616− :: Expression params tables grouping ('Required (nullity ty))
617− -> Expression params tables grouping ('Required (nullity ty))
618− -> Expression params tables grouping ('Required (nullity 'PGbool))
619−(/=*) = unsafeBinaryOp "<>"
620−infix 4 /=*
621−
622−(>=*)
623− :: Expression params tables grouping ('Required (nullity ty))
624− -> Expression params tables grouping ('Required (nullity ty))
625− -> Expression params tables grouping ('Required (nullity 'PGbool))
626−(>=*) = unsafeBinaryOp ">="
627−infix 4 >=*
628−
629−(*<)
630− :: Expression params tables grouping ('Required (nullity ty))
631− -> Expression params tables grouping ('Required (nullity ty))
632− -> Expression params tables grouping ('Required (nullity 'PGbool))
633−(*<) = unsafeBinaryOp "<"
634−infix 4 *<
635−
636−(*<=)
637− :: Expression params tables grouping ('Required (nullity ty))
638− -> Expression params tables grouping ('Required (nullity ty))
639− -> Expression params tables grouping ('Required (nullity 'PGbool))
640−(*<=) = unsafeBinaryOp "<="
641−infix 4 *<=
642−
643−(>*)
644− :: Expression params tables grouping ('Required (nullity ty))
645− -> Expression params tables grouping ('Required (nullity ty))
646− -> Expression params tables grouping ('Required (nullity 'PGbool))
647−(>*) = unsafeBinaryOp ">"
648−infix 4 >*
649−
650−currentDate
651− :: Expression params tables grouping ('Required (nullity 'PGdate))
652−currentDate = UnsafeExpression "CURRENT_DATE"
653−
654−currentTime
655− :: Expression params tables grouping ('Required (nullity 'PGtimetz))
656−currentTime = UnsafeExpression "CURRENT_TIME"
657−
658−currentTimestamp
659− :: Expression params tables grouping ('Required (nullity 'PGtimestamptz))
660−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
661−
662−localTime
663− :: Expression params tables grouping ('Required (nullity 'PGtime))
664−localTime = UnsafeExpression "LOCALTIME"
665−
666−localTimestamp
667− :: Expression params tables grouping ('Required (nullity 'PGtimestamp))
668−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
669−
670−data SortExpression params tables grouping where
671− Asc
672− :: Expression params tables grouping ('Required ('NotNull ty))
673− -> SortExpression params tables grouping
674− Desc
675− :: Expression params tables grouping ('Required ('NotNull ty))
676− -> SortExpression params tables grouping
677− AscNullsFirst
678− :: Expression params tables grouping ('Required ('Null ty))
679− -> SortExpression params tables grouping
680− AscNullsLast
681− :: Expression params tables grouping ('Required ('Null ty))
682− -> SortExpression params tables grouping
683− DescNullsFirst
684− :: Expression params tables grouping ('Required ('Null ty))
685− -> SortExpression params tables grouping
686− DescNullsLast
687− :: Expression params tables grouping ('Required ('Null ty))
688− -> SortExpression params tables grouping
689−deriving instance Show (SortExpression params tables grouping)
690−
691−renderSortExpression :: SortExpression params tables grouping -> ByteString
692−renderSortExpression = \case
693− Asc expression -> renderExpression expression <+> "ASC"
694− Desc expression -> renderExpression expression <+> "DESC"
695− AscNullsFirst expression -> renderExpression expression
696− <+> "ASC NULLS FIRST"
697− DescNullsFirst expression -> renderExpression expression
698− <+> "DESC NULLS FIRST"
699− AscNullsLast expression -> renderExpression expression <+> "ASC NULLS LAST"
700− DescNullsLast expression -> renderExpression expression <+> "DESC NULLS LAST"
701−
702−
703−{-----------------------------------------
704−aggregation
705−-----------------------------------------}
706−
707−data By
708− (tables :: TablesType)
709− (by :: (Symbol,Symbol)) where
710− By
711− :: (HasUnique table tables columns, HasColumn column columns ty)
712− => Alias column
713− -> By tables '(table, column)
714− By2
715− :: (HasTable table tables columns, HasColumn column columns ty)
716− => (Alias table, Alias column)
717− -> By tables '(table, column)
718−deriving instance Show (By tables by)
719−deriving instance Eq (By tables by)
720−deriving instance Ord (By tables by)
721−
722−renderBy :: By tables tabcolty -> ByteString
723−renderBy = \case
724− By column -> renderAlias column
725− By2 (table, column) -> renderAlias table <> "." <> renderAlias column
726−
727−data GroupByClause tables grouping where
728− NoGroups :: GroupByClause tables 'Ungrouped
729− Group
730− :: SListI bys
731− => NP (By tables) bys
732− -> GroupByClause tables ('Grouped bys)
733−
734−renderGroupByClause :: GroupByClause tables grouping -> ByteString
735−renderGroupByClause = \case
736− NoGroups -> ""
737− Group Nil -> ""
738− Group bys -> " GROUP BY" <+> renderCommaSeparated renderBy bys
739−
740−data HavingClause params tables grouping where
741− NoHaving :: HavingClause params tables 'Ungrouped
742− Having
743− :: [Condition params tables ('Grouped bys)]
744− -> HavingClause params tables ('Grouped bys)
745−deriving instance Show (HavingClause params tables grouping)
746−deriving instance Eq (HavingClause params tables grouping)
747−deriving instance Ord (HavingClause params tables grouping)
748−
749−renderHavingClause :: HavingClause params tables grouping -> ByteString
750−renderHavingClause = \case
751− NoHaving -> ""
752− Having [] -> ""
753− Having conditions ->
754− " HAVING" <+> commaSeparated (renderExpression <$> conditions)
755−
756−class (KnownSymbol table, KnownSymbol column)
757− => GroupedBy table column bys where
758− getGroup1
759− :: (HasUnique table tables columns, HasColumn column columns ty)
760− => Alias column
761− -> Expression params tables ('Grouped bys) ty
762− getGroup1 column = UnsafeExpression $ renderAlias column
763− getGroup2
764− :: (HasTable table tables columns, HasColumn column columns ty)
765− => Alias table
766− -> Alias column
767− -> Expression params tables ('Grouped bys) ty
768− getGroup2 table column = UnsafeExpression $
769− renderAlias table <> "." <> renderAlias column
770−instance {-# OVERLAPPING #-} (KnownSymbol table, KnownSymbol column)
771− => GroupedBy table column ('(table,column) ': bys)
772−instance {-# OVERLAPPABLE #-}
773− ( KnownSymbol table
774− , KnownSymbol column
775− , GroupedBy table column bys
776− ) => GroupedBy table column (tabcol ': bys)
777−
778−instance
779− ( HasUnique table tables columns
780− , HasColumn column columns ty
781− , GroupedBy table column bys
782− ) => IsLabel column
783− (Expression params tables ('Grouped bys) ty) where
784− fromLabel = getGroup1 (Alias @column)
785−
786−instance
787− ( HasTable table tables columns
788− , HasColumn column columns ty
789− , GroupedBy table column bys
790− ) => IsTableColumn table column
791− (Expression params tables ('Grouped bys) ty) where (!) = getGroup2
792−
793−-- data AllOrDistinct = All | Distinct
794−-- deriving (GHC.Generic,Show,Eq,Ord,Data)
795−-- instance NFData AllOrDistinct
796−
797−-- renderAllOrDistinct :: AllOrDistinct -> ByteString
798−-- renderAllOrDistinct = \case
799−-- All -> "ALL"
800−-- Distinct -> "DISTINCT"
801−
802−unsafeAggregate, unsafeAggregateDistinct
803− :: ByteString
804− -> Expression params tables 'Ungrouped ('Required xty)
805− -> Expression params tables ('Grouped bys) ('Required yty)
806−unsafeAggregate fun x = UnsafeExpression $ mconcat
807− [fun, "(", renderExpression x, ")"]
808−unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
809− [fun, "(DISTINCT ", renderExpression x, ")"]
810−
811−sum_, sumDistinct
812− :: PGNum ty
813− => Expression params tables 'Ungrouped ('Required (nullity ty))
814− -> Expression params tables ('Grouped bys) ('Required (nullity ty))
815−sum_ = unsafeAggregate "sum"
816−sumDistinct = unsafeAggregateDistinct "sum"
817−
818−class PGAvg ty avg | ty -> avg where
819− avg, avgDistinct
820− :: Expression params tables 'Ungrouped ('Required (nullity ty))
821− -> Expression params tables ('Grouped bys) ('Required (nullity avg))
822− avg = unsafeAggregate "avg"
823− avgDistinct = unsafeAggregateDistinct "avg"
824−instance PGAvg 'PGint2 'PGnumeric
825−instance PGAvg 'PGint4 'PGnumeric
826−instance PGAvg 'PGint8 'PGnumeric
827−instance PGAvg 'PGnumeric 'PGnumeric
828−instance PGAvg 'PGfloat4 'PGfloat8
829−instance PGAvg 'PGfloat8 'PGfloat8
830−instance PGAvg 'PGinterval 'PGinterval
831−
832−bitAnd, bitOr
833− :: PGIntegral int
834− => Expression params tables 'Ungrouped ('Required (nullity int))
835− -> Expression params tables ('Grouped bys) ('Required (nullity int))
836−bitAnd = unsafeAggregate "bit_and"
837−bitOr = unsafeAggregate "bit_or"
838−
839−boolAnd, boolOr
840− :: Expression params tables 'Ungrouped ('Required (nullity 'PGbool))
841− -> Expression params tables ('Grouped bys) ('Required (nullity 'PGbool))
842−boolAnd = unsafeAggregate "bool_and"
843−boolOr = unsafeAggregate "bool_or"
844−
845−countStar, countDistinctStar
846− :: Expression params table ('Grouped bys) ('Required ('NotNull 'PGint8))
847−countStar = UnsafeExpression $ "count(*)"
848−countDistinctStar = UnsafeExpression $ "count(DISTINCT *)"
849−
850−count
851− :: Expression params tables 'Ungrouped ('Required ty)
852− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGint8))
853−count = unsafeAggregate "count"
854−
855−every
856− :: Expression params tables 'Ungrouped ('Required (nullity 'PGbool))
857− -> Expression params tables ('Grouped bys) ('Required (nullity 'PGbool))
858−every = unsafeAggregate "every"
859−
860−jsonAgg
861− :: Expression params tables 'Ungrouped ('Required ty)
862− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGjson))
863−jsonAgg = unsafeAggregate "json_agg"
864−
865−jsonbAgg
866− :: Expression params tables 'Ungrouped ('Required ty)
867− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGjsonb))
868−jsonbAgg = unsafeAggregate "jsonb_agg"
869−
870−jsonObjectAgg
871− :: Expression params tables 'Ungrouped ('Required ('NotNull keyty))
872− -> Expression params tables 'Ungrouped ('Required valty)
873− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGjson))
874−jsonObjectAgg k v = UnsafeExpression $
875− "json_object_agg(" <> renderExpression k
876− <> ", " <> renderExpression v <> ")"
877−
878−jsonbObjectAgg
879− :: Expression params tables 'Ungrouped ('Required ('NotNull keyty))
880− -> Expression params tables 'Ungrouped ('Required valty)
881− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGjsonb))
882−jsonbObjectAgg k v = UnsafeExpression $
883− "jsonb_object_agg("
884− <> renderExpression k <> ", " <> renderExpression v <> ")"
885−
886−max_, min_
887− :: Expression params tables 'Ungrouped ('Required (nullity ty))
888− -> Expression params tables ('Grouped bys) ('Required (nullity ty))
889−max_ = unsafeAggregate "max"
890−min_ = unsafeAggregate "min"
891−
892−{-----------------------------------------
893−tables
894−-----------------------------------------}
895−
896−newtype Table
897− (schema :: TablesType)
898− (columns :: ColumnsType)
899− = UnsafeTable { renderTable :: ByteString }
900− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
901−
902−class KnownSymbol table => HasTable table tables columns
903− | table tables -> columns where
904− getTable :: Alias table -> Table tables columns
905− getTable table = UnsafeTable $ renderAlias table
906−instance {-# OVERLAPPING #-} KnownSymbol table
907− => HasTable table ((table ::: columns) ': tables) columns
908−instance {-# OVERLAPPABLE #-}
909− (KnownSymbol table, HasTable table schema columns)
910− => HasTable table (table' ': schema) columns
911−
912−instance HasTable table schema columns
913− => IsLabel table (Table schema columns) where
914− fromLabel = getTable (Alias @table)
915−
916−data FromClause params schema tables where
917− Table
918− :: Aliased (Table schema) table
919− -> FromClause params schema '[table]
920− Subquery
921− :: Aliased (Query schema params) table
922− -> FromClause params schema '[table]
923− CrossJoin
924− :: FromClause params schema right
925− -> FromClause params schema left
926− -> FromClause params schema (Join left right)
927− InnerJoin
928− :: FromClause params schema right
929− -> Condition params (Join left right) 'Ungrouped
930− -> FromClause params schema left
931− -> FromClause params schema (Join left right)
932− LeftOuterJoin
933− :: FromClause params schema right
934− -> Condition params (Join left right) 'Ungrouped
935− -> FromClause params schema left
936− -> FromClause params schema (Join left (NullifyTables right))
937− RightOuterJoin
938− :: FromClause params schema right
939− -> Condition params (Join left right) 'Ungrouped
940− -> FromClause params schema left
941− -> FromClause params schema (Join (NullifyTables left) right)
942− FullOuterJoin
943− :: FromClause params schema right
944− -> Condition params (Join left right) 'Ungrouped
945− -> FromClause params schema left
946− -> FromClause params schema
947− (Join (NullifyTables left) (NullifyTables right))
948−
949−renderFromClause :: FromClause params schema tables -> ByteString
950−renderFromClause = \case
951− Table table -> renderAliased renderTable table
952− Subquery selection -> renderAliased (parenthesized . renderQuery) selection
953− CrossJoin right left ->
954− renderFromClause left <+> "CROSS JOIN" <+> renderFromClause right
955− InnerJoin right on left -> renderJoin "INNER JOIN" right on left
956− LeftOuterJoin right on left -> renderJoin "LEFT OUTER JOIN" right on left
957− RightOuterJoin right on left -> renderJoin "RIGHT OUTER JOIN" right on left
958− FullOuterJoin right on left -> renderJoin "FULL OUTER JOIN" right on left
959− where
960− renderJoin op right on left =
961− renderFromClause left <+> op <+> renderFromClause right
962− <+> "ON" <+> renderExpression on
963−
964−data TableExpression
965− (params :: [ColumnType])
966− (schema :: TablesType)
967− (tables :: TablesType)
968− (grouping :: Grouping)
969− = TableExpression
970− { fromClause :: FromClause params schema tables
971− , whereClause :: [Condition params tables 'Ungrouped]
972− , groupByClause :: GroupByClause tables grouping
973− , havingClause :: HavingClause params tables grouping
974− , orderByClause :: [SortExpression params tables grouping]
975− , limitClause :: [Word64]
976− , offsetClause :: [Word64]
977− }
978−
979−renderTableExpression
980− :: TableExpression params schema tables grouping
981− -> ByteString
982−renderTableExpression
983− (TableExpression tables whs' grps' hvs' srts' lims' offs') = mconcat
984− [ "FROM ", renderFromClause tables
985− , renderWheres whs'
986− , renderGroupByClause grps'
987− , renderHavingClause hvs'
988− , renderSorts srts'
989− , renderLimits lims'
990− , renderOffsets offs'
991− ]
992− where
993− renderWheres = \case
994− [] -> ""
995− wh:[] -> " WHERE" <+> renderExpression wh
996− wh:whs -> " WHERE" <+> renderExpression (foldr (&&*) wh whs)
997− renderSorts = \case
998− [] -> ""
999− srts -> " SORT BY"
1000− <+> commaSeparated (renderSortExpression <$> srts)
1001− renderLimits = \case
1002− [] -> ""
1003− lims -> " LIMIT" <+> fromString (show (minimum lims))
1004− renderOffsets = \case
1005− [] -> ""
1006− offs -> " OFFSET" <+> fromString (show (sum offs))
1007−
1008−from
1009− :: FromClause params schema tables
1010− -> TableExpression params schema tables 'Ungrouped
1011−from tables = TableExpression tables [] NoGroups NoHaving [] [] []
1012−
1013−where_
1014− :: Condition params tables 'Ungrouped
1015− -> TableExpression params schema tables grouping
1016− -> TableExpression params schema tables grouping
1017−where_ wh tables = tables {whereClause = wh : whereClause tables}
1018−
1019−group
1020− :: SListI bys
1021− => NP (By tables) bys
1022− -> TableExpression params schema tables 'Ungrouped
1023− -> TableExpression params schema tables ('Grouped bys)
1024−group bys tables = TableExpression
1025− { fromClause = fromClause tables
1026− , whereClause = whereClause tables
1027− , groupByClause = Group bys
1028− , havingClause = Having []
1029− , orderByClause = []
1030− , limitClause = limitClause tables
1031− , offsetClause = offsetClause tables
1032− }
1033−
1034−having
1035− :: Condition params tables ('Grouped bys)
1036− -> TableExpression params schema tables ('Grouped bys)
1037− -> TableExpression params schema tables ('Grouped bys)
1038−having hv tables = tables
1039− { havingClause = case havingClause tables of Having hvs -> Having (hv:hvs) }
1040−
1041−orderBy
1042− :: [SortExpression params tables grouping]
1043− -> TableExpression params schema tables grouping
1044− -> TableExpression params schema tables grouping
1045−orderBy srts tables = tables {orderByClause = orderByClause tables ++ srts}
1046−
1047−limit
1048− :: Word64
1049− -> TableExpression params schema tables grouping
1050− -> TableExpression params schema tables grouping
1051−limit lim tables = tables {limitClause = lim : limitClause tables}
1052−
1053−offset
1054− :: Word64
1055− -> TableExpression params schema tables grouping
1056− -> TableExpression params schema tables grouping
1057−offset off tables = tables {offsetClause = off : offsetClause tables}
1058−
1059−{-----------------------------------------
1060−type expressions
1061−-----------------------------------------}
1062−
1063−newtype TypeExpression (ty :: ColumnType)
1064− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1065− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
1066−
1067−bool :: TypeExpression ('Required ('Null 'PGbool))
1068−bool = UnsafeTypeExpression "bool"
1069−int2 :: TypeExpression ('Required ('Null 'PGint2))
1070−int2 = UnsafeTypeExpression "int2"
1071−smallint :: TypeExpression ('Required ('Null 'PGint2))
1072−smallint = UnsafeTypeExpression "smallint"
1073−int4 :: TypeExpression ('Required ('Null 'PGint4))
1074−int4 = UnsafeTypeExpression "int4"
1075−int :: TypeExpression ('Required ('Null 'PGint4))
1076−int = UnsafeTypeExpression "int"
1077−integer :: TypeExpression ('Required ('Null 'PGint4))
1078−integer = UnsafeTypeExpression "integer"
1079−int8 :: TypeExpression ('Required ('Null 'PGint8))
1080−int8 = UnsafeTypeExpression "int8"
1081−bigint :: TypeExpression ('Required ('Null 'PGint8))
1082−bigint = UnsafeTypeExpression "bigint"
1083−numeric :: TypeExpression ('Required ('Null 'PGnumeric))
1084−numeric = UnsafeTypeExpression "numeric"
1085−float4 :: TypeExpression ('Required ('Null 'PGfloat4))
1086−float4 = UnsafeTypeExpression "float4"
1087−real :: TypeExpression ('Required ('Null 'PGfloat4))
1088−real = UnsafeTypeExpression "real"
1089−float8 :: TypeExpression ('Required ('Null 'PGfloat8))
1090−float8 = UnsafeTypeExpression "float8"
1091−doublePrecision :: TypeExpression ('Required ('Null 'PGfloat8))
1092−doublePrecision = UnsafeTypeExpression "double precision"
1093−serial2 :: TypeExpression ('Optional ('NotNull 'PGint2))
1094−serial2 = UnsafeTypeExpression "serial2"
1095−smallserial :: TypeExpression ('Optional ('NotNull 'PGint2))
1096−smallserial = UnsafeTypeExpression "smallserial"
1097−serial4 :: TypeExpression ('Optional ('NotNull 'PGint4))
1098−serial4 = UnsafeTypeExpression "serial4"
1099−serial :: TypeExpression ('Optional ('NotNull 'PGint4))
1100−serial = UnsafeTypeExpression "serial"
1101−serial8 :: TypeExpression ('Optional ('NotNull 'PGint8))
1102−serial8 = UnsafeTypeExpression "serial8"
1103−bigserial :: TypeExpression ('Optional ('NotNull 'PGint8))
1104−bigserial = UnsafeTypeExpression "bigserial"
1105−text :: TypeExpression ('Required ('Null 'PGtext))
1106−text = UnsafeTypeExpression "text"
1107−char
1108− :: (KnownNat n, 1 <= n)
1109− => proxy n
1110− -> TypeExpression ('Required ('Null ('PGchar n)))
1111−char p = UnsafeTypeExpression $ "char(" <> renderNat p <> ")"
1112−character
1113− :: (KnownNat n, 1 <= n)
1114− => proxy n
1115− -> TypeExpression ('Required ('Null ('PGchar n)))
1116−character p = UnsafeTypeExpression $ "character(" <> renderNat p <> ")"
1117−varchar
1118− :: (KnownNat n, 1 <= n)
1119− => proxy n
1120− -> TypeExpression ('Required ('Null ('PGvarchar n)))
1121−varchar p = UnsafeTypeExpression $ "varchar(" <> renderNat p <> ")"
1122−characterVarying
1123− :: (KnownNat n, 1 <= n)
1124− => proxy n
1125− -> TypeExpression ('Required ('Null ('PGvarchar n)))
1126−characterVarying p = UnsafeTypeExpression $
1127− "character varying(" <> renderNat p <> ")"
1128−bytea :: TypeExpression ('Required ('Null ('PGbytea)))
1129−bytea = UnsafeTypeExpression "bytea"
1130−timestamp :: TypeExpression ('Required ('Null ('PGtimestamp)))
1131−timestamp = UnsafeTypeExpression "timestamp"
1132−timestampWithTimeZone :: TypeExpression ('Required ('Null ('PGtimestamptz)))
1133−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1134−date :: TypeExpression ('Required ('Null ('PGdate)))
1135−date = UnsafeTypeExpression "date"
1136−time :: TypeExpression ('Required ('Null ('PGtime)))
1137−time = UnsafeTypeExpression "time"
1138−timeWithTimeZone :: TypeExpression ('Required ('Null ('PGtimetz)))
1139−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1140−interval :: TypeExpression ('Required ('Null ('PGinterval)))
1141−interval = UnsafeTypeExpression "interval"
1142−uuid :: TypeExpression ('Required ('Null ('PGuuid)))
1143−uuid = UnsafeTypeExpression "uuid"
1144−json :: TypeExpression ('Required ('Null ('PGjson)))
1145−json = UnsafeTypeExpression "json"
1146−jsonb :: TypeExpression ('Required ('Null ('PGjsonb)))
1147−jsonb = UnsafeTypeExpression "jsonb"
1148−
1149−notNull
1150− :: TypeExpression (optionality ('Null ty))
1151− -> TypeExpression (optionality ('NotNull ty))
1152−notNull ty = UnsafeTypeExpression $ renderTypeExpression ty <+> "NOT NULL"
1153−default_
1154− :: Expression '[] '[] 'Ungrouped ('Required ty)
1155− -> TypeExpression ('Required ty)
1156− -> TypeExpression ('Optional ty)
1157−default_ x ty = UnsafeTypeExpression $
1158− renderTypeExpression ty <+> "DEFAULT" <+> renderExpression x
1159−
1160−class PGTyped (ty :: PGType) where
1161− pgtype :: TypeExpression ('Required ('Null ty))
1162−instance PGTyped 'PGbool where pgtype = bool
1163−instance PGTyped 'PGint2 where pgtype = int2
1164−instance PGTyped 'PGint4 where pgtype = int4
1165−instance PGTyped 'PGint8 where pgtype = int8
1166−instance PGTyped 'PGnumeric where pgtype = numeric
1167−instance PGTyped 'PGfloat4 where pgtype = float4
1168−instance PGTyped 'PGfloat8 where pgtype = float8
1169−instance PGTyped 'PGtext where pgtype = text
1170−instance (KnownNat n, 1 <= n)
1171− => PGTyped ('PGchar n) where pgtype = char (Proxy @n)
1172−instance (KnownNat n, 1 <= n)
1173− => PGTyped ('PGvarchar n) where pgtype = varchar (Proxy @n)
1174−instance PGTyped 'PGbytea where pgtype = bytea
1175−instance PGTyped 'PGtimestamp where pgtype = timestamp
1176−instance PGTyped 'PGtimestamptz where pgtype = timestampWithTimeZone
1177−instance PGTyped 'PGdate where pgtype = date
1178−instance PGTyped 'PGtime where pgtype = time
1179−instance PGTyped 'PGtimetz where pgtype = timeWithTimeZone
1180−instance PGTyped 'PGinterval where pgtype = interval
1181−instance PGTyped 'PGuuid where pgtype = uuid
1182−instance PGTyped 'PGjson where pgtype = json
1183−instance PGTyped 'PGjsonb where pgtype = jsonb
1184−
1185−{-----------------------------------------
1186−statements
1187−-----------------------------------------}
1188−
1189−newtype Definition
1190− (schema0 :: TablesType)
1191− (schema1 :: TablesType)
1192− = UnsafeDefinition { renderDefinition :: ByteString }
1193− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
1194−
1195−instance Category Definition where
1196− id = UnsafeDefinition ";"
1197− ddl1 . ddl0 = UnsafeDefinition $
1198− renderDefinition ddl0 <+> renderDefinition ddl1
1199−
1200−newtype Manipulation
1201− (schema :: TablesType)
1202− (params :: [ColumnType])
1203− (columns :: ColumnsType)
1204− = UnsafeManipulation { renderManipulation :: ByteString }
1205− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
1206−
1207−newtype Query
1208− (schema :: TablesType)
1209− (params :: [ColumnType])
1210− (columns :: ColumnsType)
1211− = UnsafeQuery { renderQuery :: ByteString }
1212− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
1213−
1214−queryStatement
1215− :: Query schema params columns
1216− -> Manipulation schema params columns
1217−queryStatement q = UnsafeManipulation $ renderQuery q <> ";"
1218−
1219−union, unionAll, intersect, intersectAll, except, exceptAll
1220− :: Query schema params columns
1221− -> Query schema params columns
1222− -> Query schema params columns
1223−q1 `union` q2 = UnsafeQuery $
1224− parenthesized (renderQuery q1)
1225− <+> "UNION"
1226− <+> parenthesized (renderQuery q2)
1227−q1 `unionAll` q2 = UnsafeQuery $
1228− parenthesized (renderQuery q1)
1229− <+> "UNION" <+> "ALL"
1230− <+> parenthesized (renderQuery q2)
1231−q1 `intersect` q2 = UnsafeQuery $
1232− parenthesized (renderQuery q1)
1233− <+> "INTERSECT"
1234− <+> parenthesized (renderQuery q2)
1235−q1 `intersectAll` q2 = UnsafeQuery $
1236− parenthesized (renderQuery q1)
1237− <+> "INTERSECT" <+> "ALL"
1238− <+> parenthesized (renderQuery q2)
1239−q1 `except` q2 = UnsafeQuery $
1240− parenthesized (renderQuery q1)
1241− <+> "EXCEPT"
1242− <+> parenthesized (renderQuery q2)
1243−q1 `exceptAll` q2 = UnsafeQuery $
1244− parenthesized (renderQuery q1)
1245− <+> "EXCEPT" <+> "ALL"
1246− <+> parenthesized (renderQuery q2)
1247−
1248−{-----------------------------------------
1249−SELECT statements
1250−-----------------------------------------}
1251−
1252−select
1253− :: SListI columns
1254− => NP (Aliased (Expression params tables grouping)) (column ': columns)
1255− -> TableExpression params schema tables grouping
1256− -> Query schema params (column ': columns)
1257−select list tabs = UnsafeQuery $
1258− "SELECT"
1259− <+> renderCommaSeparated (renderAliased renderExpression) list
1260− <+> renderTableExpression tabs
1261−
1262−selectDistinct
1263− :: SListI columns
1264− => NP (Aliased (Expression params tables grouping)) (column ': columns)
1265− -> TableExpression params schema tables grouping
1266− -> Query schema params (column ': columns)
1267−selectDistinct list tabs = UnsafeQuery $
1268− "SELECT DISTINCT"
1269− <+> renderCommaSeparated (renderAliased renderExpression) list
1270− <+> renderTableExpression tabs
1271−
1272−selectStar
1273− :: HasUnique table tables columns
1274− => TableExpression params schema tables 'Ungrouped
1275− -> Query schema params columns
1276−selectStar tabs = UnsafeQuery $ "SELECT" <+> "*" <+> renderTableExpression tabs
1277−
1278−selectDistinctStar
1279− :: HasUnique table tables columns
1280− => TableExpression params schema tables 'Ungrouped
1281− -> Query schema params columns
1282−selectDistinctStar tabs = UnsafeQuery $
1283− "SELECT DISTINCT" <+> "*" <+> renderTableExpression tabs
1284−
1285−selectDotStar
1286− :: HasTable table tables columns
1287− => Alias table
1288− -> TableExpression params schema tables 'Ungrouped
1289− -> Query schema params columns
1290−selectDotStar table tables = UnsafeQuery $
1291− "SELECT" <+> renderAlias table <> ".*" <+> renderTableExpression tables
1292−
1293−selectDistinctDotStar
1294− :: HasTable table tables columns
1295− => Alias table
1296− -> TableExpression params schema tables 'Ungrouped
1297− -> Query schema params columns
1298−selectDistinctDotStar table tables = UnsafeQuery $
1299− "SELECT DISTINCT" <+> renderAlias table <> ".*"
1300− <+> renderTableExpression tables
1301−
1302−{-----------------------------------------
1303−CREATE statements
1304−-----------------------------------------}
1305−
1306−createTable
1307− :: (KnownSymbol table, SListI columns)
1308− => Alias table
1309− -> NP (Aliased TypeExpression) (column ': columns)
1310− -> [TableConstraint schema (column ': columns)]
1311− -> Definition schema (Create table (column ': columns) schema)
1312−createTable table columns constraints = UnsafeDefinition $
1313− "CREATE TABLE" <+> renderAlias table
1314− <+> parenthesized
1315− ( renderCommaSeparated renderColumnDef columns
1316− <> renderConstraints constraints )
1317− <> ";"
1318− where
1319− renderColumnDef :: Aliased TypeExpression x -> ByteString
1320− renderColumnDef (ty `As` column) =
1321− renderAlias column <+> renderTypeExpression ty
1322− renderConstraints :: [TableConstraint schema columns] -> ByteString
1323− renderConstraints = \case
1324− [] -> ""
1325− _ -> ", " <> commaSeparated (renderTableConstraint <$> constraints)
1326−
1327−newtype TableConstraint
1328− (schema :: TablesType)
1329− (columns :: ColumnsType)
1330− = UnsafeTableConstraint { renderTableConstraint :: ByteString }
1331− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
1332−
1333−check
1334− :: Condition '[] '[table ::: columns] 'Ungrouped
1335− -> TableConstraint schema columns
1336−check condition = UnsafeTableConstraint $
1337− "CHECK" <+> parenthesized (renderExpression condition)
1338−
1339−renderColumn :: Column columns columnty -> ByteString
1340−renderColumn (Column column) = renderAlias column
1341−
1342−unique
1343− :: SListI subcolumns
1344− => NP (Column columns) subcolumns
1345− -> TableConstraint schema columns
1346−unique columns = UnsafeTableConstraint $
1347− "UNIQUE" <+> parenthesized (renderCommaSeparated renderColumn columns)
1348−
1349−primaryKey
1350− :: (SListI subcolumns, AllNotNull subcolumns)
1351− => NP (Column columns) subcolumns
1352− -> TableConstraint schema columns
1353−primaryKey columns = UnsafeTableConstraint $
1354− "PRIMARY KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
1355−
1356−foreignKey
1357− :: ( HasTable reftable schema refcolumns
1358− , SameTypes subcolumns refsubcolumns
1359− , NotAllNull subcolumns
1360− , SListI subcolumns
1361− , SListI refsubcolumns)
1362− => NP (Column columns) subcolumns
1363− -> Alias reftable
1364− -> NP (Column refcolumns) refsubcolumns
1365− -> OnDelete
1366− -> OnUpdate
1367− -> TableConstraint schema columns
1368−foreignKey columns reftable refcolumns onDelete onUpdate =
1369− UnsafeTableConstraint $
1370− "FOREIGN KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
1371− <+> "REFERENCES" <+> renderAlias reftable
1372− <+> parenthesized (renderCommaSeparated renderColumn refcolumns)
1373− <+> renderOnDelete onDelete
1374− <+> renderOnUpdate onUpdate
1375−
1376−data OnDelete
1377− = OnDeleteNoAction
1378− | OnDeleteRestrict
1379− | OnDeleteCascade
1380− deriving (GHC.Generic,Show,Eq,Ord,Data)
1381−instance NFData OnDelete
1382−
1383−renderOnDelete :: OnDelete -> ByteString
1384−renderOnDelete = \case
1385− OnDeleteNoAction -> "ON DELETE NO ACTION"
1386− OnDeleteRestrict -> "ON DELETE RESTRICT"
1387− OnDeleteCascade -> "ON DELETE CASCADE"
1388−
1389−data OnUpdate
1390− = OnUpdateNoAction
1391− | OnUpdateRestrict
1392− | OnUpdateCascade
1393− deriving (GHC.Generic,Show,Eq,Ord,Data)
1394−instance NFData OnUpdate
1395−
1396−renderOnUpdate :: OnUpdate -> ByteString
1397−renderOnUpdate = \case
1398− OnUpdateNoAction -> "ON UPDATE NO ACTION"
1399− OnUpdateRestrict -> "ON UPDATE RESTRICT"
1400− OnUpdateCascade -> "ON UPDATE CASCADE"
1401−
1402−{-----------------------------------------
1403−DROP statements
1404−-----------------------------------------}
1405−
1406−dropTable
1407− :: KnownSymbol table
1408− => Alias table
1409− -> Definition schema (Drop table schema)
1410−dropTable table = UnsafeDefinition $ "DROP TABLE" <+> renderAlias table <> ";"
1411−
1412−{-----------------------------------------
1413−ALTER statements
1414−-----------------------------------------}
1415−
1416−alterTable
1417− :: HasTable table schema columns0
1418− => Alias table
1419− -> AlterTable columns0 columns1
1420− -> Definition schema (Alter table schema columns1)
1421−alterTable table alteration = UnsafeDefinition $
1422− "ALTER TABLE"
1423− <+> renderAlias table
1424− <+> renderAlterTable alteration
1425− <> ";"
1426−
1427−alterTableRename
1428− :: (KnownSymbol table0, KnownSymbol table1)
1429− => Alias table0
1430− -> Alias table1
1431− -> Definition schema (Rename table0 table1 schema)
1432−alterTableRename table0 table1 = UnsafeDefinition $
1433− "ALTER TABLE" <+> renderAlias table0
1434− <+> "RENAME TO" <+> renderAlias table1 <> ";"
1435−
1436−newtype AlterTable
1437− (columns0 :: ColumnsType)
1438− (columns1 :: ColumnsType) =
1439− UnsafeAlterTable {renderAlterTable :: ByteString}
1440− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
1441−
1442−addColumnDefault
1443− :: KnownSymbol column
1444− => Alias column
1445− -> TypeExpression ('Optional ty)
1446− -> AlterTable columns (Create column ('Optional ty) columns)
1447−addColumnDefault column ty = UnsafeAlterTable $
1448− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
1449−
1450−addColumnNull
1451− :: KnownSymbol column
1452− => Alias column
1453− -> TypeExpression ('Required ('Null ty))
1454− -> AlterTable columns (Create column ('Required ('Null ty)) columns)
1455−addColumnNull column ty = UnsafeAlterTable $
1456− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
1457−
1458−dropColumn
1459− :: KnownSymbol column
1460− => Alias column
1461− -> AlterTable columns (Drop column columns)
1462−dropColumn column = UnsafeAlterTable $
1463− "DROP COLUMN" <+> renderAlias column
1464−
1465−renameColumn
1466− :: (KnownSymbol column0, KnownSymbol column1)
1467− => Alias column0
1468− -> Alias column1
1469− -> AlterTable columns (Rename column0 column1 columns)
1470−renameColumn column0 column1 = UnsafeAlterTable $
1471− "RENAME COLUMN" <+> renderAlias column0 <+> "TO" <+> renderAlias column1
1472−
1473−alterColumn
1474− :: (KnownSymbol column, HasColumn column columns ty0)
1475− => Alias column
1476− -> AlterColumn ty0 ty1
1477− -> AlterTable columns (Alter column columns ty1)
1478−alterColumn column alteration = UnsafeAlterTable $
1479− "ALTER COLUMN" <+> renderAlias column <+> renderAlterColumn alteration
1480−
1481−newtype AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
1482− UnsafeAlterColumn {renderAlterColumn :: ByteString}
1483− deriving (GHC.Generic,Show,Eq,Ord,Data,NFData)
1484−
1485−setDefault
1486− :: Expression '[] '[] 'Ungrouped ('Required ty)
1487− -> AlterColumn ('Required ty) ('Optional ty)
1488−setDefault expression = UnsafeAlterColumn $
1489− "SET DEFAULT" <+> renderExpression expression
1490−
1491−dropDefault :: AlterColumn ('Optional ty) ('Required ty)
1492−dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
1493−
1494−setNotNull
1495− :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
1496−setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
1497−
1498−dropNotNull
1499− :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
1500−dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
1501−
1502−alterType
1503− :: TypeExpression (optionality (nullity ty1))
1504− -> AlterColumn (optionality (nullity ty0)) (optionality (nullity ty1))
1505−alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty
1506−
1507−{-----------------------------------------
1508−INSERT statements
1509−-----------------------------------------}
1510−
1511−insertInto
1512− :: (SListI columns, SListI results, HasTable table schema columns)
1513− => Alias table
1514− -> ValuesClause schema params columns
1515− -> ConflictClause params columns
1516− -> ReturningClause params columns results
1517− -> Manipulation schema params results
1518−insertInto table insert conflict returning = UnsafeManipulation $
1519− "INSERT" <+> "INTO" <+> renderAlias table
1520− <+> renderValuesClause insert
1521− <> renderConflictClause conflict
1522− <> renderReturningClause returning
1523−
1524−data ValuesClause
1525− (schema :: TablesType)
1526− (params :: [ColumnType])
1527− (columns :: ColumnsType)
1528− = Values
1529− (NP (Aliased (Expression params '[] 'Ungrouped)) columns)
1530− [NP (Aliased (Expression params '[] 'Ungrouped)) columns]
1531− | ValuesQuery (Query schema params columns)
1532−
1533−renderValuesClause
1534− :: SListI columns
1535− => ValuesClause schema params columns
1536− -> ByteString
1537−renderValuesClause = \case
1538− Values row rows ->
1539− parenthesized (renderCommaSeparated renderAliasPart row)
1540− <+> "VALUES"
1541− <+> commaSeparated
1542− (parenthesized . renderCommaSeparated renderValuePart <$> row:rows)
1543− where
1544− renderAliasPart, renderValuePart
1545− :: Aliased (Expression params '[] 'Ungrouped) ty -> ByteString
1546− renderAliasPart (_ `As` name) = renderAlias name
1547− renderValuePart (value `As` _) = renderExpression value
1548− ValuesQuery q -> renderQuery q
1549−
1550−data ReturningClause
1551− (params :: [ColumnType])
1552− (columns :: ColumnsType)
1553− (results :: ColumnsType)
1554− where
1555− ReturningStar :: ReturningClause params columns columns
1556− Returning
1557− :: NP
1558− (Aliased (Expression params '[table ::: columns] 'Ungrouped))
1559− results
1560− -> ReturningClause params columns results
1561−
1562−renderReturningClause
1563− :: SListI results
1564− => ReturningClause params columns results
1565− -> ByteString
1566−renderReturningClause = \case
1567− ReturningStar -> " RETURNING *;"
1568− Returning Nil -> ";"
1569− Returning results -> " RETURNING"
1570− <+> renderCommaSeparated (renderAliased renderExpression) results <> ";"
1571−
1572−data ConflictClause params columns where
1573− Conflict :: ConflictClause params columns
1574− OnConflictDoNothing :: ConflictClause params columns
1575− OnConflictDoUpdate
1576− :: NP (Aliased (UpdateExpression params columns)) columns
1577− -> Maybe (Condition params '[table ::: columns] 'Ungrouped)
1578− -> ConflictClause params columns
1579−
1580−renderConflictClause
1581− :: SListI columns
1582− => ConflictClause params columns
1583− -> ByteString
1584−renderConflictClause = \case
1585− Conflict -> ""
1586− OnConflictDoNothing -> " ON CONFLICT DO NOTHING"
1587− OnConflictDoUpdate updates whMaybe
1588− -> " ON CONFLICT DO UPDATE SET"
1589− <+> renderCommaSeparatedMaybe renderUpdateExpression updates
1590− <> case whMaybe of
1591− Nothing -> ""
1592− Just wh -> " WHERE" <+> renderExpression wh
1593−
1594−{-----------------------------------------
1595−UPDATE statements
1596−-----------------------------------------}
1597−
1598−data UpdateExpression params columns ty
1599− = Same
1600− | Set (forall table. Expression params '[table ::: columns] 'Ungrouped ty)
1601−deriving instance Show (UpdateExpression params columns ty)
1602−deriving instance Eq (UpdateExpression params columns ty)
1603−deriving instance Ord (UpdateExpression params columns ty)
1604−
1605−renderUpdateExpression
1606− :: Aliased (UpdateExpression params columns) column
1607− -> Maybe ByteString
1608−renderUpdateExpression = \case
1609− Same `As` _ -> Nothing
1610− Set expression `As` column -> Just $
1611− renderAlias column <+> "=" <+> renderExpression expression
1612−
1613−update
1614− :: (HasTable table schema columns, SListI columns, SListI results)
1615− => Alias table
1616− -> NP (Aliased (UpdateExpression params columns)) columns
1617− -> Condition params '[tab ::: columns] 'Ungrouped
1618− -> ReturningClause params columns results
1619− -> Manipulation schema params results
1620−update table columns wh returning = UnsafeManipulation $
1621− "UPDATE"
1622− <+> renderAlias table
1623− <+> "SET"
1624− <+> renderCommaSeparatedMaybe renderUpdateExpression columns
1625− <+> "WHERE" <+> renderExpression wh
1626− <> renderReturningClause returning
1627−
1628−{-----------------------------------------
1629−DELETE statements
1630−-----------------------------------------}
1631−
1632−deleteFrom
1633− :: HasTable table schema columns
1634− => Alias table
1635− -> Condition params '[table ::: columns] 'Ungrouped
1636− -> Manipulation schema params '[]
1637−deleteFrom table wh = UnsafeManipulation $
1638− "DELETE FROM" <+> renderAlias table
1639− <+> "WHERE" <+> renderExpression wh <> ";"
1640−
1641−{-----------------------------------------
1642−render helper functions
1643−-----------------------------------------}
1644−
1645−parenthesized :: ByteString -> ByteString
1646−parenthesized str = "(" <> str <> ")"
1647−
1648−(<+>) :: ByteString -> ByteString -> ByteString
1649−str1 <+> str2 = str1 <> " " <> str2
1650−
1651−commaSeparated :: [ByteString] -> ByteString
1652−commaSeparated = ByteString.intercalate ", "
1653−
1654−renderCommaSeparated
1655− :: SListI xs
1656− => (forall x. expression x -> ByteString)
1657− -> NP expression xs -> ByteString
1658−renderCommaSeparated render
1659− = commaSeparated
1660− . hcollapse
1661− . hmap (K . render)
1662−
1663−renderCommaSeparatedMaybe
1664− :: SListI xs
1665− => (forall x. expression x -> Maybe ByteString)
1666− -> NP expression xs -> ByteString
1667−renderCommaSeparatedMaybe render
1668− = commaSeparated
1669− . catMaybes
1670− . hcollapse
1671− . hmap (K . render)
1672−
1673−renderNat :: KnownNat n => proxy n -> ByteString
1674−renderNat (_ :: proxy n) = fromString (show (natVal' (proxy# :: Proxy# n)))