@@ -1,1198 +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− "$" <> paramNum <+> "::" <+> renderTypeExpression (pgtype @(BaseType ty))
58− paramNum = fromString $ show $ natVal (Proxy @n)
59−instance {-# OVERLAPPING #-} PGTyped (BaseType ty1)
60− => HasParameter 1 (ty1:tys) ty1
61−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
62− => HasParameter n (ty' : params) ty
64−class KnownSymbol column => HasColumn column columns ty
65− | column columns -> ty where
68− -> Expression params '[table ::: columns] 'Ungrouped ty
69− getColumn column = UnsafeExpression $ renderSymbol column
70−instance {-# OVERLAPPING #-} KnownSymbol column
71− => HasColumn column ((column ::: optionality ty) ': tys) ('Required ty)
72−instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
73− => HasColumn column (ty' ': table) ty
75−instance (HasColumn column columns ty, tables ~ '[table ::: columns])
76− => IsLabel column (Expression params tables 'Ungrouped ty) where
77− fromLabel = getColumn
79−instance (HasTable table tables columns, HasColumn column columns ty)
80− => IsTableColumn table column (Expression params tables 'Ungrouped ty) where
81− table &. column = UnsafeExpression $
82− renderAlias table <> "." <> renderAlias column
84−def :: Expression params '[] grouping ('Optional (nullity ty))
85−def = UnsafeExpression "DEFAULT"
88− :: Expression params '[] grouping ('Required (nullity ty))
89− -> Expression params '[] grouping ('Optional (nullity ty))
90−unDef = UnsafeExpression . renderExpression
92−null :: Expression params tables grouping (optionality ('Null ty))
93−null = UnsafeExpression "NULL"
96− :: Expression params tables grouping (optionality ('NotNull ty))
97− -> Expression params tables grouping (optionality ('Null ty))
98−unNull = UnsafeExpression . renderExpression
101− :: [Expression params tables grouping ('Required ('Null x))]
102− -> Expression params tables grouping ('Required ('NotNull x))
103− -> Expression params tables grouping ('Required ('NotNull x))
104−coalesce nulls isn'tNull = UnsafeExpression $
105− "COALESCE" <> parenthesized (commaSeparated
106− ((renderExpression <$> nulls) <> [renderExpression isn'tNull]))
110− -> Expression params tables grouping ty0
111− -> Expression params tables grouping ty1
112− -> Expression params tables grouping ty2
113−unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
114− renderExpression x <+> op <+> renderExpression y
118− -> Expression params tables grouping ty0
119− -> Expression params tables grouping ty1
120−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
121− op <+> renderExpression x
125− -> Expression params tables grouping xty
126− -> Expression params tables grouping yty
127−unsafeFunction fun x = UnsafeExpression $
128− fun <> parenthesized (renderExpression x)
131− => Num (Expression params tables grouping ('Required (nullity ty))) where
132− (+) = unsafeBinaryOp "+"
133− (-) = unsafeBinaryOp "-"
134− (*) = unsafeBinaryOp "*"
135− abs = unsafeFunction "abs"
136− signum = unsafeFunction "sign"
139− . (<> if decimal (Proxy :: Proxy ty) then "." else "")
143−instance PGFloating ty => Fractional
144− (Expression params tables grouping ('Required (nullity ty))) where
145− (/) = unsafeBinaryOp "/"
146− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
148−instance (PGFloating ty, PGTyped ty) => Floating
149− (Expression params tables grouping ('Required (nullity ty))) where
150− pi = UnsafeExpression "pi()"
151− exp = unsafeFunction "exp"
152− log = unsafeFunction "ln"
153− sqrt = unsafeFunction "sqrt"
154− b ** x = UnsafeExpression $
155− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
156− logBase b y = cast pgtype $ logBaseNumeric b y
159− :: Expression params tables grouping ('Required (nullity ty))
160− -> Expression params tables grouping ('Required (nullity ty))
161− -> Expression params tables grouping ('Required (nullity 'PGnumeric))
162− logBaseNumeric b' y' = UnsafeExpression $ mconcat
164− , renderExpression (cast numeric b')
166− , renderExpression (cast numeric y')
169− sin = unsafeFunction "sin"
170− cos = unsafeFunction "cos"
171− tan = unsafeFunction "tan"
172− asin = unsafeFunction "asin"
173− acos = unsafeFunction "acos"
174− atan = unsafeFunction "atan"
175− sinh x = (exp x - exp (-x)) / 2
176− cosh x = (exp x + exp (-x)) / 2
177− tanh x = sinh x / cosh x
178− asinh x = log (x + sqrt (x*x + 1))
179− acosh x = log (x + sqrt (x*x - 1))
180− atanh x = log ((1 + x) / (1 - x)) / 2
184− => Expression params tables grouping ('Required (nullity float))
185− -> Expression params tables grouping ('Required (nullity float))
186− -> Expression params tables grouping ('Required (nullity float))
187−atan2 y x = UnsafeExpression $
188− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
191− :: TypeExpression ('Required ('Null ty1))
192− -> Expression params tables grouping ('Required (nullity ty0))
193− -> Expression params tables grouping ('Required (nullity ty1))
194−cast ty x = UnsafeExpression $
195− "(" <> renderExpression x <> " :: " <> renderTypeExpression ty <> ")"
199− => Expression params tables grouping ('Required (nullity ty))
200− -> Expression params tables grouping ('Required (nullity ty))
201− -> Expression params tables grouping ('Required (nullity ty))
202−div = unsafeBinaryOp "/"
206− => Expression params tables grouping ('Required (nullity ty))
207− -> Expression params tables grouping ('Required (nullity ty))
208− -> Expression params tables grouping ('Required (nullity ty))
209−mod = unsafeBinaryOp "%"
212− :: (PGFloating frac, PGTyped int)
213− => Expression params tables grouping ('Required (nullity frac))
214− -> Expression params tables grouping ('Required (nullity int))
215−truncate = cast pgtype . truncate'
218− :: Expression params tables grouping ('Required (nullity frac))
219− -> Expression params tables grouping ('Required (nullity frac))
220− truncate' = unsafeFunction "trunc"
223− :: (PGFloating frac, PGTyped int)
224− => Expression params tables grouping ('Required (nullity frac))
225− -> Expression params tables grouping ('Required (nullity int))
226−round = cast pgtype . round'
229− :: Expression params tables grouping ('Required (nullity frac))
230− -> Expression params tables grouping ('Required (nullity frac))
231− round' = unsafeFunction "round"
234− :: (PGFloating frac, PGTyped int)
235− => Expression params tables grouping ('Required (nullity frac))
236− -> Expression params tables grouping ('Required (nullity int))
237−ceiling = cast pgtype . ceiling'
240− :: Expression params tables grouping ('Required (nullity frac))
241− -> Expression params tables grouping ('Required (nullity frac))
242− ceiling' = unsafeFunction "ceiling"
245− (Expression params tables grouping ('Required (nullity 'PGtext))) where
246− fromString str = UnsafeExpression $
247− "E\'" <> fromString (escape =<< str) <> "\'"
260−type Condition params tables grouping =
261− Expression params tables grouping ('Required ('NotNull 'PGbool))
263−true :: Condition params tables grouping
264−true = UnsafeExpression "TRUE"
266−false :: Condition params tables grouping
267−false = UnsafeExpression "FALSE"
270− :: Condition params tables grouping
271− -> Condition params tables grouping
272−not_ = unsafeUnaryOp "NOT"
275− :: Condition params tables grouping
276− -> Condition params tables grouping
277− -> Condition params tables grouping
278−(&&*) = unsafeBinaryOp "AND"
281− :: Condition params tables grouping
282− -> Condition params tables grouping
283− -> Condition params tables grouping
284−(||*) = unsafeBinaryOp "OR"
287− :: [(Condition params tables grouping, Expression params tables grouping ty)]
288− -> Expression params tables grouping ty
289− -> Expression params tables grouping ty
290−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
294− [ " WHEN ", renderExpression when_
295− , " THEN ", renderExpression then_
297− | (when_,then_) <- whenThens
299− , " ELSE ", renderExpression else_
304− :: Condition params tables grouping
305− -> Expression params tables grouping ty
306− -> Expression params tables grouping ty
307− -> Expression params tables grouping ty
308−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
311− :: Expression params tables grouping ('Required (nullity ty))
312− -> Expression params tables grouping ('Required (nullity ty))
313− -> Expression params tables grouping ('Required (nullity 'PGbool))
314−(==*) = unsafeBinaryOp "="
317− :: Expression params tables grouping ('Required (nullity ty))
318− -> Expression params tables grouping ('Required (nullity ty))
319− -> Expression params tables grouping ('Required (nullity 'PGbool))
320−(/=*) = unsafeBinaryOp "<>"
323− :: Expression params tables grouping ('Required (nullity ty))
324− -> Expression params tables grouping ('Required (nullity ty))
325− -> Expression params tables grouping ('Required (nullity 'PGbool))
326−(>=*) = unsafeBinaryOp ">="
329− :: Expression params tables grouping ('Required (nullity ty))
330− -> Expression params tables grouping ('Required (nullity ty))
331− -> Expression params tables grouping ('Required (nullity 'PGbool))
332−(<*) = unsafeBinaryOp "<"
335− :: Expression params tables grouping ('Required (nullity ty))
336− -> Expression params tables grouping ('Required (nullity ty))
337− -> Expression params tables grouping ('Required (nullity 'PGbool))
338−(<=*) = unsafeBinaryOp "<="
341− :: Expression params tables grouping ('Required (nullity ty))
342− -> Expression params tables grouping ('Required (nullity ty))
343− -> Expression params tables grouping ('Required (nullity 'PGbool))
344−(>*) = unsafeBinaryOp ">"
346−data SortExpression params tables grouping where
348− :: Expression params tables grouping ty
349− -> SortExpression params tables grouping
351− :: Expression params tables grouping ty
352− -> SortExpression params tables grouping
354−renderSortExpression :: SortExpression params tables grouping -> ByteString
355−renderSortExpression = \case
356− Asc expression -> renderExpression expression <+> "ASC"
357− Desc expression -> renderExpression expression <+> "DESC"
359−{-----------------------------------------
361−-----------------------------------------}
364− (tables :: [(Symbol,[(Symbol,ColumnType)])])
365− (tabcol :: (Symbol,Symbol)) where
367− :: (tables ~ '[table ::: columns], HasColumn column columns ty)
369− -> By tables '(table, column)
371− :: (HasTable table tables columns, HasColumn column columns ty)
372− => (Alias table, Alias column)
373− -> By tables '(table, column)
375−renderBy :: By tables tabcolty -> ByteString
377− By column -> renderAlias column
378− By2 (table, column) -> renderAlias table <> "." <> renderAlias column
380−data GroupByClause tables grouping where
381− NoGroups :: GroupByClause tables 'Ungrouped
384− => NP (By tables) bys
385− -> GroupByClause tables ('Grouped bys)
387−renderGroupByClause :: GroupByClause tables grouping -> ByteString
388−renderGroupByClause = \case
391− Group bys -> " GROUP BY" <+> renderCommaSeparated renderBy bys
393−data HavingClause params tables grouping where
394− NoHaving :: HavingClause params tables 'Ungrouped
396− :: [Condition params tables ('Grouped bys)]
397− -> HavingClause params tables ('Grouped bys)
399−renderHavingClause :: HavingClause params tables grouping -> ByteString
400−renderHavingClause = \case
403− Having conditions ->
404− " HAVING" <+> commaSeparated (renderExpression <$> conditions)
406−class (KnownSymbol table, KnownSymbol column)
407− => GroupedBy table column bys where
409− :: (tables ~ '[table ::: columns], HasColumn column columns ty)
411− -> Expression params tables ('Grouped bys) ty
412− getGroup1 column = UnsafeExpression $ fromString (symbolVal' column)
414− :: (HasTable table tables columns, HasColumn column columns ty)
417− -> Expression params tables ('Grouped bys) ty
418− getGroup2 table column = UnsafeExpression $
419− renderAlias table <> "." <> renderAlias column
420−instance {-# OVERLAPPING #-} (KnownSymbol table, KnownSymbol column)
421− => GroupedBy table column ('(table,column) ': bys)
422−instance {-# OVERLAPPABLE #-}
424− , KnownSymbol column
425− , GroupedBy table column bys
426− ) => GroupedBy table column (tabcol ': bys)
429− ( tables ~ '[table ::: columns]
430− , HasColumn column columns ty
431− , GroupedBy table column bys
433− (Expression params tables ('Grouped bys) ty) where fromLabel = getGroup1
436− ( HasTable table tables columns
437− , HasColumn column columns ty
438− , GroupedBy table column bys
439− ) => IsTableColumn table column
440− (Expression params tables ('Grouped bys) ty) where (&.) = getGroup2
444− -> Expression params tables 'Ungrouped xty
445− -> Expression params tables ('Grouped bys) yty
446−unsafeAggregate fun x = UnsafeExpression $ mconcat
447− [fun, "(", renderExpression x, ")"]
451− => Expression params tables 'Ungrouped ('Required (nullity ty))
452− -> Expression params tables ('Grouped bys) ('Required (nullity ty))
453−sum_ = unsafeAggregate "sum"
455−{-----------------------------------------
457−-----------------------------------------}
460− (schema :: [(Symbol,[(Symbol,ColumnType)])])
461− (columns :: [(Symbol,ColumnType)])
462− = UnsafeTable { renderTable :: ByteString }
465−class KnownSymbol table => HasTable table tables columns
466− | table tables -> columns where
467− getTable :: Proxy# table -> Table tables columns
468− getTable table = UnsafeTable $ fromString $ symbolVal' table
469−instance {-# OVERLAPPING #-} KnownSymbol table
470− => HasTable table ((table ::: columns) ': tables) columns
471−instance {-# OVERLAPPABLE #-}
472− (KnownSymbol table, HasTable table schema columns)
473− => HasTable table (table' ': schema) columns
475−instance HasTable table schema columns
476− => IsLabel table (Table schema columns) where
477− fromLabel = getTable
479−data TableReference params schema tables where
481− :: Aliased (Table schema) table
482− -> TableReference params schema '[table]
484− :: Aliased (Query schema params) table
485− -> TableReference params schema '[table]
487− :: TableReference params schema right
488− -> TableReference params schema left
489− -> TableReference params schema (Join left right)
491− :: TableReference params schema right
492− -> Condition params (Join left right) 'Ungrouped
493− -> TableReference params schema left
494− -> TableReference params schema (Join left right)
496− :: TableReference params schema right
497− -> Condition params (Join left right) 'Ungrouped
498− -> TableReference params schema left
499− -> TableReference params schema (Join left (NullifyTables right))
501− :: TableReference params schema right
502− -> Condition params (Join left right) 'Ungrouped
503− -> TableReference params schema left
504− -> TableReference params schema (Join (NullifyTables left) right)
506− :: TableReference params schema right
507− -> Condition params (Join left right) 'Ungrouped
508− -> TableReference params schema left
509− -> TableReference params schema
510− (Join (NullifyTables left) (NullifyTables right))
512−renderTableReference :: TableReference params schema tables -> ByteString
513−renderTableReference = \case
514− Table table -> renderAliased renderTable table
515− Subquery selection -> renderAliased renderQuery selection
516− CrossJoin right left ->
517− renderTableReference left <+> "CROSS JOIN" <+> renderTableReference right
518− InnerJoin right on left -> renderJoin "INNER JOIN" right on left
519− LeftOuterJoin right on left -> renderJoin "LEFT OUTER JOIN" right on left
520− RightOuterJoin right on left -> renderJoin "RIGHT OUTER JOIN" right on left
521− FullOuterJoin right on left -> renderJoin "FULL OUTER JOIN" right on left
523− renderJoin op right on left =
524− renderTableReference left <+> op <+> renderTableReference right
525− <+> "ON" <+> renderExpression on
528− (params :: [ColumnType])
529− (schema :: [(Symbol,[(Symbol,ColumnType)])])
530− (tables :: [(Symbol,[(Symbol,ColumnType)])])
531− (grouping :: Grouping)
533− { fromClause :: TableReference params schema tables
534− , whereClause :: [Condition params tables 'Ungrouped]
535− , groupByClause :: GroupByClause tables grouping
536− , havingClause :: HavingClause params tables grouping
537− , orderByClause :: [SortExpression params tables grouping]
538− , limitClause :: [Word64]
539− , offsetClause :: [Word64]
542−renderTableExpression
543− :: TableExpression params schema tables grouping
545−renderTableExpression
546− (TableExpression tables whs' grps' hvs' srts' lims' offs') = mconcat
547− [ "FROM ", renderTableReference tables
549− , renderGroupByClause grps'
550− , renderHavingClause hvs'
552− , renderLimits lims'
553− , renderOffsets offs'
556− renderWheres = \case
558− wh:[] -> " WHERE" <+> renderExpression wh
559− wh:whs -> " WHERE" <+> renderExpression (foldr (&&*) wh whs)
563− <+> commaSeparated (renderSortExpression <$> srts)
564− renderLimits = \case
566− lims -> " LIMIT" <+> fromString (show (minimum lims))
567− renderOffsets = \case
569− offs -> " OFFSET" <+> fromString (show (sum offs))
572− :: TableReference params schema tables
573− -> TableExpression params schema tables 'Ungrouped
574−from tables = TableExpression tables [] NoGroups NoHaving [] [] []
577− :: Condition params tables 'Ungrouped
578− -> TableExpression params schema tables grouping
579− -> TableExpression params schema tables grouping
580−where_ wh tables = tables {whereClause = wh : whereClause tables}
584− => NP (By tables) bys
585− -> TableExpression params schema tables 'Ungrouped
586− -> TableExpression params schema tables ('Grouped bys)
587−group bys tables = TableExpression
588− { fromClause = fromClause tables
589− , whereClause = whereClause tables
590− , groupByClause = Group bys
591− , havingClause = Having []
592− , orderByClause = []
593− , limitClause = limitClause tables
594− , offsetClause = offsetClause tables
598− :: Condition params tables ('Grouped bys)
599− -> TableExpression params schema tables ('Grouped bys)
600− -> TableExpression params schema tables ('Grouped bys)
601−having hv tables = tables
602− { havingClause = case havingClause tables of Having hvs -> Having (hv:hvs) }
605− :: [SortExpression params tables grouping]
606− -> TableExpression params schema tables grouping
607− -> TableExpression params schema tables grouping
608−orderBy srts tables = tables {orderByClause = orderByClause tables ++ srts}
612− -> TableExpression params schema tables grouping
613− -> TableExpression params schema tables grouping
614−limit lim tables = tables {limitClause = lim : limitClause tables}
618− -> TableExpression params schema tables grouping
619− -> TableExpression params schema tables grouping
620−offset off tables = tables {offsetClause = off : offsetClause tables}
622−{-----------------------------------------
624−-----------------------------------------}
626−newtype TypeExpression (ty :: ColumnType)
627− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
630−bool :: TypeExpression ('Required ('Null 'PGbool))
631−bool = UnsafeTypeExpression "bool"
632−int2 :: TypeExpression ('Required ('Null 'PGint2))
633−int2 = UnsafeTypeExpression "int2"
634−smallint :: TypeExpression ('Required ('Null 'PGint2))
635−smallint = UnsafeTypeExpression "smallint"
636−int4 :: TypeExpression ('Required ('Null 'PGint4))
637−int4 = UnsafeTypeExpression "int4"
638−int :: TypeExpression ('Required ('Null 'PGint4))
639−int = UnsafeTypeExpression "int"
640−integer :: TypeExpression ('Required ('Null 'PGint4))
641−integer = UnsafeTypeExpression "integer"
642−int8 :: TypeExpression ('Required ('Null 'PGint8))
643−int8 = UnsafeTypeExpression "int8"
644−bigint :: TypeExpression ('Required ('Null 'PGint8))
645−bigint = UnsafeTypeExpression "bigint"
646−numeric :: TypeExpression ('Required ('Null 'PGnumeric))
647−numeric = UnsafeTypeExpression "numeric"
648−float4 :: TypeExpression ('Required ('Null 'PGfloat4))
649−float4 = UnsafeTypeExpression "float4"
650−real :: TypeExpression ('Required ('Null 'PGfloat4))
651−real = UnsafeTypeExpression "real"
652−float8 :: TypeExpression ('Required ('Null 'PGfloat8))
653−float8 = UnsafeTypeExpression "float8"
654−doublePrecision :: TypeExpression ('Required ('Null 'PGfloat8))
655−doublePrecision = UnsafeTypeExpression "double precision"
656−serial2 :: TypeExpression ('Optional ('NotNull 'PGint2))
657−serial2 = UnsafeTypeExpression "serial2"
658−smallserial :: TypeExpression ('Optional ('NotNull 'PGint2))
659−smallserial = UnsafeTypeExpression "smallserial"
660−serial4 :: TypeExpression ('Optional ('NotNull 'PGint4))
661−serial4 = UnsafeTypeExpression "serial4"
662−serial :: TypeExpression ('Optional ('NotNull 'PGint4))
663−serial = UnsafeTypeExpression "serial"
664−serial8 :: TypeExpression ('Optional ('NotNull 'PGint8))
665−serial8 = UnsafeTypeExpression "serial8"
666−bigserial :: TypeExpression ('Optional ('NotNull 'PGint8))
667−bigserial = UnsafeTypeExpression "bigserial"
668−text :: TypeExpression ('Required ('Null 'PGtext))
669−text = UnsafeTypeExpression "text"
673− -> TypeExpression ('Required ('Null ('PGchar n)))
674−char (_ :: proxy n) = UnsafeTypeExpression $
675− "char(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
679− -> TypeExpression ('Required ('Null ('PGchar n)))
680−character (_ :: proxy n) = UnsafeTypeExpression $
681− "character(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
685− -> TypeExpression ('Required ('Null ('PGvarchar n)))
686−varchar (_ :: proxy n) = UnsafeTypeExpression $
687− "varchar(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
691− -> TypeExpression ('Required ('Null ('PGvarchar n)))
692−characterVarying p = UnsafeTypeExpression $
693− "character varying(" <> renderNat p <> ")"
694−bytea :: TypeExpression ('Required ('Null ('PGbytea)))
695−bytea = UnsafeTypeExpression "bytea"
696−timestamp :: TypeExpression ('Required ('Null ('PGtimestamp)))
697−timestamp = UnsafeTypeExpression "timestamp"
698−timestampWithTimeZone :: TypeExpression ('Required ('Null ('PGtimestamptz)))
699−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
700−date :: TypeExpression ('Required ('Null ('PGdate)))
701−date = UnsafeTypeExpression "date"
702−time :: TypeExpression ('Required ('Null ('PGtime)))
703−time = UnsafeTypeExpression "time"
704−timeWithTimeZone :: TypeExpression ('Required ('Null ('PGtimetz)))
705−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
706−interval :: TypeExpression ('Required ('Null ('PGinterval)))
707−interval = UnsafeTypeExpression "interval"
708−uuid :: TypeExpression ('Required ('Null ('PGuuid)))
709−uuid = UnsafeTypeExpression "uuid"
710−json :: TypeExpression ('Required ('Null ('PGjson)))
711−json = UnsafeTypeExpression "json"
712−jsonb :: TypeExpression ('Required ('Null ('PGjsonb)))
713−jsonb = UnsafeTypeExpression "jsonb"
716− :: TypeExpression (optionality ('Null ty))
717− -> TypeExpression (optionality ('NotNull ty))
718−notNull ty = UnsafeTypeExpression $ renderTypeExpression ty <+> "NOT NULL"
720− :: Expression '[] '[] 'Ungrouped ('Required ty)
721− -> TypeExpression ('Required ty)
722− -> TypeExpression ('Optional ty)
723−default_ x ty = UnsafeTypeExpression $
724− renderTypeExpression ty <+> "DEFAULT" <+> renderExpression x
726−class PGTyped (ty :: PGType) where
727− pgtype :: TypeExpression ('Required ('Null ty))
728−instance PGTyped 'PGbool where pgtype = bool
729−instance PGTyped 'PGint2 where pgtype = int2
730−instance PGTyped 'PGint4 where pgtype = int4
731−instance PGTyped 'PGint8 where pgtype = int8
732−instance PGTyped 'PGnumeric where pgtype = numeric
733−instance PGTyped 'PGfloat4 where pgtype = float4
734−instance PGTyped 'PGfloat8 where pgtype = float8
735−instance PGTyped 'PGtext where pgtype = text
736−instance KnownNat n => PGTyped ('PGchar n) where pgtype = char (Proxy @n)
737−instance KnownNat n => PGTyped ('PGvarchar n) where pgtype = varchar (Proxy @n)
738−instance PGTyped 'PGbytea where pgtype = bytea
739−instance PGTyped 'PGtimestamp where pgtype = timestamp
740−instance PGTyped 'PGtimestamptz where pgtype = timestampWithTimeZone
741−instance PGTyped 'PGdate where pgtype = date
742−instance PGTyped 'PGtime where pgtype = time
743−instance PGTyped 'PGtimetz where pgtype = timeWithTimeZone
744−instance PGTyped 'PGinterval where pgtype = interval
745−instance PGTyped 'PGuuid where pgtype = uuid
746−instance PGTyped 'PGjson where pgtype = json
747−instance PGTyped 'PGjsonb where pgtype = jsonb
749−{-----------------------------------------
751−-----------------------------------------}
754− (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
755− (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
756− = UnsafeDefinition { renderDefinition :: ByteString }
758−instance Category Definition where
759− id = UnsafeDefinition ";"
760− ddl1 . ddl0 = UnsafeDefinition $
761− renderDefinition ddl0 <+> renderDefinition ddl1
764− (schema :: [(Symbol,[(Symbol,ColumnType)])])
765− (params :: [ColumnType])
766− (columns :: [(Symbol,ColumnType)])
767− = UnsafeManipulation { renderManipulation :: ByteString }
770− (schema :: [(Symbol,[(Symbol,ColumnType)])])
771− (params :: [ColumnType])
772− (columns :: [(Symbol,ColumnType)])
773− = UnsafeQuery { renderQuery :: ByteString }
776− :: Query schema params columns
777− -> Manipulation schema params columns
778−query q = UnsafeManipulation $ renderQuery q <> ";"
780−union, unionAll, intersect, intersectAll, except, exceptAll
781− :: Query schema params columns
782− -> Query schema params columns
783− -> Query schema params columns
784−q1 `union` q2 = UnsafeQuery $
785− parenthesized (renderQuery q1)
787− <+> parenthesized (renderQuery q2)
788−q1 `unionAll` q2 = UnsafeQuery $
789− parenthesized (renderQuery q1)
790− <+> "UNION" <+> "ALL"
791− <+> parenthesized (renderQuery q2)
792−q1 `intersect` q2 = UnsafeQuery $
793− parenthesized (renderQuery q1)
795− <+> parenthesized (renderQuery q2)
796−q1 `intersectAll` q2 = UnsafeQuery $
797− parenthesized (renderQuery q1)
798− <+> "INTERSECT" <+> "ALL"
799− <+> parenthesized (renderQuery q2)
800−q1 `except` q2 = UnsafeQuery $
801− parenthesized (renderQuery q1)
803− <+> parenthesized (renderQuery q2)
804−q1 `exceptAll` q2 = UnsafeQuery $
805− parenthesized (renderQuery q1)
806− <+> "EXCEPT" <+> "ALL"
807− <+> parenthesized (renderQuery q2)
809−{-----------------------------------------
811−-----------------------------------------}
815− => NP (Aliased (Expression params tables grouping)) columns
816− -> TableExpression params schema tables grouping
817− -> Query schema params columns
818−select list tabs = UnsafeQuery $
820− <+> renderCommaSeparated (renderAliased renderExpression) list
821− <+> renderTableExpression tabs
824− :: (tables ~ '[table ::: columns])
825− => TableExpression params schema tables 'Ungrouped
826− -> Query schema params columns
827−selectStar tabs = UnsafeQuery $ "SELECT" <+> "*" <+> renderTableExpression tabs
830− :: HasTable table tables columns
832− -> TableExpression params schema tables 'Ungrouped
833− -> Query schema params columns
834−selectDotStar table tables = UnsafeQuery $
835− "SELECT" <+> renderAlias table <> ".*" <+> renderTableExpression tables
839− => NP (Aliased (Expression params '[] 'Ungrouped)) columns
840− -> Query schema params columns
841−selectRow row = UnsafeQuery $
842− "SELECT" <+> renderCommaSeparated (renderAliased renderExpression) row
844−{-----------------------------------------
846−-----------------------------------------}
849− :: (KnownSymbol table, SListI columns)
851− -> NP (Aliased TypeExpression) columns
852− -> [TableConstraint schema columns]
853− -> Definition schema (Create table columns schema)
854−createTable table columns constraints = UnsafeDefinition $
855− "CREATE TABLE" <+> renderAlias table
857− ( renderCommaSeparated renderColumnDef columns
858− <> renderConstraints constraints )
861− renderColumnDef :: Aliased TypeExpression x -> ByteString
862− renderColumnDef (ty `As` column) =
863− renderAlias column <+> renderTypeExpression ty
864− renderConstraints :: [TableConstraint schema columns] -> ByteString
865− renderConstraints = \case
867− _ -> ", " <> commaSeparated (renderTableConstraint <$> constraints)
870− (schema :: [(Symbol,[(Symbol,ColumnType)])])
871− (columns :: [(Symbol,ColumnType)])
872− = UnsafeTableConstraint { renderTableConstraint :: ByteString }
875− :: Condition '[] '[table ::: columns] 'Ungrouped
876− -> TableConstraint schema columns
877−check condition = UnsafeTableConstraint $
878− "CHECK" <+> parenthesized (renderExpression condition)
881− (columns :: [(Symbol,ColumnType)])
882− (columnty :: (Symbol,ColumnType))
885− :: HasColumn column columns ty
887− -> Column columns (column ::: ty)
889−renderColumn :: Column columns columnty -> ByteString
890−renderColumn (Column column) = renderAlias column
893− :: SListI subcolumns
894− => NP (Column columns) subcolumns
895− -> TableConstraint schema columns
896−unique columns = UnsafeTableConstraint $
897− "UNIQUE" <+> parenthesized (renderCommaSeparated renderColumn columns)
900− :: (SListI subcolumns, NotNullTypes subcolumns)
901− => NP (Column columns) subcolumns
902− -> TableConstraint schema columns
903−primaryKey columns = UnsafeTableConstraint $
904− "PRIMARY KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
906−type family SameTypes columns0 columns1 :: Constraint where
907− SameTypes '[] '[] = ()
908− SameTypes ((column0 ::: ty0) ': columns0) ((column1 ::: ty1) ': columns1)
909− = (ty0 ~ ty1, SameTypes columns0 columns1)
911−type family NotNullTypes columns :: Constraint where
912− NotNullTypes '[] = ()
913− NotNullTypes ((column ::: (optionality ('NotNull ty))) ': columns)
914− = NotNullTypes columns
917− :: ( HasTable reftable schema refcolumns
918− , SameTypes subcolumns refsubcolumns
919− , NotNullTypes subcolumns
921− , SListI refsubcolumns)
922− => NP (Column columns) subcolumns
924− -> NP (Column refcolumns) refsubcolumns
925− -> TableConstraint schema columns
926−foreignKey columns reftable refcolumns = UnsafeTableConstraint $
927− "FOREIGN KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
928− <+> "REFERENCES" <+> renderAlias reftable
929− <+> parenthesized (renderCommaSeparated renderColumn refcolumns)
931−{-----------------------------------------
933−-----------------------------------------}
936− :: KnownSymbol table
938− -> Definition schema (Drop table schema)
939−dropTable table = UnsafeDefinition $ "DROP TABLE" <+> renderAlias table <> ";"
941−{-----------------------------------------
943−-----------------------------------------}
946− :: HasTable table schema columns0
948− -> AlterTable columns0 columns1
949− -> Definition schema (Alter table schema columns1)
950−alterTable table alteration = UnsafeDefinition $
952− <+> renderAlias table
953− <+> renderAlterTable alteration
957− :: (KnownSymbol table0, KnownSymbol table1)
960− -> Definition schema (Rename table0 table1 schema)
961−alterTableRename table0 table1 = UnsafeDefinition $
962− "ALTER TABLE" <+> renderAlias table0
963− <+> "RENAME TO" <+> renderAlias table1 <> ";"
966− (columns0 :: [(Symbol, ColumnType)])
967− (columns1 :: [(Symbol, ColumnType)]) =
968− UnsafeAlterTable {renderAlterTable :: ByteString}
971− :: KnownSymbol column
973− -> TypeExpression ('Optional ty)
974− -> AlterTable columns (Create column ('Optional ty) columns)
975−addColumnDefault column ty = UnsafeAlterTable $
976− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
979− :: KnownSymbol column
981− -> TypeExpression ('Required ('Null ty))
982− -> AlterTable columns ((column ::: 'Required ('Null ty)) ': columns)
983−addColumnNull column ty = UnsafeAlterTable $
984− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
987− :: KnownSymbol column
989− -> AlterTable columns (Drop column columns)
990−dropColumn column = UnsafeAlterTable $
991− "DROP COLUMN" <+> renderAlias column
994− :: (KnownSymbol column0, KnownSymbol column1)
997− -> AlterTable columns (Rename column0 column1 columns)
998−renameColumn column0 column1 = UnsafeAlterTable $
999− "RENAME COLUMN" <+> renderAlias column0 <+> "TO" <+> renderAlias column1
1002− :: (KnownSymbol column, HasColumn column columns ty0)
1004− -> AlterColumn ty0 ty1
1005− -> AlterTable columns (Alter column columns ty1)
1006−alterColumn column alteration = UnsafeAlterTable $
1007− "ALTER COLUMN" <+> renderAlias column <+> renderAlterColumn alteration
1009−data AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
1010− UnsafeAlterColumn {renderAlterColumn :: ByteString}
1013− :: Expression '[] '[] 'Ungrouped ('Required ty)
1014− -> AlterColumn ('Required ty) ('Optional ty)
1015−setDefault expression = UnsafeAlterColumn $
1016− "SET DEFAULT" <+> renderExpression expression
1018−dropDefault :: AlterColumn ('Optional ty) ('Required ty)
1019−dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
1022− :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
1023−setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
1026− :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
1027−dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
1030− :: TypeExpression (optionality (nullity ty1))
1031− -> AlterColumn (optionality (nullity ty0)) (optionality (nullity ty1))
1032−alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty
1034−{-----------------------------------------
1036−-----------------------------------------}
1039− :: (SListI columns, SListI results, HasTable table schema columns)
1041− -> ValuesClause schema params columns
1042− -> ConflictClause params columns
1043− -> ReturningClause params columns results
1044− -> Manipulation schema params results
1045−insertInto table insert conflict returning = UnsafeManipulation $
1046− "INSERT" <+> "INTO" <+> renderAlias table
1047− <+> renderValuesClause insert
1048− <> renderConflictClause conflict
1049− <> renderReturningClause returning
1052− (schema :: [(Symbol,[(Symbol,ColumnType)])])
1053− (params :: [ColumnType])
1054− (columns :: [(Symbol,ColumnType)])
1056− (NP (Aliased (Expression params '[] 'Ungrouped)) columns)
1057− [NP (Aliased (Expression params '[] 'Ungrouped)) columns]
1058− | ValuesQuery (Query schema params columns)
1062− => ValuesClause schema params columns
1064−renderValuesClause = \case
1066− parenthesized (renderCommaSeparated renderAliasPart row)
1069− (parenthesized . renderCommaSeparated renderValuePart <$> row:rows)
1071− renderAliasPart, renderValuePart
1072− :: Aliased (Expression params '[] 'Ungrouped) ty -> ByteString
1073− renderAliasPart (_ `As` name) = renderAlias name
1074− renderValuePart (value `As` _) = renderExpression value
1075− ValuesQuery q -> renderQuery q
1077−data ReturningClause
1078− (params :: [ColumnType])
1079− (columns :: [(Symbol,ColumnType)])
1080− (results :: [(Symbol,ColumnType)])
1082− ReturningNil :: ReturningClause params columns '[]
1083− ReturningStar :: ReturningClause params columns columns
1085− :: NP (Aliased (Expression params '[table ::: columns] 'Ungrouped)) results
1086− -> ReturningClause params columns results
1088−renderReturningClause
1090− => ReturningClause params columns results
1092−renderReturningClause = \case
1093− ReturningNil -> ";"
1094− ReturningStar -> " RETURNING *;"
1095− Returning results -> " RETURNING"
1096− <+> renderCommaSeparated (renderAliased renderExpression) results <> ";"
1098−data ConflictClause params columns where
1099− Conflict :: ConflictClause params columns
1100− OnConflictDoNothing :: ConflictClause params columns
1102− :: NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1103− -> Condition params '[table ::: columns] 'Ungrouped
1104− -> ConflictClause params columns
1106−renderConflictClause
1108− => ConflictClause params columns
1110−renderConflictClause = \case
1112− OnConflictDoNothing -> " ON CONFLICT DO NOTHING"
1113− OnConflictDoUpdate updates wh
1114− -> " ON CONFLICT DO UPDATE SET"
1115− <+> renderCommaSeparatedMaybe renderUpdateExpression updates
1116− <+> "WHERE" <+> renderExpression wh
1118−{-----------------------------------------
1120−-----------------------------------------}
1122−data UpdateExpression params table ty
1124− | Set (Expression params table 'Ungrouped ty)
1126−renderUpdateExpression
1127− :: Aliased (UpdateExpression params '[table ::: columns]) column
1128− -> Maybe ByteString
1129−renderUpdateExpression = \case
1130− Same `As` _ -> Nothing
1131− Set expression `As` column -> Just $
1132− renderAlias column <+> "=" <+> renderExpression expression
1135− :: (HasTable table schema columns, SListI columns, SListI results)
1137− -> NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1138− -> Condition params '[table ::: columns] 'Ungrouped
1139− -> ReturningClause params columns results
1140− -> Manipulation schema params results
1141−update table columns wh returning = UnsafeManipulation $
1143− <+> renderAlias table
1145− <+> renderCommaSeparatedMaybe renderUpdateExpression columns
1146− <+> "WHERE" <+> renderExpression wh
1147− <> renderReturningClause returning
1149−{-----------------------------------------
1151−-----------------------------------------}
1154− :: HasTable table schema columns
1156− -> Condition params '[table ::: columns] 'Ungrouped
1157− -> Manipulation schema params '[]
1158−deleteFrom table wh = UnsafeManipulation $
1159− "DELETE FROM" <+> renderAlias table
1160− <+> "WHERE" <+> renderExpression wh <> ";"
1162−{-----------------------------------------
1163−render helper functions
1164−-----------------------------------------}
1166−parenthesized :: ByteString -> ByteString
1167−parenthesized str = "(" <> str <> ")"
1169−(<+>) :: ByteString -> ByteString -> ByteString
1170−str1 <+> str2 = str1 <> " " <> str2
1172−commaSeparated :: [ByteString] -> ByteString
1173−commaSeparated = ByteString.intercalate ", "
1175−renderCommaSeparated
1177− => (forall x. expression x -> ByteString)
1178− -> NP expression xs -> ByteString
1179−renderCommaSeparated render
1182− . hmap (K . render)
1184−renderCommaSeparatedMaybe
1186− => (forall x. expression x -> Maybe ByteString)
1187− -> NP expression xs -> ByteString
1188−renderCommaSeparatedMaybe render
1192− . hmap (K . render)
1194−renderSymbol :: KnownSymbol str => Proxy# str -> ByteString
1195−renderSymbol p = fromString $ symbolVal' p
1197−renderNat :: KnownNat n => proxy n -> ByteString
1198−renderNat (_ :: proxy n) = fromString (show (natVal' (proxy# :: Proxy# n)))