on dev help sign in
use lists for modifier clauses
f53dc5bEitan Chatav
squeel-postgresql/src/Squeel/PostgreSQL/Statement.hs+33−46
@@ -19,6 +19,7 @@ module Squeel.PostgreSQL.Statement where
19import Data.Boolean
19import Data.Boolean
20import Data.Boolean.Numbers
20import Data.Boolean.Numbers
21import Data.ByteString (ByteString)
21import Data.ByteString (ByteString)
22+import Data.Foldable
22import Data.Maybe
23import Data.Maybe
23import Data.Monoid
24import Data.Monoid
24import Data.Ratio
25import Data.Ratio
@@ -425,78 +426,67 @@ instance HasTable table schema columns
425 => IsLabel table (Join params schema '[table ::: columns]) where
426 => IsLabel table (Join params schema '[table ::: columns]) where
426 fromLabel p = Table $ fromLabel p
427 fromLabel p = Table $ fromLabel p
427
428
428−data Clauses params tables = Clauses
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)))
432− }
433−
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)
452− }
453−
454data From
429data From
455 (params :: [ColumnType])
430 (params :: [ColumnType])
456 (schema :: [(Symbol,[(Symbol,ColumnType)])])
431 (schema :: [(Symbol,[(Symbol,ColumnType)])])
457 (tables :: [(Symbol,[(Symbol,ColumnType)])])
432 (tables :: [(Symbol,[(Symbol,ColumnType)])])
458 = From
433 = From
459− { fromJoin :: Join params schema tables
434+ { joinClause :: Join params schema tables
460− , fromClauses :: Clauses params tables
435+ , whereClause :: [Expression params tables ('Required ('NotNull 'PGBool))]
436+ , limitClause :: [Expression params '[] ('Required ('NotNull 'PGInt8))]
437+ , offsetClause :: [Expression params '[] ('Required ('NotNull 'PGInt8))]
461 }
438 }
462
439
463join
440join
464 :: Join params schema tables
441 :: Join params schema tables
465 -> From params schema tables
442 -> From params schema tables
466−join tables = From tables mempty
443+join tables = From tables [] [] []
467
444
468renderFrom :: From params schema tables -> ByteString
445renderFrom :: From params schema tables -> ByteString
469−renderFrom (From tref (Clauses wh lim off))= mconcat
446+renderFrom (From tables whs' lims' offs') = mconcat
470− [ renderJoin tref
447+ [ renderJoin tables
448+ , renderWheres whs'
449+ , renderLimits lims'
450+ , renderOffsets offs'
451+ ] where
452+ renderWheres = \case
453+ [] -> ""
454+ wh:[] -> " WHERE " <> renderExpression wh
471− , maybe "" ((" WHERE " <>) . renderExpression) wh
455+ wh:whs -> " WHERE " <> renderExpression (foldr (&&*) wh whs)
456+ renderLimits = \case
457+ [] -> ""
458+ lim:[] -> " LIMIT " <> renderExpression lim
459+ lims -> mconcat
460+ [ " LIMIT LEAST("
472− , maybe "" ((" LIMIT " <>) . renderExpression) lim
461+ , ByteString.intercalate ", " (renderExpression <$> reverse lims)
462+ , ")"
463+ ]
464+ renderOffsets = \case
465+ [] -> ""
466+ off:[] -> " OFFSET " <> renderExpression off
473− , maybe "" ((" OFFSET " <>) . renderExpression) off
467+ off:offs -> " OFFSET " <> renderExpression (foldr (+) off offs)
474− ]
475
468
476instance (HasTable table schema columns, table ~ table')
469instance (HasTable table schema columns, table ~ table')
477 => IsLabel table (From params schema '[table' ::: columns]) where
470 => IsLabel table (From params schema '[table' ::: columns]) where
478− fromLabel p = From (fromLabel p) mempty
471+ fromLabel p = join (fromLabel p)
479
472
480where_
473where_
481 :: Expression params tables ('Required ('NotNull 'PGBool))
474 :: Expression params tables ('Required ('NotNull 'PGBool))
482 -> From params schema tables
475 -> From params schema tables
483 -> From params schema tables
476 -> From params schema tables
484−where_ wh (From tabs fromClauses1) = From tabs
477+where_ wh (From tabs whs lims offs) = From tabs (wh:whs) lims offs
485− (fromClauses1 <> Clauses (Just wh) Nothing Nothing)
486
478
487limit
479limit
488 :: Expression params '[] ('Required ('NotNull 'PGInt8))
480 :: Expression params '[] ('Required ('NotNull 'PGInt8))
489 -> From params schema tables
481 -> From params schema tables
490 -> From params schema tables
482 -> From params schema tables
491−limit lim (From tabs fromClauses1) = From tabs
483+limit lim (From tabs whs lims offs) = From tabs whs (lim:lims) offs
492− (fromClauses1 <> Clauses Nothing (Just lim) Nothing)
493
484
494offset
485offset
495 :: Expression params '[] ('Required ('NotNull 'PGInt8))
486 :: Expression params '[] ('Required ('NotNull 'PGInt8))
496 -> From params schema tables
487 -> From params schema tables
497 -> From params schema tables
488 -> From params schema tables
498−offset off (From tabs fromClauses1) = From tabs
489+offset off (From tabs whs lims offs) = From tabs whs lims (off:offs)
499− (fromClauses1 <> Clauses Nothing Nothing (Just off))
500
490
501newtype Selection
491newtype Selection
502 (params :: [ColumnType])
492 (params :: [ColumnType])
@@ -540,10 +530,7 @@ select = UnsafeStatement . ("SELECT " <>) . (<> ";") . renderSelection
540subselect
530subselect
541 :: Aliased (Selection params schema) table
531 :: Aliased (Selection params schema) table
542 -> From params schema '[table]
532 -> From params schema '[table]
543−subselect selection = From
533+subselect selection = join (Subselect selection)
544− { fromJoin = Subselect selection
545− , fromClauses = mempty
546− }
547
534
548{-----------------------------------------
535{-----------------------------------------
549INSERT statements
536INSERT statements
squeel-postgresql/test/Squeel/PostgreSQL/StatementSpec.hs+1−1
@@ -53,7 +53,7 @@ spec = do
53 statement :: Statement '[] Columns Tables Tables
53 statement :: Statement '[] Columns Tables Tables
54 statement = select $ starFrom (#table1 & limit 1 & limit 2)
54 statement = select $ starFrom (#table1 & limit 1 & limit 2)
55 statement `shouldRenderAs`
55 statement `shouldRenderAs`
56− "SELECT * FROM table1 AS table1 LIMIT CASE WHEN (1 <= 2) THEN 1 ELSE 2 END;"
56+ "SELECT * FROM table1 AS table1 LIMIT LEAST(1, 2);"
57 it "should render parameters using $ signs" $ do
57 it "should render parameters using $ signs" $ do
58 let
58 let
59 statement :: Statement '[ 'Required ('NotNull 'PGInt8)] Columns Tables Tables
59 statement :: Statement '[ 'Required ('NotNull 'PGInt8)] Columns Tables Tables