Skip to content

Commit

Permalink
Querying PlanetScale for booleans with sqlx
Browse files Browse the repository at this point in the history
Now we have a deployed Rust Netlify Function that is querying PlanetScale and responding to users with JSON representations of a subset of the Pokemon data we have stored.

There's a couple hangups that I want to cover before we move on. The first is querying for boolean values, which are stored as `TinyInt` in MySQL, which are `i8`s that can be either 0 or 1.

First we'll add the `legendary_or_mythical` value to our `PokemonHp` struct.

```rust
struct PokemonHp {
    name: String,
    hp: u16,
    legendary_or_mythical: bool,
}
```

Then we'll add the field in our SQL query as well.

```sql
SELECT name, hp, legendary_or_mythical FROM pokemon WHERE slug = ?
```

With these two in place, if we test our application with `cargo test` we'll see a warning `expected bool, found i8`.

```sql
error[E0308]: mismatched types
  --> crates/pokemon-api/src/main.rs:66:26
   |
66 |               let result = sqlx::query_as!(
   |  __________________________^
67 | |                     PokemonHp,
68 | |                     r#"SELECT name, hp, legendary_or_mythical FROM pokemon WHERE slug = ?"#,
69 | |                     pokemon_name
70 | |                 )
   | |_________________^ expected `bool`, found `i8`
   |
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` (in Nightly builds, run with -Z macro-backtrace for more info)
```

This is because of the way MySQL stores booleans, which isn't as booleans at all. We have to modify our SQL query to inform sqlx of our intent to return a boolean.

```bash
legendary_or_mythical as "legendary_or_mythical!: bool",
```

This will compile, and we still need to update our *`handler_handles`* test with the additional field.

```sql
body: Some(Body::Text(
    serde_json::to_string(&PokemonHp {
        name: String::from("Bulbasaur"),
        hp: 45,
        legendary_or_mythical: false
    },)
    .unwrap()
)),
```

Altogether we'll now get the `legendary_or_mythical` boolean in our API responses.
  • Loading branch information
ChristopherBiscardi committed Nov 2, 2021
1 parent 3fa71da commit 8c4bdc9
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions crates/pokemon-api/src/main.rs
Expand Up @@ -33,6 +33,7 @@ async fn main() -> Result<(), Error> {
struct PokemonHp {
name: String,
hp: u16,
legendary_or_mythical: bool,
}

#[instrument]
Expand Down Expand Up @@ -64,7 +65,16 @@ async fn handler(
info!(pokemon_name,"requested a pokemon");
let result = sqlx::query_as!(
PokemonHp,
r#"SELECT name, hp FROM pokemon WHERE slug = ?"#,
r#"
SELECT
name,
hp,
legendary_or_mythical as "legendary_or_mythical!: bool"
FROM
pokemon
WHERE
slug = ?
"#,
pokemon_name
)
.fetch_one(POOL.get().unwrap())
Expand Down Expand Up @@ -113,7 +123,8 @@ mod tests {
body: Some(Body::Text(
serde_json::to_string(&PokemonHp {
name: String::from("Bulbasaur"),
hp: 45
hp: 45,
legendary_or_mythical: false
},)
.unwrap()
)),
Expand Down

0 comments on commit 8c4bdc9

Please sign in to comment.