From 6474a83221638d5ee93efca84862fece8f1212f8 Mon Sep 17 00:00:00 2001 From: Joe Nelson Date: Sat, 28 Feb 2015 23:04:07 -0800 Subject: [PATCH] Support IN query param operator --- src/PgQuery.hs | 16 ++++++++++++---- test/Feature/QuerySpec.hs | 8 ++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/PgQuery.hs b/src/PgQuery.hs index 01972b8a8..48aeecb04 100644 --- a/src/PgQuery.hs +++ b/src/PgQuery.hs @@ -138,15 +138,22 @@ update t cols vals = B.Stmt wherePred :: Net.QueryItem -> PStmt wherePred (col, predicate) = B.Stmt - (" " <> cs (pgFmtIdent $ cs col) <> " " <> op <> " " <> cs (pgFmtLit value) <> "::unknown ") + (" " <> cs (pgFmtIdent $ cs col) <> " " <> op <> " " <> cs sqlValue) empty True where opCode:rest = T.split (=='.') $ cs $ fromMaybe "." predicate - unStarredVal = T.intercalate "." rest + value = T.intercalate "." rest + star c = if c == '*' then '%' else c - value = if opCode == "like" || opCode == "ilike" - then T.map star unStarredVal else unStarredVal + unknownLiteral = (<> "::unknown ") . pgFmtLit + + sqlValue = case opCode of + "like" -> unknownLiteral $ T.map star value + "ilike" -> unknownLiteral $ T.map star value + "in" -> "(" <> T.intercalate ", " (map unknownLiteral $ T.split (==',') value) <> ") " + _ -> unknownLiteral value + op = case opCode of "eq" -> "=" "gt" -> ">" @@ -156,6 +163,7 @@ wherePred (col, predicate) = B.Stmt "neq" -> "<>" "like"-> "like" "ilike"-> "ilike" + "in" -> "in" _ -> "=" orderParse :: Net.Query -> [OrderTerm] diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs index 9de45f565..0bfc1dcd7 100644 --- a/test/Feature/QuerySpec.hs +++ b/test/Feature/QuerySpec.hs @@ -38,6 +38,14 @@ spec = beforeAll testSet . afterAll_ (clearTable "items") . around withApp $ do , matchHeaders = ["Content-Range" <:> "0-0/1"] } + it "matches items IN" $ + get "/items?id=in.1,3,5" + `shouldRespondWith` ResponseMatcher { + matchBody = Just [json| [{"id":1},{"id":3},{"id":5}] |] + , matchStatus = 200 + , matchHeaders = ["Content-Range" <:> "0-2/3"] + } + it "matches with like" $ do get "/no_pk?a=like.*yx" `shouldRespondWith` [json| [{"a":"xyyx","b":"u"}]|]