2 | import public Sqlite3
8 | Resource (Async e) Stmt where
9 | cleanup = liftIO . sqliteFinalize'
12 | Resource (Async e) DB where
13 | cleanup = liftIO . sqliteClose'
15 | parameters {auto has : Has SqlError es}
18 | openSqlite : String -> Async e es DB
19 | openSqlite = injectIO . sqliteOpen
22 | openStmt : DB => String -> Async e es Stmt
23 | openStmt = injectIO . sqlitePrepare
31 | withDB : String -> (DB => Async e es a) -> Async e es a
32 | withDB s f = use1 (openSqlite s) $
\_ => f
39 | withStmt : DB => String -> (Stmt => Async e es a) -> Async e es a
40 | withStmt s f = use1 (openStmt s) $
\_ => f
47 | bindParams : DB => Stmt => List Parameter -> Async e es ()
48 | bindParams = injectIO . sqliteBind
51 | openBoundStmt : DB => ParamStmt -> Async e es Stmt
52 | openBoundStmt st = Prelude.do
53 | let (ps, str) := runState init st
65 | withBoundStmt : DB => ParamStmt -> (Stmt => Async e es a) -> Async e es a
66 | withBoundStmt st f = use1 (openBoundStmt st) $
\_ => f
70 | step : (s : Stmt) => Async e es SqlResult
71 | step @{s} = liftIO $
sqliteStep s
78 | commit : DB => ParamStmt -> Async e es ()
79 | commit st = withBoundStmt st (ignore step)
84 | selectRows : DB => FromRow a => ParamStmt -> (n : Nat) -> Async e es (List a)
85 | selectRows st n = withBoundStmt st (injectIO $
loadRows n)
90 | selectRow : DB => FromRow a => ParamStmt -> Async e es a
92 | [v] <- selectRows st 1 | _ => throw NoMoreData
98 | findRow : DB => FromRow a => ParamStmt -> Async e es (Maybe a)
100 | [v] <- selectRows st 1 | _ => pure Nothing
105 | {auto cs : ChunkSize}
107 | -> {auto fr : FromRow a}
109 | -> AsyncStream e es (List a)
110 | rows {cs = CS sz} st =
111 | resource (openBoundStmt st) $
\_ =>
113 | (\case [] => Nothing;
xs => Just xs) <$> injectIO (loadRows sz)
121 | cmd : DB => Cmd t -> Async e es ()
122 | cmd = commit . encodeCmd
124 | rollback : DB => HSum es -> Async e es a
125 | rollback x = ignore (withStmt "ROLLBACK TRANSACTION" step) >> fail x
131 | cmds : DB => Cmds -> Async e es ()
133 | uncancelable $
\poll => Prelude.do
134 | ignore $
withStmt "BEGIN TRANSACTION" step
135 | handleErrors rollback (runCommands cs)
136 | ignore $
withStmt "COMMIT TRANSACTION" step
139 | runCommands : Cmds -> Async e es ()
140 | runCommands [] = pure ()
141 | runCommands (c::cs) = cmd c >> runCommands cs
145 | query : DB => Query t -> (n : Nat) -> Async e es (List t)
146 | query q = selectRows (encodeQuery q)
150 | query1 : DB => Query t -> Async e es (Maybe t)
151 | query1 q = map (\case h::_ => Just h;
[] => Nothing) $
query q 1
155 | queryRows : (cs : ChunkSize) => DB => Query t -> AsyncStream e es (List t)
156 | queryRows q = rows (encodeQuery q)
165 | -> {auto tr : ToRow t}
167 | -> {auto 0 prf : ToRowTypes t === FromRowTypes t}
169 | -> Async e es (Table t)
170 | queryTable {prf} q n = do
172 | pure (T (rewrite prf in hmap columnName q.columns) rs)