Skip to content

Commit

Permalink
sqlx: initial commit w/ todos example
Browse files Browse the repository at this point in the history
  • Loading branch information
LucioFranco committed Sep 27, 2024
1 parent 9a6e342 commit 2b4a9f0
Show file tree
Hide file tree
Showing 8 changed files with 1,269 additions and 13 deletions.
562 changes: 549 additions & 13 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ members = [
"libsql-wal",
"libsql-storage",
"libsql-storage-server",
"sqlx-libsql",
"sqlx-libsql/examples/todos"
]

exclude = [
Expand Down
11 changes: 11 additions & 0 deletions sqlx-libsql/Cargo.toml
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"
14 changes: 14 additions & 0 deletions sqlx-libsql/examples/todos/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "sqlx-example-sqlite-todos"
version = "0.1.0"
edition = "2021"
publish = false
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"]}
41 changes: 41 additions & 0 deletions sqlx-libsql/examples/todos/README.md
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
```
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
);
101 changes: 101 additions & 0 deletions sqlx-libsql/examples/todos/src/main.rs
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(())
}
Loading

0 comments on commit 2b4a9f0

Please sign in to comment.