Skip to content

Commit

Permalink
Merge pull request #18 from stefan-hoeck/syntax
Browse files Browse the repository at this point in the history
[ syntax ] infix ops to assemble queries
  • Loading branch information
stefan-hoeck authored Nov 8, 2023
2 parents 230bbd8 + aeaa445 commit 95b2fd0
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 30 deletions.
2 changes: 1 addition & 1 deletion sqlite3-rio/src/Control/RIO/Sqlite3.idr
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,4 @@ parameters {auto has : Has SqlError es}

export %inline
query : {auto db : DB} -> Query t -> Nat -> App es (List t)
query q@(SELECT {}) = selectRows (encodeQuery q)
query q = selectRows (encodeQuery q)
41 changes: 32 additions & 9 deletions src/Sqlite3/Cmd.idr
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,39 @@ record OrderingTerm (s : Schema) where

||| Different types of `SELECT` commands.
public export
data Query : Type -> Type where
SELECT :
{auto as : AsRow t}
-> (xs : LAll (Expr s) (RowTypes t))
-> (from : From s)
-> (where_ : Expr s BOOL)
-> (group_by : List (OrderingTerm s))
-> (order_by : List (OrderingTerm s))
-> Query t
record Query (t : Type) where
[noHints]
constructor Q
{auto asRow : AsRow t}
schema : Schema
from : From schema
columns : LAll (Expr schema) (RowTypes t)
where_ : Expr schema BOOL
group_by : List (OrderingTerm schema)
order_by : List (OrderingTerm schema)

public export %inline %hint
queryAsRow : (q : Query t) => AsRow t
queryAsRow = q.asRow

public export
0 LQuery : List Type -> Type
LQuery = Query . HList

infixl 7 `GROUP_BY`,`ORDER_BY`,`WHERE`

public export %inline
SELECT : {s : _} -> AsRow t => LAll (Expr s) (RowTypes t) -> From s -> Query t
SELECT xs from = Q s from xs TRUE [] []

public export %inline
GROUP_BY : (q : Query t) -> List (OrderingTerm q.schema) -> Query t
GROUP_BY q os = {group_by := os} q

public export %inline
WHERE : (q : Query t) -> Expr q.schema BOOL -> Query t
WHERE q p = {where_ := p} q

public export %inline
ORDER_BY : (q : Query t) -> List (OrderingTerm q.schema) -> Query t
ORDER_BY q os = {order_by := os} q
2 changes: 1 addition & 1 deletion src/Sqlite3/Parameter.idr
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ encodeOrd s xs = do
||| inserted as placeholders for literal values where appropriate.
export
encodeQuery : Query ts -> ParamStmt
encodeQuery (SELECT vs from where_ group_by order_by) = do
encodeQuery (Q _ from vs where_ group_by order_by) = do
vstr <- exprs [<] vs
fstr <- encodeFrom from
wh <- encodeExprP where_
Expand Down
27 changes: 8 additions & 19 deletions test/src/Schema.idr
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,11 @@ mol x =
SELECT
["molecule_id", "name", "casnr", "molweight", "type"]
[<FROM Molecules]
x
[]
[]
`WHERE` x

export
file : Expr [<Files] BOOL -> Query (Item File)
file x = SELECT ["file_id", "content"] [<FROM Files] x [] []
file x = SELECT ["file_id", "content"] [<FROM Files] `WHERE` x

export
employee : Query (Item $ Employee String)
Expand All @@ -189,9 +187,8 @@ employee =
[< FROM (Employees `AS` "e")
, JOIN (Units `AS` "u") `USING` ["unit_id"]
]
("e.salary" > 3000.0)
[]
[O "e.salary" None ASC, O "e.name" NOCASE ASC]
`WHERE` ("e.salary" > 3000.0)
`ORDER_BY` [O "e.salary" None ASC, O "e.name" NOCASE ASC]

export
unitStats : LQuery [String,Bits32,Double,Double,Double]
Expand All @@ -201,9 +198,7 @@ unitStats =
[< FROM (Employees `AS` "e")
, JOIN (Units `AS` "u") `USING` ["unit_id"]
]
TRUE
[O "e.unit_id" None NoAsc]
[]
`GROUP_BY` [O "e.unit_id" None NoAsc]

export
heads : Query (OrgUnit String)
Expand All @@ -213,9 +208,6 @@ heads =
[< FROM $ Employees `AS` "e"
, JOIN (Units `AS` "u") `ON` ("e.employee_id" == "u.head")
]
TRUE
[]
[]

export
nonHeads : LQuery [Bits32, String]
Expand All @@ -225,9 +217,8 @@ nonHeads =
[< FROM $ Employees `AS` "e"
, OUTER_JOIN (Units `AS` "u") `ON` ("e.employee_id" == "u.head")
]
(IS NULL "u.head")
[]
[O "e.name" None ASC]
`WHERE` IS NULL "u.head"
`ORDER_BY` [O "e.name" None ASC]

export
tuples : LQuery [String,Double,Double,MolType]
Expand All @@ -238,6 +229,4 @@ tuples =
, CROSS_JOIN $ Molecules `AS` "m1"
, CROSS_JOIN $ Molecules `AS` "m2"
]
("m1.molweight" < "m2.molweight")
[]
[]
`WHERE` ("m1.molweight" < "m2.molweight")

0 comments on commit 95b2fd0

Please sign in to comment.