@@ -3,9 +3,7 @@
33 , FlexibleContexts
44 , FlexibleInstances
55 , GADTs
6− , MagicHash
76 , MultiParamTypeClasses
8− , OverloadedLabels
97 , OverloadedStrings
108 , PolyKinds
119 , RankNTypes
@@ -35,7 +33,7 @@ class HasField label xs x where
3533instance {-# OVERLAPPING #-} KnownSymbol label
3634 => HasField label ('(label, x) ': xs) x where
3735 fieldName _ _ _ = Char8.pack (symbolVal (Proxy @label))
38−instance {-# OVERLAPPABLE #-} HasField label xs y
36+instance HasField label xs y
3937 => HasField label (x ': xs) y where
4038 fieldName _ _ _ = fieldName (Proxy @label) (Proxy @xs) (Proxy @y)
4139
@@ -76,7 +74,7 @@ instance (KnownSymbol label, AllAliased (x' ': xs))
7674 (x :& xs :: Rec (Aliased obj) ('(label, x) ': x' : xs)) =
7775 renderAliased render x <> ", " <> renderAllAliased render xs
7876
79−newtype Expression ps xs y =
77+newtype Expression ps (xs :: [(Symbol,PGType)]) y =
8078 UnsafeExpression { renderExpression :: ByteString }
8179
8280param1 :: Expression (p1:ps) cols p1
@@ -97,6 +95,14 @@ instance HasField label xs x => IsLabel label (Expression ps xs x) where
9795instance IsString (Expression ps xs 'PGText) where
9896 fromString str = UnsafeExpression $ "\'" <> fromString str <> "\'"
9997
98+instance Num (Expression ps xs 'PGInt2) where
99+ fromInteger n = UnsafeExpression . fromString $ show n
100+ x + y = UnsafeExpression $ renderExpression x <> "+" <> renderExpression y
101+ x * y = UnsafeExpression $ renderExpression x <> "*" <> renderExpression y
102+ UnsafeExpression x - UnsafeExpression y = UnsafeExpression $ x <> "+" <> y
103+ abs (UnsafeExpression x) = UnsafeExpression $ "@" <> x
104+ signum (UnsafeExpression x) = UnsafeExpression $ "sign(" <> x <> ")"
105+
100106instance Num (Expression ps xs 'PGInt4) where
101107 fromInteger n = UnsafeExpression . fromString $ show n
102108 x + y = UnsafeExpression $ renderExpression x <> "+" <> renderExpression y
@@ -105,6 +111,14 @@ instance Num (Expression ps xs 'PGInt4) where
105111 abs (UnsafeExpression x) = UnsafeExpression $ "@" <> x
106112 signum (UnsafeExpression x) = UnsafeExpression $ "sign(" <> x <> ")"
107113
114+instance Num (Expression ps xs 'PGInt8) where
115+ fromInteger n = UnsafeExpression . fromString $ show n
116+ x + y = UnsafeExpression $ renderExpression x <> "+" <> renderExpression y
117+ x * y = UnsafeExpression $ renderExpression x <> "*" <> renderExpression y
118+ UnsafeExpression x - UnsafeExpression y = UnsafeExpression $ x <> "+" <> y
119+ abs (UnsafeExpression x) = UnsafeExpression $ "@" <> x
120+ signum (UnsafeExpression x) = UnsafeExpression $ "sign(" <> x <> ")"
121+
108122instance Boolean (Expression ps xs 'PGBool) where
109123 true = UnsafeExpression "TRUE"
110124 false = UnsafeExpression "FALSE"
@@ -118,11 +132,10 @@ type instance BooleanOf (Expression ps xs y) = Expression ps xs 'PGBool
118132
119133instance IfB (Expression ps xs y) where
120134 ifB predicate then_ else_ = UnsafeExpression $ mconcat
121− [ "CASE"
122− , "\n WHEN ",renderExpression predicate
123− , "\n THEN ",renderExpression then_
124− , "\n ELSE ",renderExpression else_
125− , "\nEND"
135+ [ "CASE WHEN ",renderExpression predicate
136+ , " THEN ",renderExpression then_
137+ , " ELSE ",renderExpression else_
138+ , " END"
126139 ]
127140
128141instance EqB (Expression ps xs y) where
@@ -153,11 +166,16 @@ data Tabulation ps xss xs = UnsafeTabulation
153166data Relation ps xss xs = Relation
154167 { tabulation :: Tabulation ps xss xs
155168 , restriction :: Maybe (Expression ps xs 'PGBool)
169+ , limitation :: Maybe (Expression ps '[] 'PGInt8)
170+ , offsetting :: Maybe (Expression ps '[] 'PGInt8)
156171 }
157172
158173renderRelation :: Relation ps xss xs -> ByteString
159−renderRelation (Relation tab wh) =
160− renderTabulation tab <> maybe "" ((" WHERE " <>) . renderExpression) wh
174+renderRelation (Relation tab wh lim off) =
175+ renderTabulation tab
176+ <> maybe "" ((" WHERE " <>) . renderExpression) wh
177+ <> maybe "" ((" LIMIT " <>) . renderExpression) lim
178+ <> maybe "" ((" OFFSET " <>) . renderExpression) off
161179
162180where_
163181 :: Relation ps xss xs
@@ -169,12 +187,34 @@ ys `where_` condition = ys
169187 Just conditions -> Just (conditions &&* condition)
170188 }
171189
190+limit
191+ :: Relation ps xss xs
192+ -> Expression ps '[] 'PGInt8
193+ -> Relation ps xss xs
194+ys `limit` n = ys
195+ { limitation = case limitation ys of
196+ Nothing -> Just n
197+ Just n' -> Just (n' `minB` n)
198+ }
199+
200+offset
201+ :: Relation ps xss xs
202+ -> Expression ps '[] 'PGInt8
203+ -> Relation ps xss xs
204+ys `offset` n = ys
205+ { offsetting = case offsetting ys of
206+ Nothing -> Just n
207+ Just n' -> Just (n' + n)
208+ }
209+
172210instance HasField label xss xs
173211 => IsLabel label (Relation ps xss xs) where
174212 fromLabel _ = Relation
175213 { tabulation = UnsafeTabulation $
176214 fieldName (Proxy @label) (Proxy @xss) (Proxy @xs)
177215 , restriction = Nothing
216+ , limitation = Nothing
217+ , offsetting = Nothing
178218 }
179219
180220newtype Selection ps xss ys = UnsafeSelection
@@ -188,6 +228,8 @@ subselect :: Selection ps xss ys -> Relation ps xss ys
188228subselect selection = Relation
189229 { tabulation = UnsafeTabulation $ "SELECT " <> renderSelection selection
190230 , restriction = Nothing
231+ , limitation = Nothing
232+ , offsetting = Nothing
191233 }
192234
193235newtype Query ps xss yss zs = UnsafeQuery { renderQuery :: ByteString }