Remove example playground and add a small example, a todo cli

This commit is contained in:
Ryan Leckey 2019-08-06 22:28:06 -07:00
parent a0f8117389
commit 9df8813d4b
4 changed files with 151 additions and 73 deletions

View File

@ -1,3 +1,9 @@
[workspace]
members = [
".",
"examples/todo"
]
[package]
name = "sqlx"
version = "0.0.0"
@ -22,5 +28,4 @@ memchr = "2.2.1"
runtime = { version = "=0.3.0-alpha.6", default-features = false }
[dev-dependencies]
env_logger = "0.6.2"
runtime-tokio = { version = "=0.3.0-alpha.5" }
runtime = { version = "=0.3.0-alpha.6", default-features = true }

View File

@ -1,71 +0,0 @@
#![feature(async_await)]
use futures::{future, TryStreamExt};
use sqlx::{postgres::Connection, ConnectOptions};
use std::{collections::HashMap, io};
// TODO: Connection strings ala postgres@localhost/sqlx_dev
#[runtime::main(runtime_tokio::Tokio)]
async fn main() -> io::Result<()> {
env_logger::init();
let mut conn = Connection::establish(
ConnectOptions::new()
.host("127.0.0.1")
.port(5432)
.user("postgres")
.database("sqlx__dev"),
)
.await?;
println!(" :: create schema");
conn.prepare(
r#"
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
password TEXT
);
"#,
)
.execute()
.await?;
println!(" :: insert");
let user_id: i64 = conn
.prepare("INSERT INTO users (name) VALUES ($1) RETURNING id")
.bind("Joe")
.get()
.await?;
println!("insert {:?}", user_id);
println!(" :: select");
// Iterate through each row, one-by-one
conn.prepare("SELECT id, name, password FROM users")
.select()
.try_for_each(|(id, name, password): (i64, String, Option<String>)| {
println!("select {} -> {} (password = {:?})", id, name, password);
future::ok(())
})
.await?;
// Get a map of id -> name of users with a name of JOE
let map: HashMap<i64, String> = conn
.prepare("SELECT id, name FROM users WHERE name = $1")
.bind("Joe")
.select()
.try_collect()
.await?;
println!(" :: users\n{:#?}\n", map);
conn.close().await?;
Ok(())
}

13
examples/todo/Cargo.toml Normal file
View File

@ -0,0 +1,13 @@
[package]
name = "todo"
version = "0.1.0"
edition = "2018"
[dependencies]
sqlx = { path = "../.." }
failure = "0.1.5"
env_logger = "0.6.2"
runtime = { version = "=0.3.0-alpha.6", default-features = false }
runtime-tokio = { version = "=0.3.0-alpha.5" }
futures-preview = "=0.3.0-alpha.17"
structopt = "0.2.18"

131
examples/todo/src/main.rs Normal file
View File

@ -0,0 +1,131 @@
#![feature(async_await)]
use failure::Fallible;
use futures::{future, TryStreamExt};
use sqlx::postgres::Connection;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
struct Options {
#[structopt(subcommand)]
cmd: Option<Command>
}
#[derive(StructOpt, Debug)]
enum Command {
#[structopt(name = "add")]
Add {
text: String,
},
#[structopt(name = "done")]
MarkAsDone { id: i64 }
}
#[runtime::main(runtime_tokio::Tokio)]
async fn main() -> Fallible<()> {
env_logger::try_init()?;
let opt = Options::from_args();
let mut conn = Connection::establish(
sqlx::ConnectOptions::new()
.host("127.0.0.1")
.port(5432)
.user("postgres")
.database("sqlx__dev__tasks"),
)
.await?;
ensure_schema(&mut conn).await?;
match opt.cmd {
Some(Command::Add { text }) => {
add_task(&mut conn, &text).await?;
}
Some(Command::MarkAsDone { id }) => {
mark_task_as_done(&mut conn, id).await?;
}
None => {
print_all_tasks(&mut conn).await?;
}
}
Ok(())
}
async fn ensure_schema(conn: &mut Connection) -> Fallible<()> {
conn.prepare("BEGIN").execute().await?;
// language=sql
conn.prepare(
r#"
CREATE TABLE IF NOT EXISTS tasks (
id BIGSERIAL PRIMARY KEY,
text TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
done_at TIMESTAMPTZ
)
"#,
)
.execute()
.await?;
conn.prepare("COMMIT").execute().await?;
Ok(())
}
async fn print_all_tasks(conn: &mut Connection) -> Fallible<()> {
// language=sql
conn.prepare(
r#"
SELECT id, text
FROM tasks
WHERE done_at IS NULL
"#,
)
.select()
.try_for_each(|(id, text): (i64, String)| {
// language=text
println!("{:>5} | {}", id, text);
future::ok(())
})
.await?;
Ok(())
}
async fn add_task(conn: &mut Connection, text: &str) -> Fallible<()> {
// language=sql
conn.prepare(
r#"
INSERT INTO tasks ( text )
VALUES ( $1 )
"#,
)
.bind(text)
.execute()
.await?;
Ok(())
}
async fn mark_task_as_done(conn: &mut Connection, id: i64) -> Fallible<()> {
// language=sql
conn.prepare(
r#"
UPDATE tasks
SET done_at = now()
WHERE id = $1
"#,
)
.bind(id)
.execute()
.await?;
Ok(())
}