Skip to content

Commit c45b85f

Browse files
committed
Fix SQLx User Data Parsing
SQLx gives you a hard time if you don't explicitly define a tuple's type (Ex joining against Users and taking * as a row).
1 parent e33c11c commit c45b85f

File tree

4 files changed

+27
-25
lines changed

4 files changed

+27
-25
lines changed

src/db/car.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ impl Car {
9494
VALUES ($1, $2, $3, $4, $5, $6) RETURNING *
9595
)
9696
SELECT car.id, car.event_id, car.max_capacity, car.departure_time, car.return_time, car.comment,
97-
(driverUser.id, driverUser.realm::text, driverUser.name, driverUser.email) AS "driver!: UserData",
97+
ROW(driverUser.*)::users AS "driver!: UserData",
9898
ARRAY_REMOVE(ARRAY_AGG(
9999
CASE WHEN riderUser.id IS NOT NULL
100-
THEN (riderUser.id, riderUser.realm::text, riderUser.name, riderUser.email)
100+
THEN ROW(riderUser.*)::users
101101
END
102102
), NULL) as "riders!: Vec<UserData>"
103103
FROM car
@@ -138,10 +138,10 @@ impl Car {
138138
WHERE event_id = $5 AND id = $6 AND driver = $7 RETURNING *
139139
)
140140
SELECT new_car.id, new_car.event_id, new_car.max_capacity, new_car.departure_time, new_car.return_time, new_car.comment,
141-
(driverUser.id, driverUser.realm::text, driverUser.name, driverUser.email) AS "driver!: UserData",
141+
ROW(driverUser.*)::users AS "driver!: UserData",
142142
ARRAY_REMOVE(ARRAY_AGG(
143143
CASE WHEN riderUser.id IS NOT NULL
144-
THEN (riderUser.id, riderUser.realm::text, riderUser.name, riderUser.email)
144+
THEN ROW(riderUser.*)::users
145145
END
146146
), NULL) as "riders!: Vec<UserData>"
147147
FROM new_car
@@ -168,10 +168,10 @@ impl Car {
168168
query_as!(
169169
Car,
170170
r#"SELECT car.id, car.event_id, car.max_capacity, car.departure_time, car.return_time, car.comment,
171-
(driverUser.id, driverUser.realm::text, driverUser.name, driverUser.email) AS "driver!: UserData",
171+
ROW(driverUser.*)::users AS "driver!: UserData",
172172
ARRAY_REMOVE(ARRAY_AGG(
173173
CASE WHEN riderUser.id IS NOT NULL
174-
THEN (riderUser.id, riderUser.realm::text, riderUser.name, riderUser.email)
174+
THEN ROW(riderUser.*)::users
175175
END
176176
), NULL) as "riders!: Vec<UserData>"
177177
FROM car
@@ -190,10 +190,10 @@ impl Car {
190190
query_as!(
191191
Car,
192192
r#"SELECT car.id, car.event_id, car.max_capacity, car.departure_time, car.return_time, car.comment,
193-
(driverUser.id, driverUser.realm::text, driverUser.name, driverUser.email) AS "driver!: UserData",
193+
ROW(driverUser.*)::users AS "driver!: UserData",
194194
ARRAY_REMOVE(ARRAY_AGG(
195195
CASE WHEN riderUser.id IS NOT NULL
196-
THEN (riderUser.id, riderUser.realm::text, riderUser.name, riderUser.email)
196+
THEN ROW(riderUser.*)::users
197197
END
198198
), NULL) as "riders!: Vec<UserData>"
199199
FROM car

src/db/event.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl Event {
6060
INSERT INTO event (name, location, start_time, end_time, creator) VALUES ($1, $2, $3, $4, $5) RETURNING *
6161
)
6262
SELECT new_event.id, new_event.name, new_event.location, new_event.start_time, new_event.end_time,
63-
(users.id, users.realm, users.name, users.email) AS "creator!: UserData"
63+
(users.id, users.realm, users.name, users.email)::users AS "creator!: UserData"
6464
FROM new_event LEFT JOIN users ON new_event.creator = users.id
6565
"#,
6666
data.name, data.location, data.start_time, data.end_time, creator_id
@@ -90,8 +90,8 @@ impl Event {
9090
RETURNING *
9191
)
9292
SELECT new_event.id, new_event.name, new_event.location, new_event.start_time, new_event.end_time,
93-
(users.id, users.realm, users.name, users.email) AS "creator!: UserData"
94-
FROM new_event LEFT JOIN users ON new_event.creator = users.id
93+
ROW(users.*)::users AS "creator!: UserData"
94+
FROM new_event JOIN users ON new_event.creator = users.id
9595
"#,
9696
data.name,
9797
data.location,
@@ -112,7 +112,7 @@ impl Event {
112112
r#"
113113
SELECT
114114
event.id, event.name, event.location, event.start_time, event.end_time,
115-
(users.id, users.realm::text, users.name, users.email) AS "creator!: UserData"
115+
ROW(users.*)::users AS "creator!: UserData"
116116
FROM event
117117
JOIN users ON users.id = event.creator
118118
WHERE (end_time >= NOW() AND $1 = False) OR (end_time < NOW() AND $1)
@@ -133,7 +133,7 @@ impl Event {
133133
r#"
134134
SELECT
135135
event.id, event.name, event.location, event.start_time, event.end_time,
136-
(users.id, users.realm, users.name, users.email) AS "creator!: UserData"
136+
ROW(users.*)::users AS "creator!: UserData"
137137
FROM event
138138
JOIN users ON users.id = event.creator
139139
WHERE event.id = $1

src/db/user.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ use serde::{Deserialize, Serialize};
55
use sqlx::{query_as, Executor, Postgres};
66
use utoipa::ToSchema;
77

8-
#[derive(Serialize, Deserialize, sqlx::Type)]
8+
#[derive(Serialize, Deserialize, sqlx::Type, Clone, PartialEq)]
99
#[sqlx(type_name = "user_realm", rename_all = "lowercase")]
1010
pub enum UserRealm {
1111
Csh,
1212
Google,
1313
}
1414

15+
16+
1517
#[derive(Serialize, Deserialize, sqlx::Type, ToSchema, Clone)]
1618
#[serde(rename_all = "camelCase")]
1719
pub struct UserData {
1820
pub id: String,
19-
pub realm: String,
21+
pub realm: UserRealm,
2022
pub name: String,
2123
pub email: String,
2224
}
@@ -37,7 +39,7 @@ impl UserData {
3739
r#"INSERT INTO users (id, realm, name, email)
3840
VALUES ($1, $2, $3, $4)
3941
ON CONFLICT (id) DO UPDATE SET realm = EXCLUDED.realm, name = EXCLUDED.name, email = EXCLUDED.email
40-
RETURNING id AS "id!", realm::text AS "realm!", name AS "name!", email AS "email!";"#,
42+
RETURNING id AS "id!", realm AS "realm!: UserRealm", name AS "name!", email AS "email!";"#,
4143
id,
4244
realm as _,
4345
name,
@@ -50,7 +52,7 @@ impl UserData {
5052
where
5153
C: Executor<'c, Database = Postgres>,
5254
{
53-
query_as!(UserData, r#"SELECT id AS "id!", realm::text AS "realm!", name AS "name!", email AS "email!" FROM users WHERE LOWER(name) LIKE $1 OR LOWER(email) LIKE $1;"#, query.to_lowercase())
55+
query_as!(UserData, r#"SELECT id AS "id!", realm AS "realm!: UserRealm", name AS "name!", email AS "email!" FROM users WHERE LOWER(name) LIKE $1 OR LOWER(email) LIKE $1;"#, query.to_lowercase())
5456
.fetch_all(conn)
5557
.await.map_err(|err| anyhow!("Failed to get users: {}", err))
5658
}
@@ -61,7 +63,7 @@ impl UserData {
6163
let data = query_as!(
6264
UserData,
6365
r#"
64-
SELECT id AS "id!", realm::text AS "realm!", name AS "name!", email AS "email!"
66+
SELECT id AS "id!", realm AS "realm!: UserRealm", name AS "name!", email AS "email!"
6567
FROM users WHERE id IN (SELECT UNNEST($1::VARCHAR[]))
6668
"#,
6769
&ids
@@ -80,7 +82,7 @@ impl UserData {
8082
query_as!(
8183
UserData,
8284
r#"
83-
SELECT users.id AS "id!", users.realm::text AS "realm!", users.name AS "name!", users.email AS "email!"
85+
SELECT users.id AS "id!", users.realm AS "realm!: UserRealm", users.name AS "name!", users.email AS "email!"
8486
FROM users where id = $1;
8587
"#, id
8688
).fetch_optional(conn).await

src/worker.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::time::Duration;
99

1010
use crate::{
1111
app::{RedisJob, SimpleRiderChange},
12-
db::user::UserData,
12+
db::user::{UserData, UserRealm},
1313
pings::PingClient,
1414
};
1515

@@ -56,7 +56,7 @@ async fn get_driver(car_id: i32, db_pool: &Pool<Postgres>) -> Result<UserData> {
5656
query_as!(
5757
UserData,
5858
r#"
59-
SELECT users.id AS "id!", users.realm::text AS "realm!", users.name AS "name!", users.email AS "email!"
59+
SELECT users.id AS "id!", users.realm AS "realm!: UserRealm", users.name AS "name!", users.email AS "email!"
6060
FROM car JOIN users ON car.driver = users.id WHERE car.id = $1;
6161
"#, car_id
6262
).fetch_one(db_pool).await.map_err(|err| anyhow!("Failed to get driver: {}", err))
@@ -90,7 +90,7 @@ async fn work(job: &Item, db_pool: &Pool<Postgres>, pings: &PingClient) -> Resul
9090
msg: err.to_string(),
9191
should_retry: false,
9292
})?;
93-
if driver.realm != "csh" {
93+
if driver.realm != UserRealm::Csh {
9494
return Ok(());
9595
}
9696
pings
@@ -113,7 +113,7 @@ async fn work(job: &Item, db_pool: &Pool<Postgres>, pings: &PingClient) -> Resul
113113
msg: err.to_string(),
114114
should_retry: false,
115115
})?;
116-
if driver.realm != "csh" {
116+
if driver.realm != UserRealm::Csh {
117117
return Ok(());
118118
}
119119
pings
@@ -161,7 +161,7 @@ async fn work(job: &Item, db_pool: &Pool<Postgres>, pings: &PingClient) -> Resul
161161
msg: "User was missing from map.".to_string(),
162162
should_retry: false,
163163
})?;
164-
if user.realm != "csh" {
164+
if user.realm != UserRealm::Csh {
165165
continue;
166166
}
167167
pings
@@ -181,7 +181,7 @@ async fn work(job: &Item, db_pool: &Pool<Postgres>, pings: &PingClient) -> Resul
181181
msg: "User was missing from map.".to_string(),
182182
should_retry: false,
183183
})?;
184-
if user.realm != "csh" {
184+
if user.realm != UserRealm::Csh {
185185
continue;
186186
}
187187
pings

0 commit comments

Comments
 (0)