{-# LANGUAGE AllowAmbiguousTypes #-}
module Database.GP.SqlGenerator
( insertStmtFor,
updateStmtFor,
selectStmtFor,
deleteStmtFor,
selectAllStmtFor,
selectAllWhereStmtFor,
createTableStmtFor,
dropTableStmtFor,
)
where
import Data.List (intercalate)
import Database.GP.Entity
insertStmtFor :: forall a. Entity a => String
insertStmtFor :: forall a. Entity a => String
insertStmtFor =
String
"INSERT INTO "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
tableName @a
forall a. [a] -> [a] -> [a]
++ String
" ("
forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
columns
forall a. [a] -> [a] -> [a]
++ String
") VALUES ("
forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
", " (Int -> [String]
params (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
columns))
forall a. [a] -> [a] -> [a]
++ String
");"
where
columns :: [String]
columns = forall a. Entity a => [String]
columnNamesFor @a
columnNamesFor :: forall a. Entity a => [String]
columnNamesFor :: forall a. Entity a => [String]
columnNamesFor = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(String, String)]
fieldColumnPairs
where
fieldColumnPairs :: [(String, String)]
fieldColumnPairs = forall a. Entity a => [(String, String)]
fieldsToColumns @a
params :: Int -> [String]
params :: Int -> [String]
params Int
n = forall a. Int -> a -> [a]
replicate Int
n String
"?"
updateStmtFor :: forall a. (Entity a) => String
updateStmtFor :: forall a. Entity a => String
updateStmtFor =
String
"UPDATE "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
tableName @a
forall a. [a] -> [a] -> [a]
++ String
" SET "
forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
updatePairs
forall a. [a] -> [a] -> [a]
++ String
" WHERE "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
idColumn @a
forall a. [a] -> [a] -> [a]
++ String
" = ?"
forall a. [a] -> [a] -> [a]
++ String
";"
where
updatePairs :: [String]
updatePairs = forall a b. (a -> b) -> [a] -> [b]
map (forall a. [a] -> [a] -> [a]
++ String
" = ?") (forall a. Entity a => [String]
columnNamesFor @a)
idColumn :: forall a. (Entity a) => String
idColumn :: forall a. Entity a => String
idColumn = forall a. Entity a => String -> String
columnNameFor @a (forall a. Entity a => String
idField @a)
selectStmtFor :: forall a. (Entity a) => String
selectStmtFor :: forall a. Entity a => String
selectStmtFor =
String
"SELECT "
forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
", " (forall a. Entity a => [String]
columnNamesFor @a)
forall a. [a] -> [a] -> [a]
++ String
" FROM "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
tableName @a
forall a. [a] -> [a] -> [a]
++ String
" WHERE "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
idColumn @a
forall a. [a] -> [a] -> [a]
++ String
" = ?;"
selectAllStmtFor :: forall a. (Entity a) => String
selectAllStmtFor :: forall a. Entity a => String
selectAllStmtFor =
String
"SELECT "
forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
", " (forall a. Entity a => [String]
columnNamesFor @a)
forall a. [a] -> [a] -> [a]
++ String
" FROM "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
tableName @a
forall a. [a] -> [a] -> [a]
++ String
";"
selectAllWhereStmtFor :: forall a. (Entity a) => String -> String
selectAllWhereStmtFor :: forall a. Entity a => String -> String
selectAllWhereStmtFor String
field =
String
"SELECT "
forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
", " (forall a. Entity a => [String]
columnNamesFor @a)
forall a. [a] -> [a] -> [a]
++ String
" FROM "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
tableName @a
forall a. [a] -> [a] -> [a]
++ String
" WHERE "
forall a. [a] -> [a] -> [a]
++ String
column
forall a. [a] -> [a] -> [a]
++ String
" = ?;"
where
column :: String
column = forall a. Entity a => String -> String
columnNameFor @a String
field
deleteStmtFor :: forall a. (Entity a) => String
deleteStmtFor :: forall a. Entity a => String
deleteStmtFor =
String
"DELETE FROM "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
tableName @a
forall a. [a] -> [a] -> [a]
++ String
" WHERE "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
idColumn @a
forall a. [a] -> [a] -> [a]
++ String
" = ?;"
createTableStmtFor :: forall a. (Entity a) => Database -> String
createTableStmtFor :: forall a. Entity a => Database -> String
createTableStmtFor Database
dbServer =
String
"CREATE TABLE "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
tableName @a
forall a. [a] -> [a] -> [a]
++ String
" ("
forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
", " (forall a b. (a -> b) -> [a] -> [b]
map (\(String
f, String
c) -> String
c forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Entity a => Database -> String -> String
columnTypeFor @a Database
dbServer String
f forall a. [a] -> [a] -> [a]
++ String -> String
optionalPK String
f) (forall a. Entity a => [(String, String)]
fieldsToColumns @a))
forall a. [a] -> [a] -> [a]
++ String
");"
where
isIdField :: String -> Bool
isIdField String
f = String
f forall a. Eq a => a -> a -> Bool
== forall a. Entity a => String
idField @a
optionalPK :: String -> String
optionalPK String
f = if String -> Bool
isIdField String
f then String
" PRIMARY KEY" else String
""
columnTypeFor :: forall a. (Entity a) => Database -> String -> String
columnTypeFor :: forall a. Entity a => Database -> String -> String
columnTypeFor Database
SQLite String
field =
case String
fType of
String
"Int" -> String
"INTEGER"
String
"String" -> String
"TEXT"
String
"Double" -> String
"REAL"
String
"Float" -> String
"REAL"
String
"Bool" -> String
"INT"
String
_ -> String
"TEXT"
where
maybeFType :: Maybe TypeRep
maybeFType = forall a. Entity a => String -> Maybe TypeRep
maybeFieldTypeFor @a String
field
fType :: String
fType = forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"OTHER" forall a. Show a => a -> String
show Maybe TypeRep
maybeFType
columnTypeFor Database
other String
_ = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Schema creation for " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Database
other forall a. [a] -> [a] -> [a]
++ String
" not implemented yet"
dropTableStmtFor :: forall a. (Entity a) => String
dropTableStmtFor :: forall a. Entity a => String
dropTableStmtFor =
String
"DROP TABLE IF EXISTS "
forall a. [a] -> [a] -> [a]
++ forall a. Entity a => String
tableName @a
forall a. [a] -> [a] -> [a]
++ String
";"