Add.hs: now fails with error message when given bad flag
[hdata.git] / Add.hs
blob8426b9bafd6e308803a31864b3e6e38cf5a76e93
1 module Add (
2 add,
3 usageAdd
4 ) where
6 import Data.Char
7 import Data.List
8 import Database.HDBC
9 import Database.HDBC.Sqlite3
10 import System.Directory
11 import Util
13 data Flag = Path String
14 | Title String
15 | Authors String
16 | Keywords String
17 | Journal String
18 | Volume String
19 | Issue String
20 | Date String
21 | Pages String
22 deriving (Eq,Show)
24 isFlag :: String -> Bool
25 isFlag f = f `elem` ["-f","-p","-t","-j","-i","-d","-v","-a","-k"]
27 isPathFlag :: Flag -> Bool
28 isPathFlag f = case f of
29 Path _ -> True
30 _ -> False
32 add :: [String] -> IO ()
33 add [] = error $ "add: no arguments specified ('" ++ progName ++ " add help' for help)"
34 add argv = if isHelp $ head argv
35 then do putStrLn usageAdd
36 else do
37 case parseFlags argv of
38 Left msg -> error $ "add: " ++ msg
39 Right flags -> do checkFile flags
40 putStrLn (flagsToString flags)
41 runSQL (buildSQL flags)
43 buildSQL :: [Flag] -> String
44 buildSQL flags = buildSQL' ("INSERT INTO " ++ tableName ++ " (") "VALUES(" flags
45 where buildSQL' t1 t2 [] = ((init t1) ++ ") ") ++ (init(t2) ++ ");")
46 buildSQL' t1 t2 (f:fs) = buildSQL' (t1++key++",") (t2++"'"++value++"',") fs
47 where (key,val) = break (==' ') $ show f
48 value = filter (/= '\"') (tail val)
50 checkFile :: [Flag] -> IO ()
51 checkFile fs = case filter isPathFlag fs of
52 [] -> return ()
53 ((Path p):_) -> do exists <- doesFileExist p
54 if exists
55 then do return ()
56 else do error $ "File does not exists: " ++ p
58 isDate :: String -> Bool
59 isDate str = and [and (map isDigit str), (size == 4) || (size == 6) || (size == 8)]
60 where size = length str
62 isPages :: String -> Bool
63 isPages str = and (map isDigit (pf ++ pt))
64 where (pf,pt') = break (=='-') str
65 pt = if null pt' then "0" else tail pt'
67 flagsToString :: [Flag] -> String
68 flagsToString xs = foldl' step [] xs
69 where step ys x = show x ++ "\n" ++ ys
71 parseFlags :: [String] -> Either String [Flag]
72 parseFlags argv = parseFlags' [] argv
73 where parseFlags' _ (x:[]) = Left "too few arguments"
74 parseFlags' fs [] = Right fs
75 parseFlags' fs xs =
76 let flag = getFlag xs
77 in case flag of
78 Left msg -> Left msg
79 Right f -> parseFlags' (f:fs) (dropWhile (not . isFlag) (tail xs))
81 getFlag :: [String] -> Either String Flag
82 getFlag x@(x0:x1:_) =
83 if isFlag x1
84 then Left "too few argument"
85 else case x0 of
86 "-f" -> Right $ Path x1
87 "-t" -> Right $ Title x1
88 "-j" -> Right $ Journal x1
89 "-v" -> Right $ Volume x1
90 "-i" -> Right $ Issue x1
91 "-d" -> if isDate x1
92 then Right $ Date x1
93 else Left $ "Invalid date: " ++ x1 ++ " ('" ++ progName ++ "\
94 \ add help' for help)"
95 "-p" -> if isPages x1
96 then Right $ Pages x1
97 else Left $ "Invalid pages: " ++ x1 ++ " ('" ++ progName ++ "\
98 \ add help' for help)"
99 "-k" -> Right $ Keywords $ getValues $ tail x
100 "-a" -> Right $ Authors $ getValues $ tail x
101 _ -> Left $ "Invalid argument: " ++ x0
103 getValues :: [String] -> String
104 getValues argv = intercalate "/" $ takeWhile (not . isFlag) argv
107 runSQL :: String -> IO ()
108 runSQL sql = do
109 db <- opendb
110 run db sql []
111 commit db
112 disconnect db
113 return ()
115 usageAdd :: String
116 usageAdd = "usage: " ++ progName ++ " add <filters>\n\
117 \filters:\n\
118 \ -f <file>\n\
119 \ -t <title>\n\
120 \ -a <author1 [author2] ...>\n\
121 \ -k <keyword1 [keyword2] ...>\n\
122 \ -j <journal>\n\
123 \ -i <issue>\n\
124 \ -d <date> : <yyyy> OR <mmyyyy> OR <ddmmyyyy>\n\
125 \ -p <page-from>-<page-to>"