1 | 1 |
module Main where
|
2 | 2 |
|
| 3 |
import Control.Monad (when)
|
3 | 4 |
import Data.Char (isSpace, isAlphaNum)
|
| 5 |
import Data.Monoid ((<>))
|
4 | 6 |
import Data.Text (Text)
|
5 | 7 |
import qualified Data.Text as T
|
6 | 8 |
import qualified Data.Text.IO as T
|
|
11 | 13 |
} deriving (Eq, Show)
|
12 | 14 |
|
13 | 15 |
data Field = Field
|
14 | |
{ fName :: Text
|
15 | |
, fType :: Text
|
16 | |
, fNull :: Bool
|
| 16 |
{ fName :: Text
|
| 17 |
, fType :: Text
|
| 18 |
, fNull :: Bool
|
| 19 |
, fUniq :: Bool
|
| 20 |
, fDefault :: Maybe Text
|
17 | 21 |
} deriving (Eq, Show)
|
18 | 22 |
|
19 | 23 |
uncomment :: Text -> Text
|
|
22 | 26 |
isValid :: Text -> Bool
|
23 | 27 |
isValid = T.all (\ x -> isAlphaNum x || x == '_')
|
24 | 28 |
|
| 29 |
isSpecial :: Char -> Bool
|
| 30 |
isSpecial c = c == '?' || c == '!'
|
| 31 |
|
| 32 |
parseField :: Text -> Field
|
| 33 |
parseField ln =
|
| 34 |
let (name, tt) = T.break (== ':') (T.strip ln)
|
| 35 |
(typ, def) = T.break (== '=') (T.strip tt)
|
| 36 |
in Field
|
| 37 |
{ fName = T.strip name
|
| 38 |
, fType = T.strip (T.drop 1 (T.filter (not . isSpecial) typ))
|
| 39 |
, fNull = T.any (== '?') typ
|
| 40 |
, fUniq = T.any (== '!') typ
|
| 41 |
, fDefault =
|
| 42 |
case def of
|
| 43 |
"" -> Nothing
|
| 44 |
rs -> Just (T.strip (T.drop 1 rs))
|
| 45 |
}
|
| 46 |
|
25 | 47 |
parse :: Text -> Either String [Decl]
|
26 | 48 |
parse = go [] . map uncomment . T.lines
|
27 | 49 |
where go ds [] = return ds
|
28 | 50 |
go ds (l:ls)
|
29 | 51 |
| T.length (T.takeWhile isSpace l) > 0 =
|
30 | |
let (n, t) = T.break (== ':') (T.strip l)
|
31 | |
f = Field { fName = T.strip n
|
32 | |
, fType = T.strip (T.drop 1 (T.filter (/= '?') t))
|
33 | |
, fNull = T.any (== '?') t
|
34 | |
}
|
| 52 |
let f = parseField l
|
35 | 53 |
in case ds of
|
36 | 54 |
(d:ds') -> go (d { dFields = f : dFields d } : ds') ls
|
37 | 55 |
[] -> Left "indented line outside of table decl"
|
|
80 | 98 |
where printField Field { fName = f
|
81 | 99 |
, fType = t
|
82 | 100 |
, fNull = l
|
| 101 |
, fUniq = u
|
| 102 |
, fDefault = d
|
83 | 103 |
} = do
|
84 | 104 |
T.putStr " , "
|
85 | 105 |
T.putStr f
|
86 | 106 |
T.putStr " "
|
87 | 107 |
T.putStr (typeName t)
|
88 | |
if not l
|
89 | |
then T.putStrLn " NOT NULL"
|
90 | |
else T.putStrLn ""
|
| 108 |
when (not l) $
|
| 109 |
T.putStr " NOT NULL"
|
| 110 |
when u $
|
| 111 |
T.putStr " UNIQUE"
|
| 112 |
case d of
|
| 113 |
Nothing -> return ()
|
| 114 |
Just dv -> T.putStr (" DEFAULT " <> dv)
|
| 115 |
T.putStrLn ""
|
91 | 116 |
printForeign Field { fName = f, fType = t }
|
92 | 117 |
| t `elem` builtins = return ()
|
93 | 118 |
| otherwise = do
|
|
105 | 130 |
cs <- T.getContents
|
106 | 131 |
case parse cs of
|
107 | 132 |
Left err -> putStrLn err
|
108 | |
Right ds -> case check ds of
|
109 | |
Left err -> putStrLn err
|
110 | |
Right () -> mapM_ pprint (rev ds)
|
| 133 |
Right ds -> do
|
| 134 |
case check ds of
|
| 135 |
Left err -> putStrLn err
|
| 136 |
Right () -> mapM_ pprint (rev ds)
|