{-# LANGUAGE TemplateHaskell #-}
module Hasura.RQL.DDL.Schema
( module M,
RunSQLRes (..),
)
where
import Data.Aeson
import Data.Aeson.TH (deriveJSON)
import Data.Text.Encoding qualified as TE
import Database.PG.Query qualified as Q
import Database.PostgreSQL.LibPQ qualified as PQ
import Hasura.Prelude
import Hasura.RQL.DDL.Schema.Cache as M
import Hasura.RQL.DDL.Schema.Catalog as M
import Hasura.RQL.DDL.Schema.Function as M
import Hasura.RQL.DDL.Schema.Rename as M
import Hasura.RQL.DDL.Schema.Table as M
data RunSQLRes = RunSQLRes
{ RunSQLRes -> Text
rrResultType :: Text,
RunSQLRes -> Value
rrResult :: Value
}
deriving (Int -> RunSQLRes -> ShowS
[RunSQLRes] -> ShowS
RunSQLRes -> String
(Int -> RunSQLRes -> ShowS)
-> (RunSQLRes -> String)
-> ([RunSQLRes] -> ShowS)
-> Show RunSQLRes
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RunSQLRes] -> ShowS
$cshowList :: [RunSQLRes] -> ShowS
show :: RunSQLRes -> String
$cshow :: RunSQLRes -> String
showsPrec :: Int -> RunSQLRes -> ShowS
$cshowsPrec :: Int -> RunSQLRes -> ShowS
Show, RunSQLRes -> RunSQLRes -> Bool
(RunSQLRes -> RunSQLRes -> Bool)
-> (RunSQLRes -> RunSQLRes -> Bool) -> Eq RunSQLRes
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RunSQLRes -> RunSQLRes -> Bool
$c/= :: RunSQLRes -> RunSQLRes -> Bool
== :: RunSQLRes -> RunSQLRes -> Bool
$c== :: RunSQLRes -> RunSQLRes -> Bool
Eq)
$(deriveJSON hasuraJSON ''RunSQLRes)
instance Q.FromRes RunSQLRes where
fromRes :: ResultOk -> ExceptT Text IO RunSQLRes
fromRes (Q.ResultOkEmpty Result
_) =
RunSQLRes -> ExceptT Text IO RunSQLRes
forall (m :: * -> *) a. Monad m => a -> m a
return (RunSQLRes -> ExceptT Text IO RunSQLRes)
-> RunSQLRes -> ExceptT Text IO RunSQLRes
forall a b. (a -> b) -> a -> b
$ Text -> Value -> RunSQLRes
RunSQLRes Text
"CommandOk" Value
Null
fromRes (Q.ResultOkData Result
res) = do
[[Text]]
csvRows <- Result -> ExceptT Text IO [[Text]]
resToCSV Result
res
RunSQLRes -> ExceptT Text IO RunSQLRes
forall (m :: * -> *) a. Monad m => a -> m a
return (RunSQLRes -> ExceptT Text IO RunSQLRes)
-> RunSQLRes -> ExceptT Text IO RunSQLRes
forall a b. (a -> b) -> a -> b
$ Text -> Value -> RunSQLRes
RunSQLRes Text
"TuplesOk" (Value -> RunSQLRes) -> Value -> RunSQLRes
forall a b. (a -> b) -> a -> b
$ [[Text]] -> Value
forall a. ToJSON a => a -> Value
toJSON [[Text]]
csvRows
where
resToCSV :: PQ.Result -> ExceptT Text IO [[Text]]
resToCSV :: Result -> ExceptT Text IO [[Text]]
resToCSV Result
r = do
Row
nr <- IO Row -> ExceptT Text IO Row
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Row -> ExceptT Text IO Row) -> IO Row -> ExceptT Text IO Row
forall a b. (a -> b) -> a -> b
$ Result -> IO Row
PQ.ntuples Result
r
Column
nc <- IO Column -> ExceptT Text IO Column
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Column -> ExceptT Text IO Column)
-> IO Column -> ExceptT Text IO Column
forall a b. (a -> b) -> a -> b
$ Result -> IO Column
PQ.nfields Result
r
[Text]
hdr <- [Column]
-> (Column -> ExceptT Text IO Text) -> ExceptT Text IO [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Column
0 .. Column -> Column
forall a. Enum a => a -> a
pred Column
nc] ((Column -> ExceptT Text IO Text) -> ExceptT Text IO [Text])
-> (Column -> ExceptT Text IO Text) -> ExceptT Text IO [Text]
forall a b. (a -> b) -> a -> b
$ \Column
ic -> do
Maybe ByteString
colNameBS <- IO (Maybe ByteString) -> ExceptT Text IO (Maybe ByteString)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe ByteString) -> ExceptT Text IO (Maybe ByteString))
-> IO (Maybe ByteString) -> ExceptT Text IO (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ Result -> Column -> IO (Maybe ByteString)
PQ.fname Result
r Column
ic
ExceptT Text IO Text
-> (ByteString -> ExceptT Text IO Text)
-> Maybe ByteString
-> ExceptT Text IO Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> ExceptT Text IO Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
"unknown") ByteString -> ExceptT Text IO Text
decodeBS Maybe ByteString
colNameBS
[[Text]]
rows <- [Row]
-> (Row -> ExceptT Text IO [Text]) -> ExceptT Text IO [[Text]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Row
0 .. Row -> Row
forall a. Enum a => a -> a
pred Row
nr] ((Row -> ExceptT Text IO [Text]) -> ExceptT Text IO [[Text]])
-> (Row -> ExceptT Text IO [Text]) -> ExceptT Text IO [[Text]]
forall a b. (a -> b) -> a -> b
$ \Row
ir ->
[Column]
-> (Column -> ExceptT Text IO Text) -> ExceptT Text IO [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Column
0 .. Column -> Column
forall a. Enum a => a -> a
pred Column
nc] ((Column -> ExceptT Text IO Text) -> ExceptT Text IO [Text])
-> (Column -> ExceptT Text IO Text) -> ExceptT Text IO [Text]
forall a b. (a -> b) -> a -> b
$ \Column
ic -> do
Maybe ByteString
cellValBS <- IO (Maybe ByteString) -> ExceptT Text IO (Maybe ByteString)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe ByteString) -> ExceptT Text IO (Maybe ByteString))
-> IO (Maybe ByteString) -> ExceptT Text IO (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ Result -> Row -> Column -> IO (Maybe ByteString)
PQ.getvalue Result
r Row
ir Column
ic
ExceptT Text IO Text
-> (ByteString -> ExceptT Text IO Text)
-> Maybe ByteString
-> ExceptT Text IO Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> ExceptT Text IO Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
"NULL") ByteString -> ExceptT Text IO Text
decodeBS Maybe ByteString
cellValBS
[[Text]] -> ExceptT Text IO [[Text]]
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Text]] -> ExceptT Text IO [[Text]])
-> [[Text]] -> ExceptT Text IO [[Text]]
forall a b. (a -> b) -> a -> b
$ [Text]
hdr [Text] -> [[Text]] -> [[Text]]
forall a. a -> [a] -> [a]
: [[Text]]
rows
decodeBS :: ByteString -> ExceptT Text IO Text
decodeBS = (UnicodeException -> ExceptT Text IO Text)
-> (Text -> ExceptT Text IO Text)
-> Either UnicodeException Text
-> ExceptT Text IO Text
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Text -> ExceptT Text IO Text
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (Text -> ExceptT Text IO Text)
-> (UnicodeException -> Text)
-> UnicodeException
-> ExceptT Text IO Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnicodeException -> Text
forall a. Show a => a -> Text
tshow) Text -> ExceptT Text IO Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Either UnicodeException Text -> ExceptT Text IO Text)
-> (ByteString -> Either UnicodeException Text)
-> ByteString
-> ExceptT Text IO Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either UnicodeException Text
TE.decodeUtf8'