JSON+macros example using overrides

This commit is contained in:
Raphaël Thériault 2020-08-24 15:44:55 -04:00 committed by Ryan Leckey
parent b27ad1193b
commit 04f68632b4
6 changed files with 175 additions and 0 deletions

15
Cargo.lock generated
View File

@ -1026,6 +1026,21 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "json"
version = "0.1.0"
dependencies = [
"anyhow",
"async-std",
"dotenv",
"futures",
"paw",
"serde",
"serde_json",
"sqlx",
"structopt",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"

View File

@ -8,6 +8,7 @@ members = [
"sqlx-cli",
"sqlx-bench",
"examples/mysql/todos",
"examples/postgres/json",
"examples/postgres/listen",
"examples/postgres/todos",
"examples/sqlite/todos",

View File

@ -0,0 +1,16 @@
[package]
name = "json"
version = "0.1.0"
edition = "2018"
workspace = "../../../"
[dependencies]
anyhow = "1.0"
async-std = { version = "1.6.0", features = [ "attributes" ] }
dotenv = "0.15.0"
futures = "0.3"
paw = "1.0"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sqlx = { path = "../../../", features = ["postgres", "json"] }
structopt = { version = "0.3", features = ["paw"] }

View File

@ -0,0 +1,41 @@
# JSON Example
## Setup
1. Declare the database URL
```
export DATABASE_URL="postgres://postgres:password@localhost/json"
```
2. Create the database.
```
$ sqlx db create
```
3. Run sql migrations
```
$ sqlx migrate run
```
## Usage
Add a person
```
echo '{ "name": "John Doe", "age": 30 }' | cargo run -- add
```
or with extra keys
```
echo '{ "name": "Jane Doe", "age": 25, "array": ["string", true, 0] }' | cargo run -- add
```
List all people
```
cargo run
```

View File

@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS people
(
id BIGSERIAL PRIMARY KEY,
person JSONB NOT NULL
);

View File

@ -0,0 +1,97 @@
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use sqlx::postgres::PgPool;
use sqlx::types::Json;
use std::io::{self, Read};
use std::num::NonZeroU8;
use structopt::StructOpt;
#[derive(StructOpt)]
struct Args {
#[structopt(subcommand)]
cmd: Option<Command>,
}
#[derive(StructOpt)]
enum Command {
Add,
}
#[derive(Deserialize, Serialize)]
struct Person {
name: String,
age: NonZeroU8,
#[serde(flatten)]
extra: Map<String, Value>,
}
struct Row {
id: i64,
person: Json<Person>,
}
#[async_std::main]
#[paw::main]
async fn main(args: Args) -> anyhow::Result<()> {
let pool = PgPool::connect(&dotenv::var("DATABASE_URL")?).await?;
match args.cmd {
Some(Command::Add) => {
let mut json = String::new();
io::stdin().read_to_string(&mut json)?;
let person: Person = serde_json::from_str(&json)?;
println!(
"Adding new person: {}",
&serde_json::to_string_pretty(&person)?
);
let person_id = add_person(&pool, person).await?;
println!("Added new person with ID {}", person_id);
}
None => {
println!("Printing all people");
list_people(&pool).await?;
}
}
Ok(())
}
async fn add_person(pool: &PgPool, person: Person) -> anyhow::Result<i64> {
let rec = sqlx::query!(
r#"
INSERT INTO people ( person )
VALUES ( $1 )
RETURNING id
"#,
Json(person) as _
)
.fetch_one(pool)
.await?;
Ok(rec.id)
}
async fn list_people(pool: &PgPool) -> anyhow::Result<()> {
let rows = sqlx::query_as!(
Row,
r#"
SELECT id, person as "person: Json<Person>"
FROM people
ORDER BY id
"#
)
.fetch_all(pool)
.await?;
for row in rows {
println!(
"{}: {}",
row.id,
&serde_json::to_string_pretty(&row.person)?
);
}
Ok(())
}