-
Notifications
You must be signed in to change notification settings - Fork 283
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sqlx: initial commit w/ todos example
- Loading branch information
1 parent
9a6e342
commit cd150ab
Showing
8 changed files
with
1,268 additions
and
13 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "sqlx-libsql" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
libsql = { version = "0.6", path = "../libsql" } | ||
sqlx-core = "=0.8.2" | ||
futures-core = "0.3" | ||
futures-util = "0.3" | ||
log = "0.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "sqlx-example-sqlite-todos" | ||
version = "0.1.0" | ||
edition = "2018" | ||
workspace = "../../../" | ||
|
||
[dependencies] | ||
anyhow = "1.0" | ||
futures = "0.3" | ||
sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-native-tls" ] } | ||
sqlx-libsql = { path = "../.." } | ||
clap = { version = "4", features = ["derive"] } | ||
tokio = { version = "1.20.0", features = ["rt", "macros"]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# TODOs Example | ||
|
||
## Setup | ||
|
||
1. Declare the database URL | ||
|
||
``` | ||
export DATABASE_URL="sqlite:todos.db" | ||
``` | ||
|
||
2. Create the database. | ||
|
||
``` | ||
$ sqlx db create | ||
``` | ||
|
||
3. Run sql migrations | ||
|
||
``` | ||
$ sqlx migrate run | ||
``` | ||
|
||
## Usage | ||
|
||
Add a todo | ||
|
||
``` | ||
cargo run -- add "todo description" | ||
``` | ||
|
||
Complete a todo. | ||
|
||
``` | ||
cargo run -- done <todo id> | ||
``` | ||
|
||
List all todos | ||
|
||
``` | ||
cargo run | ||
``` |
6 changes: 6 additions & 0 deletions
6
sqlx-libsql/examples/todos/migrations/20200718111257_todos.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
CREATE TABLE IF NOT EXISTS todos | ||
( | ||
id INTEGER PRIMARY KEY NOT NULL, | ||
description TEXT NOT NULL, | ||
done BOOLEAN NOT NULL DEFAULT 0 | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use clap::{Parser, Subcommand}; | ||
use sqlx_libsql::LibsqlPool; | ||
use std::env; | ||
|
||
#[derive(Parser)] | ||
struct Args { | ||
#[command(subcommand)] | ||
cmd: Option<Command>, | ||
} | ||
|
||
#[derive(Subcommand)] | ||
enum Command { | ||
Add { description: String }, | ||
Done { id: i64 }, | ||
} | ||
|
||
#[tokio::main(flavor = "current_thread")] | ||
async fn main() -> anyhow::Result<()> { | ||
let args = Args::parse(); | ||
let pool = LibsqlPool::connect(&env::var("DATABASE_URL")?).await?; | ||
|
||
match args.cmd { | ||
Some(Command::Add { description }) => { | ||
println!("Adding new todo with description '{description}'"); | ||
let todo_id = add_todo(&pool, description).await?; | ||
println!("Added new todo with id {todo_id}"); | ||
} | ||
Some(Command::Done { id }) => { | ||
println!("Marking todo {id} as done"); | ||
if complete_todo(&pool, id).await? { | ||
println!("Todo {id} is marked as done"); | ||
} else { | ||
println!("Invalid id {id}"); | ||
} | ||
} | ||
None => { | ||
println!("Printing list of all todos"); | ||
list_todos(&pool).await?; | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
async fn add_todo(pool: &LibsqlPool, description: String) -> anyhow::Result<i64> { | ||
let mut conn = pool.acquire().await?; | ||
|
||
// Insert the task, then obtain the ID of this row | ||
let id = sqlx::query( | ||
r#" | ||
INSERT INTO todos ( description ) | ||
VALUES ( ?1 ) | ||
"#, | ||
) | ||
.bind(description) | ||
.execute(&mut *conn) | ||
.await? | ||
.last_insert_rowid(); | ||
|
||
Ok(id) | ||
} | ||
|
||
async fn complete_todo(pool: &LibsqlPool, id: i64) -> anyhow::Result<bool> { | ||
let rows_affected = sqlx::query( | ||
r#" | ||
UPDATE todos | ||
SET done = TRUE | ||
WHERE id = ?1 | ||
"#, | ||
) | ||
.bind(id) | ||
.execute(pool) | ||
.await? | ||
.rows_affected(); | ||
|
||
Ok(rows_affected > 0) | ||
} | ||
|
||
async fn list_todos(pool: &LibsqlPool) -> anyhow::Result<()> { | ||
let recs = sqlx::query( | ||
r#" | ||
SELECT id, description, done | ||
FROM todos | ||
ORDER BY id | ||
"#, | ||
) | ||
.fetch_all(pool) | ||
.await?; | ||
|
||
for _rec in recs { | ||
// TODO(lucio): impl this | ||
// println!( | ||
// "- [{}] {}: {}", | ||
// if rec.done { "x" } else { " " }, | ||
// rec.id, | ||
// &rec.description, | ||
// ); | ||
} | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.