9 import Database
.HDBC
.Sqlite3
10 import System
.Directory
13 data Flag
= Path
String
23 isFlag
:: String -> Bool
24 isFlag f
= f `
elem`
["-f","-p","-t","-j","-d","-v","-a","-k"]
26 isPathFlag
:: Flag
-> Bool
27 isPathFlag f
= case f
of
31 add
:: [String] -> IO ()
32 add
[] = error $ "add: no arguments specified ('" ++ progName
++ " add help' for help)"
33 add argv
= if isHelp
$ head argv
34 then do putStrLn usageAdd
36 case parseFlags argv
of
37 Left msg
-> error $ "add: " ++ msg
38 Right flags
-> do checkFile flags
39 putStrLn (flagsToString flags
)
40 runSQL
(buildSQL flags
)
42 buildSQL
:: [Flag
] -> String
43 buildSQL flags
= buildSQL
' ("INSERT INTO " ++ tableName
++ " (") "VALUES(" flags
44 where buildSQL
' t1 t2
[] = ((init t1
) ++ ") ") ++ (init(t2
) ++ ");")
45 buildSQL
' t1 t2
(f
:fs
) = buildSQL
' (t1
++key
++",") (t2
++"'"++value++"',") fs
46 where (key
,val
) = break (==' ') $ show f
47 value = filter (/= '\"') (tail val
)
49 checkFile
:: [Flag
] -> IO ()
50 checkFile fs
= case filter isPathFlag fs
of
52 ((Path p
):_
) -> do exists
<- doesFileExist p
55 else do error $ "File does not exists: " ++ p
57 isDate
:: String -> Bool
58 isDate str
= and [and (map isDigit str
), (size
== 4) ||
(size
== 6) ||
(size
== 8)]
59 where size
= length str
61 isPages
:: String -> Bool
62 isPages str
= and (map isDigit (pf
++ pt
))
63 where (pf
,pt
') = break (=='-') str
64 pt
= if null pt
' then "0" else tail pt
'
66 flagsToString
:: [Flag
] -> String
67 flagsToString xs
= foldl' step
[] xs
68 where step ys x
= show x
++ "\n" ++ ys
70 parseFlags
:: [String] -> Either String [Flag
]
71 parseFlags argv
= parseFlags
' [] argv
72 where parseFlags
' _
(x
:[]) = if isFlag x
73 then Left
"too few arguments"
74 else Left
$ "Invalid argument: " ++ x
75 parseFlags
' fs
[] = Right fs
80 Right f
-> parseFlags
' (f
:fs
) (dropWhile (not . isFlag
) (tail xs
))
82 getFlag
:: [String] -> Either String Flag
85 then Left
"too few argument"
87 "-f" -> Right
$ Path x1
88 "-t" -> Right
$ Title x1
89 "-j" -> Right
$ Journal x1
90 "-v" -> Right
$ Volume x1
93 else Left
$ "Invalid date: " ++ x1
++ " ('" ++ progName
++ "\
94 \ add help' for help)"
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 ()
116 usageAdd
= "usage: " ++ progName
++ " add <filters>\n\
120 \ -a <author1 [author2] ...>\n\
121 \ -k <keyword1 [keyword2] ...>\n\
123 \ -d <date> : <yyyy> OR <mmyyyy> OR <ddmmyyyy>\n\
124 \ -p <page-from>-<page-to>"