Safe Haskell | None |
---|---|
Language | Haskell2010 |
- data Section
- data SQLFragment e p = SQLFragment {}
- toSelectQuery :: SQLFragment e p -> String
- toInsertQuery :: SQLFragment e p -> String
- forgetTypes :: SQLFragment e p -> SQLFragment e' p'
- clearTypes :: SQLFragment e p -> SQLFragment [] []
- nullable :: SQLFragment e p -> SQLFragment (Nullable e) (Nullable p)
- notnull :: SQLFragment e p -> SQLFragment (NotNull e) (NotNull p)
- data JoinType
- data Join = Join {
- source :: String
- destination :: String
- joinClause :: Maybe String
- joinType :: JoinType
- innerJoin :: Boolables a => SQLFragment a ([] *) -> Join
- leftJoin :: Boolables a => SQLFragment a ([] *) -> Join
- rightJoin :: Boolables a => SQLFragment a ([] *) -> Join
- outerJoin :: Boolables a => SQLFragment a ([] *) -> Join
- open :: Join -> Join
- openLeft :: Join -> Join
- openRight :: Join -> Join
- close :: Join -> Join
- closeLeft :: Join -> Join
- closeRight :: Join -> Join
- reverseJoinType :: Join -> Join
- inverseJoinType :: Join -> Join
- bracketize :: String -> String
- qualify :: String -> String -> String
- aliasWithPrefix :: String -> String -> String
- from :: String -> SQLFragment [] []
Types
data Section
data SQLFragment e p
Represents a bit of an SQL Query. Could be equivalent to
"name FROM user"
"FROM user WHERE name = Smith
"GROUP BY name ORDER BY name"
Fragments can be combined to form a full query. However, the type of the query "SELECT", "INSERT" is not carried by the fragment but decided when generating the query. Fragments also carry some phantom types which are used to type the query results and its parameters if any. Phantom types allow type safe query composition even though SQLFragment is designed to not be "on the way", and so can be retyped easily.
Fragments can be left untyped by simply using "SQLFragment '[] '[]"
SQLFragment
can be constructing from a string using
the OverloadedStrings extension.
Accepted format are :
column
table.column
table [AS] alias.column
table.
table [AS] alis.
database.table.column
>>>
:set -XOverloadedStrings
>>>
toSelectQuery "a"
"SELECT a">>>
toSelectQuery "t.a"
"SELECT t.a\nFROM t">>>
toSelectQuery "t as t2."
"FROM t as t2">>>
toSelectQuery "db.t as t2.a"
"SELECT t2.a\nFROM db.t as t2"
Eq (SQLFragment e p) | |
Fractionals a => Fractional (SQLFragment a ([] *)) | |
Nums a => Num (SQLFragment a ([] *)) | |
Show (SQLFragment e p) | |
IsString (SQLFragment e p) | |
Monoid (SQLFragment ([] *) ([] *)) | |
Fractional a => Dequantify (SQLFragment ((:) * a ([] *)) p) (Unit d a) (SQLFragment ((:) * (Quantity d a) ([] *)) p) | |
Fractional a => Dequantify (SQLFragment ((:) * (Tagged * l a) ([] *)) p) (Unit d a) (SQLFragment ((:) * (Tagged * l (Quantity d a)) ([] *)) p) | |
Num a => Quantify (SQLFragment ((:) * a ([] *)) p) (Unit d a) (SQLFragment ((:) * (Quantity d a) ([] *)) p) | |
Num a => Quantify (SQLFragment ((:) * (Tagged * l a) ([] *)) p) (Unit d a) (SQLFragment ((:) * (Tagged * l (Quantity d a)) ([] *)) p) | |
(Num n, Mul a b c) => Divisible (SQLFragment ((:) * (Tagged * l (Dimensional v a n)) ([] *)) ([] *)) (SQLFragment ((:) * (Tagged * l' (Dimensional v b n)) ([] *)) ([] *)) (SQLFragment ((:) * (Tagged * l (Dimensional v c n)) ([] *)) ([] *)) | |
(Num n, Div a b c) => Divisible (SQLFragment ((:) * (Dimensional v a n) ([] *)) ([] *)) (SQLFragment ((:) * (Dimensional v b n) ([] *)) ([] *)) (SQLFragment ((:) * (Dimensional v c n) ([] *)) ([] *)) | |
(Num n, Mul a b c) => Multipliable (SQLFragment ((:) * (Tagged * l (Dimensional v a n)) ([] *)) ([] *)) (SQLFragment ((:) * (Tagged * l' (Dimensional v b n)) ([] *)) ([] *)) (SQLFragment ((:) * (Tagged * l (Dimensional v c n)) ([] *)) ([] *)) | |
(Num n, Mul a b c) => Multipliable (SQLFragment ((:) * (Dimensional v a n) ([] *)) ([] *)) (SQLFragment ((:) * (Dimensional v b n) ([] *)) ([] *)) (SQLFragment ((:) * (Dimensional v c n) ([] *)) ([] *)) | |
Num n => Addable (SQLFragment ((:) * (Tagged * l (Dimensional v a n)) ([] *)) ([] *)) (SQLFragment ((:) * (Tagged * l' (Dimensional v a n)) ([] *)) ([] *)) (SQLFragment ((:) * (Tagged * l (Dimensional v a n)) ([] *)) ([] *)) | |
Num n => Addable (SQLFragment ((:) * (Dimensional v a n) ([] *)) ([] *)) (SQLFragment ((:) * (Dimensional v a n) ([] *)) ([] *)) (SQLFragment ((:) * (Dimensional v a n) ([] *)) ([] *)) |
Query Generations
toSelectQuery :: SQLFragment e p -> String
toInsertQuery :: SQLFragment e p -> String
Insert using VALUES and ?
>>>
toInsertQuery' $ "t.a"
"INSERT INTO t (t.a) VALUES (?)"
Types Manipulation
The following functions change the type signature of a fragment. Combined with OverloadedStrings, they can be used to create a fragment from a string.
forgetTypes :: SQLFragment e p -> SQLFragment e' p'
Forget the phantom types to whatever is needed.
>>>
:set -XDataKinds
>>>
let a = "a" :: SQLFragment '[] '[]
>>>
let b = forgetTypes a :: SQLFragment '[String] '[]
clearTypes :: SQLFragment e p -> SQLFragment [] []
nullable :: SQLFragment e p -> SQLFragment (Nullable e) (Nullable p)
Change types to Maybe version if needed
notnull :: SQLFragment e p -> SQLFragment (NotNull e) (NotNull p)
Joins
data JoinType
Type of Join. At the moment only left and inner join are supported.
data Join
Join between 2 tables.
Join | |
|
innerJoin :: Boolables a => SQLFragment a ([] *) -> Join
leftJoin :: Boolables a => SQLFragment a ([] *) -> Join
rightJoin :: Boolables a => SQLFragment a ([] *) -> Join
outerJoin :: Boolables a => SQLFragment a ([] *) -> Join
closeRight :: Join -> Join
reverseJoinType :: Join -> Join
inverseJoinType :: Join -> Join
Miscellaneous
bracketize :: String -> String
Alias a string with a prefix
>>>
aliasWithPrefix "2" "table"
"table table2"
from :: String -> SQLFragment [] []