···77};
88use serde::{Deserialize, Serialize};
99use serde_json::json;
1010-use sqlx::Row;
1110use tracing::error;
12111312#[derive(Deserialize)]
···5756 .into_response();
5857 }
59586060- let result = sqlx::query(
5959+ let result = sqlx::query!(
6160 r#"
6261 SELECT did, handle, email, created_at
6362 FROM users
6463 WHERE did = $1
6564 "#,
6565+ did
6666 )
6767- .bind(did)
6867 .fetch_optional(&state.db)
6968 .await;
70697170 match result {
7271 Ok(Some(row)) => {
7373- let user_did: String = row.get("did");
7474- let handle: String = row.get("handle");
7575- let email: String = row.get("email");
7676- let created_at: chrono::DateTime<chrono::Utc> = row.get("created_at");
7777-7872 (
7973 StatusCode::OK,
8074 Json(AccountInfo {
8181- did: user_did,
8282- handle,
8383- email: Some(email),
8484- indexed_at: created_at.to_rfc3339(),
7575+ did: row.did,
7676+ handle: row.handle,
7777+ email: Some(row.email),
7878+ indexed_at: row.created_at.to_rfc3339(),
8579 invite_note: None,
8680 invites_disabled: false,
8781 email_confirmed_at: None,
···141135 continue;
142136 }
143137144144- let result = sqlx::query(
138138+ let result = sqlx::query!(
145139 r#"
146140 SELECT did, handle, email, created_at
147141 FROM users
148142 WHERE did = $1
149143 "#,
144144+ did
150145 )
151151- .bind(did)
152146 .fetch_optional(&state.db)
153147 .await;
154148155149 if let Ok(Some(row)) = result {
156156- let user_did: String = row.get("did");
157157- let handle: String = row.get("handle");
158158- let email: String = row.get("email");
159159- let created_at: chrono::DateTime<chrono::Utc> = row.get("created_at");
160160-161150 infos.push(AccountInfo {
162162- did: user_did,
163163- handle,
164164- email: Some(email),
165165- indexed_at: created_at.to_rfc3339(),
151151+ did: row.did,
152152+ handle: row.handle,
153153+ email: Some(row.email),
154154+ indexed_at: row.created_at.to_rfc3339(),
166155 invite_note: None,
167156 invites_disabled: false,
168157 email_confirmed_at: None,
···202191 .into_response();
203192 }
204193205205- let user = sqlx::query("SELECT id FROM users WHERE did = $1")
206206- .bind(did)
194194+ let user = sqlx::query!("SELECT id FROM users WHERE did = $1", did)
207195 .fetch_optional(&state.db)
208196 .await;
209197210210- let user_id: uuid::Uuid = match user {
211211- Ok(Some(row)) => row.get("id"),
198198+ let user_id = match user {
199199+ Ok(Some(row)) => row.id,
212200 Ok(None) => {
213201 return (
214202 StatusCode::NOT_FOUND,
···226214 }
227215 };
228216229229- let _ = sqlx::query("DELETE FROM sessions WHERE did = $1")
230230- .bind(did)
217217+ let _ = sqlx::query!("DELETE FROM sessions WHERE did = $1", did)
231218 .execute(&state.db)
232219 .await;
233220234234- let _ = sqlx::query("DELETE FROM records WHERE repo_id = $1")
235235- .bind(user_id)
221221+ let _ = sqlx::query!("DELETE FROM records WHERE repo_id = $1", user_id)
236222 .execute(&state.db)
237223 .await;
238224239239- let _ = sqlx::query("DELETE FROM repos WHERE user_id = $1")
240240- .bind(user_id)
225225+ let _ = sqlx::query!("DELETE FROM repos WHERE user_id = $1", user_id)
241226 .execute(&state.db)
242227 .await;
243228244244- let _ = sqlx::query("DELETE FROM blobs WHERE created_by_user = $1")
245245- .bind(user_id)
229229+ let _ = sqlx::query!("DELETE FROM blobs WHERE created_by_user = $1", user_id)
246230 .execute(&state.db)
247231 .await;
248232249249- let _ = sqlx::query("DELETE FROM user_keys WHERE user_id = $1")
250250- .bind(user_id)
233233+ let _ = sqlx::query!("DELETE FROM user_keys WHERE user_id = $1", user_id)
251234 .execute(&state.db)
252235 .await;
253236254254- let result = sqlx::query("DELETE FROM users WHERE id = $1")
255255- .bind(user_id)
237237+ let result = sqlx::query!("DELETE FROM users WHERE id = $1", user_id)
256238 .execute(&state.db)
257239 .await;
258240···300282 .into_response();
301283 }
302284303303- let result = sqlx::query("UPDATE users SET email = $1 WHERE did = $2")
304304- .bind(email)
305305- .bind(account)
285285+ let result = sqlx::query!("UPDATE users SET email = $1 WHERE did = $2", email, account)
306286 .execute(&state.db)
307287 .await;
308288···370350 .into_response();
371351 }
372352373373- let existing = sqlx::query("SELECT id FROM users WHERE handle = $1 AND did != $2")
374374- .bind(handle)
375375- .bind(did)
353353+ let existing = sqlx::query!("SELECT id FROM users WHERE handle = $1 AND did != $2", handle, did)
376354 .fetch_optional(&state.db)
377355 .await;
378356···384362 .into_response();
385363 }
386364387387- let result = sqlx::query("UPDATE users SET handle = $1 WHERE did = $2")
388388- .bind(handle)
389389- .bind(did)
365365+ let result = sqlx::query!("UPDATE users SET handle = $1 WHERE did = $2", handle, did)
390366 .execute(&state.db)
391367 .await;
392368···455431 }
456432 };
457433458458- let result = sqlx::query("UPDATE users SET password_hash = $1 WHERE did = $2")
459459- .bind(&password_hash)
460460- .bind(did)
434434+ let result = sqlx::query!("UPDATE users SET password_hash = $1 WHERE did = $2", password_hash, did)
461435 .execute(&state.db)
462436 .await;
463437
+11-15
src/api/feed/timeline.rs
···5959 .unwrap_or("")
6060 .replace("Bearer ", "");
61616262- let session = sqlx::query(
6363- "SELECT s.did, k.key_bytes FROM sessions s JOIN users u ON s.did = u.did JOIN user_keys k ON u.id = k.user_id WHERE s.access_jwt = $1"
6262+ let session = sqlx::query!(
6363+ "SELECT s.did, k.key_bytes FROM sessions s JOIN users u ON s.did = u.did JOIN user_keys k ON u.id = k.user_id WHERE s.access_jwt = $1",
6464+ token
6465 )
6565- .bind(&token)
6666 .fetch_optional(&state.db)
6767 .await
6868 .unwrap_or(None);
69697070 let (did, key_bytes) = match session {
7171- Some(row) => (
7272- row.get::<String, _>("did"),
7373- row.get::<Vec<u8>, _>("key_bytes"),
7474- ),
7171+ Some(row) => (row.did, row.key_bytes),
7572 None => {
7673 return (
7774 StatusCode::UNAUTHORIZED,
···8986 .into_response();
9087 }
91889292- let user_query = sqlx::query("SELECT id FROM users WHERE did = $1")
9393- .bind(&did)
8989+ let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did)
9490 .fetch_optional(&state.db)
9591 .await;
96929797- let user_id: uuid::Uuid = match user_query {
9898- Ok(Some(row)) => row.get("id"),
9393+ let user_id = match user_query {
9494+ Ok(Some(row)) => row.id,
9995 _ => {
10096 return (
10197 StatusCode::INTERNAL_SERVER_ERROR,
···105101 }
106102 };
107103108108- let follows_query = sqlx::query(
109109- "SELECT record_cid FROM records WHERE repo_id = $1 AND collection = 'app.bsky.graph.follow'"
104104+ let follows_query = sqlx::query!(
105105+ "SELECT record_cid FROM records WHERE repo_id = $1 AND collection = 'app.bsky.graph.follow'",
106106+ user_id
110107 )
111111- .bind(user_id)
112108 .fetch_all(&state.db)
113109 .await;
114110115111 let follow_cids: Vec<String> = match follows_query {
116116- Ok(rows) => rows.iter().map(|r| r.get("record_cid")).collect(),
112112+ Ok(rows) => rows.iter().map(|r| r.record_cid.clone()).collect(),
117113 Err(e) => {
118114 error!("Failed to get follows: {:?}", e);
119115 return (
+19-29
src/api/identity/account.rs
···1313use rand::rngs::OsRng;
1414use serde::{Deserialize, Serialize};
1515use serde_json::json;
1616-use sqlx::Row;
1716use std::sync::Arc;
1817use tracing::{error, info};
1918···8281 }
8382 };
84838585- let exists_query = sqlx::query("SELECT 1 FROM users WHERE handle = $1")
8686- .bind(&input.handle)
8484+ let exists_query = sqlx::query!("SELECT 1 as one FROM users WHERE handle = $1", input.handle)
8785 .fetch_optional(&mut *tx)
8886 .await;
8987···108106109107 if let Some(code) = &input.invite_code {
110108 let invite_query =
111111- sqlx::query("SELECT available_uses FROM invite_codes WHERE code = $1 FOR UPDATE")
112112- .bind(code)
109109+ sqlx::query!("SELECT available_uses FROM invite_codes WHERE code = $1 FOR UPDATE", code)
113110 .fetch_optional(&mut *tx)
114111 .await;
115112116113 match invite_query {
117114 Ok(Some(row)) => {
118118- let uses: i32 = row.get("available_uses");
119119- if uses <= 0 {
115115+ if row.available_uses <= 0 {
120116 return (StatusCode::BAD_REQUEST, Json(json!({"error": "InvalidInviteCode", "message": "Invite code exhausted"}))).into_response();
121117 }
122118123123- let update_invite = sqlx::query(
119119+ let update_invite = sqlx::query!(
124120 "UPDATE invite_codes SET available_uses = available_uses - 1 WHERE code = $1",
121121+ code
125122 )
126126- .bind(code)
127123 .execute(&mut *tx)
128124 .await;
129125···166162 }
167163 };
168164169169- let user_insert = sqlx::query("INSERT INTO users (handle, email, did, password_hash) VALUES ($1, $2, $3, $4) RETURNING id")
170170- .bind(&input.handle)
171171- .bind(&input.email)
172172- .bind(&did)
173173- .bind(&password_hash)
165165+ let user_insert = sqlx::query!(
166166+ "INSERT INTO users (handle, email, did, password_hash) VALUES ($1, $2, $3, $4) RETURNING id",
167167+ input.handle,
168168+ input.email,
169169+ did,
170170+ password_hash
171171+ )
174172 .fetch_one(&mut *tx)
175173 .await;
176174177177- let user_id: uuid::Uuid = match user_insert {
178178- Ok(row) => row.get("id"),
175175+ let user_id = match user_insert {
176176+ Ok(row) => row.id,
179177 Err(e) => {
180178 error!("Error inserting user: {:?}", e);
181179 // TODO: Check for unique constraint violation on email/did specifically
···190188 let secret_key = SecretKey::random(&mut OsRng);
191189 let secret_key_bytes = secret_key.to_bytes();
192190193193- let key_insert = sqlx::query("INSERT INTO user_keys (user_id, key_bytes) VALUES ($1, $2)")
194194- .bind(user_id)
195195- .bind(&secret_key_bytes[..])
191191+ let key_insert = sqlx::query!("INSERT INTO user_keys (user_id, key_bytes) VALUES ($1, $2)", user_id, &secret_key_bytes[..])
196192 .execute(&mut *tx)
197193 .await;
198194···257253 }
258254 };
259255260260- let repo_insert = sqlx::query("INSERT INTO repos (user_id, repo_root_cid) VALUES ($1, $2)")
261261- .bind(user_id)
262262- .bind(commit_cid.to_string())
256256+ let commit_cid_str = commit_cid.to_string();
257257+ let repo_insert = sqlx::query!("INSERT INTO repos (user_id, repo_root_cid) VALUES ($1, $2)", user_id, commit_cid_str)
263258 .execute(&mut *tx)
264259 .await;
265260···274269275270 if let Some(code) = &input.invite_code {
276271 let use_insert =
277277- sqlx::query("INSERT INTO invite_code_uses (code, used_by_user) VALUES ($1, $2)")
278278- .bind(code)
279279- .bind(user_id)
272272+ sqlx::query!("INSERT INTO invite_code_uses (code, used_by_user) VALUES ($1, $2)", code, user_id)
280273 .execute(&mut *tx)
281274 .await;
282275···317310 };
318311319312 let session_insert =
320320- sqlx::query("INSERT INTO sessions (access_jwt, refresh_jwt, did) VALUES ($1, $2, $3)")
321321- .bind(&access_jwt)
322322- .bind(&refresh_jwt)
323323- .bind(&did)
313313+ sqlx::query!("INSERT INTO sessions (access_jwt, refresh_jwt, did) VALUES ($1, $2, $3)", access_jwt, refresh_jwt, did)
324314 .execute(&mut *tx)
325315 .await;
326316
+14-35
src/api/identity/did.rs
···1111use reqwest;
1212use serde::Deserialize;
1313use serde_json::json;
1414-use sqlx::Row;
1514use tracing::error;
16151716#[derive(Deserialize)]
···3332 .into_response();
3433 }
35343636- let user = sqlx::query("SELECT did FROM users WHERE handle = $1")
3737- .bind(handle)
3535+ let user = sqlx::query!("SELECT did FROM users WHERE handle = $1", handle)
3836 .fetch_optional(&state.db)
3937 .await;
40384139 match user {
4240 Ok(Some(row)) => {
4343- let did: String = row.get("did");
4444- (StatusCode::OK, Json(json!({ "did": did }))).into_response()
4141+ (StatusCode::OK, Json(json!({ "did": row.did }))).into_response()
4542 }
4643 Ok(None) => (
4744 StatusCode::NOT_FOUND,
···9794pub async fn user_did_doc(State(state): State<AppState>, Path(handle): Path<String>) -> Response {
9895 let hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string());
9996100100- let user = sqlx::query("SELECT id, did FROM users WHERE handle = $1")
101101- .bind(&handle)
9797+ let user = sqlx::query!("SELECT id, did FROM users WHERE handle = $1", handle)
10298 .fetch_optional(&state.db)
10399 .await;
104100105101 let (user_id, did) = match user {
106106- Ok(Some(row)) => {
107107- let id: uuid::Uuid = row.get("id");
108108- let d: String = row.get("did");
109109- (id, d)
110110- }
102102+ Ok(Some(row)) => (row.id, row.did),
111103 Ok(None) => {
112104 return (StatusCode::NOT_FOUND, Json(json!({"error": "NotFound"}))).into_response();
113105 }
···129121 .into_response();
130122 }
131123132132- let key_row = sqlx::query("SELECT key_bytes FROM user_keys WHERE user_id = $1")
133133- .bind(user_id)
124124+ let key_row = sqlx::query!("SELECT key_bytes FROM user_keys WHERE user_id = $1", user_id)
134125 .fetch_optional(&state.db)
135126 .await;
136127137128 let key_bytes: Vec<u8> = match key_row {
138138- Ok(Some(row)) => row.get("key_bytes"),
129129+ Ok(Some(row)) => row.key_bytes,
139130 _ => {
140131 return (
141132 StatusCode::INTERNAL_SERVER_ERROR,
···294285 .unwrap_or("")
295286 .replace("Bearer ", "");
296287297297- let session = sqlx::query(
288288+ let session = sqlx::query!(
298289 r#"
299290 SELECT s.did, k.key_bytes, u.handle
300291 FROM sessions s
···302293 JOIN user_keys k ON u.id = k.user_id
303294 WHERE s.access_jwt = $1
304295 "#,
296296+ token
305297 )
306306- .bind(&token)
307298 .fetch_optional(&state.db)
308299 .await;
309300310301 let (_did, key_bytes, handle) = match session {
311311- Ok(Some(row)) => (
312312- row.get::<String, _>("did"),
313313- row.get::<Vec<u8>, _>("key_bytes"),
314314- row.get::<String, _>("handle"),
315315- ),
302302+ Ok(Some(row)) => (row.did, row.key_bytes, row.handle),
316303 Ok(None) => {
317304 return (
318305 StatusCode::UNAUTHORIZED,
···404391 .unwrap_or("")
405392 .replace("Bearer ", "");
406393407407- let session = sqlx::query(
394394+ let session = sqlx::query!(
408395 r#"
409396 SELECT s.did, k.key_bytes, u.id as user_id
410397 FROM sessions s
···412399 JOIN user_keys k ON u.id = k.user_id
413400 WHERE s.access_jwt = $1
414401 "#,
402402+ token
415403 )
416416- .bind(&token)
417404 .fetch_optional(&state.db)
418405 .await;
419406420407 let (_did, key_bytes, user_id) = match session {
421421- Ok(Some(row)) => (
422422- row.get::<String, _>("did"),
423423- row.get::<Vec<u8>, _>("key_bytes"),
424424- row.get::<uuid::Uuid, _>("user_id"),
425425- ),
408408+ Ok(Some(row)) => (row.did, row.key_bytes, row.user_id),
426409 Ok(None) => {
427410 return (
428411 StatusCode::UNAUTHORIZED,
···468451 .into_response();
469452 }
470453471471- let existing = sqlx::query("SELECT id FROM users WHERE handle = $1 AND id != $2")
472472- .bind(new_handle)
473473- .bind(user_id)
454454+ let existing = sqlx::query!("SELECT id FROM users WHERE handle = $1 AND id != $2", new_handle, user_id)
474455 .fetch_optional(&state.db)
475456 .await;
476457···482463 .into_response();
483464 }
484465485485- let result = sqlx::query("UPDATE users SET handle = $1 WHERE id = $2")
486486- .bind(new_handle)
487487- .bind(user_id)
466466+ let result = sqlx::query!("UPDATE users SET handle = $1 WHERE id = $2", new_handle, user_id)
488467 .execute(&state.db)
489468 .await;
490469
···66 response::{IntoResponse, Response},
77};
88use reqwest::Client;
99-use sqlx::Row;
109use std::collections::HashMap;
1110use tracing::{error, info};
1211···4847 if let Ok(token) = auth_val.to_str() {
4948 let token = token.replace("Bearer ", "");
5049 if let Ok(did) = crate::auth::get_did_from_token(&token) {
5151- let key_row = sqlx::query("SELECT k.key_bytes FROM user_keys k JOIN users u ON k.user_id = u.id WHERE u.did = $1")
5252- .bind(&did)
5050+ let key_row = sqlx::query!("SELECT k.key_bytes FROM user_keys k JOIN users u ON k.user_id = u.id WHERE u.did = $1", did)
5351 .fetch_optional(&state.db)
5452 .await;
55535654 if let Ok(Some(row)) = key_row {
5757- let key_bytes: Vec<u8> = row.get("key_bytes");
5855 if let Ok(new_token) =
5959- crate::auth::create_service_token(&did, aud, &method, &key_bytes)
5656+ crate::auth::create_service_token(&did, aud, &method, &row.key_bytes)
6057 {
6158 if let Ok(val) =
6259 axum::http::HeaderValue::from_str(&format!("Bearer {}", new_token))
+31-42
src/api/repo/blob.rs
···1212use serde::{Deserialize, Serialize};
1313use serde_json::json;
1414use sha2::{Digest, Sha256};
1515-use sqlx::Row;
1615use std::str::FromStr;
1716use tracing::error;
1817···3534 .unwrap_or("")
3635 .replace("Bearer ", "");
37363838- let session = sqlx::query(
3939- "SELECT s.did, k.key_bytes FROM sessions s JOIN users u ON s.did = u.did JOIN user_keys k ON u.id = k.user_id WHERE s.access_jwt = $1"
3737+ let session = sqlx::query!(
3838+ "SELECT s.did, k.key_bytes FROM sessions s JOIN users u ON s.did = u.did JOIN user_keys k ON u.id = k.user_id WHERE s.access_jwt = $1",
3939+ token
4040 )
4141- .bind(&token)
4241 .fetch_optional(&state.db)
4342 .await
4443 .unwrap_or(None);
45444645 let (did, key_bytes) = match session {
4747- Some(row) => (
4848- row.get::<String, _>("did"),
4949- row.get::<Vec<u8>, _>("key_bytes"),
5050- ),
4646+ Some(row) => (row.did, row.key_bytes),
5147 None => {
5248 return (
5349 StatusCode::UNAUTHORIZED,
···9288 .into_response();
9389 }
94909595- let user_query = sqlx::query("SELECT id FROM users WHERE did = $1")
9696- .bind(&did)
9191+ let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did)
9792 .fetch_optional(&state.db)
9893 .await;
9994100100- let user_id: uuid::Uuid = match user_query {
101101- Ok(Some(row)) => row.get("id"),
9595+ let user_id = match user_query {
9696+ Ok(Some(row)) => row.id,
10297 _ => {
10398 return (
10499 StatusCode::INTERNAL_SERVER_ERROR,
···108103 }
109104 };
110105111111- let insert = sqlx::query(
112112- "INSERT INTO blobs (cid, mime_type, size_bytes, created_by_user, storage_key) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (cid) DO NOTHING"
106106+ let insert = sqlx::query!(
107107+ "INSERT INTO blobs (cid, mime_type, size_bytes, created_by_user, storage_key) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (cid) DO NOTHING",
108108+ cid_str,
109109+ mime_type,
110110+ size,
111111+ user_id,
112112+ storage_key
113113 )
114114- .bind(&cid_str)
115115- .bind(&mime_type)
116116- .bind(size)
117117- .bind(user_id)
118118- .bind(&storage_key)
119114 .execute(&state.db)
120115 .await;
121116···202197 .unwrap_or("")
203198 .replace("Bearer ", "");
204199205205- let session = sqlx::query(
206206- "SELECT s.did, k.key_bytes FROM sessions s JOIN users u ON s.did = u.did JOIN user_keys k ON u.id = k.user_id WHERE s.access_jwt = $1"
200200+ let session = sqlx::query!(
201201+ "SELECT s.did, k.key_bytes FROM sessions s JOIN users u ON s.did = u.did JOIN user_keys k ON u.id = k.user_id WHERE s.access_jwt = $1",
202202+ token
207203 )
208208- .bind(&token)
209204 .fetch_optional(&state.db)
210205 .await
211206 .unwrap_or(None);
212207213208 let (did, key_bytes) = match session {
214214- Some(row) => (
215215- row.get::<String, _>("did"),
216216- row.get::<Vec<u8>, _>("key_bytes"),
217217- ),
209209+ Some(row) => (row.did, row.key_bytes),
218210 None => {
219211 return (
220212 StatusCode::UNAUTHORIZED,
···232224 .into_response();
233225 }
234226235235- let user_query = sqlx::query("SELECT id FROM users WHERE did = $1")
236236- .bind(&did)
227227+ let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did)
237228 .fetch_optional(&state.db)
238229 .await;
239230240240- let user_id: uuid::Uuid = match user_query {
241241- Ok(Some(row)) => row.get("id"),
231231+ let user_id = match user_query {
232232+ Ok(Some(row)) => row.id,
242233 _ => {
243234 return (
244235 StatusCode::INTERNAL_SERVER_ERROR,
···257248 (String::new(), String::new())
258249 };
259250260260- let records_query = sqlx::query(
261261- "SELECT collection, rkey, record_cid FROM records WHERE repo_id = $1 AND (collection, rkey) > ($2, $3) ORDER BY collection, rkey LIMIT $4"
251251+ let records_query = sqlx::query!(
252252+ "SELECT collection, rkey, record_cid FROM records WHERE repo_id = $1 AND (collection, rkey) > ($2, $3) ORDER BY collection, rkey LIMIT $4",
253253+ user_id,
254254+ cursor_collection,
255255+ cursor_rkey,
256256+ limit
262257 )
263263- .bind(user_id)
264264- .bind(cursor_collection)
265265- .bind(cursor_rkey)
266266- .bind(limit)
267258 .fetch_all(&state.db)
268259 .await;
269260···283274 let mut last_cursor = None;
284275285276 for row in &records {
286286- let collection: String = row.get("collection");
287287- let rkey: String = row.get("rkey");
288288- let record_cid_str: String = row.get("record_cid");
277277+ let collection = &row.collection;
278278+ let rkey = &row.rkey;
279279+ let record_cid_str = &row.record_cid;
289280290281 last_cursor = Some(format!("{}|{}", collection, rkey));
291282···308299 find_blobs(&record_val, &mut blobs);
309300310301 for blob_cid_str in blobs {
311311- let exists = sqlx::query("SELECT 1 FROM blobs WHERE cid = $1 AND created_by_user = $2")
312312- .bind(&blob_cid_str)
313313- .bind(user_id)
302302+ let exists = sqlx::query!("SELECT 1 as one FROM blobs WHERE cid = $1 AND created_by_user = $2", blob_cid_str, user_id)
314303 .fetch_optional(&state.db)
315304 .await;
316305