odbc-0.2.0: app/Main.hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings, LambdaCase #-}
-- | A helpful client for debugging connections.
import Control.Exception
import Data.List
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Database.ODBC.Internal as ODBC
import System.Environment
import System.IO
import Text.Printf
-- | Main entry point.
main :: IO ()
main = do
args <- getArgs
case args of
[connStr] -> do
conn <- ODBC.connect (T.pack connStr)
repl conn
_ -> error "usage: <connection string>"
-- | Accepts a query/command and prints any results.
repl :: ODBC.Connection -> IO ()
repl c = do
result <- prompt
case result of
Nothing -> pure ()
Just input -> do
hSetBuffering stdout LineBuffering
catch
(catch
(do count <- ODBC.stream c input output (0 :: Int)
putStrLn ("Rows: " ++ show count))
(\case
UserInterrupt -> pure ()
e -> throwIO e))
(\(e :: ODBC.ODBCException) -> putStrLn (displayException e))
repl c
where
prompt = do
hSetBuffering stdout NoBuffering
putStr "> "
catch (fmap Just T.getLine) (\(_ :: IOException) -> pure Nothing)
output count row = do
putStrLn (intercalate ", " (map showColumn row))
pure (ODBC.Continue (count + 1))
where
showColumn =
\case
ODBC.NullValue -> "NULL"
ODBC.TextValue t -> show t
ODBC.ByteStringValue bs -> show bs
ODBC.BinaryValue bs -> show bs
ODBC.BoolValue b -> show b
ODBC.DoubleValue d -> printf "%f" d
ODBC.FloatValue d -> printf "%f" d
ODBC.IntValue i -> show i
ODBC.DayValue d -> show d
ODBC.ByteValue b -> show b
ODBC.TimeOfDayValue v -> show v
ODBC.LocalTimeValue v -> show v