this repo has no description

SQLx raw text queries to yummy query macro

lewis 04c58ef4 4825105b

Changed files
+1567 -381
.sqlx
src
api
admin
feed
identity
moderation
repo
server
repo
sync
-1
.gitignore
··· 1 1 /target 2 - .sqlx 3 2 4 3 .env 5 4
+40
.sqlx/query-09d75b756a6bd981cf2a9e922eccc38677bee474813c66465904aec3c0da1c3e.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT u.handle, u.did, u.email, k.key_bytes\n FROM sessions s\n JOIN users u ON s.did = u.did\n JOIN user_keys k ON u.id = k.user_id\n WHERE s.access_jwt = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "handle", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "did", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "email", 19 + "type_info": "Text" 20 + }, 21 + { 22 + "ordinal": 3, 23 + "name": "key_bytes", 24 + "type_info": "Bytea" 25 + } 26 + ], 27 + "parameters": { 28 + "Left": [ 29 + "Text" 30 + ] 31 + }, 32 + "nullable": [ 33 + false, 34 + false, 35 + false, 36 + false 37 + ] 38 + }, 39 + "hash": "09d75b756a6bd981cf2a9e922eccc38677bee474813c66465904aec3c0da1c3e" 40 + }
+18
.sqlx/query-0f10bde03edc0233a332e210a84a4186977c71efd3be80e2508a60ea5802cb1b.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO blobs (cid, mime_type, size_bytes, created_by_user, storage_key) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (cid) DO NOTHING", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + "Int8", 11 + "Uuid", 12 + "Text" 13 + ] 14 + }, 15 + "nullable": [] 16 + }, 17 + "hash": "0f10bde03edc0233a332e210a84a4186977c71efd3be80e2508a60ea5802cb1b" 18 + }
+29
.sqlx/query-0f8fd9cbb1ff0fd8951ce082a82cc058ec6db0dde3ab0059d6f340a1fd9ddade.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT u.did, r.repo_root_cid\n FROM repos r\n JOIN users u ON r.user_id = u.id\n WHERE u.did > $1\n ORDER BY u.did ASC\n LIMIT $2\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "repo_root_cid", 14 + "type_info": "Text" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text", 20 + "Int8" 21 + ] 22 + }, 23 + "nullable": [ 24 + false, 25 + false 26 + ] 27 + }, 28 + "hash": "0f8fd9cbb1ff0fd8951ce082a82cc058ec6db0dde3ab0059d6f340a1fd9ddade" 29 + }
+25
.sqlx/query-0fdf13907693d130babae38f4bb1df772dc11ab682f47918cacb5ae186b4eb24.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT cid FROM blobs\n WHERE created_by_user = $1 AND cid > $2 AND created_at > $3\n ORDER BY cid ASC\n LIMIT $4\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "cid", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid", 15 + "Text", 16 + "Timestamptz", 17 + "Int8" 18 + ] 19 + }, 20 + "nullable": [ 21 + false 22 + ] 23 + }, 24 + "hash": "0fdf13907693d130babae38f4bb1df772dc11ab682f47918cacb5ae186b4eb24" 25 + }
+15
.sqlx/query-14a68a119586aa980fb7b64646c1373eecd788e508246b5ad84e31b1adbdd2c1.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO repos (user_id, repo_root_cid) VALUES ($1, $2)", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid", 9 + "Text" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "14a68a119586aa980fb7b64646c1373eecd788e508246b5ad84e31b1adbdd2c1" 15 + }
+18
.sqlx/query-15a3cb31c36192c76c0cfa881043d70a1cc2c212fa382f8d9efc3c35ea4e66c1.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO app_passwords (user_id, name, password_hash, created_at, privileged) VALUES ($1, $2, $3, $4, $5)", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid", 9 + "Text", 10 + "Text", 11 + "Timestamptz", 12 + "Bool" 13 + ] 14 + }, 15 + "nullable": [] 16 + }, 17 + "hash": "15a3cb31c36192c76c0cfa881043d70a1cc2c212fa382f8d9efc3c35ea4e66c1" 18 + }
+40
.sqlx/query-176d30f31356a4d128764c9c2eece81f8079a29e40b07ba58adc4380d58068c8.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT did, handle, email, created_at\n FROM users\n WHERE did = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "handle", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "email", 19 + "type_info": "Text" 20 + }, 21 + { 22 + "ordinal": 3, 23 + "name": "created_at", 24 + "type_info": "Timestamptz" 25 + } 26 + ], 27 + "parameters": { 28 + "Left": [ 29 + "Text" 30 + ] 31 + }, 32 + "nullable": [ 33 + false, 34 + false, 35 + false, 36 + false 37 + ] 38 + }, 39 + "hash": "176d30f31356a4d128764c9c2eece81f8079a29e40b07ba58adc4380d58068c8" 40 + }
+28
.sqlx/query-1d3748694f23a407e26c793cc43e91c4fa9753dc7c7fd964f6c43de27c5bac4a.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT u.did, r.repo_root_cid\n FROM users u\n LEFT JOIN repos r ON u.id = r.user_id\n WHERE u.did = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "repo_root_cid", 14 + "type_info": "Text" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "1d3748694f23a407e26c793cc43e91c4fa9753dc7c7fd964f6c43de27c5bac4a" 28 + }
+14
.sqlx/query-1ee6eda3e44660e7f14fcfe56adc2d41c72901b9c701fc7b992314e5370b32dc.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE invite_codes SET available_uses = available_uses - 1 WHERE code = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "1ee6eda3e44660e7f14fcfe56adc2d41c72901b9c701fc7b992314e5370b32dc" 14 + }
+15
.sqlx/query-222699c46b99152404863463b8bdffb9452112e3d50ec352c96c1398d3e21504.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO invite_code_uses (code, used_by_user) VALUES ($1, $2)", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Uuid" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "222699c46b99152404863463b8bdffb9452112e3d50ec352c96c1398d3e21504" 15 + }
+46
.sqlx/query-2305db96343fcb721adc4a6a608b64678f707928d3f9395070f5e21a5ca9b601.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT u.id, u.did, u.handle, u.password_hash, k.key_bytes FROM users u JOIN user_keys k ON u.id = k.user_id WHERE u.handle = $1 OR u.email = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "did", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "handle", 19 + "type_info": "Text" 20 + }, 21 + { 22 + "ordinal": 3, 23 + "name": "password_hash", 24 + "type_info": "Text" 25 + }, 26 + { 27 + "ordinal": 4, 28 + "name": "key_bytes", 29 + "type_info": "Bytea" 30 + } 31 + ], 32 + "parameters": { 33 + "Left": [ 34 + "Text" 35 + ] 36 + }, 37 + "nullable": [ 38 + false, 39 + false, 40 + false, 41 + false, 42 + false 43 + ] 44 + }, 45 + "hash": "2305db96343fcb721adc4a6a608b64678f707928d3f9395070f5e21a5ca9b601" 46 + }
+14
.sqlx/query-23201d4e26bc650939e30f69fb0bca00d351d057098afebc1017f70a84b4bd22.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET deactivated_at = NULL WHERE did = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "23201d4e26bc650939e30f69fb0bca00d351d057098afebc1017f70a84b4bd22" 14 + }
+23
.sqlx/query-423bbfd2ddf9b41d3bb339b8b94ac47524dc9233ec70cf2b6c5e9bc2de49b22d.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT 1 as one FROM blobs WHERE cid = $1 AND created_by_user = $2", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "one", 9 + "type_info": "Int4" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text", 15 + "Uuid" 16 + ] 17 + }, 18 + "nullable": [ 19 + null 20 + ] 21 + }, 22 + "hash": "423bbfd2ddf9b41d3bb339b8b94ac47524dc9233ec70cf2b6c5e9bc2de49b22d" 23 + }
+34
.sqlx/query-47c914ca6080c5cedf0c3f6ca7cd4cd49e8fb691b34d19511b7a1ab8b3606cdf.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT s.did, k.key_bytes, u.handle\n FROM sessions s\n JOIN users u ON s.did = u.did\n JOIN user_keys k ON u.id = k.user_id\n WHERE s.access_jwt = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "key_bytes", 14 + "type_info": "Bytea" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "handle", 19 + "type_info": "Text" 20 + } 21 + ], 22 + "parameters": { 23 + "Left": [ 24 + "Text" 25 + ] 26 + }, 27 + "nullable": [ 28 + false, 29 + false, 30 + false 31 + ] 32 + }, 33 + "hash": "47c914ca6080c5cedf0c3f6ca7cd4cd49e8fb691b34d19511b7a1ab8b3606cdf" 34 + }
+15
.sqlx/query-48915485884524f68783351bd61e9790dd7e729e5776adc66b9d0114bb8cd73a.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET email = $1 WHERE did = $2", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "48915485884524f68783351bd61e9790dd7e729e5776adc66b9d0114bb8cd73a" 15 + }
+28
.sqlx/query-48ae289ec37b367a6ec3d74895acaf8c3dc93e65d243434b6947ead95ca8c416.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT s.did, k.key_bytes\n FROM sessions s\n JOIN users u ON s.did = u.did\n JOIN user_keys k ON u.id = k.user_id\n WHERE s.access_jwt = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "key_bytes", 14 + "type_info": "Bytea" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "48ae289ec37b367a6ec3d74895acaf8c3dc93e65d243434b6947ead95ca8c416" 28 + }
+14
.sqlx/query-50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM users WHERE id = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7" 14 + }
+14
.sqlx/query-52437f0d7f91d29d7438263a1f658a838601038d911be8781b91ebeec8a54b89.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM sessions WHERE access_jwt = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "52437f0d7f91d29d7438263a1f658a838601038d911be8781b91ebeec8a54b89" 14 + }
+15
.sqlx/query-572b136b4196b7d755a252bc5bbf14b3765fc2e606b9512493e90efb4f1305fb.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET handle = $1 WHERE id = $2", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Uuid" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "572b136b4196b7d755a252bc5bbf14b3765fc2e606b9512493e90efb4f1305fb" 15 + }
+15
.sqlx/query-59e975c8599091b527ea2d097c68a8288360962d3e67f4db22e3dd92be924932.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET password_hash = $1 WHERE did = $2", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "59e975c8599091b527ea2d097c68a8288360962d3e67f4db22e3dd92be924932" 15 + }
+22
.sqlx/query-5b692e8f6d32dcbdcb45a3fff152a2be5672aadd807a4abab6914f80d57cba02.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT r.repo_root_cid\n FROM repos r\n JOIN users u ON r.user_id = u.id\n WHERE u.did = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "repo_root_cid", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "5b692e8f6d32dcbdcb45a3fff152a2be5672aadd807a4abab6914f80d57cba02" 22 + }
+25
.sqlx/query-6c3a6dbf8d0d2a460054f093bd2ec1130ea91911d7d187cafcb4573be12bfcf4.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO users (handle, email, did, password_hash) VALUES ($1, $2, $3, $4) RETURNING id", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text", 15 + "Text", 16 + "Text", 17 + "Text" 18 + ] 19 + }, 20 + "nullable": [ 21 + false 22 + ] 23 + }, 24 + "hash": "6c3a6dbf8d0d2a460054f093bd2ec1130ea91911d7d187cafcb4573be12bfcf4" 25 + }
+23
.sqlx/query-6fd476d5640c20dc67db8e61e16b2f805e947ec404021cf93f6699f87bd7cfa5.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT id FROM users WHERE handle = $1 AND id != $2", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text", 15 + "Uuid" 16 + ] 17 + }, 18 + "nullable": [ 19 + false 20 + ] 21 + }, 22 + "hash": "6fd476d5640c20dc67db8e61e16b2f805e947ec404021cf93f6699f87bd7cfa5" 23 + }
+22
.sqlx/query-77dfbc702362db9bb87c9d17c4d985287d8faa024981ae26c995dfc53fb486fd.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT repo_root_cid FROM repos WHERE user_id = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "repo_root_cid", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "77dfbc702362db9bb87c9d17c4d985287d8faa024981ae26c995dfc53fb486fd" 22 + }
+14
.sqlx/query-7d0e11989d1b3f9c74daa3009505161369600509f103244fcd485b88869ee365.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM user_keys WHERE user_id = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "7d0e11989d1b3f9c74daa3009505161369600509f103244fcd485b88869ee365" 14 + }
+22
.sqlx/query-7d65d4608e93daa645ca0f8f6c7a23fb1bdaf50c7b0de900b1777542baf79d74.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT did FROM users WHERE handle = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "7d65d4608e93daa645ca0f8f6c7a23fb1bdaf50c7b0de900b1777542baf79d74" 22 + }
+14
.sqlx/query-824293a46fd22d2c6bf7dde85156214d561a95125ee3ba0f3bd6bb2c3a7625e5.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM repos WHERE user_id = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "824293a46fd22d2c6bf7dde85156214d561a95125ee3ba0f3bd6bb2c3a7625e5" 14 + }
+22
.sqlx/query-8e69c8aebcb15c6956b8a0b9324dcc8668b2e14731945ceaf30b756050be9882.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT id FROM users WHERE did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "8e69c8aebcb15c6956b8a0b9324dcc8668b2e14731945ceaf30b756050be9882" 22 + }
+14
.sqlx/query-997cff04226e18bf4d5025092d0daf0450292bcbdba21b8530706797144dcafa.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM blobs WHERE created_by_user = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "997cff04226e18bf4d5025092d0daf0450292bcbdba21b8530706797144dcafa" 14 + }
+14
.sqlx/query-9c42b607a971b3a102d247def6c6fd322013f3885e9d0232d6e846220f893c49.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM sessions WHERE did = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "9c42b607a971b3a102d247def6c6fd322013f3885e9d0232d6e846220f893c49" 14 + }
+16
.sqlx/query-a5b7ceaa177ef136a0e2421eaca3f3edf283e9305bd4675d72a1b7a02c3dfc83.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE sessions SET access_jwt = $1, refresh_jwt = $2 WHERE refresh_jwt = $3", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + "Text" 11 + ] 12 + }, 13 + "nullable": [] 14 + }, 15 + "hash": "a5b7ceaa177ef136a0e2421eaca3f3edf283e9305bd4675d72a1b7a02c3dfc83" 16 + }
+14
.sqlx/query-a802bf661ef9a9baa41604b31e3cca9067ca467faef9c952e98db418157c0642.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET deactivated_at = NOW() WHERE did = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "a802bf661ef9a9baa41604b31e3cca9067ca467faef9c952e98db418157c0642" 14 + }
+15
.sqlx/query-aac3acbfc4f27b98054602de28b763ce15e3a70a9e6741114d12f2d173f631fe.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET handle = $1 WHERE did = $2", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "aac3acbfc4f27b98054602de28b763ce15e3a70a9e6741114d12f2d173f631fe" 15 + }
+28
.sqlx/query-b2c53e6a278c4549c99a5b98cc7ca77fc1e9cd39a591c1d8ec1ca41adfffa3a6.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT id, did FROM users WHERE handle = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "did", 14 + "type_info": "Text" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "b2c53e6a278c4549c99a5b98cc7ca77fc1e9cd39a591c1d8ec1ca41adfffa3a6" 28 + }
+28
.sqlx/query-bb243abd63d10a43b11fa4f93644149f315894496255c5538f131b2c7aeb763b.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT storage_key, mime_type FROM blobs WHERE cid = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "storage_key", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "mime_type", 14 + "type_info": "Text" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "bb243abd63d10a43b11fa4f93644149f315894496255c5538f131b2c7aeb763b" 28 + }
+22
.sqlx/query-bf2b237ee5cfe66d038dce3f564c05a683d391aebda7871d65d302e04b5d733f.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT deactivated_at FROM users WHERE did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "deactivated_at", 9 + "type_info": "Timestamptz" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + true 19 + ] 20 + }, 21 + "hash": "bf2b237ee5cfe66d038dce3f564c05a683d391aebda7871d65d302e04b5d733f" 22 + }
+24
.sqlx/query-bf55c87dfdeb7bc18663a50d10eeee0e53fade51c1c47bed9580072435baefea.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT cid FROM blobs\n WHERE created_by_user = $1 AND cid > $2\n ORDER BY cid ASC\n LIMIT $3\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "cid", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid", 15 + "Text", 16 + "Int8" 17 + ] 18 + }, 19 + "nullable": [ 20 + false 21 + ] 22 + }, 23 + "hash": "bf55c87dfdeb7bc18663a50d10eeee0e53fade51c1c47bed9580072435baefea" 24 + }
+22
.sqlx/query-bf60faafb5c79a149ba237a984f78d068b5d691f6762641412a5aa1517605c04.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT record_cid FROM records WHERE repo_id = $1 AND collection = 'app.bsky.graph.follow'", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "record_cid", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "bf60faafb5c79a149ba237a984f78d068b5d691f6762641412a5aa1517605c04" 22 + }
+40
.sqlx/query-c2a90157c47bf1c36f08f4608932d214cc26b4794e0b922b1dae3dad18a7ddc0.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT did, handle, email, created_at\n FROM users\n WHERE did = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "handle", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "email", 19 + "type_info": "Text" 20 + }, 21 + { 22 + "ordinal": 3, 23 + "name": "created_at", 24 + "type_info": "Timestamptz" 25 + } 26 + ], 27 + "parameters": { 28 + "Left": [ 29 + "Text" 30 + ] 31 + }, 32 + "nullable": [ 33 + false, 34 + false, 35 + false, 36 + false 37 + ] 38 + }, 39 + "hash": "c2a90157c47bf1c36f08f4608932d214cc26b4794e0b922b1dae3dad18a7ddc0" 40 + }
+15
.sqlx/query-c4c9842e69c5fd4f4a2ebc176078af2a5f98beb3ea4d3c6af5b1b8fed2ec50e3.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO user_keys (user_id, key_bytes) VALUES ($1, $2)", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid", 9 + "Bytea" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "c4c9842e69c5fd4f4a2ebc176078af2a5f98beb3ea4d3c6af5b1b8fed2ec50e3" 15 + }
+28
.sqlx/query-c949b23cf6d795c58e4c35907628bbb85714e9c49a569653b17acab60e1674ac.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "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.refresh_jwt = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "key_bytes", 14 + "type_info": "Bytea" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "c949b23cf6d795c58e4c35907628bbb85714e9c49a569653b17acab60e1674ac" 28 + }
+22
.sqlx/query-ce27e2da1f15cad97d2e31fda964e1d7017154fa559a8d9851728fb23af871cd.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT key_bytes FROM user_keys WHERE user_id = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "key_bytes", 9 + "type_info": "Bytea" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "ce27e2da1f15cad97d2e31fda964e1d7017154fa559a8d9851728fb23af871cd" 22 + }
+34
.sqlx/query-cec87a805457bcac6db8be601861b351a9332c649433894547176f6e4d672d01.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT name, created_at, privileged FROM app_passwords WHERE user_id = $1 ORDER BY created_at DESC", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "name", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "created_at", 14 + "type_info": "Timestamptz" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "privileged", 19 + "type_info": "Bool" 20 + } 21 + ], 22 + "parameters": { 23 + "Left": [ 24 + "Uuid" 25 + ] 26 + }, 27 + "nullable": [ 28 + false, 29 + false, 30 + false 31 + ] 32 + }, 33 + "hash": "cec87a805457bcac6db8be601861b351a9332c649433894547176f6e4d672d01" 34 + }
+34
.sqlx/query-d31423ddcb625250d7c15581e8c9242ec6290b41507eb710744ad900d482222d.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT s.did, k.key_bytes, u.id as user_id\n FROM sessions s\n JOIN users u ON s.did = u.did\n JOIN user_keys k ON u.id = k.user_id\n WHERE s.access_jwt = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "key_bytes", 14 + "type_info": "Bytea" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "user_id", 19 + "type_info": "Uuid" 20 + } 21 + ], 22 + "parameters": { 23 + "Left": [ 24 + "Text" 25 + ] 26 + }, 27 + "nullable": [ 28 + false, 29 + false, 30 + false 31 + ] 32 + }, 33 + "hash": "d31423ddcb625250d7c15581e8c9242ec6290b41507eb710744ad900d482222d" 34 + }
+16
.sqlx/query-db9950690548510474a2bf755b4c4c103b284e82e3cf23d17fc99cd2fc728c64.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO sessions (access_jwt, refresh_jwt, did) VALUES ($1, $2, $3)", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + "Text" 11 + ] 12 + }, 13 + "nullable": [] 14 + }, 15 + "hash": "db9950690548510474a2bf755b4c4c103b284e82e3cf23d17fc99cd2fc728c64" 16 + }
+22
.sqlx/query-e2746221a24351293447246af539b5a847129cf93233dd98161193d4b7156b45.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT available_uses FROM invite_codes WHERE code = $1 FOR UPDATE", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "available_uses", 9 + "type_info": "Int4" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "e2746221a24351293447246af539b5a847129cf93233dd98161193d4b7156b45" 22 + }
+23
.sqlx/query-e80274b0731ed0ff9a1a1ae444eefadc193a172795b41c71445717020e6367d6.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT id FROM users WHERE handle = $1 AND did != $2", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text", 15 + "Text" 16 + ] 17 + }, 18 + "nullable": [ 19 + false 20 + ] 21 + }, 22 + "hash": "e80274b0731ed0ff9a1a1ae444eefadc193a172795b41c71445717020e6367d6" 23 + }
+22
.sqlx/query-ec5e14110d69ba47e8dd4447569c31506220df7759d0449e20d224609c7e6c4c.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT handle FROM users WHERE did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "handle", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "ec5e14110d69ba47e8dd4447569c31506220df7759d0449e20d224609c7e6c4c" 22 + }
+22
.sqlx/query-ed34111a7f41b419a23d16ddd23cbc6aff9ab373946ff243512c52f857b7980d.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT 1 as one FROM users WHERE handle = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "one", 9 + "type_info": "Int4" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + null 19 + ] 20 + }, 21 + "hash": "ed34111a7f41b419a23d16ddd23cbc6aff9ab373946ff243512c52f857b7980d" 22 + }
+23
.sqlx/query-eecc3bc506aafe17d7804b9749dc00bd9fedcb148d2a339bbf7ffba08541e8f6.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT id FROM app_passwords WHERE user_id = $1 AND name = $2", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid", 15 + "Text" 16 + ] 17 + }, 18 + "nullable": [ 19 + false 20 + ] 21 + }, 22 + "hash": "eecc3bc506aafe17d7804b9749dc00bd9fedcb148d2a339bbf7ffba08541e8f6" 23 + }
+14
.sqlx/query-eed03ee02de1828a665bc268ba135511005416b122bccb79374204a8023ace41.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM records WHERE repo_id = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "eed03ee02de1828a665bc268ba135511005416b122bccb79374204a8023ace41" 14 + }
+22
.sqlx/query-ef55a06bcea9b1a0d744df4fe353260ae4d6d93bbf5ea73133db65e38f6241ee.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT k.key_bytes FROM user_keys k JOIN users u ON k.user_id = u.id WHERE u.did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "key_bytes", 9 + "type_info": "Bytea" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "ef55a06bcea9b1a0d744df4fe353260ae4d6d93bbf5ea73133db65e38f6241ee" 22 + }
+15
.sqlx/query-f1d4742aaa1d48f4a944d50743a51b0938cec852d0238347883dc110050e8d3a.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM app_passwords WHERE user_id = $1 AND name = $2", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid", 9 + "Text" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "f1d4742aaa1d48f4a944d50743a51b0938cec852d0238347883dc110050e8d3a" 15 + }
+22
.sqlx/query-f8bee08776a6e246bdee70c0452217e8b654bf8617524edb4add139582b966ac.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT password_hash FROM app_passwords WHERE user_id = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "password_hash", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "f8bee08776a6e246bdee70c0452217e8b654bf8617524edb4add139582b966ac" 22 + }
+28
.sqlx/query-f91a07e40484ade5b4c72addf62e4ad82feab312645c0b7a4ea69c0e55e17b14.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "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", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "key_bytes", 14 + "type_info": "Bytea" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "f91a07e40484ade5b4c72addf62e4ad82feab312645c0b7a4ea69c0e55e17b14" 28 + }
+22
.sqlx/query-fa09feeb85d8648a8ebf339a69114ab6b3c6336642d6907ed4549b601e401f82.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT COUNT(*) FROM records WHERE repo_id = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "count", 9 + "type_info": "Int8" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + null 19 + ] 20 + }, 21 + "hash": "fa09feeb85d8648a8ebf339a69114ab6b3c6336642d6907ed4549b601e401f82" 22 + }
+19
.sqlx/query-fc06fa0ba9ae769e68c7386a9236995fe678a15e63a692b8460d692b242ea3c7.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO reports (id, reason_type, reason, subject_json, reported_by_did, created_at) VALUES ($1, $2, $3, $4, $5, $6)", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Int8", 9 + "Text", 10 + "Text", 11 + "Jsonb", 12 + "Text", 13 + "Timestamptz" 14 + ] 15 + }, 16 + "nullable": [] 17 + }, 18 + "hash": "fc06fa0ba9ae769e68c7386a9236995fe678a15e63a692b8460d692b242ea3c7" 19 + }
+22
.sqlx/query-fd42681b7af9c795643baf65a998a55822ea81a07b651385740401f62bf8a8ae.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT COUNT(*) FROM blobs WHERE created_by_user = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "count", 9 + "type_info": "Int8" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + null 19 + ] 20 + }, 21 + "hash": "fd42681b7af9c795643baf65a998a55822ea81a07b651385740401f62bf8a8ae" 22 + }
+37
.sqlx/query-ff7899984ea138f1e608fa862def47402369a428ac9116c653890e5fcaa0015b.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT collection, rkey, record_cid FROM records WHERE repo_id = $1 AND (collection, rkey) > ($2, $3) ORDER BY collection, rkey LIMIT $4", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "collection", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "rkey", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "record_cid", 19 + "type_info": "Text" 20 + } 21 + ], 22 + "parameters": { 23 + "Left": [ 24 + "Uuid", 25 + "Text", 26 + "Text", 27 + "Int8" 28 + ] 29 + }, 30 + "nullable": [ 31 + false, 32 + false, 33 + false 34 + ] 35 + }, 36 + "hash": "ff7899984ea138f1e608fa862def47402369a428ac9116c653890e5fcaa0015b" 37 + }
+25 -51
src/api/admin/mod.rs
··· 7 7 }; 8 8 use serde::{Deserialize, Serialize}; 9 9 use serde_json::json; 10 - use sqlx::Row; 11 10 use tracing::error; 12 11 13 12 #[derive(Deserialize)] ··· 57 56 .into_response(); 58 57 } 59 58 60 - let result = sqlx::query( 59 + let result = sqlx::query!( 61 60 r#" 62 61 SELECT did, handle, email, created_at 63 62 FROM users 64 63 WHERE did = $1 65 64 "#, 65 + did 66 66 ) 67 - .bind(did) 68 67 .fetch_optional(&state.db) 69 68 .await; 70 69 71 70 match result { 72 71 Ok(Some(row)) => { 73 - let user_did: String = row.get("did"); 74 - let handle: String = row.get("handle"); 75 - let email: String = row.get("email"); 76 - let created_at: chrono::DateTime<chrono::Utc> = row.get("created_at"); 77 - 78 72 ( 79 73 StatusCode::OK, 80 74 Json(AccountInfo { 81 - did: user_did, 82 - handle, 83 - email: Some(email), 84 - indexed_at: created_at.to_rfc3339(), 75 + did: row.did, 76 + handle: row.handle, 77 + email: Some(row.email), 78 + indexed_at: row.created_at.to_rfc3339(), 85 79 invite_note: None, 86 80 invites_disabled: false, 87 81 email_confirmed_at: None, ··· 141 135 continue; 142 136 } 143 137 144 - let result = sqlx::query( 138 + let result = sqlx::query!( 145 139 r#" 146 140 SELECT did, handle, email, created_at 147 141 FROM users 148 142 WHERE did = $1 149 143 "#, 144 + did 150 145 ) 151 - .bind(did) 152 146 .fetch_optional(&state.db) 153 147 .await; 154 148 155 149 if let Ok(Some(row)) = result { 156 - let user_did: String = row.get("did"); 157 - let handle: String = row.get("handle"); 158 - let email: String = row.get("email"); 159 - let created_at: chrono::DateTime<chrono::Utc> = row.get("created_at"); 160 - 161 150 infos.push(AccountInfo { 162 - did: user_did, 163 - handle, 164 - email: Some(email), 165 - indexed_at: created_at.to_rfc3339(), 151 + did: row.did, 152 + handle: row.handle, 153 + email: Some(row.email), 154 + indexed_at: row.created_at.to_rfc3339(), 166 155 invite_note: None, 167 156 invites_disabled: false, 168 157 email_confirmed_at: None, ··· 202 191 .into_response(); 203 192 } 204 193 205 - let user = sqlx::query("SELECT id FROM users WHERE did = $1") 206 - .bind(did) 194 + let user = sqlx::query!("SELECT id FROM users WHERE did = $1", did) 207 195 .fetch_optional(&state.db) 208 196 .await; 209 197 210 - let user_id: uuid::Uuid = match user { 211 - Ok(Some(row)) => row.get("id"), 198 + let user_id = match user { 199 + Ok(Some(row)) => row.id, 212 200 Ok(None) => { 213 201 return ( 214 202 StatusCode::NOT_FOUND, ··· 226 214 } 227 215 }; 228 216 229 - let _ = sqlx::query("DELETE FROM sessions WHERE did = $1") 230 - .bind(did) 217 + let _ = sqlx::query!("DELETE FROM sessions WHERE did = $1", did) 231 218 .execute(&state.db) 232 219 .await; 233 220 234 - let _ = sqlx::query("DELETE FROM records WHERE repo_id = $1") 235 - .bind(user_id) 221 + let _ = sqlx::query!("DELETE FROM records WHERE repo_id = $1", user_id) 236 222 .execute(&state.db) 237 223 .await; 238 224 239 - let _ = sqlx::query("DELETE FROM repos WHERE user_id = $1") 240 - .bind(user_id) 225 + let _ = sqlx::query!("DELETE FROM repos WHERE user_id = $1", user_id) 241 226 .execute(&state.db) 242 227 .await; 243 228 244 - let _ = sqlx::query("DELETE FROM blobs WHERE created_by_user = $1") 245 - .bind(user_id) 229 + let _ = sqlx::query!("DELETE FROM blobs WHERE created_by_user = $1", user_id) 246 230 .execute(&state.db) 247 231 .await; 248 232 249 - let _ = sqlx::query("DELETE FROM user_keys WHERE user_id = $1") 250 - .bind(user_id) 233 + let _ = sqlx::query!("DELETE FROM user_keys WHERE user_id = $1", user_id) 251 234 .execute(&state.db) 252 235 .await; 253 236 254 - let result = sqlx::query("DELETE FROM users WHERE id = $1") 255 - .bind(user_id) 237 + let result = sqlx::query!("DELETE FROM users WHERE id = $1", user_id) 256 238 .execute(&state.db) 257 239 .await; 258 240 ··· 300 282 .into_response(); 301 283 } 302 284 303 - let result = sqlx::query("UPDATE users SET email = $1 WHERE did = $2") 304 - .bind(email) 305 - .bind(account) 285 + let result = sqlx::query!("UPDATE users SET email = $1 WHERE did = $2", email, account) 306 286 .execute(&state.db) 307 287 .await; 308 288 ··· 370 350 .into_response(); 371 351 } 372 352 373 - let existing = sqlx::query("SELECT id FROM users WHERE handle = $1 AND did != $2") 374 - .bind(handle) 375 - .bind(did) 353 + let existing = sqlx::query!("SELECT id FROM users WHERE handle = $1 AND did != $2", handle, did) 376 354 .fetch_optional(&state.db) 377 355 .await; 378 356 ··· 384 362 .into_response(); 385 363 } 386 364 387 - let result = sqlx::query("UPDATE users SET handle = $1 WHERE did = $2") 388 - .bind(handle) 389 - .bind(did) 365 + let result = sqlx::query!("UPDATE users SET handle = $1 WHERE did = $2", handle, did) 390 366 .execute(&state.db) 391 367 .await; 392 368 ··· 455 431 } 456 432 }; 457 433 458 - let result = sqlx::query("UPDATE users SET password_hash = $1 WHERE did = $2") 459 - .bind(&password_hash) 460 - .bind(did) 434 + let result = sqlx::query!("UPDATE users SET password_hash = $1 WHERE did = $2", password_hash, did) 461 435 .execute(&state.db) 462 436 .await; 463 437
+11 -15
src/api/feed/timeline.rs
··· 59 59 .unwrap_or("") 60 60 .replace("Bearer ", ""); 61 61 62 - let session = sqlx::query( 63 - "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" 62 + let session = sqlx::query!( 63 + "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", 64 + token 64 65 ) 65 - .bind(&token) 66 66 .fetch_optional(&state.db) 67 67 .await 68 68 .unwrap_or(None); 69 69 70 70 let (did, key_bytes) = match session { 71 - Some(row) => ( 72 - row.get::<String, _>("did"), 73 - row.get::<Vec<u8>, _>("key_bytes"), 74 - ), 71 + Some(row) => (row.did, row.key_bytes), 75 72 None => { 76 73 return ( 77 74 StatusCode::UNAUTHORIZED, ··· 89 86 .into_response(); 90 87 } 91 88 92 - let user_query = sqlx::query("SELECT id FROM users WHERE did = $1") 93 - .bind(&did) 89 + let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did) 94 90 .fetch_optional(&state.db) 95 91 .await; 96 92 97 - let user_id: uuid::Uuid = match user_query { 98 - Ok(Some(row)) => row.get("id"), 93 + let user_id = match user_query { 94 + Ok(Some(row)) => row.id, 99 95 _ => { 100 96 return ( 101 97 StatusCode::INTERNAL_SERVER_ERROR, ··· 105 101 } 106 102 }; 107 103 108 - let follows_query = sqlx::query( 109 - "SELECT record_cid FROM records WHERE repo_id = $1 AND collection = 'app.bsky.graph.follow'" 104 + let follows_query = sqlx::query!( 105 + "SELECT record_cid FROM records WHERE repo_id = $1 AND collection = 'app.bsky.graph.follow'", 106 + user_id 110 107 ) 111 - .bind(user_id) 112 108 .fetch_all(&state.db) 113 109 .await; 114 110 115 111 let follow_cids: Vec<String> = match follows_query { 116 - Ok(rows) => rows.iter().map(|r| r.get("record_cid")).collect(), 112 + Ok(rows) => rows.iter().map(|r| r.record_cid.clone()).collect(), 117 113 Err(e) => { 118 114 error!("Failed to get follows: {:?}", e); 119 115 return (
+19 -29
src/api/identity/account.rs
··· 13 13 use rand::rngs::OsRng; 14 14 use serde::{Deserialize, Serialize}; 15 15 use serde_json::json; 16 - use sqlx::Row; 17 16 use std::sync::Arc; 18 17 use tracing::{error, info}; 19 18 ··· 82 81 } 83 82 }; 84 83 85 - let exists_query = sqlx::query("SELECT 1 FROM users WHERE handle = $1") 86 - .bind(&input.handle) 84 + let exists_query = sqlx::query!("SELECT 1 as one FROM users WHERE handle = $1", input.handle) 87 85 .fetch_optional(&mut *tx) 88 86 .await; 89 87 ··· 108 106 109 107 if let Some(code) = &input.invite_code { 110 108 let invite_query = 111 - sqlx::query("SELECT available_uses FROM invite_codes WHERE code = $1 FOR UPDATE") 112 - .bind(code) 109 + sqlx::query!("SELECT available_uses FROM invite_codes WHERE code = $1 FOR UPDATE", code) 113 110 .fetch_optional(&mut *tx) 114 111 .await; 115 112 116 113 match invite_query { 117 114 Ok(Some(row)) => { 118 - let uses: i32 = row.get("available_uses"); 119 - if uses <= 0 { 115 + if row.available_uses <= 0 { 120 116 return (StatusCode::BAD_REQUEST, Json(json!({"error": "InvalidInviteCode", "message": "Invite code exhausted"}))).into_response(); 121 117 } 122 118 123 - let update_invite = sqlx::query( 119 + let update_invite = sqlx::query!( 124 120 "UPDATE invite_codes SET available_uses = available_uses - 1 WHERE code = $1", 121 + code 125 122 ) 126 - .bind(code) 127 123 .execute(&mut *tx) 128 124 .await; 129 125 ··· 166 162 } 167 163 }; 168 164 169 - let user_insert = sqlx::query("INSERT INTO users (handle, email, did, password_hash) VALUES ($1, $2, $3, $4) RETURNING id") 170 - .bind(&input.handle) 171 - .bind(&input.email) 172 - .bind(&did) 173 - .bind(&password_hash) 165 + let user_insert = sqlx::query!( 166 + "INSERT INTO users (handle, email, did, password_hash) VALUES ($1, $2, $3, $4) RETURNING id", 167 + input.handle, 168 + input.email, 169 + did, 170 + password_hash 171 + ) 174 172 .fetch_one(&mut *tx) 175 173 .await; 176 174 177 - let user_id: uuid::Uuid = match user_insert { 178 - Ok(row) => row.get("id"), 175 + let user_id = match user_insert { 176 + Ok(row) => row.id, 179 177 Err(e) => { 180 178 error!("Error inserting user: {:?}", e); 181 179 // TODO: Check for unique constraint violation on email/did specifically ··· 190 188 let secret_key = SecretKey::random(&mut OsRng); 191 189 let secret_key_bytes = secret_key.to_bytes(); 192 190 193 - let key_insert = sqlx::query("INSERT INTO user_keys (user_id, key_bytes) VALUES ($1, $2)") 194 - .bind(user_id) 195 - .bind(&secret_key_bytes[..]) 191 + let key_insert = sqlx::query!("INSERT INTO user_keys (user_id, key_bytes) VALUES ($1, $2)", user_id, &secret_key_bytes[..]) 196 192 .execute(&mut *tx) 197 193 .await; 198 194 ··· 257 253 } 258 254 }; 259 255 260 - let repo_insert = sqlx::query("INSERT INTO repos (user_id, repo_root_cid) VALUES ($1, $2)") 261 - .bind(user_id) 262 - .bind(commit_cid.to_string()) 256 + let commit_cid_str = commit_cid.to_string(); 257 + let repo_insert = sqlx::query!("INSERT INTO repos (user_id, repo_root_cid) VALUES ($1, $2)", user_id, commit_cid_str) 263 258 .execute(&mut *tx) 264 259 .await; 265 260 ··· 274 269 275 270 if let Some(code) = &input.invite_code { 276 271 let use_insert = 277 - sqlx::query("INSERT INTO invite_code_uses (code, used_by_user) VALUES ($1, $2)") 278 - .bind(code) 279 - .bind(user_id) 272 + sqlx::query!("INSERT INTO invite_code_uses (code, used_by_user) VALUES ($1, $2)", code, user_id) 280 273 .execute(&mut *tx) 281 274 .await; 282 275 ··· 317 310 }; 318 311 319 312 let session_insert = 320 - sqlx::query("INSERT INTO sessions (access_jwt, refresh_jwt, did) VALUES ($1, $2, $3)") 321 - .bind(&access_jwt) 322 - .bind(&refresh_jwt) 323 - .bind(&did) 313 + sqlx::query!("INSERT INTO sessions (access_jwt, refresh_jwt, did) VALUES ($1, $2, $3)", access_jwt, refresh_jwt, did) 324 314 .execute(&mut *tx) 325 315 .await; 326 316
+14 -35
src/api/identity/did.rs
··· 11 11 use reqwest; 12 12 use serde::Deserialize; 13 13 use serde_json::json; 14 - use sqlx::Row; 15 14 use tracing::error; 16 15 17 16 #[derive(Deserialize)] ··· 33 32 .into_response(); 34 33 } 35 34 36 - let user = sqlx::query("SELECT did FROM users WHERE handle = $1") 37 - .bind(handle) 35 + let user = sqlx::query!("SELECT did FROM users WHERE handle = $1", handle) 38 36 .fetch_optional(&state.db) 39 37 .await; 40 38 41 39 match user { 42 40 Ok(Some(row)) => { 43 - let did: String = row.get("did"); 44 - (StatusCode::OK, Json(json!({ "did": did }))).into_response() 41 + (StatusCode::OK, Json(json!({ "did": row.did }))).into_response() 45 42 } 46 43 Ok(None) => ( 47 44 StatusCode::NOT_FOUND, ··· 97 94 pub async fn user_did_doc(State(state): State<AppState>, Path(handle): Path<String>) -> Response { 98 95 let hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string()); 99 96 100 - let user = sqlx::query("SELECT id, did FROM users WHERE handle = $1") 101 - .bind(&handle) 97 + let user = sqlx::query!("SELECT id, did FROM users WHERE handle = $1", handle) 102 98 .fetch_optional(&state.db) 103 99 .await; 104 100 105 101 let (user_id, did) = match user { 106 - Ok(Some(row)) => { 107 - let id: uuid::Uuid = row.get("id"); 108 - let d: String = row.get("did"); 109 - (id, d) 110 - } 102 + Ok(Some(row)) => (row.id, row.did), 111 103 Ok(None) => { 112 104 return (StatusCode::NOT_FOUND, Json(json!({"error": "NotFound"}))).into_response(); 113 105 } ··· 129 121 .into_response(); 130 122 } 131 123 132 - let key_row = sqlx::query("SELECT key_bytes FROM user_keys WHERE user_id = $1") 133 - .bind(user_id) 124 + let key_row = sqlx::query!("SELECT key_bytes FROM user_keys WHERE user_id = $1", user_id) 134 125 .fetch_optional(&state.db) 135 126 .await; 136 127 137 128 let key_bytes: Vec<u8> = match key_row { 138 - Ok(Some(row)) => row.get("key_bytes"), 129 + Ok(Some(row)) => row.key_bytes, 139 130 _ => { 140 131 return ( 141 132 StatusCode::INTERNAL_SERVER_ERROR, ··· 294 285 .unwrap_or("") 295 286 .replace("Bearer ", ""); 296 287 297 - let session = sqlx::query( 288 + let session = sqlx::query!( 298 289 r#" 299 290 SELECT s.did, k.key_bytes, u.handle 300 291 FROM sessions s ··· 302 293 JOIN user_keys k ON u.id = k.user_id 303 294 WHERE s.access_jwt = $1 304 295 "#, 296 + token 305 297 ) 306 - .bind(&token) 307 298 .fetch_optional(&state.db) 308 299 .await; 309 300 310 301 let (_did, key_bytes, handle) = match session { 311 - Ok(Some(row)) => ( 312 - row.get::<String, _>("did"), 313 - row.get::<Vec<u8>, _>("key_bytes"), 314 - row.get::<String, _>("handle"), 315 - ), 302 + Ok(Some(row)) => (row.did, row.key_bytes, row.handle), 316 303 Ok(None) => { 317 304 return ( 318 305 StatusCode::UNAUTHORIZED, ··· 404 391 .unwrap_or("") 405 392 .replace("Bearer ", ""); 406 393 407 - let session = sqlx::query( 394 + let session = sqlx::query!( 408 395 r#" 409 396 SELECT s.did, k.key_bytes, u.id as user_id 410 397 FROM sessions s ··· 412 399 JOIN user_keys k ON u.id = k.user_id 413 400 WHERE s.access_jwt = $1 414 401 "#, 402 + token 415 403 ) 416 - .bind(&token) 417 404 .fetch_optional(&state.db) 418 405 .await; 419 406 420 407 let (_did, key_bytes, user_id) = match session { 421 - Ok(Some(row)) => ( 422 - row.get::<String, _>("did"), 423 - row.get::<Vec<u8>, _>("key_bytes"), 424 - row.get::<uuid::Uuid, _>("user_id"), 425 - ), 408 + Ok(Some(row)) => (row.did, row.key_bytes, row.user_id), 426 409 Ok(None) => { 427 410 return ( 428 411 StatusCode::UNAUTHORIZED, ··· 468 451 .into_response(); 469 452 } 470 453 471 - let existing = sqlx::query("SELECT id FROM users WHERE handle = $1 AND id != $2") 472 - .bind(new_handle) 473 - .bind(user_id) 454 + let existing = sqlx::query!("SELECT id FROM users WHERE handle = $1 AND id != $2", new_handle, user_id) 474 455 .fetch_optional(&state.db) 475 456 .await; 476 457 ··· 482 463 .into_response(); 483 464 } 484 465 485 - let result = sqlx::query("UPDATE users SET handle = $1 WHERE id = $2") 486 - .bind(new_handle) 487 - .bind(user_id) 466 + let result = sqlx::query!("UPDATE users SET handle = $1 WHERE id = $2", new_handle, user_id) 488 467 .execute(&state.db) 489 468 .await; 490 469
+12 -15
src/api/moderation/mod.rs
··· 7 7 }; 8 8 use serde::{Deserialize, Serialize}; 9 9 use serde_json::{Value, json}; 10 - use sqlx::Row; 11 10 use tracing::error; 12 11 13 12 #[derive(Deserialize)] ··· 49 48 .unwrap_or("") 50 49 .replace("Bearer ", ""); 51 50 52 - let session = sqlx::query( 51 + let session = sqlx::query!( 53 52 r#" 54 53 SELECT s.did, k.key_bytes 55 54 FROM sessions s ··· 57 56 JOIN user_keys k ON u.id = k.user_id 58 57 WHERE s.access_jwt = $1 59 58 "#, 59 + token 60 60 ) 61 - .bind(&token) 62 61 .fetch_optional(&state.db) 63 62 .await; 64 63 65 64 let (did, key_bytes) = match session { 66 - Ok(Some(row)) => ( 67 - row.get::<String, _>("did"), 68 - row.get::<Vec<u8>, _>("key_bytes"), 69 - ), 65 + Ok(Some(row)) => (row.did, row.key_bytes), 70 66 Ok(None) => { 71 67 return ( 72 68 StatusCode::UNAUTHORIZED, ··· 113 109 let created_at = chrono::Utc::now(); 114 110 let report_id = created_at.timestamp_millis(); 115 111 116 - let insert = sqlx::query( 117 - "INSERT INTO reports (id, reason_type, reason, subject_json, reported_by_did, created_at) VALUES ($1, $2, $3, $4, $5, $6)" 112 + let subject_json = json!(input.subject); 113 + let insert = sqlx::query!( 114 + "INSERT INTO reports (id, reason_type, reason, subject_json, reported_by_did, created_at) VALUES ($1, $2, $3, $4, $5, $6)", 115 + report_id, 116 + input.reason_type, 117 + input.reason, 118 + subject_json, 119 + did, 120 + created_at 118 121 ) 119 - .bind(report_id) 120 - .bind(&input.reason_type) 121 - .bind(&input.reason) 122 - .bind(json!(input.subject)) 123 - .bind(&did) 124 - .bind(created_at) 125 122 .execute(&state.db) 126 123 .await; 127 124
+2 -5
src/api/proxy.rs
··· 6 6 response::{IntoResponse, Response}, 7 7 }; 8 8 use reqwest::Client; 9 - use sqlx::Row; 10 9 use std::collections::HashMap; 11 10 use tracing::{error, info}; 12 11 ··· 48 47 if let Ok(token) = auth_val.to_str() { 49 48 let token = token.replace("Bearer ", ""); 50 49 if let Ok(did) = crate::auth::get_did_from_token(&token) { 51 - 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") 52 - .bind(&did) 50 + 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) 53 51 .fetch_optional(&state.db) 54 52 .await; 55 53 56 54 if let Ok(Some(row)) = key_row { 57 - let key_bytes: Vec<u8> = row.get("key_bytes"); 58 55 if let Ok(new_token) = 59 - crate::auth::create_service_token(&did, aud, &method, &key_bytes) 56 + crate::auth::create_service_token(&did, aud, &method, &row.key_bytes) 60 57 { 61 58 if let Ok(val) = 62 59 axum::http::HeaderValue::from_str(&format!("Bearer {}", new_token))
+31 -42
src/api/repo/blob.rs
··· 12 12 use serde::{Deserialize, Serialize}; 13 13 use serde_json::json; 14 14 use sha2::{Digest, Sha256}; 15 - use sqlx::Row; 16 15 use std::str::FromStr; 17 16 use tracing::error; 18 17 ··· 35 34 .unwrap_or("") 36 35 .replace("Bearer ", ""); 37 36 38 - let session = sqlx::query( 39 - "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" 37 + let session = sqlx::query!( 38 + "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", 39 + token 40 40 ) 41 - .bind(&token) 42 41 .fetch_optional(&state.db) 43 42 .await 44 43 .unwrap_or(None); 45 44 46 45 let (did, key_bytes) = match session { 47 - Some(row) => ( 48 - row.get::<String, _>("did"), 49 - row.get::<Vec<u8>, _>("key_bytes"), 50 - ), 46 + Some(row) => (row.did, row.key_bytes), 51 47 None => { 52 48 return ( 53 49 StatusCode::UNAUTHORIZED, ··· 92 88 .into_response(); 93 89 } 94 90 95 - let user_query = sqlx::query("SELECT id FROM users WHERE did = $1") 96 - .bind(&did) 91 + let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did) 97 92 .fetch_optional(&state.db) 98 93 .await; 99 94 100 - let user_id: uuid::Uuid = match user_query { 101 - Ok(Some(row)) => row.get("id"), 95 + let user_id = match user_query { 96 + Ok(Some(row)) => row.id, 102 97 _ => { 103 98 return ( 104 99 StatusCode::INTERNAL_SERVER_ERROR, ··· 108 103 } 109 104 }; 110 105 111 - let insert = sqlx::query( 112 - "INSERT INTO blobs (cid, mime_type, size_bytes, created_by_user, storage_key) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (cid) DO NOTHING" 106 + let insert = sqlx::query!( 107 + "INSERT INTO blobs (cid, mime_type, size_bytes, created_by_user, storage_key) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (cid) DO NOTHING", 108 + cid_str, 109 + mime_type, 110 + size, 111 + user_id, 112 + storage_key 113 113 ) 114 - .bind(&cid_str) 115 - .bind(&mime_type) 116 - .bind(size) 117 - .bind(user_id) 118 - .bind(&storage_key) 119 114 .execute(&state.db) 120 115 .await; 121 116 ··· 202 197 .unwrap_or("") 203 198 .replace("Bearer ", ""); 204 199 205 - let session = sqlx::query( 206 - "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" 200 + let session = sqlx::query!( 201 + "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", 202 + token 207 203 ) 208 - .bind(&token) 209 204 .fetch_optional(&state.db) 210 205 .await 211 206 .unwrap_or(None); 212 207 213 208 let (did, key_bytes) = match session { 214 - Some(row) => ( 215 - row.get::<String, _>("did"), 216 - row.get::<Vec<u8>, _>("key_bytes"), 217 - ), 209 + Some(row) => (row.did, row.key_bytes), 218 210 None => { 219 211 return ( 220 212 StatusCode::UNAUTHORIZED, ··· 232 224 .into_response(); 233 225 } 234 226 235 - let user_query = sqlx::query("SELECT id FROM users WHERE did = $1") 236 - .bind(&did) 227 + let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did) 237 228 .fetch_optional(&state.db) 238 229 .await; 239 230 240 - let user_id: uuid::Uuid = match user_query { 241 - Ok(Some(row)) => row.get("id"), 231 + let user_id = match user_query { 232 + Ok(Some(row)) => row.id, 242 233 _ => { 243 234 return ( 244 235 StatusCode::INTERNAL_SERVER_ERROR, ··· 257 248 (String::new(), String::new()) 258 249 }; 259 250 260 - let records_query = sqlx::query( 261 - "SELECT collection, rkey, record_cid FROM records WHERE repo_id = $1 AND (collection, rkey) > ($2, $3) ORDER BY collection, rkey LIMIT $4" 251 + let records_query = sqlx::query!( 252 + "SELECT collection, rkey, record_cid FROM records WHERE repo_id = $1 AND (collection, rkey) > ($2, $3) ORDER BY collection, rkey LIMIT $4", 253 + user_id, 254 + cursor_collection, 255 + cursor_rkey, 256 + limit 262 257 ) 263 - .bind(user_id) 264 - .bind(cursor_collection) 265 - .bind(cursor_rkey) 266 - .bind(limit) 267 258 .fetch_all(&state.db) 268 259 .await; 269 260 ··· 283 274 let mut last_cursor = None; 284 275 285 276 for row in &records { 286 - let collection: String = row.get("collection"); 287 - let rkey: String = row.get("rkey"); 288 - let record_cid_str: String = row.get("record_cid"); 277 + let collection = &row.collection; 278 + let rkey = &row.rkey; 279 + let record_cid_str = &row.record_cid; 289 280 290 281 last_cursor = Some(format!("{}|{}", collection, rkey)); 291 282 ··· 308 299 find_blobs(&record_val, &mut blobs); 309 300 310 301 for blob_cid_str in blobs { 311 - let exists = sqlx::query("SELECT 1 FROM blobs WHERE cid = $1 AND created_by_user = $2") 312 - .bind(&blob_cid_str) 313 - .bind(user_id) 302 + let exists = sqlx::query!("SELECT 1 as one FROM blobs WHERE cid = $1 AND created_by_user = $2", blob_cid_str, user_id) 314 303 .fetch_optional(&state.db) 315 304 .await; 316 305
+1 -1
src/api/server/meta.rs
··· 15 15 } 16 16 17 17 pub async fn health(State(state): State<AppState>) -> impl IntoResponse { 18 - match sqlx::query("SELECT 1").execute(&state.db).await { 18 + match sqlx::query!("SELECT 1 as one").fetch_one(&state.db).await { 19 19 Ok(_) => (StatusCode::OK, "OK"), 20 20 Err(e) => { 21 21 error!("Health check failed: {:?}", e);
+81 -127
src/api/server/session.rs
··· 8 8 use bcrypt::verify; 9 9 use serde::{Deserialize, Serialize}; 10 10 use serde_json::json; 11 - use sqlx::Row; 12 11 use tracing::{error, info, warn}; 13 12 14 13 #[derive(Deserialize)] ··· 43 42 .unwrap_or("") 44 43 .replace("Bearer ", ""); 45 44 46 - let session = sqlx::query( 45 + let session = sqlx::query!( 47 46 r#" 48 47 SELECT s.did, k.key_bytes 49 48 FROM sessions s ··· 51 50 JOIN user_keys k ON u.id = k.user_id 52 51 WHERE s.access_jwt = $1 53 52 "#, 53 + token 54 54 ) 55 - .bind(&token) 56 55 .fetch_optional(&state.db) 57 56 .await; 58 57 59 58 let (did, key_bytes) = match session { 60 - Ok(Some(row)) => ( 61 - row.get::<String, _>("did"), 62 - row.get::<Vec<u8>, _>("key_bytes"), 63 - ), 59 + Ok(Some(row)) => (row.did, row.key_bytes), 64 60 Ok(None) => { 65 61 return ( 66 62 StatusCode::UNAUTHORIZED, ··· 125 121 ) -> Response { 126 122 info!("create_session: identifier='{}'", input.identifier); 127 123 128 - let user_row = sqlx::query("SELECT u.id, u.did, u.handle, u.password_hash, k.key_bytes FROM users u JOIN user_keys k ON u.id = k.user_id WHERE u.handle = $1 OR u.email = $1") 129 - .bind(&input.identifier) 124 + let user_row = sqlx::query!( 125 + "SELECT u.id, u.did, u.handle, u.password_hash, k.key_bytes FROM users u JOIN user_keys k ON u.id = k.user_id WHERE u.handle = $1 OR u.email = $1", 126 + input.identifier 127 + ) 130 128 .fetch_optional(&state.db) 131 129 .await; 132 130 133 131 match user_row { 134 132 Ok(Some(row)) => { 135 - let user_id: uuid::Uuid = row.get("id"); 136 - let stored_hash: String = row.get("password_hash"); 137 - let did: String = row.get("did"); 138 - let handle: String = row.get("handle"); 139 - let key_bytes: Vec<u8> = row.get("key_bytes"); 133 + let user_id = row.id; 134 + let stored_hash = &row.password_hash; 135 + let did = &row.did; 136 + let handle = &row.handle; 137 + let key_bytes = &row.key_bytes; 140 138 141 - let password_valid = if verify(&input.password, &stored_hash).unwrap_or(false) { 139 + let password_valid = if verify(&input.password, stored_hash).unwrap_or(false) { 142 140 true 143 141 } else { 144 - let app_pass_rows = sqlx::query("SELECT password_hash FROM app_passwords WHERE user_id = $1") 145 - .bind(user_id) 142 + let app_pass_rows = sqlx::query!("SELECT password_hash FROM app_passwords WHERE user_id = $1", user_id) 146 143 .fetch_all(&state.db) 147 144 .await 148 145 .unwrap_or_default(); 149 146 150 147 app_pass_rows.iter().any(|row| { 151 - let hash: String = row.get("password_hash"); 152 - verify(&input.password, &hash).unwrap_or(false) 148 + verify(&input.password, &row.password_hash).unwrap_or(false) 153 149 }) 154 150 }; 155 151 ··· 178 174 } 179 175 }; 180 176 181 - let session_insert = sqlx::query( 177 + let session_insert = sqlx::query!( 182 178 "INSERT INTO sessions (access_jwt, refresh_jwt, did) VALUES ($1, $2, $3)", 179 + access_jwt, 180 + refresh_jwt, 181 + did 183 182 ) 184 - .bind(&access_jwt) 185 - .bind(&refresh_jwt) 186 - .bind(&did) 187 183 .execute(&state.db) 188 184 .await; 189 185 ··· 194 190 Json(CreateSessionOutput { 195 191 access_jwt, 196 192 refresh_jwt, 197 - handle, 198 - did, 193 + handle: handle.clone(), 194 + did: did.clone(), 199 195 }), 200 196 ) 201 197 .into_response(); ··· 255 251 .unwrap_or("") 256 252 .replace("Bearer ", ""); 257 253 258 - let result = sqlx::query( 254 + let result = sqlx::query!( 259 255 r#" 260 256 SELECT u.handle, u.did, u.email, k.key_bytes 261 257 FROM sessions s ··· 263 259 JOIN user_keys k ON u.id = k.user_id 264 260 WHERE s.access_jwt = $1 265 261 "#, 262 + token 266 263 ) 267 - .bind(&token) 268 264 .fetch_optional(&state.db) 269 265 .await; 270 266 271 267 match result { 272 268 Ok(Some(row)) => { 273 - let handle: String = row.get("handle"); 274 - let did: String = row.get("did"); 275 - let email: String = row.get("email"); 276 - let key_bytes: Vec<u8> = row.get("key_bytes"); 277 - 278 - if let Err(_) = crate::auth::verify_token(&token, &key_bytes) { 269 + if let Err(_) = crate::auth::verify_token(&token, &row.key_bytes) { 279 270 return (StatusCode::UNAUTHORIZED, Json(json!({"error": "AuthenticationFailed", "message": "Invalid token signature"}))).into_response(); 280 271 } 281 272 282 273 return ( 283 274 StatusCode::OK, 284 275 Json(json!({ 285 - "handle": handle, 286 - "did": did, 287 - "email": email, 276 + "handle": row.handle, 277 + "did": row.did, 278 + "email": row.email, 288 279 "didDoc": {} 289 280 })), 290 281 ) ··· 327 318 .unwrap_or("") 328 319 .replace("Bearer ", ""); 329 320 330 - let result = sqlx::query("DELETE FROM sessions WHERE access_jwt = $1") 331 - .bind(token) 321 + let result = sqlx::query!("DELETE FROM sessions WHERE access_jwt = $1", token) 332 322 .execute(&state.db) 333 323 .await; 334 324 ··· 369 359 .unwrap_or("") 370 360 .replace("Bearer ", ""); 371 361 372 - let session = sqlx::query( 373 - "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.refresh_jwt = $1" 362 + let session = sqlx::query!( 363 + "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.refresh_jwt = $1", 364 + refresh_token 374 365 ) 375 - .bind(&refresh_token) 376 366 .fetch_optional(&state.db) 377 367 .await; 378 368 379 369 match session { 380 370 Ok(Some(session_row)) => { 381 - let did: String = session_row.get("did"); 382 - let key_bytes: Vec<u8> = session_row.get("key_bytes"); 371 + let did = &session_row.did; 372 + let key_bytes = &session_row.key_bytes; 383 373 384 374 if let Err(_) = crate::auth::verify_token(&refresh_token, &key_bytes) { 385 375 return (StatusCode::UNAUTHORIZED, Json(json!({"error": "AuthenticationFailed", "message": "Invalid refresh token signature"}))).into_response(); ··· 408 398 } 409 399 }; 410 400 411 - let update = sqlx::query( 401 + let update = sqlx::query!( 412 402 "UPDATE sessions SET access_jwt = $1, refresh_jwt = $2 WHERE refresh_jwt = $3", 403 + new_access_jwt, 404 + new_refresh_jwt, 405 + refresh_token 413 406 ) 414 - .bind(&new_access_jwt) 415 - .bind(&new_refresh_jwt) 416 - .bind(&refresh_token) 417 407 .execute(&state.db) 418 408 .await; 419 409 420 410 match update { 421 411 Ok(_) => { 422 - let user = sqlx::query("SELECT handle FROM users WHERE did = $1") 423 - .bind(&did) 412 + let user = sqlx::query!("SELECT handle FROM users WHERE did = $1", did) 424 413 .fetch_optional(&state.db) 425 414 .await; 426 415 427 416 match user { 428 417 Ok(Some(u)) => { 429 - let handle: String = u.get("handle"); 430 418 return ( 431 419 StatusCode::OK, 432 420 Json(json!({ 433 421 "accessJwt": new_access_jwt, 434 422 "refreshJwt": new_refresh_jwt, 435 - "handle": handle, 423 + "handle": u.handle, 436 424 "did": did 437 425 })), 438 426 ) ··· 517 505 .unwrap_or("") 518 506 .replace("Bearer ", ""); 519 507 520 - let session = sqlx::query( 508 + let session = sqlx::query!( 521 509 r#" 522 510 SELECT s.did, k.key_bytes, u.id as user_id 523 511 FROM sessions s ··· 525 513 JOIN user_keys k ON u.id = k.user_id 526 514 WHERE s.access_jwt = $1 527 515 "#, 516 + token 528 517 ) 529 - .bind(&token) 530 518 .fetch_optional(&state.db) 531 519 .await; 532 520 533 521 let (did, key_bytes, user_id) = match session { 534 - Ok(Some(row)) => ( 535 - row.get::<String, _>("did"), 536 - row.get::<Vec<u8>, _>("key_bytes"), 537 - row.get::<uuid::Uuid, _>("user_id"), 538 - ), 522 + Ok(Some(row)) => (row.did, row.key_bytes, row.user_id), 539 523 Ok(None) => { 540 524 return ( 541 525 StatusCode::UNAUTHORIZED, ··· 561 545 .into_response(); 562 546 } 563 547 564 - let user_status = sqlx::query("SELECT deactivated_at FROM users WHERE did = $1") 565 - .bind(&did) 548 + let user_status = sqlx::query!("SELECT deactivated_at FROM users WHERE did = $1", did) 566 549 .fetch_optional(&state.db) 567 550 .await; 568 551 569 - let deactivated_at: Option<chrono::DateTime<chrono::Utc>> = match user_status { 570 - Ok(Some(row)) => row.get("deactivated_at"), 552 + let deactivated_at = match user_status { 553 + Ok(Some(row)) => row.deactivated_at, 571 554 _ => None, 572 555 }; 573 556 574 - let repo_result = sqlx::query("SELECT repo_root_cid FROM repos WHERE user_id = $1") 575 - .bind(user_id) 557 + let repo_result = sqlx::query!("SELECT repo_root_cid FROM repos WHERE user_id = $1", user_id) 576 558 .fetch_optional(&state.db) 577 559 .await; 578 560 579 561 let repo_commit = match repo_result { 580 - Ok(Some(row)) => row.get::<String, _>("repo_root_cid"), 562 + Ok(Some(row)) => row.repo_root_cid, 581 563 _ => String::new(), 582 564 }; 583 565 584 - let record_count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM records WHERE repo_id = $1") 585 - .bind(user_id) 566 + let record_count: i64 = sqlx::query_scalar!("SELECT COUNT(*) FROM records WHERE repo_id = $1", user_id) 586 567 .fetch_one(&state.db) 587 568 .await 569 + .unwrap_or(Some(0)) 588 570 .unwrap_or(0); 589 571 590 572 let blob_count: i64 = 591 - sqlx::query_scalar("SELECT COUNT(*) FROM blobs WHERE created_by_user = $1") 592 - .bind(user_id) 573 + sqlx::query_scalar!("SELECT COUNT(*) FROM blobs WHERE created_by_user = $1", user_id) 593 574 .fetch_one(&state.db) 594 575 .await 576 + .unwrap_or(Some(0)) 595 577 .unwrap_or(0); 596 578 597 579 let valid_did = did.starts_with("did:"); ··· 632 614 .unwrap_or("") 633 615 .replace("Bearer ", ""); 634 616 635 - let session = sqlx::query( 617 + let session = sqlx::query!( 636 618 r#" 637 619 SELECT s.did, k.key_bytes 638 620 FROM sessions s ··· 640 622 JOIN user_keys k ON u.id = k.user_id 641 623 WHERE s.access_jwt = $1 642 624 "#, 625 + token 643 626 ) 644 - .bind(&token) 645 627 .fetch_optional(&state.db) 646 628 .await; 647 629 648 630 let (did, key_bytes) = match session { 649 - Ok(Some(row)) => ( 650 - row.get::<String, _>("did"), 651 - row.get::<Vec<u8>, _>("key_bytes"), 652 - ), 631 + Ok(Some(row)) => (row.did, row.key_bytes), 653 632 Ok(None) => { 654 633 return ( 655 634 StatusCode::UNAUTHORIZED, ··· 675 654 .into_response(); 676 655 } 677 656 678 - let result = sqlx::query("UPDATE users SET deactivated_at = NULL WHERE did = $1") 679 - .bind(&did) 657 + let result = sqlx::query!("UPDATE users SET deactivated_at = NULL WHERE did = $1", did) 680 658 .execute(&state.db) 681 659 .await; 682 660 ··· 719 697 .unwrap_or("") 720 698 .replace("Bearer ", ""); 721 699 722 - let session = sqlx::query( 700 + let session = sqlx::query!( 723 701 r#" 724 702 SELECT s.did, k.key_bytes 725 703 FROM sessions s ··· 727 705 JOIN user_keys k ON u.id = k.user_id 728 706 WHERE s.access_jwt = $1 729 707 "#, 708 + token 730 709 ) 731 - .bind(&token) 732 710 .fetch_optional(&state.db) 733 711 .await; 734 712 735 713 let (did, key_bytes) = match session { 736 - Ok(Some(row)) => ( 737 - row.get::<String, _>("did"), 738 - row.get::<Vec<u8>, _>("key_bytes"), 739 - ), 714 + Ok(Some(row)) => (row.did, row.key_bytes), 740 715 Ok(None) => { 741 716 return ( 742 717 StatusCode::UNAUTHORIZED, ··· 762 737 .into_response(); 763 738 } 764 739 765 - let result = sqlx::query("UPDATE users SET deactivated_at = NOW() WHERE did = $1") 766 - .bind(&did) 740 + let result = sqlx::query!("UPDATE users SET deactivated_at = NOW() WHERE did = $1", did) 767 741 .execute(&state.db) 768 742 .await; 769 743 ··· 812 786 .unwrap_or("") 813 787 .replace("Bearer ", ""); 814 788 815 - let session = sqlx::query( 789 + let session = sqlx::query!( 816 790 r#" 817 791 SELECT s.did, k.key_bytes, u.id as user_id 818 792 FROM sessions s ··· 820 794 JOIN user_keys k ON u.id = k.user_id 821 795 WHERE s.access_jwt = $1 822 796 "#, 797 + token 823 798 ) 824 - .bind(&token) 825 799 .fetch_optional(&state.db) 826 800 .await; 827 801 828 802 let (_did, key_bytes, user_id) = match session { 829 - Ok(Some(row)) => ( 830 - row.get::<String, _>("did"), 831 - row.get::<Vec<u8>, _>("key_bytes"), 832 - row.get::<uuid::Uuid, _>("user_id"), 833 - ), 803 + Ok(Some(row)) => (row.did, row.key_bytes, row.user_id), 834 804 Ok(None) => { 835 805 return ( 836 806 StatusCode::UNAUTHORIZED, ··· 856 826 .into_response(); 857 827 } 858 828 859 - let result = sqlx::query("SELECT name, created_at, privileged FROM app_passwords WHERE user_id = $1 ORDER BY created_at DESC") 860 - .bind(user_id) 829 + let result = sqlx::query!("SELECT name, created_at, privileged FROM app_passwords WHERE user_id = $1 ORDER BY created_at DESC", user_id) 861 830 .fetch_all(&state.db) 862 831 .await; 863 832 ··· 866 835 let passwords: Vec<AppPassword> = rows 867 836 .iter() 868 837 .map(|row| { 869 - let name: String = row.get("name"); 870 - let created_at: chrono::DateTime<chrono::Utc> = row.get("created_at"); 871 - let privileged: bool = row.get("privileged"); 872 838 AppPassword { 873 - name, 874 - created_at: created_at.to_rfc3339(), 875 - privileged, 839 + name: row.name.clone(), 840 + created_at: row.created_at.to_rfc3339(), 841 + privileged: row.privileged, 876 842 } 877 843 }) 878 844 .collect(); ··· 925 891 .unwrap_or("") 926 892 .replace("Bearer ", ""); 927 893 928 - let session = sqlx::query( 894 + let session = sqlx::query!( 929 895 r#" 930 896 SELECT s.did, k.key_bytes, u.id as user_id 931 897 FROM sessions s ··· 933 899 JOIN user_keys k ON u.id = k.user_id 934 900 WHERE s.access_jwt = $1 935 901 "#, 902 + token 936 903 ) 937 - .bind(&token) 938 904 .fetch_optional(&state.db) 939 905 .await; 940 906 941 907 let (_did, key_bytes, user_id) = match session { 942 - Ok(Some(row)) => ( 943 - row.get::<String, _>("did"), 944 - row.get::<Vec<u8>, _>("key_bytes"), 945 - row.get::<uuid::Uuid, _>("user_id"), 946 - ), 908 + Ok(Some(row)) => (row.did, row.key_bytes, row.user_id), 947 909 Ok(None) => { 948 910 return ( 949 911 StatusCode::UNAUTHORIZED, ··· 978 940 .into_response(); 979 941 } 980 942 981 - let existing = sqlx::query("SELECT id FROM app_passwords WHERE user_id = $1 AND name = $2") 982 - .bind(user_id) 983 - .bind(name) 943 + let existing = sqlx::query!("SELECT id FROM app_passwords WHERE user_id = $1 AND name = $2", user_id, name) 984 944 .fetch_optional(&state.db) 985 945 .await; 986 946 ··· 1017 977 let privileged = input.privileged.unwrap_or(false); 1018 978 let created_at = chrono::Utc::now(); 1019 979 1020 - let result = sqlx::query( 1021 - "INSERT INTO app_passwords (user_id, name, password_hash, created_at, privileged) VALUES ($1, $2, $3, $4, $5)" 980 + let result = sqlx::query!( 981 + "INSERT INTO app_passwords (user_id, name, password_hash, created_at, privileged) VALUES ($1, $2, $3, $4, $5)", 982 + user_id, 983 + name, 984 + password_hash, 985 + created_at, 986 + privileged 1022 987 ) 1023 - .bind(user_id) 1024 - .bind(name) 1025 - .bind(&password_hash) 1026 - .bind(created_at) 1027 - .bind(privileged) 1028 988 .execute(&state.db) 1029 989 .await; 1030 990 ··· 1075 1035 .unwrap_or("") 1076 1036 .replace("Bearer ", ""); 1077 1037 1078 - let session = sqlx::query( 1038 + let session = sqlx::query!( 1079 1039 r#" 1080 1040 SELECT s.did, k.key_bytes, u.id as user_id 1081 1041 FROM sessions s ··· 1083 1043 JOIN user_keys k ON u.id = k.user_id 1084 1044 WHERE s.access_jwt = $1 1085 1045 "#, 1046 + token 1086 1047 ) 1087 - .bind(&token) 1088 1048 .fetch_optional(&state.db) 1089 1049 .await; 1090 1050 1091 1051 let (_did, key_bytes, user_id) = match session { 1092 - Ok(Some(row)) => ( 1093 - row.get::<String, _>("did"), 1094 - row.get::<Vec<u8>, _>("key_bytes"), 1095 - row.get::<uuid::Uuid, _>("user_id"), 1096 - ), 1052 + Ok(Some(row)) => (row.did, row.key_bytes, row.user_id), 1097 1053 Ok(None) => { 1098 1054 return ( 1099 1055 StatusCode::UNAUTHORIZED, ··· 1128 1084 .into_response(); 1129 1085 } 1130 1086 1131 - let result = sqlx::query("DELETE FROM app_passwords WHERE user_id = $1 AND name = $2") 1132 - .bind(user_id) 1133 - .bind(name) 1087 + let result = sqlx::query!("DELETE FROM app_passwords WHERE user_id = $1 AND name = $2", user_id, name) 1134 1088 .execute(&state.db) 1135 1089 .await; 1136 1090
+9 -15
src/repo/mod.rs
··· 5 5 use jacquard_repo::storage::BlockStore; 6 6 use multihash::Multihash; 7 7 use sha2::{Digest, Sha256}; 8 - use sqlx::{PgPool, Row}; 8 + use sqlx::PgPool; 9 9 10 10 #[derive(Clone)] 11 11 pub struct PostgresBlockStore { ··· 21 21 impl BlockStore for PostgresBlockStore { 22 22 async fn get(&self, cid: &Cid) -> Result<Option<Bytes>, RepoError> { 23 23 let cid_bytes = cid.to_bytes(); 24 - let row = sqlx::query("SELECT data FROM blocks WHERE cid = $1") 25 - .bind(cid_bytes) 24 + let row = sqlx::query!("SELECT data FROM blocks WHERE cid = $1", &cid_bytes) 26 25 .fetch_optional(&self.pool) 27 26 .await 28 27 .map_err(|e| RepoError::storage(e))?; 29 28 30 29 match row { 31 - Some(row) => { 32 - let data: Vec<u8> = row.get("data"); 33 - Ok(Some(Bytes::from(data))) 34 - } 30 + Some(row) => Ok(Some(Bytes::from(row.data))), 35 31 None => Ok(None), 36 32 } 37 33 } ··· 44 40 let cid = Cid::new_v1(0x71, multihash); 45 41 let cid_bytes = cid.to_bytes(); 46 42 47 - sqlx::query("INSERT INTO blocks (cid, data) VALUES ($1, $2) ON CONFLICT (cid) DO NOTHING") 48 - .bind(cid_bytes) 49 - .bind(data) 43 + sqlx::query!("INSERT INTO blocks (cid, data) VALUES ($1, $2) ON CONFLICT (cid) DO NOTHING", &cid_bytes, data) 50 44 .execute(&self.pool) 51 45 .await 52 46 .map_err(|e| RepoError::storage(e))?; ··· 56 50 57 51 async fn has(&self, cid: &Cid) -> Result<bool, RepoError> { 58 52 let cid_bytes = cid.to_bytes(); 59 - let row = sqlx::query("SELECT 1 FROM blocks WHERE cid = $1") 60 - .bind(cid_bytes) 53 + let row = sqlx::query!("SELECT 1 as one FROM blocks WHERE cid = $1", &cid_bytes) 61 54 .fetch_optional(&self.pool) 62 55 .await 63 56 .map_err(|e| RepoError::storage(e))?; ··· 72 65 let blocks: Vec<_> = blocks.into_iter().collect(); 73 66 for (cid, data) in blocks { 74 67 let cid_bytes = cid.to_bytes(); 75 - sqlx::query( 68 + let data_ref = data.as_ref(); 69 + sqlx::query!( 76 70 "INSERT INTO blocks (cid, data) VALUES ($1, $2) ON CONFLICT (cid) DO NOTHING", 71 + &cid_bytes, 72 + data_ref 77 73 ) 78 - .bind(cid_bytes) 79 - .bind(data.as_ref()) 80 74 .execute(&self.pool) 81 75 .await 82 76 .map_err(|e| RepoError::storage(e))?;
+39 -45
src/sync/mod.rs
··· 9 9 }; 10 10 use serde::{Deserialize, Serialize}; 11 11 use serde_json::json; 12 - use sqlx::Row; 13 12 use tracing::{error, info}; 14 13 15 14 #[derive(Deserialize)] ··· 37 36 .into_response(); 38 37 } 39 38 40 - let result = sqlx::query( 39 + let result = sqlx::query!( 41 40 r#" 42 41 SELECT r.repo_root_cid 43 42 FROM repos r 44 43 JOIN users u ON r.user_id = u.id 45 44 WHERE u.did = $1 46 45 "#, 46 + did 47 47 ) 48 - .bind(did) 49 48 .fetch_optional(&state.db) 50 49 .await; 51 50 52 51 match result { 53 52 Ok(Some(row)) => { 54 - let cid: String = row.get("repo_root_cid"); 55 53 ( 56 54 StatusCode::OK, 57 55 Json(GetLatestCommitOutput { 58 - cid, 56 + cid: row.repo_root_cid, 59 57 rev: chrono::Utc::now().timestamp_millis().to_string(), 60 58 }), 61 59 ) ··· 105 103 let limit = params.limit.unwrap_or(50).min(1000); 106 104 let cursor_did = params.cursor.as_deref().unwrap_or(""); 107 105 108 - let result = sqlx::query( 106 + let result = sqlx::query!( 109 107 r#" 110 108 SELECT u.did, r.repo_root_cid 111 109 FROM repos r ··· 114 112 ORDER BY u.did ASC 115 113 LIMIT $2 116 114 "#, 115 + cursor_did, 116 + limit + 1 117 117 ) 118 - .bind(cursor_did) 119 - .bind(limit + 1) 120 118 .fetch_all(&state.db) 121 119 .await; 122 120 ··· 127 125 .iter() 128 126 .take(limit as usize) 129 127 .map(|row| { 130 - let did: String = row.get("did"); 131 - let head: String = row.get("repo_root_cid"); 132 128 RepoInfo { 133 - did, 134 - head, 129 + did: row.did.clone(), 130 + head: row.repo_root_cid.clone(), 135 131 rev: chrono::Utc::now().timestamp_millis().to_string(), 136 132 active: true, 137 133 } ··· 193 189 .into_response(); 194 190 } 195 191 196 - let user_exists = sqlx::query("SELECT id FROM users WHERE did = $1") 197 - .bind(did) 192 + let user_exists = sqlx::query!("SELECT id FROM users WHERE did = $1", did) 198 193 .fetch_optional(&state.db) 199 194 .await; 200 195 ··· 217 212 Ok(Some(_)) => {} 218 213 } 219 214 220 - let blob_result = sqlx::query("SELECT storage_key, mime_type FROM blobs WHERE cid = $1") 221 - .bind(cid) 215 + let blob_result = sqlx::query!("SELECT storage_key, mime_type FROM blobs WHERE cid = $1", cid) 222 216 .fetch_optional(&state.db) 223 217 .await; 224 218 225 219 match blob_result { 226 220 Ok(Some(row)) => { 227 - let storage_key: String = row.get("storage_key"); 228 - let mime_type: String = row.get("mime_type"); 221 + let storage_key = &row.storage_key; 222 + let mime_type = &row.mime_type; 229 223 230 224 match state.blob_store.get(&storage_key).await { 231 225 Ok(data) => Response::builder() ··· 290 284 let limit = params.limit.unwrap_or(500).min(1000); 291 285 let cursor_cid = params.cursor.as_deref().unwrap_or(""); 292 286 293 - let user_result = sqlx::query("SELECT id FROM users WHERE did = $1") 294 - .bind(did) 287 + let user_result = sqlx::query!("SELECT id FROM users WHERE did = $1", did) 295 288 .fetch_optional(&state.db) 296 289 .await; 297 290 298 - let user_id: uuid::Uuid = match user_result { 299 - Ok(Some(row)) => row.get("id"), 291 + let user_id = match user_result { 292 + Ok(Some(row)) => row.id, 300 293 Ok(None) => { 301 294 return ( 302 295 StatusCode::NOT_FOUND, ··· 314 307 } 315 308 }; 316 309 317 - let result = if let Some(since) = &params.since { 318 - sqlx::query( 310 + let cids_result: Result<Vec<String>, sqlx::Error> = if let Some(since) = &params.since { 311 + let since_time = chrono::DateTime::parse_from_rfc3339(since) 312 + .map(|dt| dt.with_timezone(&chrono::Utc)) 313 + .unwrap_or_else(|_| chrono::Utc::now()); 314 + sqlx::query!( 319 315 r#" 320 316 SELECT cid FROM blobs 321 317 WHERE created_by_user = $1 AND cid > $2 AND created_at > $3 322 318 ORDER BY cid ASC 323 319 LIMIT $4 324 320 "#, 321 + user_id, 322 + cursor_cid, 323 + since_time, 324 + limit + 1 325 325 ) 326 - .bind(user_id) 327 - .bind(cursor_cid) 328 - .bind(since) 329 - .bind(limit + 1) 330 326 .fetch_all(&state.db) 331 327 .await 328 + .map(|rows| rows.into_iter().map(|r| r.cid).collect()) 332 329 } else { 333 - sqlx::query( 330 + sqlx::query!( 334 331 r#" 335 332 SELECT cid FROM blobs 336 333 WHERE created_by_user = $1 AND cid > $2 337 334 ORDER BY cid ASC 338 335 LIMIT $3 339 336 "#, 337 + user_id, 338 + cursor_cid, 339 + limit + 1 340 340 ) 341 - .bind(user_id) 342 - .bind(cursor_cid) 343 - .bind(limit + 1) 344 341 .fetch_all(&state.db) 345 342 .await 343 + .map(|rows| rows.into_iter().map(|r| r.cid).collect()) 346 344 }; 347 345 348 - match result { 349 - Ok(rows) => { 350 - let has_more = rows.len() as i64 > limit; 351 - let cids: Vec<String> = rows 352 - .iter() 346 + match cids_result { 347 + Ok(cids) => { 348 + let has_more = cids.len() as i64 > limit; 349 + let cids: Vec<String> = cids 350 + .into_iter() 353 351 .take(limit as usize) 354 - .map(|row| row.get("cid")) 355 352 .collect(); 356 353 357 354 let next_cursor = if has_more { ··· 406 403 .into_response(); 407 404 } 408 405 409 - let result = sqlx::query( 406 + let result = sqlx::query!( 410 407 r#" 411 408 SELECT u.did, r.repo_root_cid 412 409 FROM users u 413 410 LEFT JOIN repos r ON u.id = r.user_id 414 411 WHERE u.did = $1 415 412 "#, 413 + did 416 414 ) 417 - .bind(did) 418 415 .fetch_optional(&state.db) 419 416 .await; 420 417 421 418 match result { 422 419 Ok(Some(row)) => { 423 - let user_did: String = row.get("did"); 424 - let repo_root: Option<String> = row.get("repo_root_cid"); 425 - 426 - let rev = repo_root.map(|_| chrono::Utc::now().timestamp_millis().to_string()); 420 + let rev = Some(chrono::Utc::now().timestamp_millis().to_string()); 427 421 428 422 ( 429 423 StatusCode::OK, 430 424 Json(GetRepoStatusOutput { 431 - did: user_did, 425 + did: row.did, 432 426 active: true, 433 427 rev, 434 428 }),