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