@@ -14,6 +14,7 @@
15module Squeel.PostgreSQL.Statement where
15module Squeel.PostgreSQL.Statement where
17+import Control.Category
17import Data.Boolean
18import Data.Boolean
18import Data.ByteString (ByteString)
19import Data.ByteString (ByteString)
19import Data.Maybe
20import Data.Maybe
@@ -24,16 +25,22 @@ import Data.Vinyl.Functor
24import GHC.Exts
25import GHC.Exts
25import GHC.OverloadedLabels
26import GHC.OverloadedLabels
26import GHC.TypeLits
27import GHC.TypeLits
28+import Prelude hiding (id,(.))
28import qualified Data.ByteString as ByteString
30import qualified Data.ByteString as ByteString
30import Squeel.PostgreSQL.Schema
32import Squeel.PostgreSQL.Schema
34+{-----------------------------------------
36+-----------------------------------------}
32newtype Expression
38newtype Expression
33− (params :: [NullityType])
39+ (params :: [ColumnType])
34− (tables :: [(Symbol,[(Symbol,NullityType)])])
40+ (tables :: [(Symbol,[(Symbol,ColumnType)])])
35− (ty :: NullityType)
41+ (ty :: ColumnType)
36− = UnsafeExpression { renderExpression :: ByteString }
42+ = UnsafeExpression { renderExpression :: ByteString }
38class KnownNat n => HasParameter (n :: Nat) params ty | n params -> ty where
45class KnownNat n => HasParameter (n :: Nat) params ty | n params -> ty where
39 param :: Proxy# n -> Expression params tables ty
46 param :: Proxy# n -> Expression params tables ty
@@ -58,7 +65,7 @@ class KnownSymbol column => HasColumn column columns ty
58 getColumn :: Proxy# column -> Expression params '[table ::: columns] ty
65 getColumn :: Proxy# column -> Expression params '[table ::: columns] ty
59 getColumn column = UnsafeExpression $ fromString $ symbolVal' column
66 getColumn column = UnsafeExpression $ fromString $ symbolVal' column
60instance {-# OVERLAPPING #-} KnownSymbol column
67instance {-# OVERLAPPING #-} KnownSymbol column
61− => HasColumn column ((column ::: ty) ': tys) ty
68+ => HasColumn column ((column ::: optionality ty) ': tys) ('Required ty)
62instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
69instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
63 => HasColumn column (ty' ': table) ty
70 => HasColumn column (ty' ': table) ty
@@ -66,14 +73,31 @@ instance (HasColumn column columns ty, tables ~ '[table ::: columns])
66 => IsLabel column (Expression params tables ty) where
73 => IsLabel column (Expression params tables ty) where
67 fromLabel = getColumn
74 fromLabel = getColumn
70 :: (HasTable table tables columns, HasColumn column columns ty)
77 :: (HasTable table tables columns, HasColumn column columns ty)
71 => Alias table -> Alias column -> Expression params tables ty
78 => Alias table -> Alias column -> Expression params tables ty
72−Alias table .&. Alias column = UnsafeExpression $
79+Alias table &. Alias column = UnsafeExpression $
73 fromString (symbolVal' table)
80 fromString (symbolVal' table)
75 fromString (symbolVal' column)
82 fromString (symbolVal' column)
84+def :: Expression params '[] ('Optional (nullity ty))
85+def = UnsafeExpression "DEFAULT"
87+null :: Expression params tables (optionality ('Null ty))
88+null = UnsafeExpression "NULL"
91+ :: [Expression params tables ('Required ('Null x))]
92+ -> Expression params tables ('Required ('NotNull x))
93+ -> Expression params tables ('Required ('NotNull x))
94+coalesce nulls isn'tNull = UnsafeExpression $ mconcat
96+ , ByteString.intercalate ", " $ map renderExpression nulls
97+ , ", ", renderExpression isn'tNull
77unsafeBinaryOp
101unsafeBinaryOp
78 :: ByteString
102 :: ByteString
79 -> Expression params tables ty0
103 -> Expression params tables ty0
@@ -96,7 +120,7 @@ unsafeFunction
96unsafeFunction fn x = UnsafeExpression $ mconcat
120unsafeFunction fn x = UnsafeExpression $ mconcat
97 [fn, "(", renderExpression x, ")"]
121 [fn, "(", renderExpression x, ")"]
99−instance PGNum ty => Num (Expression params tables (nullity ty)) where
123+instance PGNum ty => Num (Expression params tables ('Required (nullity ty))) where
100 (+) = unsafeBinaryOp "+"
124 (+) = unsafeBinaryOp "+"
101 (-) = unsafeBinaryOp "-"
125 (-) = unsafeBinaryOp "-"
102 (*) = unsafeBinaryOp "*"
126 (*) = unsafeBinaryOp "*"
@@ -104,7 +128,7 @@ instance PGNum ty => Num (Expression params tables (nullity ty)) where
104 signum = unsafeFunction "sign"
128 signum = unsafeFunction "sign"
105 fromInteger = UnsafeExpression . fromString . show
129 fromInteger = UnsafeExpression . fromString . show
107−instance IsString (Expression params tables (nullity 'PGText)) where
131+instance IsString (Expression params tables ('Required (nullity 'PGText))) where
108 fromString str = UnsafeExpression $
132 fromString str = UnsafeExpression $
109 "E\'" <> fromString (escape =<< str) <> "\'"
133 "E\'" <> fromString (escape =<< str) <> "\'"
@@ -119,7 +143,7 @@ instance IsString (Expression params tables (nullity 'PGText)) where
119 '\\' -> "\\\\"
143 '\\' -> "\\\\"
122−instance Boolean (Expression params tables ('NotNull 'PGBool)) where
146+instance Boolean (Expression params tables ('Required ('NotNull 'PGBool))) where
123 true = UnsafeExpression "TRUE"
147 true = UnsafeExpression "TRUE"
124 false = UnsafeExpression "FALSE"
148 false = UnsafeExpression "FALSE"
125 notB = unsafeUnaryOp "NOT"
149 notB = unsafeUnaryOp "NOT"
@@ -127,21 +151,10 @@ instance Boolean (Expression params tables ('NotNull 'PGBool)) where
127 (||*) = unsafeBinaryOp "OR"
151 (||*) = unsafeBinaryOp "OR"
129type instance BooleanOf (Expression params tables ty) =
153type instance BooleanOf (Expression params tables ty) =
130− Expression params tables ('NotNull 'PGBool)
154+ Expression params tables ('Required ('NotNull 'PGBool))
133− :: [Expression params tables ('Null x)]
134− -> Expression params tables ('NotNull x)
135− -> Expression params tables ('NotNull x)
136−coalesce nulls notNull = UnsafeExpression $ mconcat
138− , ByteString.intercalate ", " $ map renderExpression nulls
139− , ", ", renderExpression notNull
143caseWhenThenElse
156caseWhenThenElse
144− :: [(Expression params tables ('NotNull 'PGBool), Expression params tables ty)]
157+ :: [(Expression params tables ('Required ('NotNull 'PGBool)), Expression params tables ty)]
145 -> Expression params tables ty
158 -> Expression params tables ty
146 -> Expression params tables ty
159 -> Expression params tables ty
147caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
160caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
@@ -160,115 +173,149 @@ caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
160instance IfB (Expression params tables ty) where
173instance IfB (Expression params tables ty) where
161 ifB if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
174 ifB if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
163−instance EqB (Expression params tables ty) where
176+instance EqB (Expression params tables (optionality ('NotNull ty))) where
164 (==*) = unsafeBinaryOp "="
177 (==*) = unsafeBinaryOp "="
165 (/=*) = unsafeBinaryOp "<>"
178 (/=*) = unsafeBinaryOp "<>"
167−instance OrdB (Expression params tables ty) where
180+instance OrdB (Expression params tables (optionality ('NotNull ty))) where
168 (>*) = unsafeBinaryOp ">"
181 (>*) = unsafeBinaryOp ">"
169 (>=*) = unsafeBinaryOp ">="
182 (>=*) = unsafeBinaryOp ">="
170 (<*) = unsafeBinaryOp "<"
183 (<*) = unsafeBinaryOp "<"
171 (<=*) = unsafeBinaryOp "<="
184 (<=*) = unsafeBinaryOp "<="
186+{-----------------------------------------
188+-----------------------------------------}
173newtype TableExpression
190newtype TableExpression
174− (params :: [NullityType])
191+ (params :: [ColumnType])
175− (schema :: [(Symbol,[(Symbol,NullityType)])])
192+ (schema :: [(Symbol,[(Symbol,ColumnType)])])
176− (columns :: [(Symbol,NullityType)])
193+ (columns :: [(Symbol,ColumnType)])
177 = UnsafeTableExpression { renderTableExpression :: ByteString }
194 = UnsafeTableExpression { renderTableExpression :: ByteString }
197+class KnownSymbol table => HasTable table tables columns
198+ | table tables -> columns where
199+ getTable :: Proxy# table -> TableExpression params tables columns
200+ getTable table = UnsafeTableExpression $ fromString $ symbolVal' table
201+instance {-# OVERLAPPING #-} KnownSymbol table
202+ => HasTable table ((table ::: columns) ': tables) columns
203+instance {-# OVERLAPPABLE #-}
204+ (KnownSymbol table, HasTable table schema columns)
205+ => HasTable table (table' ': schema) columns
207+instance HasTable table schema columns
208+ => IsLabel table (TableExpression params schema columns) where
209+ fromLabel = getTable
211+{-----------------------------------------
213+-----------------------------------------}
216+ (params :: [ColumnType])
217+ (columns :: [(Symbol,ColumnType)])
218+ (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
219+ (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
220+ = UnsafeStatement { renderStatement :: ByteString }
223+instance Category (Statement '[] '[]) where
224+ id = UnsafeStatement ";"
225+ statement2 . statement1 = UnsafeStatement $
226+ renderStatement statement1 <> " " <> renderStatement statement2
228+newtype PreparedStatement
229+ (params :: [ColumnType])
230+ (columns :: [(Symbol,ColumnType)])
231+ (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
232+ (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
233+ = UnsafePreparedStatement { renderPreparedStatement :: ByteString }
236+{-----------------------------------------
238+-----------------------------------------}
179−data JoinExpression params schema tables where
240+data Join params schema tables where
181 :: Aliased (TableExpression params schema) table
242 :: Aliased (TableExpression params schema) table
182− -> JoinExpression params schema '[table]
243+ -> Join params schema '[table]
183 Subselect
244 Subselect
184 :: Aliased (Selection params schema) table
245 :: Aliased (Selection params schema) table
185− -> JoinExpression params schema '[table]
246+ -> Join params schema '[table]
187 :: Aliased (TableExpression params schema) table
248 :: Aliased (TableExpression params schema) table
188− -> JoinExpression params schema tables
249+ -> Join params schema tables
189− -> JoinExpression params schema (table ': tables)
250+ -> Join params schema (table ': tables)
191 :: Aliased (TableExpression params schema) table
252 :: Aliased (TableExpression params schema) table
192− -> Expression params (table ': tables) ('NotNull 'PGBool)
253+ -> Expression params (table ': tables) ('Required ('NotNull 'PGBool))
193− -> JoinExpression params schema tables
254+ -> Join params schema tables
194− -> JoinExpression params schema (table ': tables)
255+ -> Join params schema (table ': tables)
195 LeftOuter
256 LeftOuter
196 :: Aliased (TableExpression params schema) right
257 :: Aliased (TableExpression params schema) right
197− -> Expression params '[left,right] ('NotNull 'PGBool)
258+ -> Expression params '[left,right] ('Required ('NotNull 'PGBool))
198− -> JoinExpression params schema (tables)
259+ -> Join params schema (tables)
199− -> JoinExpression params schema (NullifyTable right ': left ': tables)
260+ -> Join params schema (NullifyTable right ': left ': tables)
200 RightOuter
261 RightOuter
201 :: Aliased (TableExpression params schema) right
262 :: Aliased (TableExpression params schema) right
202− -> Expression params '[left,right] ('NotNull 'PGBool)
263+ -> Expression params '[left,right] ('Required ('NotNull 'PGBool))
203− -> JoinExpression params schema (left : tables)
264+ -> Join params schema (left : tables)
204− -> JoinExpression params schema (right ': NullifyTable left ': tables)
265+ -> Join params schema (right ': NullifyTable left ': tables)
205 FullOuter
266 FullOuter
206 :: Aliased (TableExpression params schema) right
267 :: Aliased (TableExpression params schema) right
207− -> Expression params '[left,right] ('NotNull 'PGBool)
268+ -> Expression params '[left,right] ('Required ('NotNull 'PGBool))
208− -> JoinExpression params schema (left : tables)
269+ -> Join params schema (left : tables)
209− -> JoinExpression params schema
270+ -> Join params schema
210 (NullifyTable right ': NullifyTable left ': tables)
271 (NullifyTable right ': NullifyTable left ': tables)
212−renderJoinExpression :: JoinExpression params schema tables -> ByteString
273+renderJoin :: Join params schema tables -> ByteString
213−renderJoinExpression = \case
274+renderJoin = \case
214 Table table -> renderAliased renderTableExpression table
275 Table table -> renderAliased renderTableExpression table
215 Subselect selection -> "SELECT " <> renderAliased renderSelection selection
276 Subselect selection -> "SELECT " <> renderAliased renderSelection selection
216 Cross table tables -> mconcat
277 Cross table tables -> mconcat
217− [ renderJoinExpression tables
278+ [ renderJoin tables
218 , " CROSS JOIN "
279 , " CROSS JOIN "
219 , renderAliased renderTableExpression table
280 , renderAliased renderTableExpression table
221 Inner table on tables -> mconcat
282 Inner table on tables -> mconcat
222− [ renderJoinExpression tables
283+ [ renderJoin tables
223 , " INNER JOIN "
284 , " INNER JOIN "
224 , renderAliased renderTableExpression table
285 , renderAliased renderTableExpression table
226 , renderExpression on
287 , renderExpression on
228 LeftOuter table on tables -> mconcat
289 LeftOuter table on tables -> mconcat
229− [ renderJoinExpression tables
290+ [ renderJoin tables
230 , " LEFT OUTER JOIN "
291 , " LEFT OUTER JOIN "
231 , renderAliased renderTableExpression table
292 , renderAliased renderTableExpression table
233 , renderExpression on
294 , renderExpression on
235 RightOuter table on tables -> mconcat
296 RightOuter table on tables -> mconcat
236− [ renderJoinExpression tables
297+ [ renderJoin tables
237 , " RIGHT OUTER JOIN "
298 , " RIGHT OUTER JOIN "
238 , renderAliased renderTableExpression table
299 , renderAliased renderTableExpression table
240 , renderExpression on
301 , renderExpression on
242 FullOuter table on tables -> mconcat
303 FullOuter table on tables -> mconcat
243− [ renderJoinExpression tables
304+ [ renderJoin tables
244 , " FULL OUTER JOIN "
305 , " FULL OUTER JOIN "
245 , renderAliased renderTableExpression table
306 , renderAliased renderTableExpression table
247 , renderExpression on
308 , renderExpression on
250−class KnownSymbol table => HasTable table tables columns
251− | table tables -> columns where
252− getTable :: Proxy# table -> TableExpression params tables columns
253− getTable table = UnsafeTableExpression $ fromString $ symbolVal' table
254−instance {-# OVERLAPPING #-} KnownSymbol table
255− => HasTable table ((table ::: columns) ': tables) columns
256−instance {-# OVERLAPPABLE #-}
257− (KnownSymbol table, HasTable table schema columns)
258− => HasTable table (table' ': schema) columns
260instance HasTable table schema columns
311instance HasTable table schema columns
261− => IsLabel table (TableExpression params schema columns) where
262− fromLabel = getTable
264−instance HasTable table schema columns
265− => IsLabel table (JoinExpression params schema '[table ::: columns]) where
312+ => IsLabel table (Join params schema '[table ::: columns]) where
266 fromLabel p = Table $ fromLabel p
313 fromLabel p = Table $ fromLabel p
268data Clauses params tables = Clauses
315data Clauses params tables = Clauses
269− { whereClause :: Maybe (Expression params tables ('NotNull 'PGBool))
316+ { whereClause :: Maybe (Expression params tables ('Required ('NotNull 'PGBool)))
270− , limitClause :: Maybe (Expression params '[] ('NotNull 'PGInt8))
317+ , limitClause :: Maybe (Expression params '[] ('Required ('NotNull 'PGInt8)))
271− , offsetClause :: Maybe (Expression params '[] ('NotNull 'PGInt8))
318+ , offsetClause :: Maybe (Expression params '[] ('Required ('NotNull 'PGInt8)))
274instance Monoid (Clauses params tables) where
321instance Monoid (Clauses params tables) where
@@ -291,124 +338,108 @@ instance Monoid (Clauses params tables) where
291 (Just o1,Just o2) -> Just (o1 + o2)
338 (Just o1,Just o2) -> Just (o1 + o2)
294−data FromExpression
341+data From
295− (params :: [NullityType])
342+ (params :: [ColumnType])
296− (schema :: [(Symbol,[(Symbol,NullityType)])])
343+ (schema :: [(Symbol,[(Symbol,ColumnType)])])
297− (tables :: [(Symbol,[(Symbol,NullityType)])])
344+ (tables :: [(Symbol,[(Symbol,ColumnType)])])
298− = FromExpression
345+ = From
299− { joinExpression :: JoinExpression params schema tables
346+ { fromJoin :: Join params schema tables
300− , clauses :: Clauses params tables
347+ , fromClauses :: Clauses params tables
304− :: JoinExpression params schema tables
351+ :: Join params schema tables
305− -> FromExpression params schema tables
352+ -> From params schema tables
306−join tref = FromExpression tref mempty
353+join tables = From tables mempty
308−renderFromExpression :: FromExpression params schema tables -> ByteString
355+renderFrom :: From params schema tables -> ByteString
309−renderFromExpression (FromExpression tref (Clauses wh lim off))= mconcat
356+renderFrom (From tref (Clauses wh lim off))= mconcat
310− [ renderJoinExpression tref
357+ [ renderJoin tref
311 , maybe "" ((" WHERE " <>) . renderExpression) wh
358 , maybe "" ((" WHERE " <>) . renderExpression) wh
312 , maybe "" ((" LIMIT " <>) . renderExpression) lim
359 , maybe "" ((" LIMIT " <>) . renderExpression) lim
313 , maybe "" ((" OFFSET " <>) . renderExpression) off
360 , maybe "" ((" OFFSET " <>) . renderExpression) off
316instance (HasTable table schema columns, table ~ table')
363instance (HasTable table schema columns, table ~ table')
317− => IsLabel table (FromExpression params schema '[table' ::: columns]) where
364+ => IsLabel table (From params schema '[table' ::: columns]) where
318− fromLabel p = FromExpression (fromLabel p) mempty
365+ fromLabel p = From (fromLabel p) mempty
321− :: Expression params tables ('NotNull 'PGBool)
368+ :: Expression params tables ('Required ('NotNull 'PGBool))
322− -> FromExpression params schema tables
369+ -> From params schema tables
323− -> FromExpression params schema tables
370+ -> From params schema tables
324−where_ wh (FromExpression tabs clauses1) = FromExpression tabs
371+where_ wh (From tabs fromClauses1) = From tabs
325− (clauses1 <> Clauses (Just wh) Nothing Nothing)
372+ (fromClauses1 <> Clauses (Just wh) Nothing Nothing)
328− :: Expression params '[] ('NotNull 'PGInt8)
375+ :: Expression params '[] ('Required ('NotNull 'PGInt8))
329− -> FromExpression params schema tables
376+ -> From params schema tables
330− -> FromExpression params schema tables
377+ -> From params schema tables
331−limit lim (FromExpression tabs clauses1) = FromExpression tabs
378+limit lim (From tabs fromClauses1) = From tabs
332− (clauses1 <> Clauses Nothing (Just lim) Nothing)
379+ (fromClauses1 <> Clauses Nothing (Just lim) Nothing)
335− :: Expression params '[] ('NotNull 'PGInt8)
382+ :: Expression params '[] ('Required ('NotNull 'PGInt8))
336− -> FromExpression params schema tables
383+ -> From params schema tables
337− -> FromExpression params schema tables
384+ -> From params schema tables
338−offset off (FromExpression tabs clauses1) = FromExpression tabs
385+offset off (From tabs fromClauses1) = From tabs
339− (clauses1 <> Clauses Nothing Nothing (Just off))
386+ (fromClauses1 <> Clauses Nothing Nothing (Just off))
341newtype Selection
388newtype Selection
342− (params :: [NullityType])
389+ (params :: [ColumnType])
343− (schema :: [(Symbol,[(Symbol,NullityType)])])
390+ (schema :: [(Symbol,[(Symbol,ColumnType)])])
344− (columns :: [(Symbol,NullityType)])
391+ (columns :: [(Symbol,ColumnType)])
345 = UnsafeSelection { renderSelection :: ByteString }
392 = UnsafeSelection { renderSelection :: ByteString }
348 :: tables ~ '[table ::: columns]
396 :: tables ~ '[table ::: columns]
349− => FromExpression params schema tables
397+ => From params schema tables
350 -> Selection params schema columns
398 -> Selection params schema columns
351−starFrom tabs = UnsafeSelection $ "* FROM " <> renderFromExpression tabs
399+starFrom tabs = UnsafeSelection $ "* FROM " <> renderFrom tabs
353dotStarFrom
401dotStarFrom
354 :: HasTable table tables columns
402 :: HasTable table tables columns
355 => Alias table
403 => Alias table
356− -> FromExpression params schema tables
404+ -> From params schema tables
357 -> Selection params schema columns
405 -> Selection params schema columns
358Alias tab `dotStarFrom` tabs = UnsafeSelection $
406Alias tab `dotStarFrom` tabs = UnsafeSelection $
359− fromString (symbolVal' tab) <> ".* FROM " <> renderFromExpression tabs
407+ fromString (symbolVal' tab) <> ".* FROM " <> renderFrom tabs
362 :: Rec (Aliased (Expression params tables)) columns
410 :: Rec (Aliased (Expression params tables)) columns
363− -> FromExpression params schema tables
411+ -> From params schema tables
364 -> Selection params schema columns
412 -> Selection params schema columns
365list `from` tabs = UnsafeSelection $
413list `from` tabs = UnsafeSelection $
366− renderList list <> " FROM " <> renderFromExpression tabs
414+ renderList list <> " FROM " <> renderFrom tabs
368 renderList
416 renderList
369 = ByteString.intercalate ", "
417 = ByteString.intercalate ", "
370 . recordToList
418 . recordToList
371 . rmap (Const . renderAliased renderExpression)
419 . rmap (Const . renderAliased renderExpression)
374− (params :: [NullityType])
375− (schema0 :: [(Symbol,[(Symbol,NullityType)])])
376− (schema1 :: [(Symbol,[(Symbol,NullityType)])])
377− (columns :: [(Symbol,NullityType)])
378− = UnsafeStatement { renderStatement :: ByteString }
381− :: Statement params schema0 schema1 '[]
382− -> Statement params schema1 schema2 results
383− -> Statement params schema0 schema2 results
384−statement1 .>>. statement2 = UnsafeStatement $
385− renderStatement statement1 <> " " <> renderStatement statement2
387−newtype PreparedStatement
388− (params :: [NullityType])
389− (schema0 :: [(Symbol,[(Symbol,NullityType)])])
390− (schema1 :: [(Symbol,[(Symbol,NullityType)])])
391− (columns :: [(Symbol,NullityType)])
392− = UnsafePreparedStatement { renderPreparedStatement :: ByteString }
395 :: Selection params schema columns
422 :: Selection params schema columns
396− -> Statement params schema schema columns
423+ -> Statement params columns schema schema
397select = UnsafeStatement . ("SELECT " <>) . (<> ";") . renderSelection
424select = UnsafeStatement . ("SELECT " <>) . (<> ";") . renderSelection
400 :: Aliased (Selection params schema) table
427 :: Aliased (Selection params schema) table
401− -> FromExpression params schema '[table]
428+ -> From params schema '[table]
402−subselect selection = FromExpression
429+subselect selection = From
403− { joinExpression = Subselect selection
430+ { fromJoin = Subselect selection
404− , clauses = mempty
431+ , fromClauses = mempty
434+{-----------------------------------------
436+-----------------------------------------}
407insertInto
438insertInto
408 :: HasTable table schema columns
439 :: HasTable table schema columns
409 => Alias table
440 => Alias table
410 -> Rec (Aliased (Expression params '[])) columns
441 -> Rec (Aliased (Expression params '[])) columns
411− -> Statement params schema schema '[]
442+ -> Statement params '[] schema schema
412insertInto (Alias table) expressions = UnsafeStatement $ "INSERT INTO "
443insertInto (Alias table) expressions = UnsafeStatement $ "INSERT INTO "
413 <> fromString (symbolVal' table)
444 <> fromString (symbolVal' table)
414 <> " (" <> ByteString.intercalate ", " aliases
445 <> " (" <> ByteString.intercalate ", " aliases
@@ -423,22 +454,62 @@ insertInto (Alias table) expressions = UnsafeStatement $ "INSERT INTO "
423 (\ (expression `As` _) -> Const (renderExpression expression))
454 (\ (expression `As` _) -> Const (renderExpression expression))
424 expressions
455 expressions
457+{-----------------------------------------
459+-----------------------------------------}
461+newtype TypeExpression (ty :: ColumnType)
462+ = UnsafeTypeExpression { renderTypeExpression :: ByteString }
465+int2 :: TypeExpression ('Required ('Null 'PGInt2))
466+int2 = UnsafeTypeExpression "int2"
467+int4 :: TypeExpression ('Required ('Null 'PGInt4))
468+int4 = UnsafeTypeExpression "int4"
469+int8 :: TypeExpression ('Required ('Null 'PGInt8))
470+int8 = UnsafeTypeExpression "int8"
471+bool :: TypeExpression ('Required ('Null 'PGBool))
472+bool = UnsafeTypeExpression "bool"
473+text :: TypeExpression ('Required ('Null 'PGText))
474+text = UnsafeTypeExpression "text"
476+ :: TypeExpression ('Required ('Null ty))
477+ -> TypeExpression ('Required ('NotNull ty))
478+notNull ty = UnsafeTypeExpression $ renderTypeExpression ty <> " NOT NULL"
480+ :: Expression '[] '[] ('Required ty)
481+ -> TypeExpression ('Required ty)
482+ -> TypeExpression ('Optional ty)
483+default_ x ty = UnsafeTypeExpression $
484+ renderTypeExpression ty <> " DEFAULT " <> renderExpression x
485+serial :: TypeExpression ('Optional ('NotNull 'PGInt4))
486+serial = UnsafeTypeExpression "serial"
426createTable
488createTable
427− :: (KnownSymbol table, KnownColumns columns)
489+ :: KnownSymbol table
428− => Alias table
490+ => Alias table
429− -> Proxy# columns
491+ -> Rec (Aliased TypeExpression) columns
430− -> Statement '[] schema ((table ::: columns) ': schema) '[]
492+ -> Statement '[] '[] schema ((table ::: columns) ': schema)
431createTable (Alias table) columns = UnsafeStatement $ mconcat
493createTable (Alias table) columns = UnsafeStatement $ mconcat
432 [ "CREATE TABLE "
494 [ "CREATE TABLE "
433 , fromString $ symbolVal' table
495 , fromString $ symbolVal' table
435− , renderColumns columns
497+ , ByteString.intercalate ", " . recordToList $
498+ rmap (Const . renderColumn) columns
502+ renderColumn :: Aliased TypeExpression x -> ByteString
503+ renderColumn (ty `As` Alias column) =
504+ fromString (symbolVal' column) <> " " <> renderTypeExpression ty
506+{-----------------------------------------
508+-----------------------------------------}
439class KnownSymbol table => DropTable table schema0 schema1
510class KnownSymbol table => DropTable table schema0 schema1
440 | table schema0 -> schema1 where
511 | table schema0 -> schema1 where
441− dropTable :: Alias table -> Statement '[] schema0 schema1 '[]
512+ dropTable :: Alias table -> Statement '[] '[] schema0 schema1
442 dropTable (Alias table) = UnsafeStatement $
513 dropTable (Alias table) = UnsafeStatement $
443 "DROP TABLE " <> fromString (symbolVal' table) <> ";"
514 "DROP TABLE " <> fromString (symbolVal' table) <> ";"
444instance {-# OVERLAPPING #-}
515instance {-# OVERLAPPING #-}
@@ -448,6 +519,10 @@ instance {-# OVERLAPPABLE #-}
448 (KnownSymbol table, DropTable table schema0 schema1)
519 (KnownSymbol table, DropTable table schema0 schema1)
449 => DropTable table (tabCols ': schema0) (tabCols ': schema1)
520 => DropTable table (tabCols ': schema0) (tabCols ': schema1)
522+{-----------------------------------------
524+-----------------------------------------}
451set :: g x -> (Maybe `Compose` g) x
526set :: g x -> (Maybe `Compose` g) x
452set = Compose . Just
527set = Compose . Just
@@ -458,8 +533,8 @@ update
458 :: HasTable table schema columns
533 :: HasTable table schema columns
459 => Alias table
534 => Alias table
460 -> Rec (Aliased (Maybe `Compose` Expression params '[table ::: columns])) columns
535 -> Rec (Aliased (Maybe `Compose` Expression params '[table ::: columns])) columns
461− -> Expression params '[table ::: columns] ('NotNull 'PGBool)
536+ -> Expression params '[table ::: columns] ('Required ('NotNull 'PGBool))
462− -> Statement params schema schema '[]
537+ -> Statement params '[] schema schema
463update (Alias table) columns where' = UnsafeStatement $ mconcat
538update (Alias table) columns where' = UnsafeStatement $ mconcat
464 [ "UPDATE "
539 [ "UPDATE "
465 , fromString $ symbolVal' table
540 , fromString $ symbolVal' table