@@ -6,8 +6,6 @@
6 , LambdaCase
6 , LambdaCase
7 , MagicHash
7 , MagicHash
8 , OverloadedStrings
8 , OverloadedStrings
10− , ScopedTypeVariables
11 , TypeFamilies
9 , TypeFamilies
12 , TypeOperators
10 , TypeOperators
13 , UndecidableInstances
11 , UndecidableInstances
@@ -62,8 +60,8 @@ instance {-# OVERLAPPING #-} KnownSymbol column
62instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
60instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
63 => HasColumn column (ty' ': table) ty
61 => HasColumn column (ty' ': table) ty
65−instance HasColumn column columns ty
63+instance (HasColumn column columns ty, tables ~ '[table ::: columns])
66− => IsLabel column (Expression params '[table ::: columns] ty) where
64+ => IsLabel column (Expression params tables ty) where
67 fromLabel = getColumn
65 fromLabel = getColumn
@@ -129,13 +127,25 @@ instance Boolean (Expression params tables 'PGBool) where
129type instance BooleanOf (Expression params tables ty) =
127type instance BooleanOf (Expression params tables ty) =
130 Expression params tables 'PGBool
128 Expression params tables 'PGBool
132−instance IfB (Expression params tables ty) where
131+ :: [(Expression params tables 'PGBool, Expression params tables ty)]
132+ -> Expression params tables ty
133+ -> Expression params tables ty
133− ifB if_ then_ else_ = UnsafeExpression $ mconcat
134+caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
134− [ "CASE WHEN ",renderExpression if_
138+ [ " WHEN ", renderExpression when_
135− , " THEN ",renderExpression then_
139+ , " THEN ", renderExpression then_
136− , " ELSE ",renderExpression else_
140+ ]
137− , " END"
141+ | (when_,then_) <- whenThens
143+ , " ELSE ", renderExpression else_
147+instance IfB (Expression params tables ty) where
148+ ifB if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
140instance EqB (Expression params tables ty) where
150instance EqB (Expression params tables ty) where
141 (==*) = unsafeBinaryOp "="
151 (==*) = unsafeBinaryOp "="
@@ -167,120 +177,144 @@ crossJoin
167 :: TableRef params schema '[table]
177 :: TableRef params schema '[table]
168 -> TableRef params schema tables
178 -> TableRef params schema tables
169 -> TableRef params schema (table ': tables)
179 -> TableRef params schema (table ': tables)
170−crossJoin table tables = UnsafeTableRef $
180+crossJoin tab tabs = UnsafeTableRef $
171− renderTableRef tables <> " CROSS JOIN " <> renderTableRef table
181+ renderTableRef tabs <> " CROSS JOIN " <> renderTableRef tab
174 :: TableRef params schema '[table]
184 :: TableRef params schema '[table]
175 -> Expression params (table ': tables) 'PGBool
185 -> Expression params (table ': tables) 'PGBool
176 -> TableRef params schema tables
186 -> TableRef params schema tables
177 -> TableRef params schema (table ': tables)
187 -> TableRef params schema (table ': tables)
178−innerJoin table on tables = UnsafeTableRef $
188+innerJoin tab on tabs = UnsafeTableRef $
179− renderTableRef tables
189+ renderTableRef tabs
180 <> " INNER JOIN " <>
190 <> " INNER JOIN " <>
181− renderTableRef table
191+ renderTableRef tab
182 <> " ON " <>
192 <> " ON " <>
183 renderExpression on
193 renderExpression on
185−newtype Projection
195+data Clauses params tables = Clauses
186− (params :: [PGType])
196+ { whereClause :: Maybe (Expression params tables 'PGBool)
187− (tables :: [(Symbol,[(Symbol,PGType)])])
197+ , limitClause :: Maybe (Expression params '[] 'PGInt8)
188− (columns :: [(Symbol,PGType)]) =
198+ , offsetClause :: Maybe (Expression params '[] 'PGInt8)
189− UnsafeProjection { renderProjection :: ByteString }
199+ }
191−star :: Projection params '[table ::: columns] columns
192−star = UnsafeProjection "*"
195− :: HasTable table tables columns
196− => Alias table -> Projection params tables columns
197−tableStar (Alias table) = UnsafeProjection $
198− fromString (symbolVal' table) <> ".*"
200−project
201+instance Monoid (Clauses params tables) where
201− :: Rec (Aliased (Expression params tables)) columns
202+ mempty = Clauses Nothing Nothing Nothing
202− -> Projection params tables columns
203+ Clauses wh1 lim1 off1 `mappend` Clauses wh2 lim2 off2 = Clauses
203−project
204+ { whereClause = case (wh1,wh2) of
204− = UnsafeProjection
205+ (Nothing,Nothing) -> Nothing
205− . ByteString.intercalate ", "
206+ (Just w1,Nothing) -> Just w1
206− . recordToList
207+ (Nothing,Just w2) -> Just w2
207− . rmap (Const . renderAliased renderExpression)
208+ (Just w1,Just w2) -> Just (w1 &&* w2)
208−
209+ , limitClause = case (lim1,lim2) of
209−data Tabulation
210+ (Nothing,Nothing) -> Nothing
211+ (Just l1,Nothing) -> Just l1
212+ (Nothing,Just l2) -> Just l2
213+ (Just l1,Just l2) -> Just (l1 `minB` l2)
214+ , offsetClause = case (off1,off2) of
215+ (Nothing,Nothing) -> Nothing
216+ (Just o1,Nothing) -> Just o1
217+ (Nothing,Just o2) -> Just o2
218+ (Just o1,Just o2) -> Just (o1 + o2)
210 (params :: [PGType])
222 (params :: [PGType])
211 (schema :: [(Symbol,[(Symbol,PGType)])])
223 (schema :: [(Symbol,[(Symbol,PGType)])])
212 (tables :: [(Symbol,[(Symbol,PGType)])])
224 (tables :: [(Symbol,[(Symbol,PGType)])])
213− = Tabulation
225+ = TableExpression
214− { fromClause :: TableRef params schema tables
226+ { tableRef :: TableRef params schema tables
215− , whereClause :: Maybe (Expression params tables 'PGBool)
227+ , clauses :: Clauses params tables
216− , limitClause :: Maybe (Expression params '[] 'PGInt8)
217− , offsetClause :: Maybe (Expression params '[] 'PGInt8)
220−tabulation :: TableRef params schema tables -> Tabulation params schema tables
231+ :: TableRef params schema tables
221−tabulation tab = Tabulation tab Nothing Nothing Nothing
232+ -> TableExpression params schema tables
233+tables tref = TableExpression tref mempty
223−renderTabulation :: Tabulation params schema tables -> ByteString
235+renderTabulation :: TableExpression params schema tables -> ByteString
224−renderTabulation (Tabulation fr wh lim off)= mconcat
236+renderTabulation (TableExpression tref (Clauses wh lim off))= mconcat
225− [ renderTableRef fr
237+ [ renderTableRef tref
226 , maybe "" ((" WHERE " <>) . renderExpression) wh
238 , maybe "" ((" WHERE " <>) . renderExpression) wh
227 , maybe "" ((" LIMIT " <>) . renderExpression) lim
239 , maybe "" ((" LIMIT " <>) . renderExpression) lim
228 , maybe "" ((" OFFSET " <>) . renderExpression) off
240 , maybe "" ((" OFFSET " <>) . renderExpression) off
231−instance HasTable table schema columns
243+instance (HasTable table schema columns, table ~ table')
232− => IsLabel table (TableRef params schema '[table ::: columns]) where
244+ => IsLabel table (TableRef params schema '[table' ::: columns]) where
233 fromLabel = getTable
245 fromLabel = getTable
235−instance HasTable table schema columns
247+instance (HasTable table schema columns, table ~ table')
236− => IsLabel table (Tabulation params schema '[table ::: columns]) where
248+ => IsLabel table (TableExpression params schema '[table' ::: columns]) where
237− fromLabel p = Tabulation (getTable p) Nothing Nothing Nothing
249+ fromLabel p = TableExpression (getTable p) mempty
240 :: Expression params tables 'PGBool
252 :: Expression params tables 'PGBool
241− -> Tabulation params schema tables
253+ -> TableExpression params schema tables
242− -> Tabulation params schema tables
254+ -> TableExpression params schema tables
243−where_ condition tables = tables
255+where_ wh (TableExpression tabs clauses1) = TableExpression tabs
244− { whereClause = case whereClause tables of
256+ (clauses1 <> Clauses (Just wh) Nothing Nothing)
245− Nothing -> Just condition
246− Just conditions -> Just (conditions &&* condition)
250 :: Expression params '[] 'PGInt8
259 :: Expression params '[] 'PGInt8
251− -> Tabulation params schema tables
260+ -> TableExpression params schema tables
252− -> Tabulation params schema tables
261+ -> TableExpression params schema tables
253−limit n tables = tables
262+limit lim (TableExpression tabs clauses1) = TableExpression tabs
254− { limitClause = case limitClause tables of
263+ (clauses1 <> Clauses Nothing (Just lim) Nothing)
256− Just n' -> Just (n' `minB` n)
260 :: Expression params '[] 'PGInt8
266 :: Expression params '[] 'PGInt8
261− -> Tabulation params schema tables
267+ -> TableExpression params schema tables
262− -> Tabulation params schema tables
268+ -> TableExpression params schema tables
263−offset n tables = tables
269+offset off (TableExpression tabs clauses1) = TableExpression tabs
264− { offsetClause = case offsetClause tables of
270+ (clauses1 <> Clauses Nothing Nothing (Just off))
265− Nothing -> Just n
271+
266− Just n' -> Just (n' + n)
272+newtype Selection
267− }
273+ (params :: [PGType])
274+ (schema :: [(Symbol,[(Symbol,PGType)])])
275+ (columns :: [(Symbol,PGType)])
277+ { renderSelection :: ByteString }
280+ :: tables ~ '[table ::: columns]
281+ => TableExpression params schema tables
282+ -> Selection params schema columns
283+starFrom tabs = UnsafeSelection $ "* FROM " <> renderTabulation tabs
286+ :: HasTable table tables columns
288+ -> TableExpression params schema tables
269−newtype Selection params schema columns = UnsafeSelection
289+ -> Selection params schema columns
270− { renderSelection :: ByteString }
290+Alias tab `tableStarFrom` tabs = UnsafeSelection $
291+ fromString (symbolVal' tab) <> ".* FROM" <> renderTabulation tabs
273− :: Projection params tables columns
294+ :: Rec (Aliased (Expression params tables)) columns
274− -> Tabulation params schema tables
295+ -> TableExpression params schema tables
275 -> Selection params schema columns
296 -> Selection params schema columns
276−from projection tables = UnsafeSelection $
297+list `from` tabs = UnsafeSelection $
277− renderProjection projection <> " FROM " <> renderTabulation tables
298+ renderList list <> " FROM " <> renderTabulation tabs
301+ = ByteString.intercalate ", "
303+ . rmap (Const . renderAliased renderExpression)
279−newtype Query params schema0 schema1 columns = UnsafeQuery
305+newtype Query
306+ (params :: [PGType])
307+ (schema0 :: [(Symbol,[(Symbol,PGType)])])
308+ (schema1 :: [(Symbol,[(Symbol,PGType)])])
309+ (columns :: [(Symbol,PGType)])
280− { renderQuery :: ByteString }
310+ = UnsafeQuery { renderQuery :: ByteString }
282−newtype PreparedQuery params schema0 schema1 columns = UnsafePreparedQuery
312+newtype PreparedQuery
313+ (params :: [PGType])
314+ (schema0 :: [(Symbol,[(Symbol,PGType)])])
315+ (schema1 :: [(Symbol,[(Symbol,PGType)])])
316+ (columns :: [(Symbol,PGType)])
283− { renderPreparedQuery :: ByteString }
317+ = UnsafePreparedQuery { renderPreparedQuery :: ByteString }
286 :: Selection params schema columns
320 :: Selection params schema columns
@@ -289,18 +323,15 @@ select = UnsafeQuery . ("SELECT " <>) . (<> ";") . renderSelection
291 :: Aliased (Selection params schema) table
325 :: Aliased (Selection params schema) table
292− -> Tabulation params schema '[table]
326+ -> TableExpression params schema '[table]
293−subselect selection = Tabulation
327+subselect selection = TableExpression
294− { fromClause = UnsafeTableRef . ("SELECT " <>) $
328+ { tableRef = UnsafeTableRef . ("SELECT " <>) $
295 renderAliased renderSelection selection
329 renderAliased renderSelection selection
296− , whereClause = Nothing
330+ , clauses = mempty
297− , limitClause = Nothing
298− , offsetClause = Nothing
301insertInto
333insertInto
302− :: forall schema columns table params
303− . HasTable table schema columns
334+ :: HasTable table schema columns
304 => Alias table
335 => Alias table
305 -> Rec (Aliased (Expression params '[])) columns
336 -> Rec (Aliased (Expression params '[])) columns
306 -> Query params schema schema '[]
337 -> Query params schema schema '[]