@@ -1,1194 +0,0 @@
1−{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
6− , FunctionalDependencies
13− , ScopedTypeVariables
17− , UndecidableInstances
20−module Squeel.PostgreSQL.Statement where
22−import Control.Category
23−import Data.ByteString (ByteString)
32−import GHC.OverloadedLabels
34−import Prelude hiding (RealFrac(..), id, (.))
36−import qualified Data.ByteString as ByteString
38−import Squeel.PostgreSQL.Schema
40−{-----------------------------------------
42−-----------------------------------------}
45− (params :: [ColumnType])
46− (tables :: [(Symbol,[(Symbol,ColumnType)])])
47− (grouping :: Grouping)
49− = UnsafeExpression { renderExpression :: ByteString }
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
63−class KnownSymbol column => HasColumn column columns ty
64− | column columns -> ty where
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
74−instance (HasColumn column columns ty, tables ~ '[table ::: columns])
75− => IsLabel column (Expression params tables 'Ungrouped ty) where
76− fromLabel = getColumn
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
83−def :: Expression params '[] grouping ('Optional (nullity ty))
84−def = UnsafeExpression "DEFAULT"
87− :: Expression params '[] grouping ('Required (nullity ty))
88− -> Expression params '[] grouping ('Optional (nullity ty))
89−unDef = UnsafeExpression . renderExpression
91−null :: Expression params tables grouping (optionality ('Null ty))
92−null = UnsafeExpression "NULL"
95− :: Expression params tables grouping (optionality ('NotNull ty))
96− -> Expression params tables grouping (optionality ('Null ty))
97−unNull = UnsafeExpression . renderExpression
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]))
109− -> Expression params tables grouping ty0
110− -> Expression params tables grouping ty1
111− -> Expression params tables grouping ty2
112−unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
113− renderExpression x <+> op <+> renderExpression y
117− -> Expression params tables grouping ty0
118− -> Expression params tables grouping ty1
119−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
120− op <+> renderExpression x
124− -> Expression params tables grouping xty
125− -> Expression params tables grouping yty
126−unsafeFunction fun x = UnsafeExpression $
127− fun <> parenthesized (renderExpression x)
130− => Num (Expression params tables grouping ('Required (nullity ty))) where
131− (+) = unsafeBinaryOp "+"
132− (-) = unsafeBinaryOp "-"
133− (*) = unsafeBinaryOp "*"
134− abs = unsafeFunction "abs"
135− signum = unsafeFunction "sign"
138− . (<> if decimal (Proxy :: Proxy ty) then "." else "")
142−instance PGFloating ty => Fractional
143− (Expression params tables grouping ('Required (nullity ty))) where
144− (/) = unsafeBinaryOp "/"
145− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
147−instance (PGFloating ty, PGTyped ty) => Floating
148− (Expression params tables grouping ('Required (nullity ty))) where
149− pi = UnsafeExpression "pi()"
150− exp = unsafeFunction "exp"
151− log = unsafeFunction "ln"
152− sqrt = unsafeFunction "sqrt"
153− b ** x = UnsafeExpression $
154− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
155− logBase b y = cast pgtype $ logBaseNumeric b y
158− :: Expression params tables grouping ('Required (nullity ty))
159− -> Expression params tables grouping ('Required (nullity ty))
160− -> Expression params tables grouping ('Required (nullity 'PGnumeric))
161− logBaseNumeric b' y' = UnsafeExpression $ mconcat
163− , renderExpression (cast numeric b')
165− , renderExpression (cast numeric y')
168− sin = unsafeFunction "sin"
169− cos = unsafeFunction "cos"
170− tan = unsafeFunction "tan"
171− asin = unsafeFunction "asin"
172− acos = unsafeFunction "acos"
173− atan = unsafeFunction "atan"
174− sinh x = (exp x - exp (-x)) / 2
175− cosh x = (exp x + exp (-x)) / 2
176− tanh x = sinh x / cosh x
177− asinh x = log (x + sqrt (x*x + 1))
178− acosh x = log (x + sqrt (x*x - 1))
179− atanh x = log ((1 + x) / (1 - x)) / 2
183− => Expression params tables grouping ('Required (nullity float))
184− -> Expression params tables grouping ('Required (nullity float))
185− -> Expression params tables grouping ('Required (nullity float))
186−atan2 y x = UnsafeExpression $
187− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
190− :: TypeExpression ('Required ('Null ty1))
191− -> Expression params tables grouping ('Required (nullity ty0))
192− -> Expression params tables grouping ('Required (nullity ty1))
193−cast ty x = UnsafeExpression $
194− "(" <> renderExpression x <+> "::" <+> renderTypeExpression ty <> ")"
198− => Expression params tables grouping ('Required (nullity ty))
199− -> Expression params tables grouping ('Required (nullity ty))
200− -> Expression params tables grouping ('Required (nullity ty))
201−div = unsafeBinaryOp "/"
205− => Expression params tables grouping ('Required (nullity ty))
206− -> Expression params tables grouping ('Required (nullity ty))
207− -> Expression params tables grouping ('Required (nullity ty))
208−mod = unsafeBinaryOp "%"
211− :: (PGFloating frac, PGTyped int)
212− => Expression params tables grouping ('Required (nullity frac))
213− -> Expression params tables grouping ('Required (nullity int))
214−truncate = cast pgtype . truncate'
217− :: Expression params tables grouping ('Required (nullity frac))
218− -> Expression params tables grouping ('Required (nullity frac))
219− truncate' = unsafeFunction "trunc"
222− :: (PGFloating frac, PGTyped int)
223− => Expression params tables grouping ('Required (nullity frac))
224− -> Expression params tables grouping ('Required (nullity int))
225−round = cast pgtype . round'
228− :: Expression params tables grouping ('Required (nullity frac))
229− -> Expression params tables grouping ('Required (nullity frac))
230− round' = unsafeFunction "round"
233− :: (PGFloating frac, PGTyped int)
234− => Expression params tables grouping ('Required (nullity frac))
235− -> Expression params tables grouping ('Required (nullity int))
236−ceiling = cast pgtype . ceiling'
239− :: Expression params tables grouping ('Required (nullity frac))
240− -> Expression params tables grouping ('Required (nullity frac))
241− ceiling' = unsafeFunction "ceiling"
244− (Expression params tables grouping ('Required (nullity 'PGtext))) where
245− fromString str = UnsafeExpression $
246− "E\'" <> fromString (escape =<< str) <> "\'"
259−type Condition params tables grouping =
260− Expression params tables grouping ('Required ('NotNull 'PGbool))
262−true :: Condition params tables grouping
263−true = UnsafeExpression "TRUE"
265−false :: Condition params tables grouping
266−false = UnsafeExpression "FALSE"
269− :: Condition params tables grouping
270− -> Condition params tables grouping
271−not_ = unsafeUnaryOp "NOT"
274− :: Condition params tables grouping
275− -> Condition params tables grouping
276− -> Condition params tables grouping
277−(&&*) = unsafeBinaryOp "AND"
280− :: Condition params tables grouping
281− -> Condition params tables grouping
282− -> Condition params tables grouping
283−(||*) = unsafeBinaryOp "OR"
286− :: [(Condition params tables grouping, Expression params tables grouping ty)]
287− -> Expression params tables grouping ty
288− -> Expression params tables grouping ty
289−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
293− [ " WHEN ", renderExpression when_
294− , " THEN ", renderExpression then_
296− | (when_,then_) <- whenThens
298− , " ELSE ", renderExpression else_
303− :: Condition params tables grouping
304− -> Expression params tables grouping ty
305− -> Expression params tables grouping ty
306− -> Expression params tables grouping ty
307−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
310− :: Expression params tables grouping ('Required (nullity ty))
311− -> Expression params tables grouping ('Required (nullity ty))
312− -> Expression params tables grouping ('Required (nullity 'PGbool))
313−(==*) = unsafeBinaryOp "="
316− :: Expression params tables grouping ('Required (nullity ty))
317− -> Expression params tables grouping ('Required (nullity ty))
318− -> Expression params tables grouping ('Required (nullity 'PGbool))
319−(/=*) = unsafeBinaryOp "<>"
322− :: Expression params tables grouping ('Required (nullity ty))
323− -> Expression params tables grouping ('Required (nullity ty))
324− -> Expression params tables grouping ('Required (nullity 'PGbool))
325−(>=*) = unsafeBinaryOp ">="
328− :: Expression params tables grouping ('Required (nullity ty))
329− -> Expression params tables grouping ('Required (nullity ty))
330− -> Expression params tables grouping ('Required (nullity 'PGbool))
331−(<*) = unsafeBinaryOp "<"
334− :: Expression params tables grouping ('Required (nullity ty))
335− -> Expression params tables grouping ('Required (nullity ty))
336− -> Expression params tables grouping ('Required (nullity 'PGbool))
337−(<=*) = unsafeBinaryOp "<="
340− :: Expression params tables grouping ('Required (nullity ty))
341− -> Expression params tables grouping ('Required (nullity ty))
342− -> Expression params tables grouping ('Required (nullity 'PGbool))
343−(>*) = unsafeBinaryOp ">"
345−data SortExpression params tables grouping where
347− :: Expression params tables grouping ty
348− -> SortExpression params tables grouping
350− :: Expression params tables grouping ty
351− -> SortExpression params tables grouping
353−renderSortExpression :: SortExpression params tables grouping -> ByteString
354−renderSortExpression = \case
355− Asc expression -> renderExpression expression <+> "ASC"
356− Desc expression -> renderExpression expression <+> "DESC"
358−{-----------------------------------------
360−-----------------------------------------}
363− (tables :: [(Symbol,[(Symbol,ColumnType)])])
364− (tabcol :: (Symbol,Symbol)) where
366− :: (tables ~ '[table ::: columns], HasColumn column columns ty)
368− -> By tables '(table, column)
370− :: (HasTable table tables columns, HasColumn column columns ty)
371− => (Alias table, Alias column)
372− -> By tables '(table, column)
374−renderBy :: By tables tabcolty -> ByteString
376− By column -> renderAlias column
377− By2 (table, column) -> renderAlias table <> "." <> renderAlias column
379−data GroupByClause tables grouping where
380− NoGroups :: GroupByClause tables 'Ungrouped
383− => NP (By tables) bys
384− -> GroupByClause tables ('Grouped bys)
386−renderGroupByClause :: GroupByClause tables grouping -> ByteString
387−renderGroupByClause = \case
390− Group bys -> " GROUP BY" <+> renderCommaSeparated renderBy bys
392−data HavingClause params tables grouping where
393− NoHaving :: HavingClause params tables 'Ungrouped
395− :: [Condition params tables ('Grouped bys)]
396− -> HavingClause params tables ('Grouped bys)
398−renderHavingClause :: HavingClause params tables grouping -> ByteString
399−renderHavingClause = \case
402− Having conditions ->
403− " HAVING" <+> commaSeparated (renderExpression <$> conditions)
405−class (KnownSymbol table, KnownSymbol column)
406− => GroupedBy table column bys where
408− :: (tables ~ '[table ::: columns], HasColumn column columns ty)
410− -> Expression params tables ('Grouped bys) ty
411− getGroup1 column = UnsafeExpression $ renderSymbol column
413− :: (HasTable table tables columns, HasColumn column columns ty)
416− -> Expression params tables ('Grouped bys) ty
417− getGroup2 table column = UnsafeExpression $
418− renderAlias table <> "." <> renderAlias column
419−instance {-# OVERLAPPING #-} (KnownSymbol table, KnownSymbol column)
420− => GroupedBy table column ('(table,column) ': bys)
421−instance {-# OVERLAPPABLE #-}
423− , KnownSymbol column
424− , GroupedBy table column bys
425− ) => GroupedBy table column (tabcol ': bys)
428− ( tables ~ '[table ::: columns]
429− , HasColumn column columns ty
430− , GroupedBy table column bys
432− (Expression params tables ('Grouped bys) ty) where fromLabel = getGroup1
435− ( HasTable table tables columns
436− , HasColumn column columns ty
437− , GroupedBy table column bys
438− ) => IsTableColumn table column
439− (Expression params tables ('Grouped bys) ty) where (&.) = getGroup2
443− -> Expression params tables 'Ungrouped xty
444− -> Expression params tables ('Grouped bys) yty
445−unsafeAggregate fun x = UnsafeExpression $ mconcat
446− [fun, "(", renderExpression x, ")"]
450− => Expression params tables 'Ungrouped ('Required (nullity ty))
451− -> Expression params tables ('Grouped bys) ('Required (nullity ty))
452−sum_ = unsafeAggregate "sum"
454−{-----------------------------------------
456−-----------------------------------------}
459− (schema :: [(Symbol,[(Symbol,ColumnType)])])
460− (columns :: [(Symbol,ColumnType)])
461− = UnsafeTable { renderTable :: ByteString }
464−class KnownSymbol table => HasTable table tables columns
465− | table tables -> columns where
466− getTable :: Proxy# table -> Table tables columns
467− getTable table = UnsafeTable $ renderSymbol table
468−instance {-# OVERLAPPING #-} KnownSymbol table
469− => HasTable table ((table ::: columns) ': tables) columns
470−instance {-# OVERLAPPABLE #-}
471− (KnownSymbol table, HasTable table schema columns)
472− => HasTable table (table' ': schema) columns
474−instance HasTable table schema columns
475− => IsLabel table (Table schema columns) where
476− fromLabel = getTable
478−data TableReference params schema tables where
480− :: Aliased (Table schema) table
481− -> TableReference params schema '[table]
483− :: Aliased (Query schema params) table
484− -> TableReference params schema '[table]
486− :: TableReference params schema right
487− -> TableReference params schema left
488− -> TableReference params schema (Join left right)
490− :: TableReference params schema right
491− -> Condition params (Join left right) 'Ungrouped
492− -> TableReference params schema left
493− -> TableReference params schema (Join left right)
495− :: TableReference params schema right
496− -> Condition params (Join left right) 'Ungrouped
497− -> TableReference params schema left
498− -> TableReference params schema (Join left (NullifyTables right))
500− :: TableReference params schema right
501− -> Condition params (Join left right) 'Ungrouped
502− -> TableReference params schema left
503− -> TableReference params schema (Join (NullifyTables left) right)
505− :: TableReference params schema right
506− -> Condition params (Join left right) 'Ungrouped
507− -> TableReference params schema left
508− -> TableReference params schema
509− (Join (NullifyTables left) (NullifyTables right))
511−renderTableReference :: TableReference params schema tables -> ByteString
512−renderTableReference = \case
513− Table table -> renderAliased renderTable table
514− Subquery selection -> renderAliased renderQuery selection
515− CrossJoin right left ->
516− renderTableReference left <+> "CROSS JOIN" <+> renderTableReference right
517− InnerJoin right on left -> renderJoin "INNER JOIN" right on left
518− LeftOuterJoin right on left -> renderJoin "LEFT OUTER JOIN" right on left
519− RightOuterJoin right on left -> renderJoin "RIGHT OUTER JOIN" right on left
520− FullOuterJoin right on left -> renderJoin "FULL OUTER JOIN" right on left
522− renderJoin op right on left =
523− renderTableReference left <+> op <+> renderTableReference right
524− <+> "ON" <+> renderExpression on
527− (params :: [ColumnType])
528− (schema :: [(Symbol,[(Symbol,ColumnType)])])
529− (tables :: [(Symbol,[(Symbol,ColumnType)])])
530− (grouping :: Grouping)
532− { fromClause :: TableReference params schema tables
533− , whereClause :: [Condition params tables 'Ungrouped]
534− , groupByClause :: GroupByClause tables grouping
535− , havingClause :: HavingClause params tables grouping
536− , orderByClause :: [SortExpression params tables grouping]
537− , limitClause :: [Word64]
538− , offsetClause :: [Word64]
541−renderTableExpression
542− :: TableExpression params schema tables grouping
544−renderTableExpression
545− (TableExpression tables whs' grps' hvs' srts' lims' offs') = mconcat
546− [ "FROM ", renderTableReference tables
548− , renderGroupByClause grps'
549− , renderHavingClause hvs'
551− , renderLimits lims'
552− , renderOffsets offs'
555− renderWheres = \case
557− wh:[] -> " WHERE" <+> renderExpression wh
558− wh:whs -> " WHERE" <+> renderExpression (foldr (&&*) wh whs)
562− <+> commaSeparated (renderSortExpression <$> srts)
563− renderLimits = \case
565− lims -> " LIMIT" <+> fromString (show (minimum lims))
566− renderOffsets = \case
568− offs -> " OFFSET" <+> fromString (show (sum offs))
571− :: TableReference params schema tables
572− -> TableExpression params schema tables 'Ungrouped
573−from tables = TableExpression tables [] NoGroups NoHaving [] [] []
576− :: Condition params tables 'Ungrouped
577− -> TableExpression params schema tables grouping
578− -> TableExpression params schema tables grouping
579−where_ wh tables = tables {whereClause = wh : whereClause tables}
583− => NP (By tables) bys
584− -> TableExpression params schema tables 'Ungrouped
585− -> TableExpression params schema tables ('Grouped bys)
586−group bys tables = TableExpression
587− { fromClause = fromClause tables
588− , whereClause = whereClause tables
589− , groupByClause = Group bys
590− , havingClause = Having []
591− , orderByClause = []
592− , limitClause = limitClause tables
593− , offsetClause = offsetClause tables
597− :: Condition params tables ('Grouped bys)
598− -> TableExpression params schema tables ('Grouped bys)
599− -> TableExpression params schema tables ('Grouped bys)
600−having hv tables = tables
601− { havingClause = case havingClause tables of Having hvs -> Having (hv:hvs) }
604− :: [SortExpression params tables grouping]
605− -> TableExpression params schema tables grouping
606− -> TableExpression params schema tables grouping
607−orderBy srts tables = tables {orderByClause = orderByClause tables ++ srts}
611− -> TableExpression params schema tables grouping
612− -> TableExpression params schema tables grouping
613−limit lim tables = tables {limitClause = lim : limitClause tables}
617− -> TableExpression params schema tables grouping
618− -> TableExpression params schema tables grouping
619−offset off tables = tables {offsetClause = off : offsetClause tables}
621−{-----------------------------------------
623−-----------------------------------------}
625−newtype TypeExpression (ty :: ColumnType)
626− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
629−bool :: TypeExpression ('Required ('Null 'PGbool))
630−bool = UnsafeTypeExpression "bool"
631−int2 :: TypeExpression ('Required ('Null 'PGint2))
632−int2 = UnsafeTypeExpression "int2"
633−smallint :: TypeExpression ('Required ('Null 'PGint2))
634−smallint = UnsafeTypeExpression "smallint"
635−int4 :: TypeExpression ('Required ('Null 'PGint4))
636−int4 = UnsafeTypeExpression "int4"
637−int :: TypeExpression ('Required ('Null 'PGint4))
638−int = UnsafeTypeExpression "int"
639−integer :: TypeExpression ('Required ('Null 'PGint4))
640−integer = UnsafeTypeExpression "integer"
641−int8 :: TypeExpression ('Required ('Null 'PGint8))
642−int8 = UnsafeTypeExpression "int8"
643−bigint :: TypeExpression ('Required ('Null 'PGint8))
644−bigint = UnsafeTypeExpression "bigint"
645−numeric :: TypeExpression ('Required ('Null 'PGnumeric))
646−numeric = UnsafeTypeExpression "numeric"
647−float4 :: TypeExpression ('Required ('Null 'PGfloat4))
648−float4 = UnsafeTypeExpression "float4"
649−real :: TypeExpression ('Required ('Null 'PGfloat4))
650−real = UnsafeTypeExpression "real"
651−float8 :: TypeExpression ('Required ('Null 'PGfloat8))
652−float8 = UnsafeTypeExpression "float8"
653−doublePrecision :: TypeExpression ('Required ('Null 'PGfloat8))
654−doublePrecision = UnsafeTypeExpression "double precision"
655−serial2 :: TypeExpression ('Optional ('NotNull 'PGint2))
656−serial2 = UnsafeTypeExpression "serial2"
657−smallserial :: TypeExpression ('Optional ('NotNull 'PGint2))
658−smallserial = UnsafeTypeExpression "smallserial"
659−serial4 :: TypeExpression ('Optional ('NotNull 'PGint4))
660−serial4 = UnsafeTypeExpression "serial4"
661−serial :: TypeExpression ('Optional ('NotNull 'PGint4))
662−serial = UnsafeTypeExpression "serial"
663−serial8 :: TypeExpression ('Optional ('NotNull 'PGint8))
664−serial8 = UnsafeTypeExpression "serial8"
665−bigserial :: TypeExpression ('Optional ('NotNull 'PGint8))
666−bigserial = UnsafeTypeExpression "bigserial"
667−text :: TypeExpression ('Required ('Null 'PGtext))
668−text = UnsafeTypeExpression "text"
672− -> TypeExpression ('Required ('Null ('PGchar n)))
673−char p = UnsafeTypeExpression $ "char(" <> renderNat p <> ")"
677− -> TypeExpression ('Required ('Null ('PGchar n)))
678−character p = UnsafeTypeExpression $ "character(" <> renderNat p <> ")"
682− -> TypeExpression ('Required ('Null ('PGvarchar n)))
683−varchar p = UnsafeTypeExpression $ "varchar(" <> renderNat p <> ")"
687− -> TypeExpression ('Required ('Null ('PGvarchar n)))
688−characterVarying p = UnsafeTypeExpression $
689− "character varying(" <> renderNat p <> ")"
690−bytea :: TypeExpression ('Required ('Null ('PGbytea)))
691−bytea = UnsafeTypeExpression "bytea"
692−timestamp :: TypeExpression ('Required ('Null ('PGtimestamp)))
693−timestamp = UnsafeTypeExpression "timestamp"
694−timestampWithTimeZone :: TypeExpression ('Required ('Null ('PGtimestamptz)))
695−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
696−date :: TypeExpression ('Required ('Null ('PGdate)))
697−date = UnsafeTypeExpression "date"
698−time :: TypeExpression ('Required ('Null ('PGtime)))
699−time = UnsafeTypeExpression "time"
700−timeWithTimeZone :: TypeExpression ('Required ('Null ('PGtimetz)))
701−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
702−interval :: TypeExpression ('Required ('Null ('PGinterval)))
703−interval = UnsafeTypeExpression "interval"
704−uuid :: TypeExpression ('Required ('Null ('PGuuid)))
705−uuid = UnsafeTypeExpression "uuid"
706−json :: TypeExpression ('Required ('Null ('PGjson)))
707−json = UnsafeTypeExpression "json"
708−jsonb :: TypeExpression ('Required ('Null ('PGjsonb)))
709−jsonb = UnsafeTypeExpression "jsonb"
712− :: TypeExpression (optionality ('Null ty))
713− -> TypeExpression (optionality ('NotNull ty))
714−notNull ty = UnsafeTypeExpression $ renderTypeExpression ty <+> "NOT NULL"
716− :: Expression '[] '[] 'Ungrouped ('Required ty)
717− -> TypeExpression ('Required ty)
718− -> TypeExpression ('Optional ty)
719−default_ x ty = UnsafeTypeExpression $
720− renderTypeExpression ty <+> "DEFAULT" <+> renderExpression x
722−class PGTyped (ty :: PGType) where
723− pgtype :: TypeExpression ('Required ('Null ty))
724−instance PGTyped 'PGbool where pgtype = bool
725−instance PGTyped 'PGint2 where pgtype = int2
726−instance PGTyped 'PGint4 where pgtype = int4
727−instance PGTyped 'PGint8 where pgtype = int8
728−instance PGTyped 'PGnumeric where pgtype = numeric
729−instance PGTyped 'PGfloat4 where pgtype = float4
730−instance PGTyped 'PGfloat8 where pgtype = float8
731−instance PGTyped 'PGtext where pgtype = text
732−instance KnownNat n => PGTyped ('PGchar n) where pgtype = char (Proxy @n)
733−instance KnownNat n => PGTyped ('PGvarchar n) where pgtype = varchar (Proxy @n)
734−instance PGTyped 'PGbytea where pgtype = bytea
735−instance PGTyped 'PGtimestamp where pgtype = timestamp
736−instance PGTyped 'PGtimestamptz where pgtype = timestampWithTimeZone
737−instance PGTyped 'PGdate where pgtype = date
738−instance PGTyped 'PGtime where pgtype = time
739−instance PGTyped 'PGtimetz where pgtype = timeWithTimeZone
740−instance PGTyped 'PGinterval where pgtype = interval
741−instance PGTyped 'PGuuid where pgtype = uuid
742−instance PGTyped 'PGjson where pgtype = json
743−instance PGTyped 'PGjsonb where pgtype = jsonb
745−{-----------------------------------------
747−-----------------------------------------}
750− (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
751− (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
752− = UnsafeDefinition { renderDefinition :: ByteString }
754−instance Category Definition where
755− id = UnsafeDefinition ";"
756− ddl1 . ddl0 = UnsafeDefinition $
757− renderDefinition ddl0 <+> renderDefinition ddl1
760− (schema :: [(Symbol,[(Symbol,ColumnType)])])
761− (params :: [ColumnType])
762− (columns :: [(Symbol,ColumnType)])
763− = UnsafeManipulation { renderManipulation :: ByteString }
766− (schema :: [(Symbol,[(Symbol,ColumnType)])])
767− (params :: [ColumnType])
768− (columns :: [(Symbol,ColumnType)])
769− = UnsafeQuery { renderQuery :: ByteString }
772− :: Query schema params columns
773− -> Manipulation schema params columns
774−query q = UnsafeManipulation $ renderQuery q <> ";"
776−union, unionAll, intersect, intersectAll, except, exceptAll
777− :: Query schema params columns
778− -> Query schema params columns
779− -> Query schema params columns
780−q1 `union` q2 = UnsafeQuery $
781− parenthesized (renderQuery q1)
783− <+> parenthesized (renderQuery q2)
784−q1 `unionAll` q2 = UnsafeQuery $
785− parenthesized (renderQuery q1)
786− <+> "UNION" <+> "ALL"
787− <+> parenthesized (renderQuery q2)
788−q1 `intersect` q2 = UnsafeQuery $
789− parenthesized (renderQuery q1)
791− <+> parenthesized (renderQuery q2)
792−q1 `intersectAll` q2 = UnsafeQuery $
793− parenthesized (renderQuery q1)
794− <+> "INTERSECT" <+> "ALL"
795− <+> parenthesized (renderQuery q2)
796−q1 `except` q2 = UnsafeQuery $
797− parenthesized (renderQuery q1)
799− <+> parenthesized (renderQuery q2)
800−q1 `exceptAll` q2 = UnsafeQuery $
801− parenthesized (renderQuery q1)
802− <+> "EXCEPT" <+> "ALL"
803− <+> parenthesized (renderQuery q2)
805−{-----------------------------------------
807−-----------------------------------------}
811− => NP (Aliased (Expression params tables grouping)) columns
812− -> TableExpression params schema tables grouping
813− -> Query schema params columns
814−select list tabs = UnsafeQuery $
816− <+> renderCommaSeparated (renderAliased renderExpression) list
817− <+> renderTableExpression tabs
820− :: (tables ~ '[table ::: columns])
821− => TableExpression params schema tables 'Ungrouped
822− -> Query schema params columns
823−selectStar tabs = UnsafeQuery $ "SELECT" <+> "*" <+> renderTableExpression tabs
826− :: HasTable table tables columns
828− -> TableExpression params schema tables 'Ungrouped
829− -> Query schema params columns
830−selectDotStar table tables = UnsafeQuery $
831− "SELECT" <+> renderAlias table <> ".*" <+> renderTableExpression tables
835− => NP (Aliased (Expression params '[] 'Ungrouped)) columns
836− -> Query schema params columns
837−selectRow row = UnsafeQuery $
838− "SELECT" <+> renderCommaSeparated (renderAliased renderExpression) row
840−{-----------------------------------------
842−-----------------------------------------}
845− :: (KnownSymbol table, SListI columns)
847− -> NP (Aliased TypeExpression) columns
848− -> [TableConstraint schema columns]
849− -> Definition schema (Create table columns schema)
850−createTable table columns constraints = UnsafeDefinition $
851− "CREATE TABLE" <+> renderAlias table
853− ( renderCommaSeparated renderColumnDef columns
854− <> renderConstraints constraints )
857− renderColumnDef :: Aliased TypeExpression x -> ByteString
858− renderColumnDef (ty `As` column) =
859− renderAlias column <+> renderTypeExpression ty
860− renderConstraints :: [TableConstraint schema columns] -> ByteString
861− renderConstraints = \case
863− _ -> ", " <> commaSeparated (renderTableConstraint <$> constraints)
866− (schema :: [(Symbol,[(Symbol,ColumnType)])])
867− (columns :: [(Symbol,ColumnType)])
868− = UnsafeTableConstraint { renderTableConstraint :: ByteString }
871− :: Condition '[] '[table ::: columns] 'Ungrouped
872− -> TableConstraint schema columns
873−check condition = UnsafeTableConstraint $
874− "CHECK" <+> parenthesized (renderExpression condition)
877− (columns :: [(Symbol,ColumnType)])
878− (columnty :: (Symbol,ColumnType))
881− :: HasColumn column columns ty
883− -> Column columns (column ::: ty)
885−renderColumn :: Column columns columnty -> ByteString
886−renderColumn (Column column) = renderAlias column
889− :: SListI subcolumns
890− => NP (Column columns) subcolumns
891− -> TableConstraint schema columns
892−unique columns = UnsafeTableConstraint $
893− "UNIQUE" <+> parenthesized (renderCommaSeparated renderColumn columns)
896− :: (SListI subcolumns, NotNullTypes subcolumns)
897− => NP (Column columns) subcolumns
898− -> TableConstraint schema columns
899−primaryKey columns = UnsafeTableConstraint $
900− "PRIMARY KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
902−type family SameTypes columns0 columns1 :: Constraint where
903− SameTypes '[] '[] = ()
904− SameTypes ((column0 ::: ty0) ': columns0) ((column1 ::: ty1) ': columns1)
905− = (ty0 ~ ty1, SameTypes columns0 columns1)
907−type family NotNullTypes columns :: Constraint where
908− NotNullTypes '[] = ()
909− NotNullTypes ((column ::: (optionality ('NotNull ty))) ': columns)
910− = NotNullTypes columns
913− :: ( HasTable reftable schema refcolumns
914− , SameTypes subcolumns refsubcolumns
915− , NotNullTypes subcolumns
917− , SListI refsubcolumns)
918− => NP (Column columns) subcolumns
920− -> NP (Column refcolumns) refsubcolumns
921− -> TableConstraint schema columns
922−foreignKey columns reftable refcolumns = UnsafeTableConstraint $
923− "FOREIGN KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
924− <+> "REFERENCES" <+> renderAlias reftable
925− <+> parenthesized (renderCommaSeparated renderColumn refcolumns)
927−{-----------------------------------------
929−-----------------------------------------}
932− :: KnownSymbol table
934− -> Definition schema (Drop table schema)
935−dropTable table = UnsafeDefinition $ "DROP TABLE" <+> renderAlias table <> ";"
937−{-----------------------------------------
939−-----------------------------------------}
942− :: HasTable table schema columns0
944− -> AlterTable columns0 columns1
945− -> Definition schema (Alter table schema columns1)
946−alterTable table alteration = UnsafeDefinition $
948− <+> renderAlias table
949− <+> renderAlterTable alteration
953− :: (KnownSymbol table0, KnownSymbol table1)
956− -> Definition schema (Rename table0 table1 schema)
957−alterTableRename table0 table1 = UnsafeDefinition $
958− "ALTER TABLE" <+> renderAlias table0
959− <+> "RENAME TO" <+> renderAlias table1 <> ";"
962− (columns0 :: [(Symbol, ColumnType)])
963− (columns1 :: [(Symbol, ColumnType)]) =
964− UnsafeAlterTable {renderAlterTable :: ByteString}
967− :: KnownSymbol column
969− -> TypeExpression ('Optional ty)
970− -> AlterTable columns (Create column ('Optional ty) columns)
971−addColumnDefault column ty = UnsafeAlterTable $
972− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
975− :: KnownSymbol column
977− -> TypeExpression ('Required ('Null ty))
978− -> AlterTable columns ((column ::: 'Required ('Null ty)) ': columns)
979−addColumnNull column ty = UnsafeAlterTable $
980− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
983− :: KnownSymbol column
985− -> AlterTable columns (Drop column columns)
986−dropColumn column = UnsafeAlterTable $
987− "DROP COLUMN" <+> renderAlias column
990− :: (KnownSymbol column0, KnownSymbol column1)
993− -> AlterTable columns (Rename column0 column1 columns)
994−renameColumn column0 column1 = UnsafeAlterTable $
995− "RENAME COLUMN" <+> renderAlias column0 <+> "TO" <+> renderAlias column1
998− :: (KnownSymbol column, HasColumn column columns ty0)
1000− -> AlterColumn ty0 ty1
1001− -> AlterTable columns (Alter column columns ty1)
1002−alterColumn column alteration = UnsafeAlterTable $
1003− "ALTER COLUMN" <+> renderAlias column <+> renderAlterColumn alteration
1005−data AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
1006− UnsafeAlterColumn {renderAlterColumn :: ByteString}
1009− :: Expression '[] '[] 'Ungrouped ('Required ty)
1010− -> AlterColumn ('Required ty) ('Optional ty)
1011−setDefault expression = UnsafeAlterColumn $
1012− "SET DEFAULT" <+> renderExpression expression
1014−dropDefault :: AlterColumn ('Optional ty) ('Required ty)
1015−dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
1018− :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
1019−setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
1022− :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
1023−dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
1026− :: TypeExpression (optionality (nullity ty1))
1027− -> AlterColumn (optionality (nullity ty0)) (optionality (nullity ty1))
1028−alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty
1030−{-----------------------------------------
1032−-----------------------------------------}
1035− :: (SListI columns, SListI results, HasTable table schema columns)
1037− -> ValuesClause schema params columns
1038− -> ConflictClause params columns
1039− -> ReturningClause params columns results
1040− -> Manipulation schema params results
1041−insertInto table insert conflict returning = UnsafeManipulation $
1042− "INSERT" <+> "INTO" <+> renderAlias table
1043− <+> renderValuesClause insert
1044− <> renderConflictClause conflict
1045− <> renderReturningClause returning
1048− (schema :: [(Symbol,[(Symbol,ColumnType)])])
1049− (params :: [ColumnType])
1050− (columns :: [(Symbol,ColumnType)])
1052− (NP (Aliased (Expression params '[] 'Ungrouped)) columns)
1053− [NP (Aliased (Expression params '[] 'Ungrouped)) columns]
1054− | ValuesQuery (Query schema params columns)
1058− => ValuesClause schema params columns
1060−renderValuesClause = \case
1062− parenthesized (renderCommaSeparated renderAliasPart row)
1065− (parenthesized . renderCommaSeparated renderValuePart <$> row:rows)
1067− renderAliasPart, renderValuePart
1068− :: Aliased (Expression params '[] 'Ungrouped) ty -> ByteString
1069− renderAliasPart (_ `As` name) = renderAlias name
1070− renderValuePart (value `As` _) = renderExpression value
1071− ValuesQuery q -> renderQuery q
1073−data ReturningClause
1074− (params :: [ColumnType])
1075− (columns :: [(Symbol,ColumnType)])
1076− (results :: [(Symbol,ColumnType)])
1078− ReturningNil :: ReturningClause params columns '[]
1079− ReturningStar :: ReturningClause params columns columns
1081− :: NP (Aliased (Expression params '[table ::: columns] 'Ungrouped)) results
1082− -> ReturningClause params columns results
1084−renderReturningClause
1086− => ReturningClause params columns results
1088−renderReturningClause = \case
1089− ReturningNil -> ";"
1090− ReturningStar -> " RETURNING *;"
1091− Returning results -> " RETURNING"
1092− <+> renderCommaSeparated (renderAliased renderExpression) results <> ";"
1094−data ConflictClause params columns where
1095− Conflict :: ConflictClause params columns
1096− OnConflictDoNothing :: ConflictClause params columns
1098− :: NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1099− -> Condition params '[table ::: columns] 'Ungrouped
1100− -> ConflictClause params columns
1102−renderConflictClause
1104− => ConflictClause params columns
1106−renderConflictClause = \case
1108− OnConflictDoNothing -> " ON CONFLICT DO NOTHING"
1109− OnConflictDoUpdate updates wh
1110− -> " ON CONFLICT DO UPDATE SET"
1111− <+> renderCommaSeparatedMaybe renderUpdateExpression updates
1112− <+> "WHERE" <+> renderExpression wh
1114−{-----------------------------------------
1116−-----------------------------------------}
1118−data UpdateExpression params table ty
1120− | Set (Expression params table 'Ungrouped ty)
1122−renderUpdateExpression
1123− :: Aliased (UpdateExpression params '[table ::: columns]) column
1124− -> Maybe ByteString
1125−renderUpdateExpression = \case
1126− Same `As` _ -> Nothing
1127− Set expression `As` column -> Just $
1128− renderAlias column <+> "=" <+> renderExpression expression
1131− :: (HasTable table schema columns, SListI columns, SListI results)
1133− -> NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1134− -> Condition params '[table ::: columns] 'Ungrouped
1135− -> ReturningClause params columns results
1136− -> Manipulation schema params results
1137−update table columns wh returning = UnsafeManipulation $
1139− <+> renderAlias table
1141− <+> renderCommaSeparatedMaybe renderUpdateExpression columns
1142− <+> "WHERE" <+> renderExpression wh
1143− <> renderReturningClause returning
1145−{-----------------------------------------
1147−-----------------------------------------}
1150− :: HasTable table schema columns
1152− -> Condition params '[table ::: columns] 'Ungrouped
1153− -> Manipulation schema params '[]
1154−deleteFrom table wh = UnsafeManipulation $
1155− "DELETE FROM" <+> renderAlias table
1156− <+> "WHERE" <+> renderExpression wh <> ";"
1158−{-----------------------------------------
1159−render helper functions
1160−-----------------------------------------}
1162−parenthesized :: ByteString -> ByteString
1163−parenthesized str = "(" <> str <> ")"
1165−(<+>) :: ByteString -> ByteString -> ByteString
1166−str1 <+> str2 = str1 <> " " <> str2
1168−commaSeparated :: [ByteString] -> ByteString
1169−commaSeparated = ByteString.intercalate ", "
1171−renderCommaSeparated
1173− => (forall x. expression x -> ByteString)
1174− -> NP expression xs -> ByteString
1175−renderCommaSeparated render
1178− . hmap (K . render)
1180−renderCommaSeparatedMaybe
1182− => (forall x. expression x -> Maybe ByteString)
1183− -> NP expression xs -> ByteString
1184−renderCommaSeparatedMaybe render
1188− . hmap (K . render)
1190−renderSymbol :: KnownSymbol str => Proxy# str -> ByteString
1191−renderSymbol p = fromString $ symbolVal' p
1193−renderNat :: KnownNat n => proxy n -> ByteString
1194−renderNat (_ :: proxy n) = fromString (show (natVal' (proxy# :: Proxy# n)))