X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2FMain.hs;h=f00ebb39dd2eb6b258d39261ca4f2a807da67d93;hb=39e047ccd8422207e01247c63f514c40e7eac31e;hp=b52bf504c02da2592670be05e44c1102a04dd413;hpb=0f6ab35ca71299d1c9db63a12df2329acf123284;p=mailbox-count.git diff --git a/src/Main.hs b/src/Main.hs index b52bf50..f00ebb3 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,22 +1,52 @@ +{-# LANGUAGE DoAndIfThenElse #-} +{-# LANGUAGE NoMonomorphismRestriction #-} module Main where +import Data.Maybe ( fromMaybe ) import Data.Monoid ( (<>) ) +import Data.String.Utils ( join ) import Database.HDBC.PostgreSQL ( connectPostgreSQL ) +import Database.HDBC.Sqlite3 ( connectSqlite3 ) import System.Console.CmdArgs ( def ) +import System.Directory ( doesFileExist ) import CommandLine ( get_args ) import Configuration ( Configuration(..), merge_optional ) import qualified OptionalConfiguration as OC ( from_rc ) import Report ( report ) + +-- | Construct a connection string (postgres-only, for now) from a +-- 'Configuration'. All of these are optional, at least for +-- Postgres, and so we want to avoid appending e.g. \"host=\" to the +-- connection string if @(host cfg)@ is 'Nothing'. +-- +-- Examples: +-- +-- >>> let default_cfg = def :: Configuration +-- >>> let cfg = default_cfg { host = Just "localhost" } +-- >>> connection_string cfg +-- "host=localhost" +-- >>> let cfg2 = cfg { username = Just "postgres" } +-- >>> connection_string cfg2 +-- "host=localhost user=postgres" +-- connection_string :: Configuration -> String connection_string cfg = - "host=" ++ (host cfg) ++ " " ++ - "port=" ++ (show $ port cfg) ++ " " ++ - "user=" ++ (username cfg) ++ " " ++ - "password=" ++ (password cfg) ++ " " ++ - "dbname=" ++ (database cfg) + trim $ join " " [host_part, port_part, user_part, pw_part, db_part] + where + -- | Strip leading/trailing whitespace, and collapse multiple + -- consecutive spaces into one. + trim :: String -> String + trim = unwords . words + + host_part = let h = fmap ("host=" ++) (host cfg) in fromMaybe "" h + port_part = let p = fmap (("port=" ++) . show) (port cfg) in fromMaybe "" p + user_part = let u = fmap ("user=" ++) (username cfg) in fromMaybe "" u + pw_part = let pw = fmap ("password=" ++) (password cfg) in fromMaybe "" pw + db_part = let db = fmap ("dbname=" ++) (database cfg) in fromMaybe "" db + main :: IO () main = do @@ -33,16 +63,16 @@ main = do -- log the errors. let cfg = (def :: Configuration) `merge_optional` opt_config - -- Check the optional config for missing required options. - --when (isNothing (OC.password opt_config)) $ do - -- report_error "No password supplied." - -- exitWith (ExitFailure exit_no_password) + -- If a database name was specified, and that name exists as a file + -- on the system, assume that the user wanted to use SQLite. + r <- case (database cfg) of + Nothing -> connectPostgreSQL (connection_string cfg) >>= report cfg - --when (isNothing (OC.username opt_config)) $ do - -- report_error "No username supplied." - --exitWith (ExitFailure exit_no_username) + Just dbname -> do + exists <- doesFileExist dbname + if exists + then connectSqlite3 dbname >>= report cfg + else connectPostgreSQL (connection_string cfg) >>= report cfg - conn <- connectPostgreSQL (connection_string cfg) - r <- report conn (both cfg) (detail cfg) + -- The DB connection is implicitly closed when it gets garbage collected. putStrLn r --- disconnect conn