mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
Clone TODOs example for SQLite
Differences to Postgres version: - Minor changes to schema - Add TODO: "RETURNING" isn't supported, so retrieve ID separately
This commit is contained in:
parent
283f0ef6d8
commit
79a5e5e1d5
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -1765,6 +1765,18 @@ dependencies = [
|
||||
"structopt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-example-sqlite-todos"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-std",
|
||||
"futures 0.3.4",
|
||||
"paw",
|
||||
"sqlx",
|
||||
"structopt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-macros"
|
||||
version = "0.3.2"
|
||||
|
||||
@ -7,6 +7,7 @@ members = [
|
||||
"examples/postgres/listen",
|
||||
"examples/postgres/realworld",
|
||||
"examples/postgres/todos",
|
||||
"examples/sqlite/todos",
|
||||
]
|
||||
|
||||
[package]
|
||||
|
||||
13
examples/sqlite/todos/Cargo.toml
Normal file
13
examples/sqlite/todos/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "sqlx-example-sqlite-todos"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
workspace = "../../../"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
async-std = { version = "1.5.0", features = [ "attributes" ] }
|
||||
futures = "0.3"
|
||||
paw = "1.0"
|
||||
sqlx = { path = "../../../", features = ["sqlite"] }
|
||||
structopt = { version = "0.3", features = ["paw"] }
|
||||
27
examples/sqlite/todos/README.md
Normal file
27
examples/sqlite/todos/README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# TODOs Example
|
||||
|
||||
## Usage
|
||||
|
||||
Declare the database URL:
|
||||
|
||||
```
|
||||
export DATABASE_URL="sqlite:///path/to/this/directory/todos.db"
|
||||
```
|
||||
|
||||
Create the database:
|
||||
|
||||
```
|
||||
sqlite3 todos.db
|
||||
```
|
||||
|
||||
Load the database schema (using the SQLite CLI interface opened from the previous command):
|
||||
|
||||
```
|
||||
sqlite> .read schema.sql
|
||||
```
|
||||
|
||||
Use `.exit` to leave the SQLite CLI. Then, to run this example:
|
||||
|
||||
- Add a todo: `cargo run -- add "todo description"`
|
||||
- Complete a todo: `cargo run -- done <todo id>`
|
||||
- List all todos: `cargo run`
|
||||
5
examples/sqlite/todos/schema.sql
Normal file
5
examples/sqlite/todos/schema.sql
Normal file
@ -0,0 +1,5 @@
|
||||
CREATE TABLE IF NOT EXISTS todos (
|
||||
id INTEGER PRIMARY KEY NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
done BOOLEAN NOT NULL DEFAULT 0
|
||||
);
|
||||
103
examples/sqlite/todos/src/main.rs
Normal file
103
examples/sqlite/todos/src/main.rs
Normal file
@ -0,0 +1,103 @@
|
||||
use sqlx::SqlitePool;
|
||||
use sqlx::sqlite::SqliteQueryAs;
|
||||
use std::env;
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(StructOpt)]
|
||||
struct Args {
|
||||
#[structopt(subcommand)]
|
||||
cmd: Option<Command>,
|
||||
}
|
||||
|
||||
#[derive(StructOpt)]
|
||||
enum Command {
|
||||
Add { description: String },
|
||||
Done { id: i64 },
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
#[paw::main]
|
||||
async fn main(args: Args) -> anyhow::Result<()> {
|
||||
let pool = SqlitePool::new(&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 {} as done", id);
|
||||
if complete_todo(&pool, id).await? {
|
||||
println!("Todo {} is marked as done", id);
|
||||
} else {
|
||||
println!("Invalid id {}", id);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
println!("Printing list of all todos");
|
||||
list_todos(&pool).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_todo(pool: &SqlitePool, description: String) -> anyhow::Result<i64> {
|
||||
// Insert the TODO, then obtain the ID of this row
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO todos ( description )
|
||||
VALUES ( $1 )
|
||||
"#,
|
||||
description
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
let rec: (i64,) = sqlx::query_as(
|
||||
"SELECT last_insert_rowid()"
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
|
||||
Ok(rec.0)
|
||||
}
|
||||
|
||||
async fn complete_todo(pool: &SqlitePool, id: i64) -> anyhow::Result<bool> {
|
||||
let rows_affected = sqlx::query!(
|
||||
r#"
|
||||
UPDATE todos
|
||||
SET done = TRUE
|
||||
WHERE id = $1
|
||||
"#,
|
||||
id
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(rows_affected > 0)
|
||||
}
|
||||
|
||||
async fn list_todos(pool: &SqlitePool) -> anyhow::Result<()> {
|
||||
let recs = sqlx::query!(
|
||||
r#"
|
||||
SELECT id, description, done
|
||||
FROM todos
|
||||
ORDER BY id
|
||||
"#
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
for rec in recs {
|
||||
println!(
|
||||
"- [{}] {}: {}",
|
||||
if rec.done { "x" } else { " " },
|
||||
rec.id,
|
||||
&rec.description,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user