Skip to content

Commit 38a908a

Browse files
chore(upd): readme and arg parsing
1 parent c6b0246 commit 38a908a

File tree

2 files changed

+97
-68
lines changed

2 files changed

+97
-68
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ curl -fsSL https://raw.githubusercontent.com/2002Bishwajeet/json-to-sql/main/set
2525
After installation, you can use the `json-to-sql` command to convert a JSON file to SQL. The basic usage is as follows:
2626

2727
```bash
28-
json-to-sql <file> [table] [--normalize] [dest]
28+
json-to-sql <file> [table] [dest] [--normalize]
2929
```
3030

3131
- `file`: The JSON file to convert.
3232
- `table`: (Optional) The table name for the SQL file. If not provided, the filename will be used.
33-
- `--normalize`: (Optional) Normalize the JSON data.
3433
- `dest`: (Optional) Destination path for the SQL file. If not provided, the current directory will be used.
34+
- `--normalize`: (Optional) Normalize the JSON data.
3535

3636
### Examples
3737

@@ -50,13 +50,19 @@ json-to-sql data.json my_table
5050
Convert a JSON file to SQL with normalization:
5151

5252
```bash
53-
json-to-sql data.json --normalize
53+
json-to-sql data.json my_table --normalize
5454
```
5555

5656
Convert a JSON file to SQL and save the output to a specific directory:
5757

5858
```bash
59-
json-to-sql data.json my_table --normalize /path/to/output
59+
json-to-sql data.json my_table /path/to/output --normalize
60+
```
61+
62+
Convert a JSON file to SQL using named arguments:
63+
64+
```bash
65+
json-to-sql --file=data.json --table=my_table --dest=/path/to/output --normalize
6066
```
6167

6268
## Motivation
@@ -69,4 +75,4 @@ Contributions are highly Welcomed 💙 . Feel free to open PRs for small issues
6975

7076
## License
7177

72-
This project is open source and available under the [ BSD-3-Clause](LICENSE).
78+
This project is open source and available under the [BSD-3-Clause](LICENSE).

app/Main.hs

Lines changed: 86 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
module 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)
56
import Data.Time.Clock (diffUTCTime, getCurrentTime)
6-
import GHC.Base
77
import Lib
88
import System.Directory (doesFileExist)
99
import System.Environment (getArgs)
10+
import System.Exit (exitSuccess)
1011
import System.FilePath (takeBaseName, takeExtension)
1112

1213
data 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
4574
readAndParseJson :: FilePath -> IO (Maybe JsonValue)
4675
readAndParseJson 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
6587
convertToSql :: Config -> JsonValue -> String
6688
convertToSql 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
79102
main :: IO ()
80103
main = 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

Comments
 (0)