@@ -1,1176 +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− , ScopedTypeVariables
12− , TypeApplications
13− , TypeFamilies
14− , TypeOperators
15− , UndecidableInstances
16−#-}
17−
18−module Squeel.PostgreSQL.Statement where
19−
20−import Control.Category
21−import Data.ByteString (ByteString)
22−import Data.Foldable
23−import Data.Maybe
24−import Data.Monoid
25−import Data.Ratio
26−import Data.String
27−import Data.Word
28−import Generics.SOP
29−import GHC.Exts
30−import GHC.OverloadedLabels
31−import GHC.TypeLits
32−import Prelude hiding (RealFrac(..), id, (.))
33−
34−import qualified Data.ByteString as ByteString
35−
36−import Squeel.PostgreSQL.Schema
37−
38−{-----------------------------------------
39−column expressions
40−-----------------------------------------}
41−
42−newtype Expression
43− (params :: [ColumnType])
44− (tables :: [(Symbol,[(Symbol,ColumnType)])])
45− (grouping :: Grouping)
46− (ty :: ColumnType)
47− = UnsafeExpression { renderExpression :: ByteString }
48− deriving (Show,Eq)
49−
50−class KnownNat n => HasParameter (n :: Nat) params ty | n params -> ty where
51− param :: Proxy# n -> Expression params tables grouping ty
52− param p = UnsafeExpression $ ("$" <>) $ fromString $ show $ natVal' p
53−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
54−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
55− => HasParameter n (ty' : params) ty
56−
57−param1 :: Expression (ty1:tys) tables grouping ty1
58−param1 = param (proxy# :: Proxy# 1)
59−param2 :: Expression (ty1:ty2:tys) tables grouping ty2
60−param2 = param (proxy# :: Proxy# 2)
61−param3 :: Expression (ty1:ty2:ty3:tys) tables grouping ty3
62−param3 = param (proxy# :: Proxy# 3)
63−param4 :: Expression (ty1:ty2:ty3:ty4:tys) tables grouping ty4
64−param4 = param (proxy# :: Proxy# 4)
65−param5 :: Expression (ty1:ty2:ty3:ty4:ty5:tys) tables grouping ty5
66−param5 = param (proxy# :: Proxy# 5)
67−
68−class KnownSymbol column => HasColumn column columns ty
69− | column columns -> ty where
70− getColumn
71− :: Proxy# column
72− -> Expression params '[table ::: columns] 'Ungrouped ty
73− getColumn column = UnsafeExpression $ fromString $ symbolVal' column
74−instance {-# OVERLAPPING #-} KnownSymbol column
75− => HasColumn column ((column ::: optionality ty) ': tys) ('Required ty)
76−instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
77− => HasColumn column (ty' ': table) ty
78−
79−instance (HasColumn column columns ty, tables ~ '[table ::: columns])
80− => IsLabel column (Expression params tables 'Ungrouped ty) where
81− fromLabel = getColumn
82−
83−def :: Expression params '[] grouping ('Optional (nullity ty))
84−def = UnsafeExpression "DEFAULT"
85−
86−notDef
87− :: Expression params '[] grouping ('Required (nullity ty))
88− -> Expression params '[] grouping ('Optional (nullity ty))
89−notDef = UnsafeExpression . renderExpression
90−
91−null :: Expression params tables grouping (optionality ('Null ty))
92−null = UnsafeExpression "NULL"
93−
94−coalesce
95− :: [Expression params tables grouping ('Required ('Null x))]
96− -> Expression params tables grouping ('Required ('NotNull x))
97− -> Expression params tables grouping ('Required ('NotNull x))
98−coalesce nulls isn'tNull = UnsafeExpression $ mconcat
99− [ "COALESCE("
100− , ByteString.intercalate ", " $ map renderExpression nulls
101− , ", ", renderExpression isn'tNull
102− , ")"
103− ]
104−
105−unsafeBinaryOp
106− :: ByteString
107− -> Expression params tables grouping ty0
108− -> Expression params tables grouping ty1
109− -> Expression params tables grouping ty2
110−unsafeBinaryOp op x y = UnsafeExpression $ mconcat
111− ["(", renderExpression x, " ", op, " ", renderExpression y, ")"]
112−
113−unsafeUnaryOp
114− :: ByteString
115− -> Expression params tables grouping ty0
116− -> Expression params tables grouping ty1
117−unsafeUnaryOp op x = UnsafeExpression $ mconcat
118− ["(", op, " ", renderExpression x, ")"]
119−
120−unsafeFunction
121− :: ByteString
122− -> Expression params tables grouping xty
123− -> Expression params tables grouping yty
124−unsafeFunction fun x = UnsafeExpression $ mconcat
125− [fun, "(", renderExpression x, ")"]
126−
127−instance PGNum ty
128− => Num (Expression params tables grouping ('Required (nullity ty))) where
129− (+) = unsafeBinaryOp "+"
130− (-) = unsafeBinaryOp "-"
131− (*) = unsafeBinaryOp "*"
132− abs = unsafeFunction "abs"
133− signum = unsafeFunction "sign"
134− fromInteger
135− = UnsafeExpression
136− . (<> if decimal (Proxy :: Proxy ty) then "." else "")
137− . fromString
138− . show
139−
140−instance PGFractional ty => Fractional
141− (Expression params tables grouping ('Required (nullity ty))) where
142− (/) = unsafeBinaryOp "/"
143− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
144−
145−instance (PGFloating ty, PGCast 'PGNumeric ty, PGTyped ty) => Floating
146− (Expression params tables grouping ('Required (nullity ty))) where
147− pi = UnsafeExpression "pi()"
148− exp = unsafeFunction "exp"
149− log = unsafeFunction "ln"
150− sqrt = unsafeFunction "sqrt"
151− b ** x = UnsafeExpression $
152− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
153− logBase b y = cast pgtype $ logBaseNumeric b y
154− where
155− logBaseNumeric
156− :: Expression params tables grouping ('Required (nullity ty))
157− -> Expression params tables grouping ('Required (nullity ty))
158− -> Expression params tables grouping ('Required (nullity 'PGNumeric))
159− logBaseNumeric b' y' = UnsafeExpression $ mconcat
160− [ "log("
161− , renderExpression b' <> "::numeric"
162− , ", "
163− , renderExpression y' <> "::numeric"
164− , ")"
165− ]
166− sin = unsafeFunction "sin"
167− cos = unsafeFunction "cos"
168− tan = unsafeFunction "tan"
169− asin = unsafeFunction "asin"
170− acos = unsafeFunction "acos"
171− atan = unsafeFunction "atan"
172− sinh x = (exp x - exp (-x)) / 2
173− cosh x = (exp x + exp (-x)) / 2
174− tanh x = sinh x / cosh x
175− asinh x = log (x + sqrt (x*x + 1))
176− acosh x = log (x + sqrt (x*x - 1))
177− atanh x = log ((1 + x) / (1 - x)) / 2
178−
179−atan2
180− :: PGFloating float
181− => Expression params tables grouping ('Required (nullity float))
182− -> Expression params tables grouping ('Required (nullity float))
183− -> Expression params tables grouping ('Required (nullity float))
184−atan2 y x = UnsafeExpression $
185− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
186−
187−class PGCast (ty0 :: PGType) (ty1 :: PGType) where
188− cast
189− :: TypeExpression ('Required ('Null ty1))
190− -> Expression params tables grouping ('Required (nullity ty0))
191− -> Expression params tables grouping ('Required (nullity ty1))
192− cast ty x = UnsafeExpression $
193− "(" <> renderExpression x <> "::" <> renderTypeExpression ty <> ")"
194−instance PGCast 'PGInt2 'PGInt2
195−instance PGCast 'PGInt2 'PGInt4
196−instance PGCast 'PGInt2 'PGInt8
197−instance PGCast 'PGInt4 'PGInt2
198−instance PGCast 'PGInt4 'PGInt4
199−instance PGCast 'PGInt4 'PGInt8
200−instance PGCast 'PGInt8 'PGInt2
201−instance PGCast 'PGInt8 'PGInt4
202−instance PGCast 'PGInt8 'PGInt8
203−instance PGCast 'PGInt8 'PGFloat4
204−instance PGCast 'PGInt8 'PGFloat8
205−instance PGCast 'PGInt8 'PGNumeric
206−
207−div
208− :: (PGNum ty, PGTyped ty, PGCast 'PGInt8 ty, PGCast ty 'PGInt8)
209− => Expression params tables grouping ('Required (nullity ty))
210− -> Expression params tables grouping ('Required (nullity ty))
211− -> Expression params tables grouping ('Required (nullity ty))
212−div = unsafeBinaryOp "/"
213−
214−mod
215− :: (PGNum ty, PGTyped ty, PGCast 'PGInt8 ty, PGCast ty 'PGInt8)
216− => Expression params tables grouping ('Required (nullity ty))
217− -> Expression params tables grouping ('Required (nullity ty))
218− -> Expression params tables grouping ('Required (nullity ty))
219−mod = unsafeBinaryOp "%"
220−
221−truncate
222− :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
223− => Expression params tables grouping ('Required (nullity frac))
224− -> Expression params tables grouping ('Required (nullity int))
225−truncate = cast pgtype . truncate'
226− where
227− truncate'
228− :: Expression params tables grouping ('Required (nullity frac))
229− -> Expression params tables grouping ('Required (nullity 'PGInt4))
230− truncate' = unsafeFunction "trunc"
231−
232−round
233− :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
234− => Expression params tables grouping ('Required (nullity frac))
235− -> Expression params tables grouping ('Required (nullity int))
236−round = cast pgtype . round'
237− where
238− round'
239− :: Expression params tables grouping ('Required (nullity frac))
240− -> Expression params tables grouping ('Required (nullity 'PGInt4))
241− round' = unsafeFunction "round"
242−
243−ceiling
244− :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
245− => Expression params tables grouping ('Required (nullity frac))
246− -> Expression params tables grouping ('Required (nullity int))
247−ceiling = cast pgtype . ceiling'
248− where
249− ceiling'
250− :: Expression params tables grouping ('Required (nullity frac))
251− -> Expression params tables grouping ('Required (nullity 'PGInt4))
252− ceiling' = unsafeFunction "ceiling"
253−
254−instance IsString
255− (Expression params tables grouping ('Required (nullity 'PGText))) where
256− fromString str = UnsafeExpression $
257− "E\'" <> fromString (escape =<< str) <> "\'"
258− where
259− escape = \case
260− '\NUL' -> "\\0"
261− '\'' -> "''"
262− '"' -> "\\\""
263− '\b' -> "\\b"
264− '\n' -> "\\n"
265− '\r' -> "\\r"
266− '\t' -> "\\t"
267− '\\' -> "\\\\"
268− c -> [c]
269−
270−type Condition params tables grouping =
271− Expression params tables grouping ('Required ('NotNull 'PGBool))
272−
273−true :: Condition params tables grouping
274−true = UnsafeExpression "TRUE"
275−
276−false :: Condition params tables grouping
277−false = UnsafeExpression "FALSE"
278−
279−not_
280− :: Condition params tables grouping
281− -> Condition params tables grouping
282−not_ = unsafeUnaryOp "NOT"
283−
284−(&&*)
285− :: Condition params tables grouping
286− -> Condition params tables grouping
287− -> Condition params tables grouping
288−(&&*) = unsafeBinaryOp "AND"
289−
290−(||*)
291− :: Condition params tables grouping
292− -> Condition params tables grouping
293− -> Condition params tables grouping
294−(||*) = unsafeBinaryOp "OR"
295−
296−caseWhenThenElse
297− :: [(Condition params tables grouping, Expression params tables grouping ty)]
298− -> Expression params tables grouping ty
299− -> Expression params tables grouping ty
300−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
301− [ "CASE"
302− , mconcat
303− [ mconcat
304− [ " WHEN ", renderExpression when_
305− , " THEN ", renderExpression then_
306− ]
307− | (when_,then_) <- whenThens
308− ]
309− , " ELSE ", renderExpression else_
310− , " END"
311− ]
312−
313−ifThenElse
314− :: Condition params tables grouping
315− -> Expression params tables grouping ty
316− -> Expression params tables grouping ty
317− -> Expression params tables grouping ty
318−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
319−
320−(==*)
321− :: Expression params tables grouping ('Required (nullity ty))
322− -> Expression params tables grouping ('Required (nullity ty))
323− -> Expression params tables grouping ('Required (nullity 'PGBool))
324−(==*) = unsafeBinaryOp "="
325−
326−(/=*)
327− :: Expression params tables grouping ('Required (nullity ty))
328− -> Expression params tables grouping ('Required (nullity ty))
329− -> Expression params tables grouping ('Required (nullity 'PGBool))
330−(/=*) = unsafeBinaryOp "<>"
331−
332−(>=*)
333− :: Expression params tables grouping ('Required (nullity ty))
334− -> Expression params tables grouping ('Required (nullity ty))
335− -> Expression params tables grouping ('Required (nullity 'PGBool))
336−(>=*) = unsafeBinaryOp ">="
337−
338−(<*)
339− :: Expression params tables grouping ('Required (nullity ty))
340− -> Expression params tables grouping ('Required (nullity ty))
341− -> Expression params tables grouping ('Required (nullity 'PGBool))
342−(<*) = unsafeBinaryOp "<"
343−
344−(<=*)
345− :: Expression params tables grouping ('Required (nullity ty))
346− -> Expression params tables grouping ('Required (nullity ty))
347− -> Expression params tables grouping ('Required (nullity 'PGBool))
348−(<=*) = unsafeBinaryOp "<="
349−
350−(>*)
351− :: Expression params tables grouping ('Required (nullity ty))
352− -> Expression params tables grouping ('Required (nullity ty))
353− -> Expression params tables grouping ('Required (nullity 'PGBool))
354−(>*) = unsafeBinaryOp ">"
355−
356−data SortExpression params tables grouping where
357− Asc
358− :: Expression params tables grouping ty
359− -> SortExpression params tables grouping
360− Desc
361− :: Expression params tables grouping ty
362− -> SortExpression params tables grouping
363−
364−renderSortExpression :: SortExpression params tables grouping -> ByteString
365−renderSortExpression = \case
366− Asc expression -> renderExpression expression <> " ASC"
367− Desc expression -> renderExpression expression <> " DESC"
368−
369−data Aggregate (ty0 :: ColumnType) (ty1 :: ColumnType) =
370− UnsafeAggregate { renderAggregate :: ByteString }
371−
372−sum_
373− :: PGNum ty
374− => Aggregate ('Required (nullity ty)) ('Required (nullity ty))
375−sum_ = UnsafeAggregate "sum"
376−
377−class (KnownSymbol table, KnownSymbol column)
378− => GroupedBy table column distincts ty where
379− getGroup
380− :: (HasTable table tables columns, HasColumn column columns ty)
381− => Alias table
382− -> Alias column
383− -> Expression params tables ('Grouped distincts) ty
384−
385−class (KnownSymbol table, KnownSymbol column)
386− => Aggregated table column distincts ty where
387− getAggregate
388− :: (HasTable table tables columns, HasColumn column columns ty0)
389− => Alias table
390− -> Alias column
391− -> Aggregate ty0 ty
392− -> Expression params tables ('Grouped distincts) ty
393−
394−class TableColumn table column expression where
395− (&.) :: Alias table -> Alias column -> expression
396−instance (HasTable table tables columns, HasColumn column columns ty)
397− => TableColumn table column (Expression params tables 'Ungrouped ty) where
398− table &. column = UnsafeExpression $
399− renderAlias table <> "." <> renderAlias column
400−instance (HasTable table tables columns, HasColumn column columns ty)
401− => TableColumn table column (By tables (table ::: (column ::: ty))) where
402− (&.) = By
403−instance
404− ( HasTable table tables columns
405− , HasColumn column columns ty
406− , GroupedBy table column distincts ty
407− ) => TableColumn table column
408− (Expression params tables ('Grouped distincts) ty) where
409− (&.) = getGroup
410−instance
411− ( HasTable table tables columns
412− , HasColumn column columns ty0
413− , Aggregated table column distincts ty
414− ) => TableColumn table column
415− (Aggregate ty0 ty -> Expression params tables ('Grouped distincts) ty) where
416− (&.) = getAggregate
417−
418−{-----------------------------------------
419−tables
420−-----------------------------------------}
421−
422−newtype Table
423− (schema :: [(Symbol,[(Symbol,ColumnType)])])
424− (columns :: [(Symbol,ColumnType)])
425− = UnsafeTable { renderTable :: ByteString }
426− deriving (Show,Eq)
427−
428−class KnownSymbol table => HasTable table tables columns
429− | table tables -> columns where
430− getTable :: Proxy# table -> Table tables columns
431− getTable table = UnsafeTable $ fromString $ symbolVal' table
432−instance {-# OVERLAPPING #-} KnownSymbol table
433− => HasTable table ((table ::: columns) ': tables) columns
434−instance {-# OVERLAPPABLE #-}
435− (KnownSymbol table, HasTable table schema columns)
436− => HasTable table (table' ': schema) columns
437−
438−instance HasTable table schema columns
439− => IsLabel table (Table schema columns) where
440− fromLabel = getTable
441−
442−data TableReference params schema tables where
443− Table
444− :: Aliased (Table schema) table
445− -> TableReference params schema '[table]
446− Subquery
447− :: Aliased (Query schema params) table
448− -> TableReference params schema '[table]
449− CrossJoin
450− :: TableReference params schema right
451− -> TableReference params schema left
452− -> TableReference params schema (Join left right)
453− InnerJoin
454− :: TableReference params schema right
455− -> Condition params (Join left right) 'Ungrouped
456− -> TableReference params schema left
457− -> TableReference params schema (Join left right)
458− LeftOuterJoin
459− :: TableReference params schema right
460− -> Condition params (Join left right) 'Ungrouped
461− -> TableReference params schema left
462− -> TableReference params schema (Join left (NullifyTables right))
463− RightOuterJoin
464− :: TableReference params schema right
465− -> Condition params (Join left right) 'Ungrouped
466− -> TableReference params schema left
467− -> TableReference params schema (Join (NullifyTables left) right)
468− FullOuterJoin
469− :: TableReference params schema right
470− -> Condition params (Join left right) 'Ungrouped
471− -> TableReference params schema left
472− -> TableReference params schema
473− (Join (NullifyTables left) (NullifyTables right))
474−
475−renderTableReference :: TableReference params schema tables -> ByteString
476−renderTableReference = \case
477− Table table -> renderAliased renderTable table
478− Subquery selection -> renderAliased renderQuery selection
479− CrossJoin right left -> mconcat
480− [ renderTableReference left
481− , " CROSS JOIN "
482− , renderTableReference right
483− ]
484− InnerJoin right on left -> mconcat
485− [ renderTableReference left
486− , " INNER JOIN "
487− , renderTableReference right
488− , " ON "
489− , renderExpression on
490− ]
491− LeftOuterJoin right on left -> mconcat
492− [ renderTableReference left
493− , " LEFT OUTER JOIN "
494− , renderTableReference right
495− , " ON "
496− , renderExpression on
497− ]
498− RightOuterJoin right on left -> mconcat
499− [ renderTableReference left
500− , " RIGHT OUTER JOIN "
501− , renderTableReference right
502− , " ON "
503− , renderExpression on
504− ]
505− FullOuterJoin right on left -> mconcat
506− [ renderTableReference left
507− , " FULL OUTER JOIN "
508− , renderTableReference right
509− , " ON "
510− , renderExpression on
511− ]
512−
513−data By tables tabcolty where
514− By
515− :: (HasTable table tables columns, HasColumn column columns ty)
516− => Alias table
517− -> Alias column
518− -> By tables (table ::: (column ::: ty))
519−
520−renderBy :: By tables tabcolty -> ByteString
521−renderBy (By table column) = renderAlias table <> "." <> renderAlias column
522−
523−data GroupByClause tables grouping where
524− NoGroups :: GroupByClause tables 'Ungrouped
525− Distinct
526− :: SListI distincts
527− => NP (By tables) distincts
528− -> GroupByClause tables ('Grouped distincts)
529−
530−renderGroupByClause :: GroupByClause tables grouping -> ByteString
531−renderGroupByClause = \case
532− NoGroups -> ""
533− Distinct Nil -> ""
534− Distinct distincts -> " GROUP BY " <> ByteString.intercalate ", "
535− (hcollapse (hmap (K . renderBy) distincts))
536−
537−data HavingClause params tables grouping where
538− NoHaving :: HavingClause params tables 'Ungrouped
539− Having
540− :: [Condition params tables ('Grouped distincts)]
541− -> HavingClause params tables ('Grouped distincts)
542−
543−renderHavingClause :: HavingClause params tables grouping -> ByteString
544−renderHavingClause = \case
545− NoHaving -> ""
546− Having [] -> ""
547− Having conditions -> " HAVING " <> ByteString.intercalate ", "
548− (renderExpression <$> conditions)
549−
550−data TableExpression
551− (params :: [ColumnType])
552− (schema :: [(Symbol,[(Symbol,ColumnType)])])
553− (tables :: [(Symbol,[(Symbol,ColumnType)])])
554− (grouping :: Grouping)
555− = TableExpression
556− { fromClause :: TableReference params schema tables
557− , whereClause :: [Condition params tables 'Ungrouped]
558− , groupByClause :: GroupByClause tables grouping
559− , havingClause :: HavingClause params tables grouping
560− , orderByClause :: [SortExpression params tables grouping]
561− , limitClause :: [Word64]
562− , offsetClause :: [Word64]
563− }
564−
565−renderTableExpression
566− :: TableExpression params schema tables grouping
567− -> ByteString
568−renderTableExpression
569− (TableExpression tables whs' grps' hvs' srts' lims' offs') = mconcat
570− [ "FROM ", renderTableReference tables
571− , renderWheres whs'
572− , renderGroupByClause grps'
573− , renderHavingClause hvs'
574− , renderSorts srts'
575− , renderLimits lims'
576− , renderOffsets offs'
577− ]
578− where
579− renderWheres = \case
580− [] -> ""
581− wh:[] -> " WHERE " <> renderExpression wh
582− wh:whs -> " WHERE " <> renderExpression (foldr (&&*) wh whs)
583− renderSorts = \case
584− [] -> ""
585− srts -> " SORT BY "
586− <> ByteString.intercalate ", " (renderSortExpression <$> srts)
587− renderLimits = \case
588− [] -> ""
589− lims -> " LIMIT " <> fromString (show (minimum lims))
590− renderOffsets = \case
591− [] -> ""
592− offs -> " OFFSET " <> fromString (show (sum offs))
593−
594−from
595− :: TableReference params schema tables
596− -> TableExpression params schema tables 'Ungrouped
597−from tables = TableExpression tables [] NoGroups NoHaving [] [] []
598−
599−where_
600− :: Condition params tables 'Ungrouped
601− -> TableExpression params schema tables grouping
602− -> TableExpression params schema tables grouping
603−where_ wh tables = tables {whereClause = wh : whereClause tables}
604−
605−group
606− :: SListI distincts
607− => NP (By tables) distincts
608− -> TableExpression params schema tables 'Ungrouped
609− -> TableExpression params schema tables ('Grouped distincts)
610−group distincts tables = TableExpression
611− { fromClause = fromClause tables
612− , whereClause = whereClause tables
613− , groupByClause = Distinct distincts
614− , havingClause = Having []
615− , orderByClause = []
616− , limitClause = limitClause tables
617− , offsetClause = offsetClause tables
618− }
619−
620−having
621− :: Condition params tables ('Grouped distincts)
622− -> TableExpression params schema tables ('Grouped distincts)
623− -> TableExpression params schema tables ('Grouped distincts)
624−having hv tables = tables
625− { havingClause = case havingClause tables of Having hvs -> Having (hv:hvs) }
626−
627−orderBy
628− :: [SortExpression params tables grouping]
629− -> TableExpression params schema tables grouping
630− -> TableExpression params schema tables grouping
631−orderBy srts tables = tables {orderByClause = orderByClause tables ++ srts}
632−
633−limit
634− :: Word64
635− -> TableExpression params schema tables grouping
636− -> TableExpression params schema tables grouping
637−limit lim tables = tables {limitClause = lim : limitClause tables}
638−
639−offset
640− :: Word64
641− -> TableExpression params schema tables grouping
642− -> TableExpression params schema tables grouping
643−offset off tables = tables {offsetClause = off : offsetClause tables}
644−
645−{-----------------------------------------
646−type expressions
647−-----------------------------------------}
648−
649−newtype TypeExpression (ty :: ColumnType)
650− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
651− deriving (Show,Eq)
652−
653−bool :: TypeExpression ('Required ('Null 'PGBool))
654−bool = UnsafeTypeExpression "bool"
655−int2 :: TypeExpression ('Required ('Null 'PGInt2))
656−int2 = UnsafeTypeExpression "int2"
657−smallint :: TypeExpression ('Required ('Null 'PGInt2))
658−smallint = UnsafeTypeExpression "smallint"
659−int4 :: TypeExpression ('Required ('Null 'PGInt4))
660−int4 = UnsafeTypeExpression "int4"
661−int :: TypeExpression ('Required ('Null 'PGInt4))
662−int = UnsafeTypeExpression "int"
663−integer :: TypeExpression ('Required ('Null 'PGInt4))
664−integer = UnsafeTypeExpression "integer"
665−int8 :: TypeExpression ('Required ('Null 'PGInt8))
666−int8 = UnsafeTypeExpression "int8"
667−bigint :: TypeExpression ('Required ('Null 'PGInt8))
668−bigint = UnsafeTypeExpression "bigint"
669−numeric :: TypeExpression ('Required ('Null 'PGNumeric))
670−numeric = UnsafeTypeExpression "numeric"
671−float4 :: TypeExpression ('Required ('Null 'PGFloat4))
672−float4 = UnsafeTypeExpression "float4"
673−real :: TypeExpression ('Required ('Null 'PGFloat4))
674−real = UnsafeTypeExpression "real"
675−float8 :: TypeExpression ('Required ('Null 'PGFloat8))
676−float8 = UnsafeTypeExpression "float8"
677−doublePrecision :: TypeExpression ('Required ('Null 'PGFloat8))
678−doublePrecision = UnsafeTypeExpression "double precision"
679−serial2 :: TypeExpression ('Optional ('NotNull 'PGInt2))
680−serial2 = UnsafeTypeExpression "serial2"
681−smallserial :: TypeExpression ('Optional ('NotNull 'PGInt2))
682−smallserial = UnsafeTypeExpression "smallserial"
683−serial4 :: TypeExpression ('Optional ('NotNull 'PGInt4))
684−serial4 = UnsafeTypeExpression "serial4"
685−serial :: TypeExpression ('Optional ('NotNull 'PGInt4))
686−serial = UnsafeTypeExpression "serial"
687−serial8 :: TypeExpression ('Optional ('NotNull 'PGInt8))
688−serial8 = UnsafeTypeExpression "serial8"
689−bigserial :: TypeExpression ('Optional ('NotNull 'PGInt8))
690−bigserial = UnsafeTypeExpression "bigserial"
691−money :: TypeExpression ('Required ('Null 'PGMoney))
692−money = UnsafeTypeExpression "money"
693−text :: TypeExpression ('Required ('Null 'PGText))
694−text = UnsafeTypeExpression "text"
695−char
696− :: KnownNat n
697− => proxy n
698− -> TypeExpression ('Required ('Null ('PGChar n)))
699−char (_ :: proxy n) = UnsafeTypeExpression $
700− "char(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
701−character
702− :: KnownNat n
703− => proxy n
704− -> TypeExpression ('Required ('Null ('PGChar n)))
705−character (_ :: proxy n) = UnsafeTypeExpression $
706− "character(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
707−varchar
708− :: KnownNat n
709− => proxy n
710− -> TypeExpression ('Required ('Null ('PGVarChar n)))
711−varchar (_ :: proxy n) = UnsafeTypeExpression $
712− "varchar(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
713−characterVarying
714− :: KnownNat n
715− => proxy n
716− -> TypeExpression ('Required ('Null ('PGVarChar n)))
717−characterVarying (_ :: proxy n) = UnsafeTypeExpression $
718− "character varying(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
719−bytea :: TypeExpression ('Required ('Null ('PGBytea)))
720−bytea = UnsafeTypeExpression "bytea"
721−timestamp :: TypeExpression ('Required ('Null ('PGTimestamp)))
722−timestamp = UnsafeTypeExpression "timestamp"
723−timestampWithTimeZone :: TypeExpression ('Required ('Null ('PGTimestampTZ)))
724−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
725−date :: TypeExpression ('Required ('Null ('PGDate)))
726−date = UnsafeTypeExpression "date"
727−time :: TypeExpression ('Required ('Null ('PGTime)))
728−time = UnsafeTypeExpression "time"
729−timeWithTimeZone :: TypeExpression ('Required ('Null ('PGTimeTZ)))
730−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
731−interval :: TypeExpression ('Required ('Null ('PGInterval)))
732−interval = UnsafeTypeExpression "interval"
733−uuid :: TypeExpression ('Required ('Null ('PGUuid)))
734−uuid = UnsafeTypeExpression "uuid"
735−json :: TypeExpression ('Required ('Null ('PGJson)))
736−json = UnsafeTypeExpression "json"
737−jsonb :: TypeExpression ('Required ('Null ('PGJsonb)))
738−jsonb = UnsafeTypeExpression "jsonb"
739−
740−notNull
741− :: TypeExpression ('Required ('Null ty))
742− -> TypeExpression ('Required ('NotNull ty))
743−notNull ty = UnsafeTypeExpression $ renderTypeExpression ty <> " NOT NULL"
744−default_
745− :: Expression '[] '[] 'Ungrouped ('Required ty)
746− -> TypeExpression ('Required ty)
747− -> TypeExpression ('Optional ty)
748−default_ x ty = UnsafeTypeExpression $
749− renderTypeExpression ty <> " DEFAULT " <> renderExpression x
750−
751−class PGTyped (ty :: PGType) where
752− pgtype :: TypeExpression ('Required ('Null ty))
753−instance PGTyped 'PGBool where pgtype = bool
754−instance PGTyped 'PGInt2 where pgtype = int2
755−instance PGTyped 'PGInt4 where pgtype = int4
756−instance PGTyped 'PGInt8 where pgtype = int8
757−instance PGTyped 'PGNumeric where pgtype = numeric
758−instance PGTyped 'PGFloat4 where pgtype = float4
759−instance PGTyped 'PGFloat8 where pgtype = float8
760−instance PGTyped 'PGMoney where pgtype = money
761−instance PGTyped 'PGText where pgtype = text
762−instance KnownNat n => PGTyped ('PGChar n) where pgtype = char (Proxy @n)
763−instance KnownNat n => PGTyped ('PGVarChar n) where pgtype = varchar (Proxy @n)
764−instance PGTyped 'PGBytea where pgtype = bytea
765−instance PGTyped 'PGTimestamp where pgtype = timestamp
766−instance PGTyped 'PGTimestampTZ where pgtype = timestampWithTimeZone
767−instance PGTyped 'PGDate where pgtype = date
768−instance PGTyped 'PGTime where pgtype = time
769−instance PGTyped 'PGTimeTZ where pgtype = timeWithTimeZone
770−instance PGTyped 'PGInterval where pgtype = interval
771−instance PGTyped 'PGUuid where pgtype = uuid
772−instance PGTyped 'PGJson where pgtype = json
773−instance PGTyped 'PGJsonb where pgtype = jsonb
774−
775−{-----------------------------------------
776−statements
777−-----------------------------------------}
778−
779−newtype Definition
780− (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
781− (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
782− = UnsafeDefinition { renderDefinition :: ByteString }
783−
784−instance Category Definition where
785− id = UnsafeDefinition ";"
786− dd1 . dd0 = UnsafeDefinition $
787− renderDefinition dd0 <> " " <> renderDefinition dd1
788−
789−newtype Manipulation
790− (schema :: [(Symbol,[(Symbol,ColumnType)])])
791− (params :: [ColumnType])
792− (columns :: [(Symbol,ColumnType)])
793− = UnsafeManipulation { renderManipulation :: ByteString }
794−
795−newtype Query
796− (schema :: [(Symbol,[(Symbol,ColumnType)])])
797− (params :: [ColumnType])
798− (columns :: [(Symbol,ColumnType)])
799− = UnsafeQuery { renderQuery :: ByteString }
800−
801−query
802− :: Query schema params columns
803− -> Manipulation schema params columns
804−query q = UnsafeManipulation $ renderQuery q <> ";"
805−
806−union, unionAll, intersect, intersectAll, except, exceptAll
807− :: Query schema params columns
808− -> Query schema params columns
809− -> Query schema params columns
810−q1 `union` q2 = UnsafeQuery $
811− renderQuery q1 <> " UNION " <> renderQuery q2
812−q1 `unionAll` q2 = UnsafeQuery $
813− renderQuery q1 <> " UNION ALL " <> renderQuery q2
814−q1 `intersect` q2 = UnsafeQuery $
815− renderQuery q1 <> " INTERSECT " <> renderQuery q2
816−q1 `intersectAll` q2 = UnsafeQuery $
817− renderQuery q1 <> " INTERSECT ALL " <> renderQuery q2
818−q1 `except` q2 = UnsafeQuery $
819− renderQuery q1 <> " EXCEPT " <> renderQuery q2
820−q1 `exceptAll` q2 = UnsafeQuery $
821− renderQuery q1 <> " EXCEPT ALL " <> renderQuery q2
822−
823−{-----------------------------------------
824−SELECT statements
825−-----------------------------------------}
826−
827−select
828− :: SListI columns
829− => NP (Aliased (Expression params tables grouping)) columns
830− -> TableExpression params schema tables grouping
831− -> Query schema params columns
832−select list tabs = UnsafeQuery $
833− "SELECT " <> renderList list <> " " <> renderTableExpression tabs
834− where
835− renderList
836− = ByteString.intercalate ", "
837− . hcollapse
838− . hmap (K . renderAliased renderExpression)
839−
840−selectStar
841− :: (tables ~ '[table ::: columns])
842− => TableExpression params schema tables 'Ungrouped
843− -> Query schema params columns
844−selectStar tabs = UnsafeQuery $ "SELECT * " <> renderTableExpression tabs
845−
846−selectDotStar
847− :: HasTable table tables columns
848− => Alias table
849− -> TableExpression params schema tables 'Ungrouped
850− -> Query schema params columns
851−selectDotStar table tables = UnsafeQuery $
852− "SELECT " <> renderAlias table <> ".* " <> renderTableExpression tables
853−
854−{-----------------------------------------
855−CREATE statements
856−-----------------------------------------}
857−
858−createTable
859− :: (KnownSymbol table, SListI columns)
860− => Alias table
861− -> NP (Aliased TypeExpression) columns
862− -> Definition schema (Create table columns schema)
863−createTable table columns = UnsafeDefinition $ mconcat
864− [ "CREATE TABLE "
865− , renderAlias table
866− , " ("
867− , ByteString.intercalate ", " . hcollapse $
868− hmap (K . renderColumn) columns
869− , ");"
870− ]
871− where
872− renderColumn :: Aliased TypeExpression x -> ByteString
873− renderColumn (ty `As` column) =
874− renderAlias column <> " " <> renderTypeExpression ty
875−
876−{-----------------------------------------
877−DROP statements
878−-----------------------------------------}
879−
880−dropTable
881− :: KnownSymbol table
882− => Alias table
883− -> Definition schema (Drop table schema)
884−dropTable table = UnsafeDefinition $ "DROP TABLE " <> renderAlias table <> ";"
885−
886−{-----------------------------------------
887−ALTER statements
888−-----------------------------------------}
889−
890−alterTable
891− :: HasTable table schema columns0
892− => Alias table
893− -> AlterTable columns0 columns1
894− -> Definition schema (Alter table schema columns1)
895−alterTable table alteration = UnsafeDefinition $
896− "ALTER TABLE "
897− <> renderAlias table
898− <> " "
899− <> renderAlterTable alteration
900− <> ";"
901−
902−alterTableRename
903− :: (KnownSymbol table0, KnownSymbol table1)
904− => Alias table0
905− -> Alias table1
906− -> Definition schema (Rename table0 table1 schema)
907−alterTableRename table0 table1 = UnsafeDefinition $
908− "ALTER TABLE "
909− <> renderAlias table0
910− <> " RENAME TO "
911− <> renderAlias table1
912− <> ";"
913−
914−data AlterTable
915− (columns0 :: [(Symbol, ColumnType)])
916− (columns1 :: [(Symbol, ColumnType)]) =
917− UnsafeAlterTable {renderAlterTable :: ByteString}
918−
919−addColumnDefault
920− :: KnownSymbol column
921− => Alias column
922− -> TypeExpression ('Optional ty)
923− -> AlterTable columns (Create column ('Optional ty) columns)
924−addColumnDefault column ty = UnsafeAlterTable $
925− "ADD COLUMN "
926− <> renderAlias column
927− <> " "
928− <> renderTypeExpression ty
929−
930−addColumnNull
931− :: KnownSymbol column
932− => Alias column
933− -> TypeExpression ('Required ('Null ty))
934− -> AlterTable columns ((column ::: 'Required ('Null ty)) ': columns)
935−addColumnNull column ty = UnsafeAlterTable $
936− "ADD COLUMN "
937− <> renderAlias column
938− <> " "
939− <> renderTypeExpression ty
940−
941−dropColumn
942− :: KnownSymbol column
943− => Alias column
944− -> AlterTable columns (Drop column columns)
945−dropColumn column = UnsafeAlterTable $
946− "DROP COLUMN " <> renderAlias column
947−
948−renameColumn
949− :: (KnownSymbol column0, KnownSymbol column1)
950− => Alias column0
951− -> Alias column1
952− -> AlterTable columns (Rename column0 column1 columns)
953−renameColumn column0 column1 = UnsafeAlterTable $
954− "RENAME COLUMN " <> renderAlias column0
955− <> " TO " <> renderAlias column1
956−
957−alterColumn
958− :: (KnownSymbol column, HasColumn column columns ty0)
959− => Alias column
960− -> AlterColumn ty0 ty1
961− -> AlterTable columns (Alter column columns ty1)
962−alterColumn column alteration = UnsafeAlterTable $
963− "ALTER COLUMN " <> renderAlias column
964− <> " " <> renderAlterColumn alteration
965−
966−data AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
967− UnsafeAlterColumn {renderAlterColumn :: ByteString}
968−
969−setDefault
970− :: Expression '[] '[] 'Ungrouped ('Required ty)
971− -> AlterColumn ('Required ty) ('Optional ty)
972−setDefault expression = UnsafeAlterColumn $
973− "SET DEFAULT " <> renderExpression expression
974−
975−dropDefault :: AlterColumn ('Optional ty) ('Required ty)
976−dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
977−
978−setNotNull
979− :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
980−setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
981−
982−dropNotNull
983− :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
984−dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
985−
986−alterType
987− :: PGCast ty0 ty1
988− => TypeExpression (optionality (nullity ty1))
989− -> AlterColumn (optionality (nullity ty0)) (optionality (nullity ty1))
990−alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty
991−
992−{-----------------------------------------
993−INSERT statements
994−-----------------------------------------}
995−
996−insertInto
997− :: (SListI columns, HasTable table schema columns)
998− => Alias table
999− -> NP (Aliased (Expression params '[] 'Ungrouped)) columns
1000− -> Manipulation schema params '[]
1001−insertInto table expressions = UnsafeManipulation $ "INSERT INTO "
1002− <> renderAlias table
1003− <> " (" <> ByteString.intercalate ", " aliases
1004− <> ") VALUES ("
1005− <> ByteString.intercalate ", " values
1006− <> ");"
1007− where
1008− aliases = hcollapse $ hmap
1009− (\ (_ `As` name) -> K (renderAlias name))
1010− expressions
1011− values = hcollapse $ hmap
1012− (\ (expression `As` _) -> K (renderExpression expression))
1013− expressions
1014−
1015−insertIntoReturning
1016− :: (SListI columns, SListI results, HasTable table schema columns)
1017− => Alias table
1018− -> NP (Aliased (Expression params '[] 'Ungrouped)) columns
1019− -> NP (Aliased (Expression params '[table ::: columns] 'Ungrouped)) results
1020− -> Manipulation schema params results
1021−insertIntoReturning table inserts results
1022− = UnsafeManipulation . mconcat $
1023− [ "INSERT INTO "
1024− , renderAlias table
1025− , " (" <> ByteString.intercalate ", " aliases
1026− , ") VALUES ("
1027− , ByteString.intercalate ", " values
1028− , ") RETURNING "
1029− , renderList results
1030− , ";"
1031− ]
1032− where
1033− aliases = hcollapse $ hmap
1034− (\ (_ `As` name) -> K (renderAlias name))
1035− inserts
1036− values = hcollapse $ hmap
1037− (\ (expression `As` _) -> K (renderExpression expression))
1038− inserts
1039− renderList
1040− = ByteString.intercalate ", "
1041− . hcollapse
1042− . hmap (K . renderAliased renderExpression)
1043−
1044−{-----------------------------------------
1045−UPDATE statements
1046−-----------------------------------------}
1047−
1048−data UpdateExpression params table ty
1049− = Same
1050− | Set (Expression params table 'Ungrouped ty)
1051−
1052−renderUpdateExpression
1053− :: Aliased (UpdateExpression params '[table ::: columns]) column
1054− -> Maybe ByteString
1055−renderUpdateExpression = \case
1056− Same `As` _ -> Nothing
1057− Set expression `As` column -> Just $ mconcat
1058− [ renderAlias column
1059− , " = "
1060− , renderExpression expression
1061− ]
1062−
1063−update
1064− :: (HasTable table schema columns, SListI columns)
1065− => Alias table
1066− -> NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1067− -> Condition params '[table ::: columns] 'Ungrouped
1068− -> Manipulation schema params '[]
1069−update table columns wh = UnsafeManipulation $ mconcat
1070− [ "UPDATE "
1071− , renderAlias table
1072− , " SET "
1073− , ByteString.intercalate ", " . catMaybes . hcollapse $
1074− hmap (K . renderUpdateExpression) columns
1075− , " WHERE ", renderExpression wh, ";"
1076− ]
1077−
1078−updateReturning
1079− :: (SListI columns, SListI results, HasTable table schema columns)
1080− => Alias table
1081− -> NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1082− -> Condition params '[table ::: columns] 'Ungrouped
1083− -> NP (Aliased (Expression params '[table ::: columns] 'Ungrouped)) results
1084− -> Manipulation schema params results
1085−updateReturning table updates wh results = UnsafeManipulation $ mconcat
1086− [ "UPDATE "
1087− , renderAlias table
1088− , " SET "
1089− , ByteString.intercalate ", " . catMaybes . hcollapse $
1090− hmap (K . renderUpdateExpression) updates
1091− , " WHERE ", renderExpression wh
1092− , " RETURNING ", renderList results
1093− , ";"
1094− ]
1095− where
1096− renderList
1097− = ByteString.intercalate ", "
1098− . hcollapse
1099− . hmap (K . renderAliased renderExpression)
1100−
1101−upsertInto
1102− :: (SListI columns, HasTable table schema columns)
1103− => Alias table
1104− -> NP (Aliased (Expression params '[] 'Ungrouped)) columns
1105− -> NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1106− -> Condition params '[table ::: columns] 'Ungrouped
1107− -> Manipulation schema params '[]
1108−upsertInto table inserts updates wh = UnsafeManipulation . mconcat $
1109− [ "INSERT INTO "
1110− , renderAlias table
1111− , " (" <> ByteString.intercalate ", " aliases
1112− , ") VALUES ("
1113− , ByteString.intercalate ", " values
1114− , ") ON CONFLICT UPDATE "
1115− , renderAlias table
1116− , " SET "
1117− , ByteString.intercalate ", " . catMaybes . hcollapse $
1118− hmap (K . renderUpdateExpression) updates
1119− , " WHERE ", renderExpression wh, ";"
1120− ] where
1121− aliases = hcollapse $ hmap
1122− (\ (_ `As` name) -> K (renderAlias name))
1123− inserts
1124− values = hcollapse $ hmap
1125− (\ (expression `As` _) -> K (renderExpression expression))
1126− inserts
1127−
1128−upsertIntoReturning
1129− :: (SListI columns, SListI results, HasTable table schema columns)
1130− => Alias table
1131− -> NP (Aliased (Expression params '[] 'Ungrouped)) columns
1132− -> NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1133− -> Condition params '[table ::: columns] 'Ungrouped
1134− -> NP (Aliased (Expression params '[table ::: columns] 'Ungrouped)) results
1135− -> Manipulation schema params results
1136−upsertIntoReturning table inserts updates wh results =
1137− UnsafeManipulation . mconcat $
1138− [ "INSERT INTO "
1139− , renderAlias table
1140− , " (" <> ByteString.intercalate ", " aliases
1141− , ") VALUES ("
1142− , ByteString.intercalate ", " values
1143− , ") ON CONFLICT UPDATE "
1144− , renderAlias table
1145− , " SET "
1146− , ByteString.intercalate ", " . catMaybes . hcollapse $
1147− hmap (K . renderUpdateExpression) updates
1148− , " WHERE ", renderExpression wh
1149− , " RETURNING ", renderList results
1150− , ";"
1151− ] where
1152− aliases = hcollapse $ hmap
1153− (\ (_ `As` name) -> K (renderAlias name))
1154− inserts
1155− values = hcollapse $ hmap
1156− (\ (expression `As` _) -> K (renderExpression expression))
1157− inserts
1158− renderList
1159− = ByteString.intercalate ", "
1160− . hcollapse
1161− . hmap (K . renderAliased renderExpression)
1162−
1163−{-----------------------------------------
1164−DELETE statements
1165−-----------------------------------------}
1166−
1167−deleteFrom
1168− :: HasTable table schema columns
1169− => Alias table
1170− -> Condition params '[table ::: columns] 'Ungrouped
1171− -> Manipulation schema params '[]
1172−deleteFrom table wh = UnsafeManipulation $ mconcat
1173− [ "DELETE FROM "
1174− , renderAlias table
1175− , " WHERE ", renderExpression wh, ";"
1176− ]