Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create executable and cabal file #4

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ cabal.sandbox.config
*.hp
*.eventlog
.stack-work/
cabal.project.local
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIX (accident)

25 changes: 25 additions & 0 deletions package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: postgresql-simple-query-validator
version: 0.1.0.0
github: "assertible/assertible"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIXME (whoops)

author: "Jonathan Curran"
maintainer: "[email protected]"
copyright: "Copyright (c) 2016, Jonathan Curran <[email protected]>"

executables:
postgresql-simple-query-validator:
main: validateSql.hs
ghc-options:
- -threaded
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO turn off all except threaded and warnings

- -rtsopts
- -with-rtsopts=-N
- -Wall
- -fno-warn-unused-do-bind
- -fwarn-incomplete-uni-patterns
- -fwarn-incomplete-record-updates
dependencies:
- base
- bytestring
- transformers
- megaparsec
- parser-combinators
- postgresql-libpq
34 changes: 34 additions & 0 deletions postgresql-simple-query-validator.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
-- This file has been generated from package.yaml by hpack version 0.28.2.
--
-- see: https://github.com/sol/hpack
--
-- hash: a5ce8b228e275e948784079c5272e0cc3b774e143ce6f4a6ea72a65bcd121f47

name: postgresql-simple-query-validator
version: 0.1.0.0
homepage: https://github.com/assertible/assertible#readme
bug-reports: https://github.com/assertible/assertible/issues
author: Jonathan Curran
maintainer: [email protected]
copyright: Copyright (c) 2016, Jonathan Curran <[email protected]>
license-file: LICENSE
build-type: Simple
cabal-version: >= 1.10

source-repository head
type: git
location: https://github.com/assertible/assertible

executable postgresql-simple-query-validator
main-is: validateSql.hs
other-modules:
Paths_postgresql_simple_query_validator
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -fno-warn-unused-do-bind -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates
build-depends:
base
, bytestring
, megaparsec
, parser-combinators
, postgresql-libpq
, transformers
default-language: Haskell2010
7 changes: 7 additions & 0 deletions stack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

resolver: lts-11.22

extra-deps: []

packages:
- '.'
38 changes: 24 additions & 14 deletions validateSql.hs
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
#!/usr/bin/env stack
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE this should "call out" to another Lib.hs style package for maximum portability, can probably be avoided for now. If not refactored, keep the shebang for backwards compatibility & document.

{- stack
--resolver lts-6.2
--install-ghc runghc
--package bytestring
--package megaparsec
--package postgresql-libpq
--package transformers
-}

{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B
import Data.Either (lefts)
import Database.PostgreSQL.LibPQ
module Main where

import Control.Monad (forM_, zipWithM)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE)
import Control.Monad.Trans.Reader (ReaderT, ask, runReaderT)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B
import Data.Either (lefts)
import Database.PostgreSQL.LibPQ hiding (fname)
import System.Environment (getArgs, getProgName)
import System.Exit (exitFailure, exitSuccess)
import System.Exit (ExitCode (..), exitFailure,
exitSuccess, exitWith)
import Text.Megaparsec
import Text.Megaparsec.Char


main :: IO ()
main =
runExceptT (getParams >>= processParams) >>= \case
Left err -> putStrLn err >> exitFailure
Left err -> putStrLn err >> exitWith (ExitFailure 255)
Right (qs, conn) -> checkAllQueries conn qs

getParams :: ExceptT String IO (FilePath, String)
Expand All @@ -47,12 +50,13 @@ processParams (fname, connstr) = do

checkAllQueries :: Connection -> [ByteString] -> IO ()
checkAllQueries conn queries = do
results <- zipWithM fn queries [B.pack $ "stmt" ++ show x | x <- [1..]]
forM_ (zip queries results) $ \case
results <- zipWithM fn queries [B.pack $ "stmt" ++ show x | x <- [(1::Int)..]]
let cleanResults = filter ((/=) (Left "ignore")) results
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE - this isn't really required in this initial change. It's my personal change to "ignore" quasi quoters with multiple statements.

Initially, I could remove this. In a subsequent PR, I can make it a proper flag.

forM_ (zip queries cleanResults) $ \case
(stmt, Left e) -> B.putStrLn stmt >> putStrLn e
_ -> return ()
finish conn
case lefts results of
case lefts cleanResults of
[] -> exitSuccess
_ -> exitFailure
where
Expand Down Expand Up @@ -84,17 +88,23 @@ processResult = \case
_ ->
liftIO (resultErrorMessage r) >>= \case
Nothing -> lift (throwE "server error")
Just e -> lift (throwE $ B.unpack e)
Just e -> if "multiple commands into a prepared statement" `B.isInfixOf` e then
lift (throwE "ignore")
else
lift (throwE $ B.unpack e)

type Parser = Parsec String String

extractSQL :: FilePath -> IO [ByteString]
extractSQL fname = do
contents <- B.readFile fname
case parse (many $ try extract) fname contents of
case parse (many $ try extract) fname (B.unpack contents) of
Left err -> print err >> exitFailure
Right qs -> return $ map (swapQs . B.pack) qs
where
-- could this be cleaner?
sqlqq :: Parser String
sqlqq = string "[sql|" >> someTill anyChar (string "|]")
extract :: Parser String
extract = manyTill anyChar (try.lookAhead $ string "[sql|") >> sqlqq
swapQs stmt =
let st = B.split '?' stmt in
Expand Down