selda-0.1.0.0: src/Database/Selda/Table/Compile.hs
{-# LANGUAGE OverloadedStrings #-}
-- | Generating SQL for creating and deleting tables.
module Database.Selda.Table.Compile where
import Database.Selda.Table
import Data.Monoid
import Data.Text (Text, intercalate, pack)
import qualified Data.Text as Text
data OnError = Fail | Ignore
deriving (Eq, Ord, Show)
-- | Compile a @CREATAE TABLE@ query from a table definition.
compileCreateTable :: (Text -> [ColAttr] -> Maybe Text) -> OnError -> Table a -> Text
compileCreateTable customColType ifex tbl = mconcat
[ "CREATE TABLE ", ifNotExists ifex, tableName tbl, "("
, intercalate ", " (map (compileTableCol customColType) (tableCols tbl))
, ")"
]
where
ifNotExists Fail = ""
ifNotExists Ignore = "IF NOT EXISTS "
-- | Compile a table column.
compileTableCol :: (Text -> [ColAttr] -> Maybe Text) -> ColInfo -> Text
compileTableCol customColType ci = Text.unwords
[ colName ci
, case customColType typ attrs of
Just s -> s
_ -> typ <> " " <> Text.unwords (map compileColAttr attrs)
]
where
typ = colType ci
attrs = colAttrs ci
-- | Compile a @DROP TABLE@ query.
compileDropTable :: OnError -> Table a -> Text
compileDropTable Fail t = Text.unwords ["DROP TABLE",tableName t]
compileDropTable _ t = Text.unwords ["DROP TABLE IF EXISTS",tableName t]
-- | Compile an @INSERT INTO@ query inserting @m@ rows with @n@ cols each.
-- Note that backends expect insertions to NOT have a semicolon at the end.
compInsert :: Table a -> Int -> Text
compInsert tbl mrows =
Text.unwords ["INSERT INTO", tableName tbl, names, "VALUES", vals]
where
nonAutos =
[ colName c
| c <- tableCols tbl
, not (AutoIncrement `elem` colAttrs c)
]
ncols = length nonAutos
names = "(" <> Text.intercalate ", " nonAutos <> ")"
cols n = "(" <> Text.intercalate ", " (mkParams ncols n) <> ")"
vals = Text.intercalate ", " $ zipWith (\f n -> f n)
(replicate mrows cols)
[0, ncols ..]
mkParams cs n = map (pack . ('$':) . show . (+n)) [1..cs]
-- | Compile a column attribute.
compileColAttr :: ColAttr -> Text
compileColAttr Primary = "PRIMARY KEY"
compileColAttr AutoIncrement = "AUTOINCREMENT"
compileColAttr Required = "NOT NULL"
compileColAttr Optional = "NULL"