<commit_before>{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Applicative

import Database.HDBC.PostgreSQL (connectPostgreSQL)

import Network.Wai
import Network.Wai.Handler.Warp hiding (Connection)
import Network.HTTP.Types.Status
import Network.HTTP.Types.Header
import Network.HTTP.Types.Method

import Options.Applicative hiding (columns)

import PgStructure (printTables, printColumns)
import PgQuery     (selectWhere)

import Debug.Trace

traceThis :: (Show a) => a -> a
traceThis x = trace (show x) x

data AppConfig = AppConfig {
    configDbUri :: String
  , configPort  :: Int }

argParser :: Parser AppConfig
argParser = AppConfig
  <$> strOption (long "db" <> short 'd' <> metavar "URI"
    <> help "database uri to expose, e.g. postgres://user:pass@host:port/database")
  <*> option (long "port" <> short 'p' <> metavar "NUMBER" <> value 3000
    <> help "port number on which to run HTTP server")

main :: IO ()
main = do
  conf <- execParser (info (helper <*> argParser) describe)

  Prelude.putStrLn $ "Listening on port " ++ (show $ configPort conf :: String)
  run (configPort conf) $ app conf

  where
    describe = progDesc "create a REST API to an existing Postgres database"

app ::  AppConfig -> Application
app config req respond = do
  r <-
    case path of
      []      -> responseLBS status200 [json] <$> (printTables =<< conn)
      [table] -> responseLBS status200 [json] <$>
                ( if verb == methodOptions
                  then printColumns table =<< conn
                  else selectWhere table qq =<< conn )
      _       -> return $ responseLBS status404 [] ""

  respond r

  where
    path = pathInfo req
    verb = requestMethod req
    json = (hContentType, "application/json")
    conn = connectPostgreSQL $ configDbUri config
    qq   = queryString req
<commit_msg>Report sql errors to client<commit_after>{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Applicative
import Control.Exception (try)

import Database.HDBC.PostgreSQL (connectPostgreSQL)
import Database.HDBC.Types (SqlError, seErrorMsg)

import Network.Wai
import Network.Wai.Handler.Warp hiding (Connection)
import Network.HTTP.Types.Status
import Network.HTTP.Types.Header
import Network.HTTP.Types.Method

import Options.Applicative hiding (columns)

import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Char8 as BS

import PgStructure (printTables, printColumns)
import PgQuery     (selectWhere)

import Debug.Trace

traceThis :: (Show a) => a -> a
traceThis x = trace (show x) x

data AppConfig = AppConfig {
    configDbUri :: String
  , configPort  :: Int }

argParser :: Parser AppConfig
argParser = AppConfig
  <$> strOption (long "db" <> short 'd' <> metavar "URI"
    <> help "database uri to expose, e.g. postgres://user:pass@host:port/database")
  <*> option (long "port" <> short 'p' <> metavar "NUMBER" <> value 3000
    <> help "port number on which to run HTTP server")

main :: IO ()
main = do
  conf <- execParser (info (helper <*> argParser) describe)

  Prelude.putStrLn $ "Listening on port " ++ (show $ configPort conf :: String)
  run (configPort conf) $ app conf

  where
    describe = progDesc "create a REST API to an existing Postgres database"

app ::  AppConfig -> Application
app config req respond = do
  r <- try $
    case path of
      []      -> responseLBS status200 [json] <$> (printTables =<< conn)
      [table] -> responseLBS status200 [json] <$>
                ( if verb == methodOptions
                  then printColumns table =<< conn
                  else selectWhere table qq =<< conn )
      _       -> return $ responseLBS status404 [] ""

  respond $ either sqlErrorHandler id r

  where
    path = pathInfo req
    verb = requestMethod req
    json = (hContentType, "application/json")
    conn = connectPostgreSQL $ configDbUri config
    qq   = queryString req

sqlErrorHandler :: SqlError -> Response
sqlErrorHandler e =
  responseLBS status400 [] $ BL.fromChunks [BS.pack (seErrorMsg e)]

{'fraction_non_alphanumeric': 0.10609816559246406, 'fraction_numerical': 0.0074367873078829945, 'mean_word_length': 3.3017057569296377, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3963815', 'n_tokens_mistral': 1255, 'n_tokens_neox': 1191, 'n_words': 398}