2 | import Data.List.Quantifiers
4 | import Sqlite3.Marshall
15 | toExprs : {ts : _} -> LAll (Maybe . IdrisType) ts -> LAll (Expr s) ts
16 | toExprs {ts = []} [] = []
17 | toExprs {ts = t::ts} (v::vs) = maybe NULL (Lit t) v :: toExprs vs
21 | record Val (t : SQLTable) where
24 | {auto 0 prf : IsJust (FindCol name t.cols)}
25 | val : Expr [<t] (TableColType name t)
30 | public export %inline
33 | -> {auto to : ToCell a}
35 | -> {auto 0 prf : IsJust (FindCol name t.cols)}
36 | -> {auto 0 eq : TableColType name t === ToCellType a}
39 | (.=) name v = V name (rewrite eq in val v)
58 | data Constraint : SQLTable -> Type where
59 | NOT_NULL : {0 x : _} -> TColumn t x -> Constraint t
60 | AUTOINCREMENT : {0 x : _} -> TColumn t x -> Constraint t
61 | UNIQUE : {0 xs : _} -> LAll (TColumn t) xs -> Constraint t
62 | PRIMARY_KEY : {0 xs : _} -> LAll (TColumn t) xs -> Constraint t
67 | -> LAll (TColumn t) xs
68 | -> LAll (TColumn s) xs
71 | CHECK : Expr [<t] BOOL -> Constraint t
75 | -> {auto 0 prf : IsJust (FindCol s t.cols)}
76 | -> (expr : Expr [<t] (TableColType s t))
85 | -> LAll (TColumn t) xs
86 | -> LAll (TColumn s) xs
88 | FOREIGN_KEY s a b = ForeignKey s a b []
96 | -> LAll (TColumn t) xs
97 | -> LAll (TColumn s) xs
100 | FOREIGN_KEY' = ForeignKey
107 | data CmdType : Type where
118 | data Cmd : CmdType -> Type where
125 | -> (attrs : List (Constraint t))
126 | -> (ifNotExists : Bool)
129 | DropTable : (t : SQLTable) -> (ifExists : Bool) -> Cmd TDrop
138 | {0 ts : List SqliteType}
140 | -> (cols : LAll (TColumn t) ts)
141 | -> (vals : LAll (Expr [<t]) ts)
155 | {0 ts : List SqliteType}
157 | -> (cols : LAll (TColumn t) ts)
158 | -> (vals : LAll (Expr [<t]) ts)
164 | -> (set : List (Val t))
165 | -> (where_ : Expr [<t] BOOL)
171 | -> (where_ : Expr [<t] BOOL)
178 | {auto as : ToRow v}
180 | -> LAll (TColumn t) (ToRowTypes v)
183 | insert t cs value = INSERT t cs (toExprs $
toRow value)
189 | {auto as : ToRow v}
191 | -> LAll (TColumn t) (ToRowTypes v)
194 | replace t cs value = REPLACE t cs (toExprs $
toRow value)
200 | data Cmds : Type where
202 | (::) : {0 t : _} -> Cmd t -> Cmds -> Cmds
205 | (++) : Cmds -> Cmds -> Cmds
207 | (h::t) ++ cs = h :: (t ++ cs)
210 | Semigroup Cmds where (<+>) = (++)
213 | Monoid Cmds where neutral = []
216 | fromList : List (Cmd t) -> Cmds
218 | fromList (c::cs) = c :: fromList cs
222 | IF_NOT_EXISTS : Cmd TCreate -> Cmd TCreate
223 | IF_NOT_EXISTS (CreateTable t attrs _) = CreateTable t attrs True
227 | IF_EXISTS : Cmd TDrop -> Cmd TDrop
228 | IF_EXISTS (DropTable t _) = DropTable t True
231 | public export %inline
232 | CREATE_TABLE : (t : SQLTable) -> List (Constraint t) -> Cmd TCreate
233 | CREATE_TABLE t as = CreateTable t as False
236 | public export %inline
237 | DROP_TABLE : (t : SQLTable) -> Cmd TDrop
238 | DROP_TABLE t = DropTable t False
241 | 0 JoinPred : Schema -> SQLTable -> Type
242 | JoinPred s t = Either (List $
JColumn s t) (Expr (s:<t) BOOL)
245 | data Join : (s : Schema) -> (t : SQLTable) -> Type where
250 | -> JoinPred (s:<t0) t
257 | -> JoinPred (s:<t0) t
260 | CROSS_JOIN : {0 t0 : _} -> {0 s : _} -> (t : SQLTable) -> Join (s:<t0) t
262 | FROM : (t : SQLTable) -> Join [<] t
264 | public export %inline
265 | USING : (JoinPred s t -> Join s t) -> List (JColumn s t) -> Join s t
268 | public export %inline
269 | ON : (JoinPred s t -> Join s t) -> Expr (s:<t) BOOL -> Join s t
274 | data From : (s : Schema) -> Type where
276 | (:<) : From s -> Join s t -> From (s :< t)
281 | data AscDesc = NoAsc | Asc | Desc
287 | data Collation : (t : SqliteType) -> Type where
289 | NOCASE : Collation TEXT
292 | record OrderingTerm (s : Schema) where
294 | {0 tpe : SqliteType}
296 | coll : Collation tpe
299 | public export %inline
300 | ASC : Expr s t -> OrderingTerm s
301 | ASC x = O x None Asc
303 | public export %inline
304 | DESC : Expr s t -> OrderingTerm s
305 | DESC x = O x None Desc
307 | public export %inline
308 | COLLATE : (o : OrderingTerm s) -> Collation o.tpe -> OrderingTerm s
309 | COLLATE o c = {coll := c} o
312 | record GroupingTerm (s : Schema) where
314 | {0 tpe : SqliteType}
316 | coll : Collation tpe
318 | namespace GroupingTerm
319 | public export %inline
323 | -> {auto 0 p : IsJust (FindSchemaCol col s)}
325 | fromString col = G (fromString col) None
327 | public export %inline
328 | ord : GroupingTerm s -> OrderingTerm s
329 | ord (G x c) = O x c NoAsc
332 | record NamedExpr (s : Schema) (t : SqliteType) where
338 | public export %inline
342 | -> {auto 0 p : IsJust (FindSchemaCol col s)}
343 | -> NamedExpr s (SchemaColType col s)
344 | fromString col = Col col `AS` ""
353 | columnName : NamedExpr s t -> String
354 | columnName (AS (Col col) "") = col
355 | columnName (AS _ n) = n
363 | ExprColumns : {ts : _} -> LAll (NamedExpr s) ts -> List Column
364 | ExprColumns [] = []
365 | ExprColumns (AS _ "" :: xs) = ExprColumns xs
366 | ExprColumns {ts = t::_} (AS _ n :: xs) = C n t :: ExprColumns xs
378 | ExprSchema : {s : _} -> {ts : _} -> LAll (NamedExpr s) ts -> Schema
380 | case ExprColumns xs of
382 | cs => s :< ST "" "" cs
386 | record Query (t : Type) where
389 | {auto fromRow : FromRow t}
393 | columns : LAll (NamedExpr schema) (FromRowTypes t)
394 | where_ : Expr (ExprSchema columns) BOOL
395 | having : Expr (ExprSchema columns) BOOL
396 | group_by : List (GroupingTerm (ExprSchema columns))
397 | order_by : List (OrderingTerm (ExprSchema columns))
401 | public export %inline %hint
402 | queryAsRow : (q : Query t) => FromRow t
403 | queryAsRow = q.fromRow
406 | 0 LQuery : List Type -> Type
407 | LQuery = Query . HList
409 | export infixl 7 `GROUP_BY`
,`ORDER_BY`
,`WHERE`
, `LIMIT`
, `OFFSET`
, `HAVING`
411 | public export %inline
414 | -> {auto fromRow : FromRow t}
415 | -> LAll (NamedExpr s) (FromRowTypes t)
418 | SELECT xs from = Q False s from xs TRUE TRUE [] [] Nothing 0
420 | public export %inline
423 | -> {auto fromRow : FromRow t}
424 | -> LAll (NamedExpr s) (FromRowTypes t)
427 | SELECT_DISTINCT xs from = Q True s from xs TRUE TRUE [] [] Nothing 0
429 | public export %inline
430 | GROUP_BY : (q : Query t) -> List (GroupingTerm $
ExprSchema q.columns) -> Query t
431 | GROUP_BY q gs = {group_by := gs} q
433 | public export %inline
434 | WHERE : (q : Query t) -> Expr (ExprSchema q.columns) BOOL -> Query t
435 | WHERE q p = {where_ := p} q
437 | public export %inline
438 | HAVING : (q : Query t) -> Expr (ExprSchema q.columns) BOOL -> Query t
439 | HAVING q p = {having := p} q
441 | public export %inline
442 | ORDER_BY : (q : Query t) -> List (OrderingTerm (ExprSchema q.columns)) -> Query t
443 | ORDER_BY q os = {order_by := os} q
445 | public export %inline
446 | LIMIT : (q : Query t) -> Nat -> Query t
447 | LIMIT q n = {limit := Just n} q
449 | public export %inline
450 | OFFSET : (q : Query t) -> Nat -> Query t
451 | OFFSET q n = {offset := n} q