Allow filtering in table view

This commit is contained in:
Joe Nelson
2014-07-12 13:41:43 -07:00
parent c64dcc409f
commit 7f29e5f448
2 changed files with 41 additions and 32 deletions
-5
View File
@@ -3,18 +3,14 @@
module Main where module Main where
import Control.Applicative import Control.Applicative
import Data.Maybe (fromMaybe)
import qualified Data.ByteString.Char8 as BS
import Database.HDBC.PostgreSQL (connectPostgreSQL) import Database.HDBC.PostgreSQL (connectPostgreSQL)
import Network.Wai import Network.Wai
import Network.URI (uriQuery, parseURI)
import Network.Wai.Handler.Warp hiding (Connection) import Network.Wai.Handler.Warp hiding (Connection)
import Network.HTTP.Types.Status import Network.HTTP.Types.Status
import Network.HTTP.Types.Header import Network.HTTP.Types.Header
import Network.HTTP.Types.Method import Network.HTTP.Types.Method
import Network.HTTP.Types.URI (parseSimpleQuery)
import Options.Applicative hiding (columns) import Options.Applicative hiding (columns)
@@ -59,5 +55,4 @@ app config req respond =
verb = requestMethod req verb = requestMethod req
json = (hContentType, "application/json") json = (hContentType, "application/json")
conn = connectPostgreSQL $ configDbUri config conn = connectPostgreSQL $ configDbUri config
--qq = fromMaybe [] $ parseSimpleQuery . BS.pack . uriQuery <$> traceThis (parseURI . BS.unpack $ traceThis $ rawPathInfo req)
qq = queryString req qq = queryString req
+32 -18
View File
@@ -112,23 +112,42 @@ printColumns table conn = JSON.encode . namedColumnHash <$> columns table conn
traceThis :: (Show a) => a -> a traceThis :: (Show a) => a -> a
traceThis x = trace (show x) x traceThis x = trace (show x) x
selectWhere :: T.Text -> Query -> Connection -> IO BL.ByteString selectWhere :: T.Text -> Query -> Connection -> IO BL.ByteString
selectWhere table qq conn = do selectWhere table qq conn = do
let sql = unwords [ s <- selectSql
"select array_to_json(array_agg(row_to_json(t)))\ w <- whereClause conn qq
\ from (select * from %I.%I) t", whereClause qq ] r <- quickQuery conn (BS.unpack $ s <> w) []
statement <- prepareDynamic conn sql
[toSql (T.pack "base"), toSql table]
_ <- execute statement []
r <- fetchAllRows statement
return $ case r of return $ case r of
[[json]] -> fromSql json [[json]] -> fromSql json
_ -> "" :: BL.ByteString _ -> "" :: BL.ByteString
where where
wherePred :: QueryItem -> BS.ByteString selectSql = pgFormat conn
wherePred (column, predicate) = "select array_to_json(array_agg(row_to_json(t)))\
let opCode:rest = BS.split ':' $ fromMaybe "" predicate \ from (select * from %I.%I) t"
[toSql (T.pack "base"), toSql table]
whereClause :: Connection -> Query -> IO BS.ByteString
whereClause _ [] = return ""
whereClause conn qs =
(" where " <>) <$> clause
where
clause :: IO BS.ByteString
clause = BS.intercalate " and " <$> preds
preds :: IO [BS.ByteString]
preds = sequence $ map (wherePred conn) qs
wherePred :: Connection -> QueryItem -> IO BS.ByteString
wherePred conn (column, predicate) =
pgFormat conn ("t.%I " <> op <> "%L") $ map toSql [column, value]
where
opCode:rest = BS.split ':' $ fromMaybe "" predicate
value = BS.intercalate ":" rest value = BS.intercalate ":" rest
op = case opCode of op = case opCode of
"eq" -> "=" "eq" -> "="
@@ -138,17 +157,12 @@ selectWhere table qq conn = do
"lte" -> "<=" "lte" -> "<="
"neq" -> "<>" "neq" -> "<>"
_ -> "=" _ -> "="
in BS.intercalate " " ["t." <> column, op, value]
whereClause :: Query -> String
whereClause [] = ""
whereClause qs = BS.unpack $ "where " <> BS.intercalate " and " (map wherePred qs)
prepareDynamic :: Connection -> String -> [SqlValue] -> IO Statement pgFormat :: Connection -> String -> [SqlValue] -> IO BS.ByteString
prepareDynamic conn sql args = do pgFormat conn sql args = do
[[escaped]] <- quickQuery conn q args [[escaped]] <- quickQuery conn q args
return $ fromSql escaped
prepare conn $ fromSql escaped
where where
q = concat [ "select format('", sql, "', ", placeholders args, ")" ] q = concat [ "select format('", sql, "', ", placeholders args, ")" ]