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