Merge pull request #76 from begriffs/order-by

Accept order query param
This commit is contained in:
Joe Nelson
2014-10-13 22:51:18 -07:00
3 changed files with 55 additions and 3 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
name: dbapi
version: 0.2.0.0
version: 0.2.1.0
synopsis: The database is your api
license: MIT
license-file: LICENSE
+38 -2
View File
@@ -19,8 +19,9 @@ module PgQuery (
import Data.Text (Text)
import Data.String.Conversions (cs)
import Data.Functor ( (<$>) )
import Data.Maybe (fromMaybe)
import Data.Maybe (fromMaybe, mapMaybe)
import Data.List (intersperse, intercalate)
import Data.List.Split (splitOn)
import Data.Monoid ((<>), mconcat)
import qualified Data.Map as M
@@ -65,6 +66,7 @@ getRows schema table qq range conn = do
jsonArrayRows
(selectStarClause schema table
<> whereClause qq
<> orderClause qq
<> limitClause range)
r <- quickQuery conn query []
@@ -78,12 +80,46 @@ getRows schema table qq range conn = do
where
offset = fromMaybe 0 $ R.offset <$> range
whereClause :: Net.Query -> QuotedSql
whereClause qs =
if null qs then ("", []) else (" where ", []) <> conjunction
where
conjunction = mconcat $ intersperse (" and ", []) (map wherePred qs)
cols = [ col | col <- qs, fst col `notElem` ["order"] ]
conjunction = mconcat $ intersperse (" and ", []) (map wherePred cols)
orderClause :: Net.Query -> QuotedSql
orderClause qs = do
let order = fromMaybe "" $ join $ lookup "order" qs
terms = mapMaybe parseOrderTerm $ splitOn "," $ cs order
termPred = mconcat $ intersperse (", ", []) (map orderTermSql terms)
if null terms
then ("", [])
else (" order by ", []) <> termPred
where
parseOrderTerm :: String -> Maybe OrderTerm
parseOrderTerm s =
case splitOn "." s of
[d,c] ->
if d `elem` ["asc", "desc"]
then Just $ OrderTerm d c
else Nothing
_ -> Nothing
orderTermSql :: OrderTerm -> QuotedSql
orderTermSql t =
("%I " <> otDirection t, [toSql $ otColumn t])
data OrderTerm = OrderTerm {
otDirection :: String
, otColumn :: String
}
wherePred :: Net.QueryItem -> QuotedSql
wherePred (column, predicate) =
+16
View File
@@ -20,6 +20,22 @@ spec = around appWithFixture $ do
, matchHeaders = ["Content-Range" <:> "0-0/1"]
}
describe "ordering response" $ do
it "by a column asc" $
get "/items?id=lte.2&order=asc.id"
`shouldRespondWith` ResponseMatcher {
matchBody = Just "[{\"id\":1},{\"id\":2}]"
, matchStatus = 200
, matchHeaders = ["Content-Range" <:> "0-1/2"]
}
it "by a column desc" $
get "/items?id=lte.2&order=desc.id"
`shouldRespondWith` ResponseMatcher {
matchBody = Just "[{\"id\":2},{\"id\":1}]"
, matchStatus = 200
, matchHeaders = ["Content-Range" <:> "0-1/2"]
}
describe "Canonical location" $
it "Sets Content-Location with alphabetized params" $
get "/no_pk?b=eq.1&a=eq.1"