module IHP.IDE.Data.View.ShowQuery where import qualified Database.PostgreSQL.Simple as PG import IHP.ViewPrelude import IHP.IDE.ToolServer.Types import IHP.IDE.Data.View.Layout data ShowQueryView = ShowQueryView { ShowQueryView -> Maybe (Either SqlError SqlConsoleResult) queryResult :: Maybe (Either PG.SqlError SqlConsoleResult) , ShowQueryView -> Text queryText :: Text } instance View ShowQueryView where html :: (?context::ControllerContext, ?view::ShowQueryView) => ShowQueryView -> Html html ShowQueryView { Maybe (Either SqlError SqlConsoleResult) Text $sel:queryResult:ShowQueryView :: ShowQueryView -> Maybe (Either SqlError SqlConsoleResult) $sel:queryText:ShowQueryView :: ShowQueryView -> Text queryResult :: Maybe (Either SqlError SqlConsoleResult) queryText :: Text .. } = [hsx| <div class="h-100"> {headerNav} <div class="container-fluid mt-2"> <form method="GET" action={QueryAction} class="sql-repl"> <input type="hidden" name="query" value={queryText}/> <div class="p-2 rounded my-2" style="background-color: #002B36; border: 1px solid #0B5163;"> <div class="query-editor" style="height:16px">{queryText}</div> </div> <button class="btn btn-primary" data-toggle="tooltip" data-placement="right" title="⌘ Enter" >Run SQL Query</button> </form> <div class="mt-3"> {renderRows} </div> </div> </div> |] where renderRows :: Html renderRows = case Maybe (Either SqlError SqlConsoleResult) queryResult of Just ((Right (SelectQueryResult []))) -> [hsx| <div class="text-muted"> The query returned an empty result set. </div> |] Just (Right (SelectQueryResult [[DynamicField]] rows)) -> [hsx| <table class="table table-sm table-hover table-striped data-rows-table"> {tableHead rows} {tableBody rows} </table> |] Just (Right (InsertOrUpdateResult Int64 count)) -> [hsx| <div class="text-muted"> {count} {if count == 1 then "row" :: Text else "rows"} affected. </div> |] Just (Left SqlError sqlError) -> [hsx| <div class="alert alert-danger" role="alert"> <h4 class="alert-heading">SQL Error - {sqlError.sqlExecStatus}</h4> {showIfNotEmpty "Message" (sqlError.sqlErrorMsg)} {showIfNotEmpty "Details" (sqlError.sqlErrorDetail)} {showIfNotEmpty "Hint" (sqlError.sqlErrorHint)} {showIfNotEmpty "State" (sqlError.sqlState)} </div> |] Maybe (Either SqlError SqlConsoleResult) Nothing -> Html forall a. Monoid a => a mempty tableHead :: [[a]] -> Html tableHead [[a]] rows = [hsx|<thead><tr>{forEach (columnNames rows) renderColumnHead}</tr></thead>|] renderColumnHead :: a -> Html renderColumnHead a name = [hsx|<th>{name}</th>|] tableBody :: mono -> Html tableBody mono rows = [hsx|<tbody>{forEach rows renderRow}</tbody>|] renderRow :: mono -> Html renderRow mono fields = [hsx|<tr>{forEach fields renderField}</tr>|] renderField :: DynamicField -> Html renderField DynamicField { Maybe ByteString ByteString fieldValue :: Maybe ByteString fieldName :: ByteString $sel:fieldValue:DynamicField :: DynamicField -> Maybe ByteString $sel:fieldName:DynamicField :: DynamicField -> ByteString .. } = [hsx|<td><span data-fieldname={fieldName}>{sqlValueToText fieldValue}</span></td>|] columnNames :: [[a]] -> [a] columnNames [[a]] rows = [a] -> ([a] -> [a]) -> Maybe [a] -> [a] forall b a. b -> (a -> b) -> Maybe a -> b maybe [] ((a -> a) -> [a] -> [a] forall a b. (a -> b) -> [a] -> [b] map (.fieldName)) ([[a]] -> Maybe [a] forall a. [a] -> Maybe a head [[a]] rows) showIfNotEmpty :: Text -> ByteString -> Html showIfNotEmpty :: Text -> ByteString -> Html showIfNotEmpty Text title = \case ByteString "" -> Html forall a. Monoid a => a mempty ByteString text -> [hsx|<div><strong>{title}:</strong> {text}</div>|]