@@ -1,1350 +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−data SortExpression params tables grouping where
383− Asc
384− :: Expression params tables grouping ('Required ('NotNull ty))
385− -> SortExpression params tables grouping
386− Desc
387− :: Expression params tables grouping ('Required ('NotNull ty))
388− -> SortExpression params tables grouping
389− AscNullsFirst
390− :: Expression params tables grouping ('Required ('Null ty))
391− -> SortExpression params tables grouping
392− AscNullsLast
393− :: Expression params tables grouping ('Required ('Null ty))
394− -> SortExpression params tables grouping
395− DescNullsFirst
396− :: Expression params tables grouping ('Required ('Null ty))
397− -> SortExpression params tables grouping
398− DescNullsLast
399− :: Expression params tables grouping ('Required ('Null ty))
400− -> SortExpression params tables grouping
401−
402−renderSortExpression :: SortExpression params tables grouping -> ByteString
403−renderSortExpression = \case
404− Asc expression -> renderExpression expression <+> "ASC"
405− Desc expression -> renderExpression expression <+> "DESC"
406− AscNullsFirst expression -> renderExpression expression
407− <+> "ASC NULLS FIRST"
408− DescNullsFirst expression -> renderExpression expression
409− <+> "DESC NULLS FIRST"
410− AscNullsLast expression -> renderExpression expression <+> "ASC NULLS LAST"
411− DescNullsLast expression -> renderExpression expression <+> "DESC NULLS LAST"
412−
413−
414−{-----------------------------------------
415−aggregation
416−-----------------------------------------}
417−
418−data By
419− (tables :: [(Symbol,[(Symbol,ColumnType)])])
420− (tabcol :: (Symbol,Symbol)) where
421− By
422− :: (tables ~ '[table ::: columns], HasColumn column columns ty)
423− => Alias column
424− -> By tables '(table, column)
425− By2
426− :: (HasTable table tables columns, HasColumn column columns ty)
427− => (Alias table, Alias column)
428− -> By tables '(table, column)
429−
430−renderBy :: By tables tabcolty -> ByteString
431−renderBy = \case
432− By column -> renderAlias column
433− By2 (table, column) -> renderAlias table <> "." <> renderAlias column
434−
435−data GroupByClause tables grouping where
436− NoGroups :: GroupByClause tables 'Ungrouped
437− Group
438− :: SListI bys
439− => NP (By tables) bys
440− -> GroupByClause tables ('Grouped bys)
441−
442−renderGroupByClause :: GroupByClause tables grouping -> ByteString
443−renderGroupByClause = \case
444− NoGroups -> ""
445− Group Nil -> ""
446− Group bys -> " GROUP BY" <+> renderCommaSeparated renderBy bys
447−
448−data HavingClause params tables grouping where
449− NoHaving :: HavingClause params tables 'Ungrouped
450− Having
451− :: [Condition params tables ('Grouped bys)]
452− -> HavingClause params tables ('Grouped bys)
453−
454−renderHavingClause :: HavingClause params tables grouping -> ByteString
455−renderHavingClause = \case
456− NoHaving -> ""
457− Having [] -> ""
458− Having conditions ->
459− " HAVING" <+> commaSeparated (renderExpression <$> conditions)
460−
461−class (KnownSymbol table, KnownSymbol column)
462− => GroupedBy table column bys where
463− getGroup1
464− :: (tables ~ '[table ::: columns], HasColumn column columns ty)
465− => Alias column
466− -> Expression params tables ('Grouped bys) ty
467− getGroup1 column = UnsafeExpression $ renderAlias column
468− getGroup2
469− :: (HasTable table tables columns, HasColumn column columns ty)
470− => Alias table
471− -> Alias column
472− -> Expression params tables ('Grouped bys) ty
473− getGroup2 table column = UnsafeExpression $
474− renderAlias table <> "." <> renderAlias column
475−instance {-# OVERLAPPING #-} (KnownSymbol table, KnownSymbol column)
476− => GroupedBy table column ('(table,column) ': bys)
477−instance {-# OVERLAPPABLE #-}
478− ( KnownSymbol table
479− , KnownSymbol column
480− , GroupedBy table column bys
481− ) => GroupedBy table column (tabcol ': bys)
482−
483−instance
484− ( tables ~ '[table ::: columns]
485− , HasColumn column columns ty
486− , GroupedBy table column bys
487− ) => IsLabel column
488− (Expression params tables ('Grouped bys) ty) where
489− fromLabel = getGroup1 (Alias @column)
490−
491−instance
492− ( HasTable table tables columns
493− , HasColumn column columns ty
494− , GroupedBy table column bys
495− ) => IsTableColumn table column
496− (Expression params tables ('Grouped bys) ty) where (!) = getGroup2
497−
498−unsafeAggregate
499− :: ByteString
500− -> Expression params tables 'Ungrouped ('Required xty)
501− -> Expression params tables ('Grouped bys) ('Required yty)
502−unsafeAggregate fun x = UnsafeExpression $ mconcat
503− [fun, "(", renderExpression x, ")"]
504−
505−sum_
506− :: PGNum ty
507− => Expression params tables 'Ungrouped ('Required (nullity ty))
508− -> Expression params tables ('Grouped bys) ('Required (nullity ty))
509−sum_ = unsafeAggregate "sum"
510−
511−avgInt
512− :: PGIntegral int
513− => Expression params tables 'Ungrouped ('Required (nullity int))
514− -> Expression params tables ('Grouped bys) ('Required (nullity 'PGnumeric))
515−avgInt = unsafeAggregate "avg"
516−
517−avgFloat
518− :: PGFloating float
519− => Expression params tables 'Ungrouped ('Required (nullity float))
520− -> Expression params tables ('Grouped bys) ('Required (nullity 'PGfloat8))
521−avgFloat = unsafeAggregate "avg"
522−
523−bitAnd
524− :: PGIntegral int
525− => Expression params tables 'Ungrouped ('Required (nullity int))
526− -> Expression params tables ('Grouped bys) ('Required (nullity int))
527−bitAnd = unsafeAggregate "bit_and"
528−
529−bitOr
530− :: PGIntegral int
531− => Expression params tables 'Ungrouped ('Required (nullity int))
532− -> Expression params tables ('Grouped bys) ('Required (nullity int))
533−bitOr = unsafeAggregate "bit_or"
534−
535−boolAnd
536− :: Expression params tables 'Ungrouped ('Required (nullity 'PGbool))
537− -> Expression params tables ('Grouped bys) ('Required (nullity 'PGbool))
538−boolAnd = unsafeAggregate "bool_and"
539−
540−boolOr
541− :: Expression params tables 'Ungrouped ('Required (nullity 'PGbool))
542− -> Expression params tables ('Grouped bys) ('Required (nullity 'PGbool))
543−boolOr = unsafeAggregate "bool_or"
544−
545−countStar
546− :: Expression params table ('Grouped bys) ('Required ('NotNull 'PGint8))
547−countStar = UnsafeExpression "count(*)"
548−
549−count
550− :: Expression params tables 'Ungrouped ('Required ty)
551− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGint8))
552−count = unsafeAggregate "count"
553−
554−every
555− :: Expression params tables 'Ungrouped ('Required (nullity 'PGbool))
556− -> Expression params tables ('Grouped bys) ('Required (nullity 'PGbool))
557−every = unsafeAggregate "every"
558−
559−jsonAgg
560− :: Expression params tables 'Ungrouped ('Required ty)
561− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGjson))
562−jsonAgg = unsafeAggregate "json_agg"
563−
564−jsonbAgg
565− :: Expression params tables 'Ungrouped ('Required ty)
566− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGjsonb))
567−jsonbAgg = unsafeAggregate "jsonb_agg"
568−
569−jsonObjectAgg
570− :: Expression params tables 'Ungrouped ('Required ('NotNull keyty))
571− -> Expression params tables 'Ungrouped ('Required valty)
572− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGjson))
573−jsonObjectAgg k v = UnsafeExpression $
574− "json_object_agg(" <> renderExpression k
575− <> ", " <> renderExpression v <> ")"
576−
577−jsonbObjectAgg
578− :: Expression params tables 'Ungrouped ('Required ('NotNull keyty))
579− -> Expression params tables 'Ungrouped ('Required valty)
580− -> Expression params tables ('Grouped bys) ('Required ('NotNull 'PGjsonb))
581−jsonbObjectAgg k v = UnsafeExpression $
582− "jsonb_object_agg(" <> renderExpression k
583− <> ", " <> renderExpression v <> ")"
584−
585−max_
586− :: Expression params tables 'Ungrouped ('Required (nullity ty))
587− -> Expression params tables ('Grouped bys) ('Required (nullity ty))
588−max_ = unsafeAggregate "max"
589−
590−min_
591− :: Expression params tables 'Ungrouped ('Required (nullity ty))
592− -> Expression params tables ('Grouped bys) ('Required (nullity ty))
593−min_ = unsafeAggregate "min"
594−
595−{-----------------------------------------
596−tables
597−-----------------------------------------}
598−
599−newtype Table
600− (schema :: [(Symbol,[(Symbol,ColumnType)])])
601− (columns :: [(Symbol,ColumnType)])
602− = UnsafeTable { renderTable :: ByteString }
603− deriving (Show,Eq)
604−
605−class KnownSymbol table => HasTable table tables columns
606− | table tables -> columns where
607− getTable :: Alias table -> Table tables columns
608− getTable table = UnsafeTable $ renderAlias table
609−instance {-# OVERLAPPING #-} KnownSymbol table
610− => HasTable table ((table ::: columns) ': tables) columns
611−instance {-# OVERLAPPABLE #-}
612− (KnownSymbol table, HasTable table schema columns)
613− => HasTable table (table' ': schema) columns
614−
615−instance HasTable table schema columns
616− => IsLabel table (Table schema columns) where
617− fromLabel = getTable (Alias @table)
618−
619−data FromClause params schema tables where
620− Table
621− :: Aliased (Table schema) table
622− -> FromClause params schema '[table]
623− Subquery
624− :: Aliased (Query schema params) table
625− -> FromClause params schema '[table]
626− CrossJoin
627− :: FromClause params schema right
628− -> FromClause params schema left
629− -> FromClause params schema (Join left right)
630− InnerJoin
631− :: FromClause params schema right
632− -> Condition params (Join left right) 'Ungrouped
633− -> FromClause params schema left
634− -> FromClause params schema (Join left right)
635− LeftOuterJoin
636− :: FromClause params schema right
637− -> Condition params (Join left right) 'Ungrouped
638− -> FromClause params schema left
639− -> FromClause params schema (Join left (NullifyTables right))
640− RightOuterJoin
641− :: FromClause params schema right
642− -> Condition params (Join left right) 'Ungrouped
643− -> FromClause params schema left
644− -> FromClause params schema (Join (NullifyTables left) right)
645− FullOuterJoin
646− :: FromClause params schema right
647− -> Condition params (Join left right) 'Ungrouped
648− -> FromClause params schema left
649− -> FromClause params schema
650− (Join (NullifyTables left) (NullifyTables right))
651−
652−renderFromClause :: FromClause params schema tables -> ByteString
653−renderFromClause = \case
654− Table table -> renderAliased renderTable table
655− Subquery selection -> renderAliased renderQuery selection
656− CrossJoin right left ->
657− renderFromClause left <+> "CROSS JOIN" <+> renderFromClause right
658− InnerJoin right on left -> renderJoin "INNER JOIN" right on left
659− LeftOuterJoin right on left -> renderJoin "LEFT OUTER JOIN" right on left
660− RightOuterJoin right on left -> renderJoin "RIGHT OUTER JOIN" right on left
661− FullOuterJoin right on left -> renderJoin "FULL OUTER JOIN" right on left
662− where
663− renderJoin op right on left =
664− renderFromClause left <+> op <+> renderFromClause right
665− <+> "ON" <+> renderExpression on
666−
667−data TableExpression
668− (params :: [ColumnType])
669− (schema :: [(Symbol,[(Symbol,ColumnType)])])
670− (tables :: [(Symbol,[(Symbol,ColumnType)])])
671− (grouping :: Grouping)
672− = TableExpression
673− { fromClause :: FromClause params schema tables
674− , whereClause :: [Condition params tables 'Ungrouped]
675− , groupByClause :: GroupByClause tables grouping
676− , havingClause :: HavingClause params tables grouping
677− , orderByClause :: [SortExpression params tables grouping]
678− , limitClause :: [Word64]
679− , offsetClause :: [Word64]
680− }
681−
682−renderTableExpression
683− :: TableExpression params schema tables grouping
684− -> ByteString
685−renderTableExpression
686− (TableExpression tables whs' grps' hvs' srts' lims' offs') = mconcat
687− [ "FROM ", renderFromClause tables
688− , renderWheres whs'
689− , renderGroupByClause grps'
690− , renderHavingClause hvs'
691− , renderSorts srts'
692− , renderLimits lims'
693− , renderOffsets offs'
694− ]
695− where
696− renderWheres = \case
697− [] -> ""
698− wh:[] -> " WHERE" <+> renderExpression wh
699− wh:whs -> " WHERE" <+> renderExpression (foldr (&&*) wh whs)
700− renderSorts = \case
701− [] -> ""
702− srts -> " SORT BY"
703− <+> commaSeparated (renderSortExpression <$> srts)
704− renderLimits = \case
705− [] -> ""
706− lims -> " LIMIT" <+> fromString (show (minimum lims))
707− renderOffsets = \case
708− [] -> ""
709− offs -> " OFFSET" <+> fromString (show (sum offs))
710−
711−from
712− :: FromClause params schema tables
713− -> TableExpression params schema tables 'Ungrouped
714−from tables = TableExpression tables [] NoGroups NoHaving [] [] []
715−
716−where_
717− :: Condition params tables 'Ungrouped
718− -> TableExpression params schema tables grouping
719− -> TableExpression params schema tables grouping
720−where_ wh tables = tables {whereClause = wh : whereClause tables}
721−
722−group
723− :: SListI bys
724− => NP (By tables) bys
725− -> TableExpression params schema tables 'Ungrouped
726− -> TableExpression params schema tables ('Grouped bys)
727−group bys tables = TableExpression
728− { fromClause = fromClause tables
729− , whereClause = whereClause tables
730− , groupByClause = Group bys
731− , havingClause = Having []
732− , orderByClause = []
733− , limitClause = limitClause tables
734− , offsetClause = offsetClause tables
735− }
736−
737−having
738− :: Condition params tables ('Grouped bys)
739− -> TableExpression params schema tables ('Grouped bys)
740− -> TableExpression params schema tables ('Grouped bys)
741−having hv tables = tables
742− { havingClause = case havingClause tables of Having hvs -> Having (hv:hvs) }
743−
744−orderBy
745− :: [SortExpression params tables grouping]
746− -> TableExpression params schema tables grouping
747− -> TableExpression params schema tables grouping
748−orderBy srts tables = tables {orderByClause = orderByClause tables ++ srts}
749−
750−limit
751− :: Word64
752− -> TableExpression params schema tables grouping
753− -> TableExpression params schema tables grouping
754−limit lim tables = tables {limitClause = lim : limitClause tables}
755−
756−offset
757− :: Word64
758− -> TableExpression params schema tables grouping
759− -> TableExpression params schema tables grouping
760−offset off tables = tables {offsetClause = off : offsetClause tables}
761−
762−{-----------------------------------------
763−type expressions
764−-----------------------------------------}
765−
766−newtype TypeExpression (ty :: ColumnType)
767− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
768− deriving (Show,Eq)
769−
770−bool :: TypeExpression ('Required ('Null 'PGbool))
771−bool = UnsafeTypeExpression "bool"
772−int2 :: TypeExpression ('Required ('Null 'PGint2))
773−int2 = UnsafeTypeExpression "int2"
774−smallint :: TypeExpression ('Required ('Null 'PGint2))
775−smallint = UnsafeTypeExpression "smallint"
776−int4 :: TypeExpression ('Required ('Null 'PGint4))
777−int4 = UnsafeTypeExpression "int4"
778−int :: TypeExpression ('Required ('Null 'PGint4))
779−int = UnsafeTypeExpression "int"
780−integer :: TypeExpression ('Required ('Null 'PGint4))
781−integer = UnsafeTypeExpression "integer"
782−int8 :: TypeExpression ('Required ('Null 'PGint8))
783−int8 = UnsafeTypeExpression "int8"
784−bigint :: TypeExpression ('Required ('Null 'PGint8))
785−bigint = UnsafeTypeExpression "bigint"
786−numeric :: TypeExpression ('Required ('Null 'PGnumeric))
787−numeric = UnsafeTypeExpression "numeric"
788−float4 :: TypeExpression ('Required ('Null 'PGfloat4))
789−float4 = UnsafeTypeExpression "float4"
790−real :: TypeExpression ('Required ('Null 'PGfloat4))
791−real = UnsafeTypeExpression "real"
792−float8 :: TypeExpression ('Required ('Null 'PGfloat8))
793−float8 = UnsafeTypeExpression "float8"
794−doublePrecision :: TypeExpression ('Required ('Null 'PGfloat8))
795−doublePrecision = UnsafeTypeExpression "double precision"
796−serial2 :: TypeExpression ('Optional ('NotNull 'PGint2))
797−serial2 = UnsafeTypeExpression "serial2"
798−smallserial :: TypeExpression ('Optional ('NotNull 'PGint2))
799−smallserial = UnsafeTypeExpression "smallserial"
800−serial4 :: TypeExpression ('Optional ('NotNull 'PGint4))
801−serial4 = UnsafeTypeExpression "serial4"
802−serial :: TypeExpression ('Optional ('NotNull 'PGint4))
803−serial = UnsafeTypeExpression "serial"
804−serial8 :: TypeExpression ('Optional ('NotNull 'PGint8))
805−serial8 = UnsafeTypeExpression "serial8"
806−bigserial :: TypeExpression ('Optional ('NotNull 'PGint8))
807−bigserial = UnsafeTypeExpression "bigserial"
808−text :: TypeExpression ('Required ('Null 'PGtext))
809−text = UnsafeTypeExpression "text"
810−char
811− :: KnownNat n
812− => proxy n
813− -> TypeExpression ('Required ('Null ('PGchar n)))
814−char p = UnsafeTypeExpression $ "char(" <> renderNat p <> ")"
815−character
816− :: KnownNat n
817− => proxy n
818− -> TypeExpression ('Required ('Null ('PGchar n)))
819−character p = UnsafeTypeExpression $ "character(" <> renderNat p <> ")"
820−varchar
821− :: KnownNat n
822− => proxy n
823− -> TypeExpression ('Required ('Null ('PGvarchar n)))
824−varchar p = UnsafeTypeExpression $ "varchar(" <> renderNat p <> ")"
825−characterVarying
826− :: KnownNat n
827− => proxy n
828− -> TypeExpression ('Required ('Null ('PGvarchar n)))
829−characterVarying p = UnsafeTypeExpression $
830− "character varying(" <> renderNat p <> ")"
831−bytea :: TypeExpression ('Required ('Null ('PGbytea)))
832−bytea = UnsafeTypeExpression "bytea"
833−timestamp :: TypeExpression ('Required ('Null ('PGtimestamp)))
834−timestamp = UnsafeTypeExpression "timestamp"
835−timestampWithTimeZone :: TypeExpression ('Required ('Null ('PGtimestamptz)))
836−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
837−date :: TypeExpression ('Required ('Null ('PGdate)))
838−date = UnsafeTypeExpression "date"
839−time :: TypeExpression ('Required ('Null ('PGtime)))
840−time = UnsafeTypeExpression "time"
841−timeWithTimeZone :: TypeExpression ('Required ('Null ('PGtimetz)))
842−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
843−interval :: TypeExpression ('Required ('Null ('PGinterval)))
844−interval = UnsafeTypeExpression "interval"
845−uuid :: TypeExpression ('Required ('Null ('PGuuid)))
846−uuid = UnsafeTypeExpression "uuid"
847−json :: TypeExpression ('Required ('Null ('PGjson)))
848−json = UnsafeTypeExpression "json"
849−jsonb :: TypeExpression ('Required ('Null ('PGjsonb)))
850−jsonb = UnsafeTypeExpression "jsonb"
851−
852−notNull
853− :: TypeExpression (optionality ('Null ty))
854− -> TypeExpression (optionality ('NotNull ty))
855−notNull ty = UnsafeTypeExpression $ renderTypeExpression ty <+> "NOT NULL"
856−default_
857− :: Expression '[] '[] 'Ungrouped ('Required ty)
858− -> TypeExpression ('Required ty)
859− -> TypeExpression ('Optional ty)
860−default_ x ty = UnsafeTypeExpression $
861− renderTypeExpression ty <+> "DEFAULT" <+> renderExpression x
862−
863−class PGTyped (ty :: PGType) where
864− pgtype :: TypeExpression ('Required ('Null ty))
865−instance PGTyped 'PGbool where pgtype = bool
866−instance PGTyped 'PGint2 where pgtype = int2
867−instance PGTyped 'PGint4 where pgtype = int4
868−instance PGTyped 'PGint8 where pgtype = int8
869−instance PGTyped 'PGnumeric where pgtype = numeric
870−instance PGTyped 'PGfloat4 where pgtype = float4
871−instance PGTyped 'PGfloat8 where pgtype = float8
872−instance PGTyped 'PGtext where pgtype = text
873−instance KnownNat n => PGTyped ('PGchar n) where pgtype = char (Proxy @n)
874−instance KnownNat n => PGTyped ('PGvarchar n) where pgtype = varchar (Proxy @n)
875−instance PGTyped 'PGbytea where pgtype = bytea
876−instance PGTyped 'PGtimestamp where pgtype = timestamp
877−instance PGTyped 'PGtimestamptz where pgtype = timestampWithTimeZone
878−instance PGTyped 'PGdate where pgtype = date
879−instance PGTyped 'PGtime where pgtype = time
880−instance PGTyped 'PGtimetz where pgtype = timeWithTimeZone
881−instance PGTyped 'PGinterval where pgtype = interval
882−instance PGTyped 'PGuuid where pgtype = uuid
883−instance PGTyped 'PGjson where pgtype = json
884−instance PGTyped 'PGjsonb where pgtype = jsonb
885−
886−{-----------------------------------------
887−statements
888−-----------------------------------------}
889−
890−newtype Definition
891− (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
892− (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
893− = UnsafeDefinition { renderDefinition :: ByteString }
894−
895−instance Category Definition where
896− id = UnsafeDefinition ";"
897− ddl1 . ddl0 = UnsafeDefinition $
898− renderDefinition ddl0 <+> renderDefinition ddl1
899−
900−newtype Manipulation
901− (schema :: [(Symbol,[(Symbol,ColumnType)])])
902− (params :: [ColumnType])
903− (columns :: [(Symbol,ColumnType)])
904− = UnsafeManipulation { renderManipulation :: ByteString }
905−
906−newtype Query
907− (schema :: [(Symbol,[(Symbol,ColumnType)])])
908− (params :: [ColumnType])
909− (columns :: [(Symbol,ColumnType)])
910− = UnsafeQuery { renderQuery :: ByteString }
911−
912−queryStatement
913− :: Query schema params columns
914− -> Manipulation schema params columns
915−queryStatement q = UnsafeManipulation $ renderQuery q <> ";"
916−
917−union, unionAll, intersect, intersectAll, except, exceptAll
918− :: Query schema params columns
919− -> Query schema params columns
920− -> Query schema params columns
921−q1 `union` q2 = UnsafeQuery $
922− parenthesized (renderQuery q1)
923− <+> "UNION"
924− <+> parenthesized (renderQuery q2)
925−q1 `unionAll` q2 = UnsafeQuery $
926− parenthesized (renderQuery q1)
927− <+> "UNION" <+> "ALL"
928− <+> parenthesized (renderQuery q2)
929−q1 `intersect` q2 = UnsafeQuery $
930− parenthesized (renderQuery q1)
931− <+> "INTERSECT"
932− <+> parenthesized (renderQuery q2)
933−q1 `intersectAll` q2 = UnsafeQuery $
934− parenthesized (renderQuery q1)
935− <+> "INTERSECT" <+> "ALL"
936− <+> parenthesized (renderQuery q2)
937−q1 `except` q2 = UnsafeQuery $
938− parenthesized (renderQuery q1)
939− <+> "EXCEPT"
940− <+> parenthesized (renderQuery q2)
941−q1 `exceptAll` q2 = UnsafeQuery $
942− parenthesized (renderQuery q1)
943− <+> "EXCEPT" <+> "ALL"
944− <+> parenthesized (renderQuery q2)
945−
946−{-----------------------------------------
947−SELECT statements
948−-----------------------------------------}
949−
950−select
951− :: SListI columns
952− => NP (Aliased (Expression params tables grouping)) (column ': columns)
953− -> TableExpression params schema tables grouping
954− -> Query schema params (column ': columns)
955−select list tabs = UnsafeQuery $
956− "SELECT"
957− <+> renderCommaSeparated (renderAliased renderExpression) list
958− <+> renderTableExpression tabs
959−
960−selectStar
961− :: tables ~ '[table ::: columns]
962− => TableExpression params schema tables 'Ungrouped
963− -> Query schema params columns
964−selectStar tabs = UnsafeQuery $ "SELECT" <+> "*" <+> renderTableExpression tabs
965−
966−selectDotStar
967− :: HasTable table tables columns
968− => Alias table
969− -> TableExpression params schema tables 'Ungrouped
970− -> Query schema params columns
971−selectDotStar table tables = UnsafeQuery $
972− "SELECT" <+> renderAlias table <> ".*" <+> renderTableExpression tables
973−
974−selectRow
975− :: SListI columns
976− => NP (Aliased (Expression params '[] 'Ungrouped)) columns
977− -> Query schema params columns
978−selectRow row = UnsafeQuery $
979− "SELECT" <+> renderCommaSeparated (renderAliased renderExpression) row
980−
981−{-----------------------------------------
982−CREATE statements
983−-----------------------------------------}
984−
985−createTable
986− :: (KnownSymbol table, SListI columns)
987− => Alias table
988− -> NP (Aliased TypeExpression) (column ': columns)
989− -> [TableConstraint schema (column ': columns)]
990− -> Definition schema (Create table (column ': columns) schema)
991−createTable table columns constraints = UnsafeDefinition $
992− "CREATE TABLE" <+> renderAlias table
993− <+> parenthesized
994− ( renderCommaSeparated renderColumnDef columns
995− <> renderConstraints constraints )
996− <> ";"
997− where
998− renderColumnDef :: Aliased TypeExpression x -> ByteString
999− renderColumnDef (ty `As` column) =
1000− renderAlias column <+> renderTypeExpression ty
1001− renderConstraints :: [TableConstraint schema columns] -> ByteString
1002− renderConstraints = \case
1003− [] -> ""
1004− _ -> ", " <> commaSeparated (renderTableConstraint <$> constraints)
1005−
1006−data TableConstraint
1007− (schema :: [(Symbol,[(Symbol,ColumnType)])])
1008− (columns :: [(Symbol,ColumnType)])
1009− = UnsafeTableConstraint { renderTableConstraint :: ByteString }
1010−
1011−check
1012− :: (forall table. Condition '[] '[table ::: columns] 'Ungrouped)
1013− -> TableConstraint schema columns
1014−check condition = UnsafeTableConstraint $
1015− "CHECK" <+> parenthesized (renderExpression condition)
1016−
1017−data Column
1018− (columns :: [(Symbol,ColumnType)])
1019− (columnty :: (Symbol,ColumnType))
1020− where
1021− Column
1022− :: HasColumn column columns ty
1023− => Alias column
1024− -> Column columns (column ::: ty)
1025−
1026−renderColumn :: Column columns columnty -> ByteString
1027−renderColumn (Column column) = renderAlias column
1028−
1029−unique
1030− :: SListI subcolumns
1031− => NP (Column columns) subcolumns
1032− -> TableConstraint schema columns
1033−unique columns = UnsafeTableConstraint $
1034− "UNIQUE" <+> parenthesized (renderCommaSeparated renderColumn columns)
1035−
1036−primaryKey
1037− :: (SListI subcolumns, AllNotNull subcolumns)
1038− => NP (Column columns) subcolumns
1039− -> TableConstraint schema columns
1040−primaryKey columns = UnsafeTableConstraint $
1041− "PRIMARY KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
1042−
1043−foreignKey
1044− :: ( HasTable reftable schema refcolumns
1045− , SameTypes subcolumns refsubcolumns
1046− , NotAllNull subcolumns
1047− , SListI subcolumns
1048− , SListI refsubcolumns)
1049− => NP (Column columns) subcolumns
1050− -> Alias reftable
1051− -> NP (Column refcolumns) refsubcolumns
1052− -> OnDelete
1053− -> OnUpdate
1054− -> TableConstraint schema columns
1055−foreignKey columns reftable refcolumns onDelete onUpdate =
1056− UnsafeTableConstraint $
1057− "FOREIGN KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
1058− <+> "REFERENCES" <+> renderAlias reftable
1059− <+> parenthesized (renderCommaSeparated renderColumn refcolumns)
1060− <+> renderOnDelete onDelete
1061− <+> renderOnUpdate onUpdate
1062−
1063−data OnDelete
1064− = OnDeleteNoAction
1065− | OnDeleteRestrict
1066− | OnDeleteCascade
1067−
1068−renderOnDelete :: OnDelete -> ByteString
1069−renderOnDelete = \case
1070− OnDeleteNoAction -> "ON DELETE NO ACTION"
1071− OnDeleteRestrict -> "ON DELETE RESTRICT"
1072− OnDeleteCascade -> "ON DELETE CASCADE"
1073−
1074−data OnUpdate
1075− = OnUpdateNoAction
1076− | OnUpdateRestrict
1077− | OnUpdateCascade
1078−
1079−renderOnUpdate :: OnUpdate -> ByteString
1080−renderOnUpdate = \case
1081− OnUpdateNoAction -> "ON UPDATE NO ACTION"
1082− OnUpdateRestrict -> "ON UPDATE RESTRICT"
1083− OnUpdateCascade -> "ON UPDATE CASCADE"
1084−
1085−{-----------------------------------------
1086−DROP statements
1087−-----------------------------------------}
1088−
1089−dropTable
1090− :: KnownSymbol table
1091− => Alias table
1092− -> Definition schema (Drop table schema)
1093−dropTable table = UnsafeDefinition $ "DROP TABLE" <+> renderAlias table <> ";"
1094−
1095−{-----------------------------------------
1096−ALTER statements
1097−-----------------------------------------}
1098−
1099−alterTable
1100− :: HasTable table schema columns0
1101− => Alias table
1102− -> AlterTable columns0 columns1
1103− -> Definition schema (Alter table schema columns1)
1104−alterTable table alteration = UnsafeDefinition $
1105− "ALTER TABLE"
1106− <+> renderAlias table
1107− <+> renderAlterTable alteration
1108− <> ";"
1109−
1110−alterTableRename
1111− :: (KnownSymbol table0, KnownSymbol table1)
1112− => Alias table0
1113− -> Alias table1
1114− -> Definition schema (Rename table0 table1 schema)
1115−alterTableRename table0 table1 = UnsafeDefinition $
1116− "ALTER TABLE" <+> renderAlias table0
1117− <+> "RENAME TO" <+> renderAlias table1 <> ";"
1118−
1119−data AlterTable
1120− (columns0 :: [(Symbol, ColumnType)])
1121− (columns1 :: [(Symbol, ColumnType)]) =
1122− UnsafeAlterTable {renderAlterTable :: ByteString}
1123−
1124−addColumnDefault
1125− :: KnownSymbol column
1126− => Alias column
1127− -> TypeExpression ('Optional ty)
1128− -> AlterTable columns (Create column ('Optional ty) columns)
1129−addColumnDefault column ty = UnsafeAlterTable $
1130− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
1131−
1132−addColumnNull
1133− :: KnownSymbol column
1134− => Alias column
1135− -> TypeExpression ('Required ('Null ty))
1136− -> AlterTable columns ((column ::: 'Required ('Null ty)) ': columns)
1137−addColumnNull column ty = UnsafeAlterTable $
1138− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
1139−
1140−dropColumn
1141− :: KnownSymbol column
1142− => Alias column
1143− -> AlterTable columns (Drop column columns)
1144−dropColumn column = UnsafeAlterTable $
1145− "DROP COLUMN" <+> renderAlias column
1146−
1147−renameColumn
1148− :: (KnownSymbol column0, KnownSymbol column1)
1149− => Alias column0
1150− -> Alias column1
1151− -> AlterTable columns (Rename column0 column1 columns)
1152−renameColumn column0 column1 = UnsafeAlterTable $
1153− "RENAME COLUMN" <+> renderAlias column0 <+> "TO" <+> renderAlias column1
1154−
1155−alterColumn
1156− :: (KnownSymbol column, HasColumn column columns ty0)
1157− => Alias column
1158− -> AlterColumn ty0 ty1
1159− -> AlterTable columns (Alter column columns ty1)
1160−alterColumn column alteration = UnsafeAlterTable $
1161− "ALTER COLUMN" <+> renderAlias column <+> renderAlterColumn alteration
1162−
1163−data AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
1164− UnsafeAlterColumn {renderAlterColumn :: ByteString}
1165−
1166−setDefault
1167− :: Expression '[] '[] 'Ungrouped ('Required ty)
1168− -> AlterColumn ('Required ty) ('Optional ty)
1169−setDefault expression = UnsafeAlterColumn $
1170− "SET DEFAULT" <+> renderExpression expression
1171−
1172−dropDefault :: AlterColumn ('Optional ty) ('Required ty)
1173−dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
1174−
1175−setNotNull
1176− :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
1177−setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
1178−
1179−dropNotNull
1180− :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
1181−dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
1182−
1183−alterType
1184− :: TypeExpression (optionality (nullity ty1))
1185− -> AlterColumn (optionality (nullity ty0)) (optionality (nullity ty1))
1186−alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty
1187−
1188−{-----------------------------------------
1189−INSERT statements
1190−-----------------------------------------}
1191−
1192−insertInto
1193− :: (SListI columns, SListI results, HasTable table schema columns)
1194− => Alias table
1195− -> ValuesClause schema params columns
1196− -> ConflictClause params columns
1197− -> ReturningClause params columns results
1198− -> Manipulation schema params results
1199−insertInto table insert conflict returning = UnsafeManipulation $
1200− "INSERT" <+> "INTO" <+> renderAlias table
1201− <+> renderValuesClause insert
1202− <> renderConflictClause conflict
1203− <> renderReturningClause returning
1204−
1205−data ValuesClause
1206− (schema :: [(Symbol,[(Symbol,ColumnType)])])
1207− (params :: [ColumnType])
1208− (columns :: [(Symbol,ColumnType)])
1209− = Values
1210− (NP (Aliased (Expression params '[] 'Ungrouped)) columns)
1211− [NP (Aliased (Expression params '[] 'Ungrouped)) columns]
1212− | ValuesQuery (Query schema params columns)
1213−
1214−renderValuesClause
1215− :: SListI columns
1216− => ValuesClause schema params columns
1217− -> ByteString
1218−renderValuesClause = \case
1219− Values row rows ->
1220− parenthesized (renderCommaSeparated renderAliasPart row)
1221− <+> "VALUES"
1222− <+> commaSeparated
1223− (parenthesized . renderCommaSeparated renderValuePart <$> row:rows)
1224− where
1225− renderAliasPart, renderValuePart
1226− :: Aliased (Expression params '[] 'Ungrouped) ty -> ByteString
1227− renderAliasPart (_ `As` name) = renderAlias name
1228− renderValuePart (value `As` _) = renderExpression value
1229− ValuesQuery q -> renderQuery q
1230−
1231−data ReturningClause
1232− (params :: [ColumnType])
1233− (columns :: [(Symbol,ColumnType)])
1234− (results :: [(Symbol,ColumnType)])
1235− where
1236− ReturningStar :: ReturningClause params columns columns
1237− Returning
1238− :: NP
1239− (Aliased (Expression params '[table ::: columns] 'Ungrouped))
1240− results
1241− -> ReturningClause params columns results
1242−
1243−renderReturningClause
1244− :: SListI results
1245− => ReturningClause params columns results
1246− -> ByteString
1247−renderReturningClause = \case
1248− ReturningStar -> " RETURNING *;"
1249− Returning Nil -> ";"
1250− Returning results -> " RETURNING"
1251− <+> renderCommaSeparated (renderAliased renderExpression) results <> ";"
1252−
1253−data ConflictClause params columns where
1254− Conflict :: ConflictClause params columns
1255− OnConflictDoNothing :: ConflictClause params columns
1256− OnConflictDoUpdate
1257− :: NP (Aliased (UpdateExpression params columns)) columns
1258− -> (forall table. Condition params '[table ::: columns] 'Ungrouped)
1259− -> ConflictClause params columns
1260−
1261−renderConflictClause
1262− :: SListI columns
1263− => ConflictClause params columns
1264− -> ByteString
1265−renderConflictClause = \case
1266− Conflict -> ""
1267− OnConflictDoNothing -> " ON CONFLICT DO NOTHING"
1268− OnConflictDoUpdate updates wh
1269− -> " ON CONFLICT DO UPDATE SET"
1270− <+> renderCommaSeparatedMaybe renderUpdateExpression updates
1271− <+> "WHERE" <+> renderExpression wh
1272−
1273−{-----------------------------------------
1274−UPDATE statements
1275−-----------------------------------------}
1276−
1277−data UpdateExpression params columns ty
1278− = Same
1279− | Set (forall table. Expression params '[table ::: columns] 'Ungrouped ty)
1280−
1281−renderUpdateExpression
1282− :: Aliased (UpdateExpression params columns) column
1283− -> Maybe ByteString
1284−renderUpdateExpression = \case
1285− Same `As` _ -> Nothing
1286− Set expression `As` column -> Just $
1287− renderAlias column <+> "=" <+> renderExpression expression
1288−
1289−update
1290− :: (HasTable table schema columns, SListI columns, SListI results)
1291− => Alias table
1292− -> NP (Aliased (UpdateExpression params columns)) columns
1293− -> (forall tab. Condition params '[tab ::: columns] 'Ungrouped)
1294− -> ReturningClause params columns results
1295− -> Manipulation schema params results
1296−update table columns wh returning = UnsafeManipulation $
1297− "UPDATE"
1298− <+> renderAlias table
1299− <+> "SET"
1300− <+> renderCommaSeparatedMaybe renderUpdateExpression columns
1301− <+> "WHERE" <+> renderExpression wh
1302− <> renderReturningClause returning
1303−
1304−{-----------------------------------------
1305−DELETE statements
1306−-----------------------------------------}
1307−
1308−deleteFrom
1309− :: HasTable table schema columns
1310− => Alias table
1311− -> Condition params '[table ::: columns] 'Ungrouped
1312− -> Manipulation schema params '[]
1313−deleteFrom table wh = UnsafeManipulation $
1314− "DELETE FROM" <+> renderAlias table
1315− <+> "WHERE" <+> renderExpression wh <> ";"
1316−
1317−{-----------------------------------------
1318−render helper functions
1319−-----------------------------------------}
1320−
1321−parenthesized :: ByteString -> ByteString
1322−parenthesized str = "(" <> str <> ")"
1323−
1324−(<+>) :: ByteString -> ByteString -> ByteString
1325−str1 <+> str2 = str1 <> " " <> str2
1326−
1327−commaSeparated :: [ByteString] -> ByteString
1328−commaSeparated = ByteString.intercalate ", "
1329−
1330−renderCommaSeparated
1331− :: SListI xs
1332− => (forall x. expression x -> ByteString)
1333− -> NP expression xs -> ByteString
1334−renderCommaSeparated render
1335− = commaSeparated
1336− . hcollapse
1337− . hmap (K . render)
1338−
1339−renderCommaSeparatedMaybe
1340− :: SListI xs
1341− => (forall x. expression x -> Maybe ByteString)
1342− -> NP expression xs -> ByteString
1343−renderCommaSeparatedMaybe render
1344− = commaSeparated
1345− . catMaybes
1346− . hcollapse
1347− . hmap (K . render)
1348−
1349−renderNat :: KnownNat n => proxy n -> ByteString
1350−renderNat (_ :: proxy n) = fromString (show (natVal' (proxy# :: Proxy# n)))