Showcasing probably the easiest library that allows using local sqlite instance with just a couple of lines of code - turbosql. Ideaologically similar to the GlueSQL integration and the Table
macro of prest. All you need to get started is to derive Turbosql
on the struct that you want to use as a table and make sure that the struct's types are compatible (all columns are optional, first goes the rowid with i64 and then others):
Cargo.toml
[package]
name = "sqlite-turbosql"
edition = "2021"
[dependencies]
prest = { path = "../../../", version = "0.4" }
turbosql = "0.9"
src/main.rs
use prest::*;
use turbosql::{execute, select, Turbosql};
#[derive(Default, Turbosql, Serialize, Deserialize)]
struct Todo {
pub rowid: Option<i64>,
pub task: Option<String>,
pub done: Option<bool>,
}
fn main() {
route(
"/",
get(|| async { html!(@for todo in select!(Vec<Todo>).unwrap() {(todo)}) })
.put(|Vals(mut todo): Vals<Todo>| async move {
todo.done = Some(false);
todo.insert().unwrap();
html!(@for todo in select!(Vec<Todo>).unwrap() {(todo)})
})
.patch(|Vals(mut todo): Vals<Todo>| async move {
todo.done = Some(!todo.done.unwrap());
todo.update().unwrap();
todo.render()
})
.delete(|Vals(Todo { rowid, .. }): Vals<Todo>| async move {
execute!("DELETE FROM todo WHERE rowid = " rowid.unwrap()).unwrap();
}),
)
.wrap_non_htmx(page)
.run()
}
impl Render for Todo {
fn render(&self) -> Markup {
let rowid = self.rowid.clone().unwrap();
let task = self.task.clone().unwrap();
let done = self.done.clone().unwrap();
html! {
$"flex items-center" into="this" swap-full vals=(json!({ "rowid": rowid, "task": task, "done": done})) {
input type="checkbox" patch="/" checked[done] {}
label $"ml-4 text-lg" {(task)}
button $"ml-auto" detele="/" {"Delete"}
}
}
}
}
async fn page(content: Markup) -> Markup {
html! { html { (Head::with_title("With Turbosql SQLite"))
body $"max-w-screen-sm mx-auto mt-12" {
form $"flex gap-4 justify-center" put="/" into="#list" swap-beforeend after-request="this.reset()" {
input $"border rounded-md" type="text" name="task" {}
button type="submit" {"Add"}
}
div #"list" $"w-full" {(content)}
(Scripts::default())
}
}}
}