on dev help sign in
inserts
commit6253103d7e8e140bc3b0fc491af049cc2bf72539 authorEitan Chatav <eitan.chatav@gmail.com> dateSun 23 Apr 2017, 09:56 (10 years ago) parent98ab760
2 files changed+36−22
squeel-postgresql/src/Squeel/PostgreSQL/Query.hs+31−6 squeel-postgresql/test/Squeel/PostgreSQL/QuerySpec.hs+5−16
squeel-postgresql/src/Squeel/PostgreSQL/Query.hs+31−6
@@ -47,6 +47,9 @@ instance IsLabel label (obj x)
4747 => IsLabel label (Aliased obj '(label, x)) where
4848 fromLabel p = fromLabel p `As` fromLabel p
4949
50+aliasName :: forall label. KnownSymbol label => Alias label -> ByteString
51+aliasName _ = Char8.pack (symbolVal (Proxy @label))
52+
5053alias :: Aliased obj '(label, x) -> Alias label
5154alias _ = Alias
5255
@@ -61,6 +64,23 @@ renderAliased
6164renderAliased render (obj `As` label) =
6265 render obj <> " AS " <> Char8.pack (symbolVal label)
6366
67+class UnzipAliased (xs :: [(Symbol,k)]) where
68+ type Unaliased xs :: [k]
69+ unzipAliased
70+ :: Rec (Aliased obj) xs
71+ -> ([ByteString], Rec obj (Unaliased xs))
72+instance UnzipAliased '[] where
73+ type Unaliased '[] = '[]
74+ unzipAliased _ = ([], RNil)
75+instance (KnownSymbol label, UnzipAliased xs)
76+ => UnzipAliased ( '(label, x) ': xs) where
77+ type Unaliased ( '(label, x) ': xs) = x ': Unaliased xs
78+ unzipAliased (x :& xs) =
79+ let
80+ (labels,values) = unzipAliased xs
81+ in
82+ (aliasName (alias x) : labels, unalias x :& values)
83+
6484class AllAliased xs where
6585 renderAllAliased
6686 :: (forall x. obj x -> ByteString)
@@ -234,19 +254,24 @@ subselect selection = Relation
234254 , offsetting = Nothing
235255 }
236256
237−newtype Insertion ps xss = UnsafeInsertion {renderInsertion :: ByteString }
257+newtype Insertion ps xss xs = UnsafeInsertion
258+ {renderInsertion :: ByteString }
238259
239260into
240261 :: forall label xss xs ps
241− . HasField label xss xs
262+ . (HasField label xss xs, UnzipAliased xs)
242263 => Proxy label
243264 -> Rec (Aliased (Expression ps '[])) xs
244− -> Insertion ps xss
265+ -> Insertion ps xss xs
245266into table values = UnsafeInsertion $ "INTO "
246267 <> fieldName table (Proxy @xss) (Proxy @xs)
247− <> " VALUES "
268+ <> " (" <> ByteString.intercalate ", " names
269+ <> ") VALUES ("
248270 <> ByteString.intercalate ", "
249− (recordToList (rmap (Const . renderExpression . unalias) values))
271+ (recordToList (rmap (Const . renderExpression) exprs))
272+ <> ")"
273+ where
274+ (names,exprs) = unzipAliased values
250275
251276newtype Query ps xss yss zs = UnsafeQuery { renderQuery :: ByteString }
252277newtype PreparedQuery ps xss yss zs =
@@ -256,6 +281,6 @@ select :: Selection ps xss ys -> Query ps xss xss ys
256281select selection = UnsafeQuery $
257282 "SELECT " <> renderSelection selection <> ";"
258283
259−insert :: Insertion ps xss -> Query ps xss xss '[]
284+insert :: Insertion ps xss xs -> Query ps xss xss '[]
260285insert insertion = UnsafeQuery $
261286 "INSERT " <> renderInsertion insertion <> ";"
squeel-postgresql/test/Squeel/PostgreSQL/QuerySpec.hs+5−16
@@ -52,20 +52,12 @@ spec = do
5252 it "correctly render simple INSERTs" $ do
5353 renderQuery (insert insertion)
5454 `shouldBe`
55− "INSERT INTO "
56−
57−
58−type Columns =
59− '[ '("col1", 'PGInt4)
60− , '("col2", 'PGInt4)
61− ]
55+ "INSERT INTO table1 (col1, col2) VALUES (2, 4);"
6256
57+type Columns = '[ '("col1", 'PGInt4), '("col2", 'PGInt4)]
6358type Tables = '[ '("table1", Columns)]
6459
65−sumAndCol1 :: Projection '[] Columns
66− '[ '("sum", 'PGInt4)
67− , '("col1", 'PGInt4)
68− ]
60+sumAndCol1 :: Projection '[] Columns '[ '("sum", 'PGInt4), '("col1", 'PGInt4)]
6961sumAndCol1 = project ((#col1 + #col2) `As` #sum :& #col1 :& RNil)
7062
7163table1 :: Relation '[] Tables Columns
@@ -74,8 +66,5 @@ table1 = #table1
7466parameterizedTable1 :: Relation '[ 'PGInt8] Tables Columns
7567parameterizedTable1 = #table1
7668
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)
69+insertion :: Insertion '[] Tables Columns
70+insertion = into (Proxy @"table1") (2 `As` #col1 :& 4 `As` #col2 :& RNil)