+1
-1
@@ -1,5 +1,5 @@
|
|||||||
name: dbapi
|
name: dbapi
|
||||||
version: 0.2.0.0
|
version: 0.2.1.0
|
||||||
synopsis: The database is your api
|
synopsis: The database is your api
|
||||||
license: MIT
|
license: MIT
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
|
|||||||
+38
-2
@@ -19,8 +19,9 @@ module PgQuery (
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Data.String.Conversions (cs)
|
import Data.String.Conversions (cs)
|
||||||
import Data.Functor ( (<$>) )
|
import Data.Functor ( (<$>) )
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe, mapMaybe)
|
||||||
import Data.List (intersperse, intercalate)
|
import Data.List (intersperse, intercalate)
|
||||||
|
import Data.List.Split (splitOn)
|
||||||
import Data.Monoid ((<>), mconcat)
|
import Data.Monoid ((<>), mconcat)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
|
||||||
@@ -65,6 +66,7 @@ getRows schema table qq range conn = do
|
|||||||
jsonArrayRows
|
jsonArrayRows
|
||||||
(selectStarClause schema table
|
(selectStarClause schema table
|
||||||
<> whereClause qq
|
<> whereClause qq
|
||||||
|
<> orderClause qq
|
||||||
<> limitClause range)
|
<> limitClause range)
|
||||||
r <- quickQuery conn query []
|
r <- quickQuery conn query []
|
||||||
|
|
||||||
@@ -78,12 +80,46 @@ getRows schema table qq range conn = do
|
|||||||
where
|
where
|
||||||
offset = fromMaybe 0 $ R.offset <$> range
|
offset = fromMaybe 0 $ R.offset <$> range
|
||||||
|
|
||||||
|
|
||||||
whereClause :: Net.Query -> QuotedSql
|
whereClause :: Net.Query -> QuotedSql
|
||||||
whereClause qs =
|
whereClause qs =
|
||||||
if null qs then ("", []) else (" where ", []) <> conjunction
|
if null qs then ("", []) else (" where ", []) <> conjunction
|
||||||
|
|
||||||
where
|
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 :: Net.QueryItem -> QuotedSql
|
||||||
wherePred (column, predicate) =
|
wherePred (column, predicate) =
|
||||||
|
|||||||
@@ -20,6 +20,22 @@ spec = around appWithFixture $ do
|
|||||||
, matchHeaders = ["Content-Range" <:> "0-0/1"]
|
, 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" $
|
describe "Canonical location" $
|
||||||
it "Sets Content-Location with alphabetized params" $
|
it "Sets Content-Location with alphabetized params" $
|
||||||
get "/no_pk?b=eq.1&a=eq.1"
|
get "/no_pk?b=eq.1&a=eq.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user