@@ -1,6 +1,7 @@
1{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
1{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
2{-# LANGUAGE
2{-# LANGUAGE
4 , FlexibleInstances
5 , FlexibleInstances
5 , FunctionalDependencies
6 , FunctionalDependencies
@@ -16,9 +17,8 @@
17module Squeel.PostgreSQL.Statement where
18module Squeel.PostgreSQL.Statement where
20−import Data.Boolean.Numbers
21import Data.ByteString (ByteString)
20import Data.ByteString (ByteString)
22import Data.Maybe
22import Data.Maybe
23import Data.Monoid
23import Data.Monoid
24import Data.Ratio
24import Data.Ratio
@@ -179,6 +179,14 @@ instance (PGFloating ty, PGCast 'PGNumeric ty, PGTyped ty)
179 acosh 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
180 atanh x = log ((1 + x) / (1 - x)) / 2
184+ => Expression params tables ('Required (nullity float))
185+ -> Expression params tables ('Required (nullity float))
186+ -> Expression params tables ('Required (nullity float))
187+atan2 y x = UnsafeExpression $
188+ "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
182class PGCast (ty0 :: PGType) (ty1 :: PGType) where
190class PGCast (ty0 :: PGType) (ty1 :: PGType) where
184 :: TypeExpression ('Required ('Null ty1))
192 :: TypeExpression ('Required ('Null ty1))
@@ -199,52 +207,52 @@ instance PGCast 'PGInt8 'PGFloat4
199instance PGCast 'PGInt8 'PGFloat8
207instance PGCast 'PGInt8 'PGFloat8
200instance PGCast 'PGInt8 'PGNumeric
208instance PGCast 'PGInt8 'PGNumeric
202−instance (PGNum ty, PGTyped ty, PGCast 'PGInt8 ty)
211+ :: (PGNum ty, PGTyped ty, PGCast 'PGInt8 ty, PGCast ty 'PGInt8)
203− => NumB (Expression params tables ('Required (nullity ty))) where
212+ => Expression params tables ('Required (nullity ty))
204− type IntegerOf (Expression params tables ('Required (nullity ty)))
213+ -> Expression params tables ('Required (nullity ty))
205− = (Expression params tables ('Required (nullity 'PGInt8)))
214+ -> Expression params tables ('Required (nullity ty))
206− fromIntegerB = cast pgtype
215+div = unsafeBinaryOp "/"
208−instance (PGNum ty, PGTyped ty, PGCast 'PGInt8 ty, PGCast ty 'PGInt8)
218+ :: (PGNum ty, PGTyped ty, PGCast 'PGInt8 ty, PGCast ty 'PGInt8)
209− => IntegralB (Expression params tables ('Required ('NotNull ty))) where
219+ => Expression params tables ('Required (nullity ty))
210− quot = unsafeBinaryOp "/"
220+ -> Expression params tables ('Required (nullity ty))
211− rem = unsafeBinaryOp "%"
221+ -> Expression params tables ('Required (nullity ty))
212− div = unsafeBinaryOp "/"
213− mod = unsafeBinaryOp "%"
222+mod = unsafeBinaryOp "%"
214− toIntegerB = cast int8
223+
216−instance
225+ :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
217− ( IntegerOf (Expression params tables ('Required ('NotNull ty)))
226+ => Expression params tables ('Required (nullity frac))
218− ~ (Expression params tables ('Required ('NotNull 'PGInt8)))
227+ -> Expression params tables ('Required (nullity int))
219− , PGNum ty
228+truncate = cast pgtype . truncate'
220− , PGTyped ty
229+ where
221− , PGCast 'PGInt8 ty
230+ truncate'
224− => RealFracB (Expression params tables ('Required ('NotNull ty))) where
231+ :: Expression params tables ('Required (nullity frac))
225− properFraction x = (truncate x, x - unsafeFunction "trunc" x)
232+ -> Expression params tables ('Required (nullity 'PGInt4))
226− truncate = fromIntegerB . unsafeFunction "trunc"
233+ truncate' = unsafeFunction "trunc"
227− round = fromIntegerB . unsafeFunction "round"
234+
228− ceiling = fromIntegerB . unsafeFunction "ceiling"
235+round
229− floor = fromIntegerB . unsafeFunction "floor"
236+ :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
230−
237+ => Expression params tables ('Required (nullity frac))
231−instance
238+ -> Expression params tables ('Required (nullity int))
239+round = cast pgtype . round'
232− ( IntegerOf (Expression params tables ('Required ('NotNull ty)))
242+ :: Expression params tables ('Required (nullity frac))
233− ~ (Expression params tables ('Required ('NotNull 'PGInt8)))
243+ -> Expression params tables ('Required (nullity 'PGInt4))
234− , PGNum ty
244+ round' = unsafeFunction "round"
236− , PGCast 'PGInt8 ty
246+ceiling
237− , PGCast 'PGNumeric ty
247+ :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
240− => RealFloatB (Expression params tables ('Required ('NotNull ty))) where
248+ => Expression params tables ('Required (nullity frac))
241− isNaN x = x ==* UnsafeExpression "\'NaN\'"
249+ -> Expression params tables ('Required (nullity int))
242− isInfinite x = x ==* UnsafeExpression "\'Infinity\'"
250+ceiling = cast pgtype . ceiling'
243− ||* x ==* UnsafeExpression "\'-Infinity\'"
251+ where
244− isNegativeZero x = x ==* UnsafeExpression "-0"
252+ ceiling'
245− isIEEE _ = true
253+ :: Expression params tables ('Required (nullity frac))
246− atan2 y x = UnsafeExpression $
254+ -> Expression params tables ('Required (nullity 'PGInt4))
247− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
255+ ceiling' = unsafeFunction "ceiling"
249instance IsString (Expression params tables ('Required (nullity 'PGText))) where
257instance IsString (Expression params tables ('Required (nullity 'PGText))) where
250 fromString str = UnsafeExpression $
258 fromString str = UnsafeExpression $
@@ -261,18 +269,33 @@ instance IsString (Expression params tables ('Required (nullity 'PGText))) where
261 '\\' -> "\\\\"
269 '\\' -> "\\\\"
264−instance Boolean (Expression params tables ('Required ('NotNull 'PGBool))) where
272+type Predicate params tables = Expression params tables ('Required ('NotNull 'PGBool))
274+true :: Predicate params tables
265− true = UnsafeExpression "TRUE"
275+true = UnsafeExpression "TRUE"
266− false = UnsafeExpression "FALSE"
267− notB = unsafeUnaryOp "NOT"
268− (&&*) = unsafeBinaryOp "AND"
269− (||*) = unsafeBinaryOp "OR"
271−type instance BooleanOf (Expression params tables ty) =
277+false :: Predicate params tables
272− Expression params tables ('Required ('NotNull 'PGBool))
278+false = UnsafeExpression "FALSE"
281+ :: Predicate params tables
282+ -> Predicate params tables
283+notB = unsafeUnaryOp "NOT"
286+ :: Predicate params tables
287+ -> Predicate params tables
288+ -> Predicate params tables
289+(&&*) = unsafeBinaryOp "AND"
292+ :: Predicate params tables
293+ -> Predicate params tables
294+ -> Predicate params tables
295+(||*) = unsafeBinaryOp "OR"
274caseWhenThenElse
297caseWhenThenElse
275− :: [(Expression params tables ('Required ('NotNull 'PGBool)), Expression params tables ty)]
298+ :: [(Predicate params tables, Expression params tables ty)]
276 -> Expression params tables ty
299 -> Expression params tables ty
277 -> Expression params tables ty
300 -> Expression params tables ty
278caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
301caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
@@ -288,34 +311,64 @@ caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
315+ :: Predicate params tables
291−instance IfB (Expression params tables ty) where
316+ -> Expression params tables ty
317+ -> Expression params tables ty
318+ -> Expression params tables ty
292− ifB if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
319+ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
322+ :: Expression params tables ty
323+ -> Expression params tables ty
324+ -> Predicate params tables
325+(==*) = unsafeBinaryOp "="
328+ :: Expression params tables ty
329+ -> Expression params tables ty
330+ -> Predicate params tables
331+(/=*) = unsafeBinaryOp "<>"
334+ :: Expression params tables ty
335+ -> Expression params tables ty
336+ -> Predicate params tables
337+(>=*) = unsafeBinaryOp ">="
340+ :: Expression params tables ty
341+ -> Expression params tables ty
342+ -> Predicate params tables
343+(<*) = unsafeBinaryOp "<"
294−instance EqB (Expression params tables (optionality ('NotNull ty))) where
346+ :: Expression params tables ty
295− (==*) = unsafeBinaryOp "="
347+ -> Expression params tables ty
348+ -> Predicate params tables
296− (/=*) = unsafeBinaryOp "<>"
349+(<=*) = unsafeBinaryOp "<="
298−instance OrdB (Expression params tables (optionality ('NotNull ty))) where
352+ :: Expression params tables ty
353+ -> Expression params tables ty
354+ -> Predicate params tables
299− (>*) = unsafeBinaryOp ">"
355+(>*) = unsafeBinaryOp ">"
300− (>=*) = unsafeBinaryOp ">="
301− (<*) = unsafeBinaryOp "<"
302− (<=*) = unsafeBinaryOp "<="
304{-----------------------------------------
357{-----------------------------------------
305−table expressions
358+tables
306-----------------------------------------}
359-----------------------------------------}
308−newtype TableExpression
361+newtype Table
309 (params :: [ColumnType])
362 (params :: [ColumnType])
310 (schema :: [(Symbol,[(Symbol,ColumnType)])])
363 (schema :: [(Symbol,[(Symbol,ColumnType)])])
311 (columns :: [(Symbol,ColumnType)])
364 (columns :: [(Symbol,ColumnType)])
312− = UnsafeTableExpression { renderTableExpression :: ByteString }
365+ = UnsafeTable { renderTable :: ByteString }
313 deriving (Show,Eq)
366 deriving (Show,Eq)
315class KnownSymbol table => HasTable table tables columns
368class KnownSymbol table => HasTable table tables columns
316 | table tables -> columns where
369 | table tables -> columns where
317− getTable :: Proxy# table -> TableExpression params tables columns
370+ getTable :: Proxy# table -> Table params tables columns
318− getTable table = UnsafeTableExpression $ fromString $ symbolVal' table
371+ getTable table = UnsafeTable $ fromString $ symbolVal' table
319instance {-# OVERLAPPING #-} KnownSymbol table
372instance {-# OVERLAPPING #-} KnownSymbol table
320 => HasTable table ((table ::: columns) ': tables) columns
373 => HasTable table ((table ::: columns) ': tables) columns
321instance {-# OVERLAPPABLE #-}
374instance {-# OVERLAPPABLE #-}
@@ -323,7 +376,7 @@ instance {-# OVERLAPPABLE #-}
323 => HasTable table (table' ': schema) columns
376 => HasTable table (table' ': schema) columns
325instance HasTable table schema columns
378instance HasTable table schema columns
326− => IsLabel table (TableExpression params schema columns) where
379+ => IsLabel table (Table params schema columns) where
327 fromLabel = getTable
380 fromLabel = getTable
329{-----------------------------------------
382{-----------------------------------------
@@ -338,13 +391,13 @@ newtype Statement
338 = UnsafeStatement { renderStatement :: ByteString }
391 = UnsafeStatement { renderStatement :: ByteString }
339 deriving (Show,Eq)
392 deriving (Show,Eq)
341−newtype PreparedStatement
394+-- newtype PreparedStatement
342− (params :: [ColumnType])
395+-- (params :: [ColumnType])
343− (columns :: [(Symbol,ColumnType)])
396+-- (columns :: [(Symbol,ColumnType)])
344− (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
397+-- (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
345− (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
398+-- (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
346− = UnsafePreparedStatement { renderPreparedStatement :: ByteString }
399+-- = UnsafePreparedStatement { renderPreparedStatement :: ByteString }
347− deriving (Show,Eq)
400+-- deriving (Show,Eq)
349{-----------------------------------------
402{-----------------------------------------
350SELECT statements
403SELECT statements
@@ -352,71 +405,71 @@ SELECT statements
353data Join params schema tables where
406data Join params schema tables where
355− :: Aliased (TableExpression params schema) table
408+ :: Aliased (Table params schema) table
356 -> Join params schema '[table]
409 -> Join params schema '[table]
357 Subselect
410 Subselect
358 :: Aliased (Selection params schema) table
411 :: Aliased (Selection params schema) table
359 -> Join params schema '[table]
412 -> Join params schema '[table]
361− :: Aliased (TableExpression params schema) table
414+ :: Aliased (Table params schema) table
362 -> Join params schema tables
415 -> Join params schema tables
363 -> Join params schema (table ': tables)
416 -> Join params schema (table ': tables)
365− :: Aliased (TableExpression params schema) table
418+ :: Aliased (Table params schema) table
366− -> Expression params (table ': tables) ('Required ('NotNull 'PGBool))
419+ -> Predicate params (table ': tables)
367 -> Join params schema tables
420 -> Join params schema tables
368 -> Join params schema (table ': tables)
421 -> Join params schema (table ': tables)
369 LeftOuter
422 LeftOuter
370− :: Aliased (TableExpression params schema) right
423+ :: Aliased (Table params schema) right
371− -> Expression params '[left,right] ('Required ('NotNull 'PGBool))
424+ -> Predicate params '[left,right]
372 -> Join params schema (tables)
425 -> Join params schema (tables)
373 -> Join params schema (NullifyTable right ': left ': tables)
426 -> Join params schema (NullifyTable right ': left ': tables)
374 RightOuter
427 RightOuter
375− :: Aliased (TableExpression params schema) right
428+ :: Aliased (Table params schema) right
376− -> Expression params '[left,right] ('Required ('NotNull 'PGBool))
429+ -> Predicate params '[left,right]
377 -> Join params schema (left : tables)
430 -> Join params schema (left : tables)
378 -> Join params schema (right ': NullifyTable left ': tables)
431 -> Join params schema (right ': NullifyTable left ': tables)
379 FullOuter
432 FullOuter
380− :: Aliased (TableExpression params schema) right
433+ :: Aliased (Table params schema) right
381− -> Expression params '[left,right] ('Required ('NotNull 'PGBool))
434+ -> Predicate params '[left,right]
382 -> Join params schema (left : tables)
435 -> Join params schema (left : tables)
383 -> Join params schema
436 -> Join params schema
384 (NullifyTable right ': NullifyTable left ': tables)
437 (NullifyTable right ': NullifyTable left ': tables)
386renderJoin :: Join params schema tables -> ByteString
439renderJoin :: Join params schema tables -> ByteString
387renderJoin = \case
440renderJoin = \case
388− Table table -> renderAliased renderTableExpression table
441+ Table table -> renderAliased renderTable table
389 Subselect selection -> "SELECT " <> renderAliased renderSelection selection
442 Subselect selection -> "SELECT " <> renderAliased renderSelection selection
390 Cross table tables -> mconcat
443 Cross table tables -> mconcat
391 [ renderJoin tables
444 [ renderJoin tables
392 , " CROSS JOIN "
445 , " CROSS JOIN "
393− , renderAliased renderTableExpression table
446+ , renderAliased renderTable table
395 Inner table on tables -> mconcat
448 Inner table on tables -> mconcat
396 [ renderJoin tables
449 [ renderJoin tables
397 , " INNER JOIN "
450 , " INNER JOIN "
398− , renderAliased renderTableExpression table
451+ , renderAliased renderTable table
400 , renderExpression on
453 , renderExpression on
402 LeftOuter table on tables -> mconcat
455 LeftOuter table on tables -> mconcat
403 [ renderJoin tables
456 [ renderJoin tables
404 , " LEFT OUTER JOIN "
457 , " LEFT OUTER JOIN "
405− , renderAliased renderTableExpression table
458+ , renderAliased renderTable table
407 , renderExpression on
460 , renderExpression on
409 RightOuter table on tables -> mconcat
462 RightOuter table on tables -> mconcat
410 [ renderJoin tables
463 [ renderJoin tables
411 , " RIGHT OUTER JOIN "
464 , " RIGHT OUTER JOIN "
412− , renderAliased renderTableExpression table
465+ , renderAliased renderTable table
414 , renderExpression on
467 , renderExpression on
416 FullOuter table on tables -> mconcat
469 FullOuter table on tables -> mconcat
417 [ renderJoin tables
470 [ renderJoin tables
418 , " FULL OUTER JOIN "
471 , " FULL OUTER JOIN "
419− , renderAliased renderTableExpression table
472+ , renderAliased renderTable table
421 , renderExpression on
474 , renderExpression on
@@ -425,78 +478,67 @@ instance HasTable table schema columns
425 => IsLabel table (Join params schema '[table ::: columns]) where
478 => IsLabel table (Join params schema '[table ::: columns]) where
426 fromLabel p = Table $ fromLabel p
479 fromLabel p = Table $ fromLabel p
428−data Clauses params tables = Clauses
481+data TableExpression
429− { whereClause :: Maybe (Expression params tables ('Required ('NotNull 'PGBool)))
430− , limitClause :: Maybe (Expression params '[] ('Required ('NotNull 'PGInt8)))
431− , offsetClause :: Maybe (Expression params '[] ('Required ('NotNull 'PGInt8)))
434−instance Monoid (Clauses params tables) where
435− mempty = Clauses Nothing Nothing Nothing
436− Clauses wh1 lim1 off1 `mappend` Clauses wh2 lim2 off2 = Clauses
437− { whereClause = case (wh1,wh2) of
438− (Nothing,Nothing) -> Nothing
439− (Just w1,Nothing) -> Just w1
440− (Nothing,Just w2) -> Just w2
441− (Just w1,Just w2) -> Just (w1 &&* w2)
442− , limitClause = case (lim1,lim2) of
443− (Nothing,Nothing) -> Nothing
444− (Just l1,Nothing) -> Just l1
445− (Nothing,Just l2) -> Just l2
446− (Just l1,Just l2) -> Just (l1 `minB` l2)
447− , offsetClause = case (off1,off2) of
448− (Nothing,Nothing) -> Nothing
449− (Just o1,Nothing) -> Just o1
450− (Nothing,Just o2) -> Just o2
451− (Just o1,Just o2) -> Just (o1 + o2)
455 (params :: [ColumnType])
482 (params :: [ColumnType])
456 (schema :: [(Symbol,[(Symbol,ColumnType)])])
483 (schema :: [(Symbol,[(Symbol,ColumnType)])])
457 (tables :: [(Symbol,[(Symbol,ColumnType)])])
484 (tables :: [(Symbol,[(Symbol,ColumnType)])])
458− = From
485+ = TableExpression
459− { fromJoin :: Join params schema tables
486+ { joinClause :: Join params schema tables
460− , fromClauses :: Clauses params tables
487+ , whereClause :: [Predicate params tables]
488+ , limitClause :: [Expression params '[] ('Required ('NotNull 'PGInt8))]
489+ , offsetClause :: [Expression params '[] ('Required ('NotNull 'PGInt8))]
464− :: Join params schema tables
465− -> From params schema tables
466−join tables = From tables mempty
468−renderFrom :: From params schema tables -> ByteString
492+renderTableExpression :: TableExpression params schema tables -> ByteString
469−renderFrom (From tref (Clauses wh lim off))= mconcat
493+renderTableExpression (TableExpression tables whs' lims' offs') = mconcat
470− [ renderJoin tref
494+ [ renderJoin tables
496+ , renderLimits lims'
497+ , renderOffsets offs'
499+ renderWheres = \case
501+ wh:[] -> " WHERE " <> renderExpression wh
471− , maybe "" ((" WHERE " <>) . renderExpression) wh
502+ wh:whs -> " WHERE " <> renderExpression (foldr (&&*) wh whs)
503+ renderLimits = \case
505+ lim:[] -> " LIMIT " <> renderExpression lim
472− , maybe "" ((" LIMIT " <>) . renderExpression) lim
508+ , ByteString.intercalate ", " (renderExpression <$> reverse lims)
511+ renderOffsets = \case
513+ off:[] -> " OFFSET " <> renderExpression off
473− , maybe "" ((" OFFSET " <>) . renderExpression) off
514+ off:offs -> " OFFSET " <> renderExpression (foldr (+) off offs)
476instance (HasTable table schema columns, table ~ table')
516instance (HasTable table schema columns, table ~ table')
477− => IsLabel table (From params schema '[table' ::: columns]) where
517+ => IsLabel table (TableExpression params schema '[table' ::: columns]) where
478− fromLabel p = From (fromLabel p) mempty
518+ fromLabel p = join (fromLabel p)
521+ :: Join params schema tables
522+ -> TableExpression params schema tables
523+join tables = TableExpression tables [] [] []
481− :: Expression params tables ('Required ('NotNull 'PGBool))
526+ :: Predicate params tables
482− -> From params schema tables
527+ -> TableExpression params schema tables
483− -> From params schema tables
528+ -> TableExpression params schema tables
484−where_ wh (From tabs fromClauses1) = From tabs
529+where_ wh (TableExpression tabs whs lims offs) = TableExpression tabs (wh:whs) lims offs
485− (fromClauses1 <> Clauses (Just wh) Nothing Nothing)
488 :: Expression params '[] ('Required ('NotNull 'PGInt8))
532 :: Expression params '[] ('Required ('NotNull 'PGInt8))
489− -> From params schema tables
533+ -> TableExpression params schema tables
490− -> From params schema tables
534+ -> TableExpression params schema tables
491−limit lim (From tabs fromClauses1) = From tabs
535+limit lim (TableExpression tabs whs lims offs) = TableExpression tabs whs (lim:lims) offs
492− (fromClauses1 <> Clauses Nothing (Just lim) Nothing)
495 :: Expression params '[] ('Required ('NotNull 'PGInt8))
538 :: Expression params '[] ('Required ('NotNull 'PGInt8))
496− -> From params schema tables
539+ -> TableExpression params schema tables
497− -> From params schema tables
540+ -> TableExpression params schema tables
498−offset off (From tabs fromClauses1) = From tabs
541+offset off (TableExpression tabs whs lims offs) = TableExpression tabs whs lims (off:offs)
499− (fromClauses1 <> Clauses Nothing Nothing (Just off))
501newtype Selection
543newtype Selection
502 (params :: [ColumnType])
544 (params :: [ColumnType])
@@ -507,25 +549,25 @@ newtype Selection
509 :: tables ~ '[table ::: columns]
551 :: tables ~ '[table ::: columns]
510− => From params schema tables
552+ => TableExpression params schema tables
511 -> Selection params schema columns
553 -> Selection params schema columns
512−starFrom tabs = UnsafeSelection $ "* FROM " <> renderFrom tabs
554+starFrom tabs = UnsafeSelection $ "* FROM " <> renderTableExpression tabs
514dotStarFrom
556dotStarFrom
515 :: HasTable table tables columns
557 :: HasTable table tables columns
516 => Alias table
558 => Alias table
517− -> From params schema tables
559+ -> TableExpression params schema tables
518 -> Selection params schema columns
560 -> Selection params schema columns
519Alias tab `dotStarFrom` tabs = UnsafeSelection $
561Alias tab `dotStarFrom` tabs = UnsafeSelection $
520− fromString (symbolVal' tab) <> ".* FROM " <> renderFrom tabs
562+ fromString (symbolVal' tab) <> ".* FROM " <> renderTableExpression tabs
523 :: SListI columns
565 :: SListI columns
524 => NP (Aliased (Expression params tables)) columns
566 => NP (Aliased (Expression params tables)) columns
525− -> From params schema tables
567+ -> TableExpression params schema tables
526 -> Selection params schema columns
568 -> Selection params schema columns
527list `from` tabs = UnsafeSelection $
569list `from` tabs = UnsafeSelection $
528− renderList list <> " FROM " <> renderFrom tabs
570+ renderList list <> " FROM " <> renderTableExpression tabs
530 renderList
572 renderList
531 = ByteString.intercalate ", "
573 = ByteString.intercalate ", "
@@ -539,34 +581,8 @@ select = UnsafeStatement . ("SELECT " <>) . (<> ";") . renderSelection
541 :: Aliased (Selection params schema) table
583 :: Aliased (Selection params schema) table
542− -> From params schema '[table]
584+ -> TableExpression params schema '[table]
543−subselect selection = From
585+subselect selection = join (Subselect selection)
544− { fromJoin = Subselect selection
545− , fromClauses = mempty
548−{-----------------------------------------
550−-----------------------------------------}
553− :: (SListI columns, HasTable table schema columns)
555− -> NP (Aliased (Expression params '[])) columns
556− -> Statement params '[] schema schema
557−insertInto (Alias table) expressions = UnsafeStatement $ "INSERT INTO "
558− <> fromString (symbolVal' table)
559− <> " (" <> ByteString.intercalate ", " aliases
561− <> ByteString.intercalate ", " values
564− aliases = hcollapse $ hmap
565− (\ (_ `As` Alias name) -> K (fromString (symbolVal' name)))
567− values = hcollapse $ hmap
568− (\ (expression `As` _) -> K (renderExpression expression))
571{-----------------------------------------
587{-----------------------------------------
572CREATE statements
588CREATE statements
@@ -732,37 +748,189 @@ instance {-# OVERLAPPABLE #-}
732 DropTable table schema0 schema1
748 DropTable table schema0 schema1
733 => DropTable table (table' ': schema0) (table' ': schema1)
749 => DropTable table (table' ': schema0) (table' ': schema1)
751+{-----------------------------------------
753+-----------------------------------------}
756+ :: (SListI columns, HasTable table schema columns)
758+ -> NP (Aliased (Expression params '[])) columns
759+ -> Statement params '[] schema schema
760+insertInto (Alias table) expressions = UnsafeStatement $ "INSERT INTO "
761+ <> fromString (symbolVal' table)
762+ <> " (" <> ByteString.intercalate ", " aliases
764+ <> ByteString.intercalate ", " values
767+ aliases = hcollapse $ hmap
768+ (\ (_ `As` Alias name) -> K (fromString (symbolVal' name)))
770+ values = hcollapse $ hmap
771+ (\ (expression `As` _) -> K (renderExpression expression))
775+ :: (SListI columns, SListI results, HasTable table schema columns)
777+ -> NP (Aliased (Expression params '[])) columns
778+ -> NP (Aliased (Expression params '[table ::: columns])) results
779+ -> Statement params results schema schema
780+insertIntoReturning (Alias table) inserts results
781+ = UnsafeStatement . mconcat $
783+ , fromString (symbolVal' table)
784+ , " (" <> ByteString.intercalate ", " aliases
786+ , ByteString.intercalate ", " values
788+ , renderList results
792+ aliases = hcollapse $ hmap
793+ (\ (_ `As` Alias name) -> K (fromString (symbolVal' name)))
795+ values = hcollapse $ hmap
796+ (\ (expression `As` _) -> K (renderExpression expression))
799+ = ByteString.intercalate ", "
801+ . hmap (K . renderAliased renderExpression)
735{-----------------------------------------
803{-----------------------------------------
736UPDATE statements
804UPDATE statements
737-----------------------------------------}
805-----------------------------------------}
739−set :: g x -> (Maybe :.: g) x
807+set :: Expression params tables x -> (Maybe :.: Expression params tables) x
740set = Comp . Just
808set = Comp . Just
742−same :: (Maybe :.: g) x
810+same :: (Maybe :.: Expression params tables) x
743same = Comp Nothing
811same = Comp Nothing
814+ :: Aliased (Maybe :.: Expression params '[table ::: columns]) column
817+ Comp (Just expression) `As` Alias column -> Just $ mconcat
818+ [ fromString $ symbolVal' column
820+ , renderExpression expression
822+ Comp Nothing `As` _ -> Nothing
746 :: (HasTable table schema columns, SListI columns)
825 :: (HasTable table schema columns, SListI columns)
747 => Alias table
826 => Alias table
748 -> NP (Aliased (Maybe :.: Expression params '[table ::: columns])) columns
827 -> NP (Aliased (Maybe :.: Expression params '[table ::: columns])) columns
749− -> Expression params '[table ::: columns] ('Required ('NotNull 'PGBool))
828+ -> Predicate params '[table ::: columns]
750 -> Statement params '[] schema schema
829 -> Statement params '[] schema schema
751−update (Alias table) columns where' = UnsafeStatement $ mconcat
830+update (Alias table) columns wh = UnsafeStatement $ mconcat
752 [ "UPDATE "
831 [ "UPDATE "
753 , fromString $ symbolVal' table
832 , fromString $ symbolVal' table
754 , " SET "
833 , " SET "
755 , ByteString.intercalate ", " . catMaybes . hcollapse $
834 , ByteString.intercalate ", " . catMaybes . hcollapse $
756 hmap (K . renderSet) columns
835 hmap (K . renderSet) columns
757− , " WHERE ", renderExpression where'
836+ , " WHERE ", renderExpression wh, ";"
840+ :: (SListI columns, SListI results, HasTable table schema columns)
842+ -> NP (Aliased (Maybe :.: Expression params '[table ::: columns])) columns
843+ -> Predicate params '[table ::: columns]
844+ -> NP (Aliased (Expression params '[table ::: columns])) results
845+ -> Statement params results schema schema
846+updateReturning (Alias table) updates wh results = UnsafeStatement $ mconcat
848+ , fromString $ symbolVal' table
850+ , ByteString.intercalate ", " . catMaybes . hcollapse $
851+ hmap (K . renderSet) updates
852+ , " WHERE ", renderExpression wh
853+ , " RETURNING ", renderList results
858+ = ByteString.intercalate ", "
860+ . hmap (K . renderAliased renderExpression)
863+ :: (SListI columns, HasTable table schema columns)
865+ -> NP (Aliased (Expression params '[])) columns
866+ -> NP (Aliased (Maybe :.: Expression params '[table ::: columns])) columns
867+ -> Predicate params '[table ::: columns]
868+ -> Statement params '[] schema schema
869+upsertInto (Alias table) inserts updates wh = UnsafeStatement . mconcat $
871+ , fromString (symbolVal' table)
872+ , " (" <> ByteString.intercalate ", " aliases
874+ , ByteString.intercalate ", " values
875+ , ") ON CONFLICT UPDATE "
876+ , fromString $ symbolVal' table
878+ , ByteString.intercalate ", " . catMaybes . hcollapse $
879+ hmap (K . renderSet) updates
880+ , " WHERE ", renderExpression wh, ";"
759− renderSet
882+ aliases = hcollapse $ hmap
760− :: Aliased (Maybe :.: Expression params tables) column
883+ (\ (_ `As` Alias name) -> K (fromString (symbolVal' name)))
761− -> Maybe ByteString
884+ inserts
762− renderSet = \case
885+ values = hcollapse $ hmap
763− Comp (Just expression) `As` Alias column -> Just $ mconcat
886+ (\ (expression `As` _) -> K (renderExpression expression))
890+ :: (SListI columns, SListI results, HasTable table schema columns)
892+ -> NP (Aliased (Expression params '[])) columns
893+ -> NP (Aliased (Maybe :.: Expression params '[table ::: columns])) columns
894+ -> Predicate params '[table ::: columns]
895+ -> NP (Aliased (Expression params '[table ::: columns])) results
896+ -> Statement params results schema schema
897+upsertIntoReturning (Alias table) inserts updates wh results = UnsafeStatement . mconcat $
899+ , fromString (symbolVal' table)
900+ , " (" <> ByteString.intercalate ", " aliases
902+ , ByteString.intercalate ", " values
903+ , ") ON CONFLICT UPDATE "
904+ , fromString $ symbolVal' table
906+ , ByteString.intercalate ", " . catMaybes . hcollapse $
907+ hmap (K . renderSet) updates
908+ , " WHERE ", renderExpression wh
909+ , " RETURNING ", renderList results
912+ aliases = hcollapse $ hmap
913+ (\ (_ `As` Alias name) -> K (fromString (symbolVal' name)))
915+ values = hcollapse $ hmap
916+ (\ (expression `As` _) -> K (renderExpression expression))
919+ = ByteString.intercalate ", "
921+ . hmap (K . renderAliased renderExpression)
923+{-----------------------------------------
925+-----------------------------------------}
928+ :: (HasTable table schema columns, SListI columns)
930+ -> Predicate params '[table ::: columns]
931+ -> Statement params '[] schema schema
932+deleteFrom (Alias table) wh = UnsafeStatement $ mconcat
764− [ fromString $ symbolVal' column
934+ , fromString $ symbolVal' table
766− , renderExpression expression
935+ , " WHERE ", renderExpression wh, ";"
768− Comp Nothing `As` _ -> Nothing