on dev help sign in
start doing inserts
98ab760Eitan Chatav
squeel-postgresql/src/Squeel/PostgreSQL/Query.hs+23−2
@@ -21,9 +21,11 @@ import Data.Monoid
21import Data.Proxy
21import Data.Proxy
22import Data.String
22import Data.String
23import Data.Vinyl
23import Data.Vinyl
24+import Data.Vinyl.Functor
24import GHC.OverloadedLabels
25import GHC.OverloadedLabels
25import GHC.TypeLits
26import GHC.TypeLits
26
27
28+import qualified Data.ByteString as ByteString
27import qualified Data.ByteString.Char8 as Char8
29import qualified Data.ByteString.Char8 as Char8
28
30
29import Squeel.PostgreSQL.Type
31import Squeel.PostgreSQL.Type
@@ -33,7 +35,7 @@ class HasField label xs x where
33instance {-# OVERLAPPING #-} KnownSymbol label
35instance {-# OVERLAPPING #-} KnownSymbol label
34 => HasField label ('(label, x) ': xs) x where
36 => HasField label ('(label, x) ': xs) x where
35 fieldName _ _ _ = Char8.pack (symbolVal (Proxy @label))
37 fieldName _ _ _ = Char8.pack (symbolVal (Proxy @label))
36−instance HasField label xs y
38+instance {-# OVERLAPPABLE #-} HasField label xs y
37 => HasField label (x ': xs) y where
39 => HasField label (x ': xs) y where
38 fieldName _ _ _ = fieldName (Proxy @label) (Proxy @xs) (Proxy @y)
40 fieldName _ _ _ = fieldName (Proxy @label) (Proxy @xs) (Proxy @y)
39
41
@@ -232,9 +234,28 @@ subselect selection = Relation
232 , offsetting = Nothing
234 , offsetting = Nothing
233 }
235 }
234
236
237+newtype Insertion ps xss = UnsafeInsertion {renderInsertion :: ByteString }
238+
239+into
240+ :: forall label xss xs ps
241+ . HasField label xss xs
242+ => Proxy label
243+ -> Rec (Aliased (Expression ps '[])) xs
244+ -> Insertion ps xss
245+into table values = UnsafeInsertion $ "INTO "
246+ <> fieldName table (Proxy @xss) (Proxy @xs)
247+ <> " VALUES "
248+ <> ByteString.intercalate ", "
249+ (recordToList (rmap (Const . renderExpression . unalias) values))
250+
235newtype Query ps xss yss zs = UnsafeQuery { renderQuery :: ByteString }
251newtype Query ps xss yss zs = UnsafeQuery { renderQuery :: ByteString }
236newtype PreparedQuery ps xss yss zs =
252newtype PreparedQuery ps xss yss zs =
237 UnsafePreparedQuery { renderPreparedQuery :: ByteString }
253 UnsafePreparedQuery { renderPreparedQuery :: ByteString }
238
254
239select :: Selection ps xss ys -> Query ps xss xss ys
255select :: Selection ps xss ys -> Query ps xss xss ys
256+select selection = UnsafeQuery $
240−select selection = UnsafeQuery $ "SELECT " <> renderSelection selection <> ";"
257+ "SELECT " <> renderSelection selection <> ";"
258+
259+insert :: Insertion ps xss -> Query ps xss xss '[]
260+insert insertion = UnsafeQuery $
261+ "INSERT " <> renderInsertion insertion <> ";"
squeel-postgresql/test/Squeel/PostgreSQL/QuerySpec.hs+16−2
@@ -2,11 +2,13 @@
2 DataKinds
2 DataKinds
3 , OverloadedLabels
3 , OverloadedLabels
4 , OverloadedStrings
4 , OverloadedStrings
5+ , TypeApplications
5#-}
6#-}
6
7
7module Squeel.PostgreSQL.QuerySpec where
8module Squeel.PostgreSQL.QuerySpec where
8
9
9import Data.Boolean
10import Data.Boolean
11+import Data.Proxy
10import Data.Vinyl
12import Data.Vinyl
11import Test.Hspec
13import Test.Hspec
12
14
@@ -47,6 +49,10 @@ spec = do
47 renderQuery (select (star `from` (table1 `offset` 1 `offset` 2)))
49 renderQuery (select (star `from` (table1 `offset` 1 `offset` 2)))
48 `shouldBe`
50 `shouldBe`
49 "SELECT * FROM table1 OFFSET 1+2;"
51 "SELECT * FROM table1 OFFSET 1+2;"
52+ it "correctly render simple INSERTs" $ do
53+ renderQuery (insert insertion)
54+ `shouldBe`
55+ "INSERT INTO "
50
56
51
57
52type Columns =
58type Columns =
@@ -54,14 +60,22 @@ type Columns =
54 , '("col2", 'PGInt4)
60 , '("col2", 'PGInt4)
55 ]
61 ]
56
62
63+type Tables = '[ '("table1", Columns)]
64+
57sumAndCol1 :: Projection '[] Columns
65sumAndCol1 :: Projection '[] Columns
58 '[ '("sum", 'PGInt4)
66 '[ '("sum", 'PGInt4)
59 , '("col1", 'PGInt4)
67 , '("col1", 'PGInt4)
60 ]
68 ]
61sumAndCol1 = project ((#col1 + #col2) `As` #sum :& #col1 :& RNil)
69sumAndCol1 = project ((#col1 + #col2) `As` #sum :& #col1 :& RNil)
62
70
63−table1 :: Relation '[] '[ '("table1", Columns)] Columns
71+table1 :: Relation '[] Tables Columns
64table1 = #table1
72table1 = #table1
65
73
66−parameterizedTable1 :: Relation '[ 'PGInt8] '[ '("table1", Columns)] Columns
74+parameterizedTable1 :: Relation '[ 'PGInt8] Tables Columns
67parameterizedTable1 = #table1
75parameterizedTable1 = #table1
76+
77+insertion :: Insertion '[] Tables
78+insertion = into (Proxy @"table1") values
79+
80+values :: Rec (Expression '[] '[]) '[ 'PGInt4, 'PGInt4]
81+values = (2 `AS` #col1 :& 4 `AS` #col2 :& RNil)