11module Main (main ) where
22
3- import Control.Monad (unless )
4- import Data.Maybe
3+ import Control.Monad (unless , when )
4+ import Data.List (isPrefixOf )
5+ import Data.Maybe (fromJust , fromMaybe )
56import Data.Time.Clock (diffUTCTime , getCurrentTime )
6- import GHC.Base
77import Lib
88import System.Directory (doesFileExist )
99import System.Environment (getArgs )
10+ import System.Exit (exitSuccess )
1011import System.FilePath (takeBaseName , takeExtension )
1112
1213data Config = Config
@@ -17,51 +18,72 @@ data Config = Config
1718 }
1819 deriving (Show )
1920
20- parseConfigs :: IO Config
21- parseConfigs = do
22- args <- getArgs
23- -- Check that we have at least file Args
21+ data Arguments = Arguments
22+ { argFile :: Maybe String ,
23+ argTable :: Maybe String ,
24+ argNormalize :: Bool ,
25+ argDest :: Maybe String ,
26+ argHelp :: Bool ,
27+ argVersion :: Bool
28+ }
29+ deriving (Show )
30+
31+ -- Parse individual argument
32+ parseArgument :: String -> Arguments -> Arguments
33+ parseArgument arg args
34+ | " --file=" `isPrefixOf` arg = args {argFile = Just (drop 7 arg)}
35+ | " --table=" `isPrefixOf` arg = args {argTable = Just (drop 8 arg)}
36+ | " --dest=" `isPrefixOf` arg = args {argDest = Just (drop 7 arg)}
37+ | " --normalize" == arg = args {argNormalize = True }
38+ | " -h" == arg || " --help" == arg = args {argHelp = True }
39+ | " -v" == arg || " --version" == arg = args {argVersion = True }
40+ | otherwise = case (argFile args, argTable args, argDest args) of
41+ (Nothing , _, _) -> args {argFile = Just arg}
42+ (Just _, Nothing , _) -> args {argTable = Just arg}
43+ (Just _, Just _, Nothing ) -> args {argDest = Just arg}
44+ _ -> args
45+
46+ -- Parse all arguments
47+ argumentParser :: [String ] -> Arguments
48+ argumentParser args = foldl (flip parseArgument) defaultArgs args
49+ where
50+ defaultArgs = Arguments Nothing Nothing False Nothing False False
2451
25- case args of
26- (file : rest) -> do
27- let tableNameArg = case rest of
28- (t : _) -> Just t
29- _ -> Nothing
30- normalizeFlag = " --normalize" `elem` rest
31- destArg = case reverse rest of
32- (d : _) -> if d == " ." then " ." else d
33- _ -> " ."
34- -- if No tablename provided, use the filename
52+ -- Parse configuration from arguments
53+ parseConfigs :: Arguments -> IO (Maybe Config )
54+ parseConfigs args = do
55+ case argFile args of
56+ Just file -> do
57+ let tableNameArg = argTable args
58+ normalizeFlag = argNormalize args
59+ destArg = fromMaybe " ." (argDest args)
3560 let table = fromMaybe (takeBaseName file) tableNameArg
36- return
37- Config
38- { filepath = file,
39- tableName = table,
40- normalize = normalizeFlag,
41- destPath = destArg
42- }
43- _ -> error " Usage: json2sql <file> [table] [--normalize] [dest]"
61+ return $
62+ Just
63+ Config
64+ { filepath = file,
65+ tableName = table,
66+ normalize = normalizeFlag,
67+ destPath = destArg
68+ }
69+ Nothing -> do
70+ putStrLn " Usage: json-to-sql <file> [table] [dest] [--normalize]"
71+ return Nothing
4472
73+ -- Read and parse JSON file
4574readAndParseJson :: FilePath -> IO (Maybe JsonValue )
4675readAndParseJson file = do
47- -- Check if file Exists
4876 fileExists <- doesFileExist file
4977 unless fileExists $ error " File does not exist"
50-
51- -- check the valid .json extension
5278 let extension = takeExtension file
5379 unless (extension == " .json" ) $ error " File must have .json extension"
54-
55- -- Read the file
5680 content <- readFile file
57- -- Clear the whitespace at the end of document if present
5881 let content' = reverse $ dropLeading $ reverse content
59- in -- if content is empty
60- -- Parse the JSON
61- case parseJsonValue content' of
62- Just (json, " " ) -> return $ Just json
63- _ -> error " Invalid JSON"
82+ case parseJsonValue content' of
83+ Just (json, " " ) -> return $ Just json
84+ _ -> error " Invalid JSON"
6485
86+ -- Convert JSON to SQL
6587convertToSql :: Config -> JsonValue -> String
6688convertToSql config json = do
6789 let isOnlyJsonArray = isOnlyJsonArrayObject json
@@ -76,37 +98,38 @@ convertToSql config json = do
7698 insertTableSql = insertTable (tableName config) json
7799 in createTableSql ++ " \n\n " ++ insertTableSql
78100
101+ -- Main function
79102main :: IO ()
80103main = do
81104 start <- getCurrentTime
82105 args <- getArgs
83- when (null args) $ error " Usage: json-to-sql -h for help"
84- if head args == " -h" || head args == " --help"
85- then do
86- putStrLn " Usage: json-to-sql <file> [table] [--normalize] [dest]"
87- putStrLn " Options:"
88- putStrLn " --normalize Normalize the JSON data"
89- putStrLn " dest Destination path for the SQL file"
90- putStrLn " table Table name for the SQL file"
91- putStrLn " file JSON file to convert"
92- putStrLn " -h Display this help message"
93- putStrLn " -v Display the version"
94- return ()
95- else
96- if head args == " -v" || head args == " --version"
97- then do
98- putStrLn " json2sql version 0.0.1"
99- return ()
100- else do
101- config <- parseConfigs
102- json <- readAndParseJson (filepath config)
103- _ <- case json of
104- Just j -> do
105- let sql = convertToSql config j
106- outputFile = destPath config ++ " /" ++ tableName config ++ " .sql"
107- writeFile outputFile sql
108- putStrLn $ " SQL file created successfully: " ++ outputFile
109- _ -> error " Invalid JSON"
106+ let parsedArgs = argumentParser args
107+ print parsedArgs
108+ when (argHelp parsedArgs) $ do
109+ putStrLn " Usage: json-to-sql <file> [table] [dest] [--normalize]"
110+ putStrLn " Options:"
111+ putStrLn " --file=filename JSON file to convert"
112+ putStrLn " --table=table Table name for the SQL file"
113+ putStrLn " --dest=dest Destination path for the SQL file"
114+ putStrLn " --normalize Normalize the JSON data"
115+ putStrLn " -h, --help Display this help message"
116+ putStrLn " -v, --version Display the version"
117+ exitSuccess
118+ when (argVersion parsedArgs) $ do
119+ putStrLn " json-to-sql version 0.0.1"
120+ exitSuccess
121+ maybeConfig <- parseConfigs parsedArgs
122+ case maybeConfig of
123+ Just config -> do
124+ json <- readAndParseJson (filepath config)
125+ case json of
126+ Just j -> do
127+ let sql = convertToSql config j
128+ outputFile = destPath config ++ " /" ++ tableName config ++ " .sql"
129+ writeFile outputFile sql
130+ putStrLn $ " SQL file created successfully: " ++ outputFile
110131 end <- getCurrentTime
111132 let diff = diffUTCTime end start
112133 putStrLn $ " Execution time: " ++ show diff
134+ _ -> error " Invalid JSON"
135+ Nothing -> return ()
0 commit comments