diff --git a/.sqlx/query-00452ebb198c69e6b83cb5f805007eb92d87b64f1c8c28cf908f695ed82f3408.json b/.sqlx/query-00452ebb198c69e6b83cb5f805007eb92d87b64f1c8c28cf908f695ed82f3408.json new file mode 100644 index 0000000..308839e --- /dev/null +++ b/.sqlx/query-00452ebb198c69e6b83cb5f805007eb92d87b64f1c8c28cf908f695ed82f3408.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO blocks (cid, data) VALUES ($1, $2) ON CONFLICT (cid) DO NOTHING", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Bytea", + "Bytea" + ] + }, + "nullable": [] + }, + "hash": "00452ebb198c69e6b83cb5f805007eb92d87b64f1c8c28cf908f695ed82f3408" +} diff --git a/.sqlx/query-1ea62c689410d98faa70a5a6075911a8eeed679b0e3d7bbd103732abc912f45e.json b/.sqlx/query-1ea62c689410d98faa70a5a6075911a8eeed679b0e3d7bbd103732abc912f45e.json new file mode 100644 index 0000000..629225d --- /dev/null +++ b/.sqlx/query-1ea62c689410d98faa70a5a6075911a8eeed679b0e3d7bbd103732abc912f45e.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO records (repo_id, collection, rkey, record_cid) VALUES ($1, $2, $3, $4)\n ON CONFLICT (repo_id, collection, rkey) DO UPDATE SET record_cid = $4, created_at = NOW()", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "1ea62c689410d98faa70a5a6075911a8eeed679b0e3d7bbd103732abc912f45e" +} diff --git a/.sqlx/query-243ff4911a7d36354e60005af13f6c7d854dc48b8c0d3674f3cbdfd60b61c9d1.json b/.sqlx/query-243ff4911a7d36354e60005af13f6c7d854dc48b8c0d3674f3cbdfd60b61c9d1.json new file mode 100644 index 0000000..2765d3e --- /dev/null +++ b/.sqlx/query-243ff4911a7d36354e60005af13f6c7d854dc48b8c0d3674f3cbdfd60b61c9d1.json @@ -0,0 +1,30 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 ORDER BY rkey ASC LIMIT $3", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "rkey", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "record_cid", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Int8" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "243ff4911a7d36354e60005af13f6c7d854dc48b8c0d3674f3cbdfd60b61c9d1" +} diff --git a/.sqlx/query-2588479ef83ed45a5d0dee599636f195ca38c5df164e225dcb1b829b497c8f14.json b/.sqlx/query-2588479ef83ed45a5d0dee599636f195ca38c5df164e225dcb1b829b497c8f14.json new file mode 100644 index 0000000..8900d0a --- /dev/null +++ b/.sqlx/query-2588479ef83ed45a5d0dee599636f195ca38c5df164e225dcb1b829b497c8f14.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Uuid" + ] + }, + "nullable": [] + }, + "hash": "2588479ef83ed45a5d0dee599636f195ca38c5df164e225dcb1b829b497c8f14" +} diff --git a/.sqlx/query-2d37a447ec4dbdb6dfd5ab8c12d1ce88b9be04d6c7b4744891352a9a3bed4f3c.json b/.sqlx/query-2d37a447ec4dbdb6dfd5ab8c12d1ce88b9be04d6c7b4744891352a9a3bed4f3c.json new file mode 100644 index 0000000..aa58028 --- /dev/null +++ b/.sqlx/query-2d37a447ec4dbdb6dfd5ab8c12d1ce88b9be04d6c7b4744891352a9a3bed4f3c.json @@ -0,0 +1,30 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 ORDER BY rkey DESC LIMIT $3", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "rkey", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "record_cid", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Int8" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "2d37a447ec4dbdb6dfd5ab8c12d1ce88b9be04d6c7b4744891352a9a3bed4f3c" +} diff --git a/.sqlx/query-347e3570a201ee339904aab43f0519ff631f160c97453e9e8aef04756cbc424e.json b/.sqlx/query-347e3570a201ee339904aab43f0519ff631f160c97453e9e8aef04756cbc424e.json new file mode 100644 index 0000000..cb26727 --- /dev/null +++ b/.sqlx/query-347e3570a201ee339904aab43f0519ff631f160c97453e9e8aef04756cbc424e.json @@ -0,0 +1,31 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 AND rkey > $3 ORDER BY rkey ASC LIMIT $4", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "rkey", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "record_cid", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Text", + "Int8" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "347e3570a201ee339904aab43f0519ff631f160c97453e9e8aef04756cbc424e" +} diff --git a/.sqlx/query-393066519bf0e1b5b4d2903984001fdd1c17c4cdf8a4af810ce95c05669a04e8.json b/.sqlx/query-393066519bf0e1b5b4d2903984001fdd1c17c4cdf8a4af810ce95c05669a04e8.json new file mode 100644 index 0000000..2079660 --- /dev/null +++ b/.sqlx/query-393066519bf0e1b5b4d2903984001fdd1c17c4cdf8a4af810ce95c05669a04e8.json @@ -0,0 +1,34 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT id, handle, did FROM users WHERE handle = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "handle", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "did", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "393066519bf0e1b5b4d2903984001fdd1c17c4cdf8a4af810ce95c05669a04e8" +} diff --git a/.sqlx/query-4343e751b03e24387f6603908a1582d20fdfa58a8e4c17c1628acc6b6f2ded15.json b/.sqlx/query-4343e751b03e24387f6603908a1582d20fdfa58a8e4c17c1628acc6b6f2ded15.json new file mode 100644 index 0000000..aeab538 --- /dev/null +++ b/.sqlx/query-4343e751b03e24387f6603908a1582d20fdfa58a8e4c17c1628acc6b6f2ded15.json @@ -0,0 +1,31 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 AND rkey < $3 ORDER BY rkey DESC LIMIT $4", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "rkey", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "record_cid", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Text", + "Int8" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "4343e751b03e24387f6603908a1582d20fdfa58a8e4c17c1628acc6b6f2ded15" +} diff --git a/.sqlx/query-4bc1e1169d95eac340756b1ba01680caa980514d77cc7b41361c2400f6a5f456.json b/.sqlx/query-4bc1e1169d95eac340756b1ba01680caa980514d77cc7b41361c2400f6a5f456.json new file mode 100644 index 0000000..e71e6d2 --- /dev/null +++ b/.sqlx/query-4bc1e1169d95eac340756b1ba01680caa980514d77cc7b41361c2400f6a5f456.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT r.record_cid, r.rkey, r.created_at, u.did, u.handle\n FROM records r\n JOIN repos rp ON r.repo_id = rp.user_id\n JOIN users u ON rp.user_id = u.id\n WHERE u.did = ANY($1) AND r.collection = 'app.bsky.feed.post'\n ORDER BY r.created_at DESC\n LIMIT 50", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "record_cid", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "rkey", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "created_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 3, + "name": "did", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "handle", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "TextArray" + ] + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "4bc1e1169d95eac340756b1ba01680caa980514d77cc7b41361c2400f6a5f456" +} diff --git a/.sqlx/query-63c2b1ecdc078446f8bd898a7c6403c7e64918027933d0a99eae6175bf0ea0ac.json b/.sqlx/query-63c2b1ecdc078446f8bd898a7c6403c7e64918027933d0a99eae6175bf0ea0ac.json new file mode 100644 index 0000000..5979a77 --- /dev/null +++ b/.sqlx/query-63c2b1ecdc078446f8bd898a7c6403c7e64918027933d0a99eae6175bf0ea0ac.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT DISTINCT collection FROM records WHERE repo_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "collection", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Uuid" + ] + }, + "nullable": [ + false + ] + }, + "hash": "63c2b1ecdc078446f8bd898a7c6403c7e64918027933d0a99eae6175bf0ea0ac" +} diff --git a/.sqlx/query-8c9297289cb753c8eaa4231ae9eab6cd3367f9bf543d9f49bca4afa53434ce0d.json b/.sqlx/query-8c9297289cb753c8eaa4231ae9eab6cd3367f9bf543d9f49bca4afa53434ce0d.json new file mode 100644 index 0000000..ecc9ad9 --- /dev/null +++ b/.sqlx/query-8c9297289cb753c8eaa4231ae9eab6cd3367f9bf543d9f49bca4afa53434ce0d.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "DELETE FROM records WHERE repo_id = $1 AND collection = $2 AND rkey = $3", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "8c9297289cb753c8eaa4231ae9eab6cd3367f9bf543d9f49bca4afa53434ce0d" +} diff --git a/.sqlx/query-bbf600f17712173206b754fd7c8f8f8fd46a03bf54e824ff8046c37a88407123.json b/.sqlx/query-bbf600f17712173206b754fd7c8f8f8fd46a03bf54e824ff8046c37a88407123.json new file mode 100644 index 0000000..d2029c2 --- /dev/null +++ b/.sqlx/query-bbf600f17712173206b754fd7c8f8f8fd46a03bf54e824ff8046c37a88407123.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT 1 as one", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "one", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null + ] + }, + "hash": "bbf600f17712173206b754fd7c8f8f8fd46a03bf54e824ff8046c37a88407123" +} diff --git a/.sqlx/query-c61fc3b2fbdf6891269908ef21f13dcabdc3b032e9f767becae34ca176df18b6.json b/.sqlx/query-c61fc3b2fbdf6891269908ef21f13dcabdc3b032e9f767becae34ca176df18b6.json new file mode 100644 index 0000000..a892f59 --- /dev/null +++ b/.sqlx/query-c61fc3b2fbdf6891269908ef21f13dcabdc3b032e9f767becae34ca176df18b6.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO records (repo_id, collection, rkey, record_cid) VALUES ($1, $2, $3, $4)\n ON CONFLICT (repo_id, collection, rkey) DO UPDATE SET record_cid = $4, created_at = NOW()", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "c61fc3b2fbdf6891269908ef21f13dcabdc3b032e9f767becae34ca176df18b6" +} diff --git a/.sqlx/query-ce7977cb9183b587a2c2a56b4e5d52a6de786b5d3a05af4c2245fd61b98d0168.json b/.sqlx/query-ce7977cb9183b587a2c2a56b4e5d52a6de786b5d3a05af4c2245fd61b98d0168.json new file mode 100644 index 0000000..0043af6 --- /dev/null +++ b/.sqlx/query-ce7977cb9183b587a2c2a56b4e5d52a6de786b5d3a05af4c2245fd61b98d0168.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT id FROM users WHERE handle = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Uuid" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "ce7977cb9183b587a2c2a56b4e5d52a6de786b5d3a05af4c2245fd61b98d0168" +} diff --git a/.sqlx/query-ebceb64378f0e06c61c72d10f65fb7df83e09e82153d92dee4efef62de057505.json b/.sqlx/query-ebceb64378f0e06c61c72d10f65fb7df83e09e82153d92dee4efef62de057505.json new file mode 100644 index 0000000..20cf437 --- /dev/null +++ b/.sqlx/query-ebceb64378f0e06c61c72d10f65fb7df83e09e82153d92dee4efef62de057505.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT data FROM blocks WHERE cid = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Bytea" + ] + }, + "nullable": [ + false + ] + }, + "hash": "ebceb64378f0e06c61c72d10f65fb7df83e09e82153d92dee4efef62de057505" +} diff --git a/.sqlx/query-f09c0e92f101ef5abe2579083a26f782946646a8bd813bcd6cc568a6b7fc8f6d.json b/.sqlx/query-f09c0e92f101ef5abe2579083a26f782946646a8bd813bcd6cc568a6b7fc8f6d.json new file mode 100644 index 0000000..bce1404 --- /dev/null +++ b/.sqlx/query-f09c0e92f101ef5abe2579083a26f782946646a8bd813bcd6cc568a6b7fc8f6d.json @@ -0,0 +1,24 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT record_cid FROM records WHERE repo_id = $1 AND collection = $2 AND rkey = $3", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "record_cid", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "f09c0e92f101ef5abe2579083a26f782946646a8bd813bcd6cc568a6b7fc8f6d" +} diff --git a/.sqlx/query-fba80b51dd803209fd2691b07213b68eade7427381a61268d16cb4cac357ac69.json b/.sqlx/query-fba80b51dd803209fd2691b07213b68eade7427381a61268d16cb4cac357ac69.json new file mode 100644 index 0000000..ac62753 --- /dev/null +++ b/.sqlx/query-fba80b51dd803209fd2691b07213b68eade7427381a61268d16cb4cac357ac69.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT 1 as one FROM blocks WHERE cid = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "one", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Bytea" + ] + }, + "nullable": [ + null + ] + }, + "hash": "fba80b51dd803209fd2691b07213b68eade7427381a61268d16cb4cac357ac69" +} diff --git a/.sqlx/query-fd1efe850ae4d8b9d834aba414a5b97f20094c790804c60079905b199e9d3858.json b/.sqlx/query-fd1efe850ae4d8b9d834aba414a5b97f20094c790804c60079905b199e9d3858.json new file mode 100644 index 0000000..4efba48 --- /dev/null +++ b/.sqlx/query-fd1efe850ae4d8b9d834aba414a5b97f20094c790804c60079905b199e9d3858.json @@ -0,0 +1,34 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT id, handle, did FROM users WHERE did = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "handle", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "did", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "fd1efe850ae4d8b9d834aba414a5b97f20094c790804c60079905b199e9d3858" +} diff --git a/Cargo.lock b/Cargo.lock index 0ede77b..502fe36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,12 +27,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - [[package]] name = "aho-corasick" version = "1.1.4" @@ -48,21 +42,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "allocator-api2" version = "0.2.21" @@ -84,12 +63,6 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -[[package]] -name = "ascii" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" - [[package]] name = "assert-json-diff" version = "2.0.2" @@ -693,12 +666,6 @@ dependencies = [ "match-lookup", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.7" @@ -879,27 +846,6 @@ dependencies = [ "cfg_aliases", ] -[[package]] -name = "brotli" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bspds" version = "0.1.0" @@ -964,16 +910,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "buf_redux" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" -dependencies = [ - "memchr", - "safemem", -] - [[package]] name = "bumpalo" version = "3.19.0" @@ -1072,12 +1008,6 @@ dependencies = [ "slab", ] -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - [[package]] name = "cfg-if" version = "1.0.4" @@ -1104,12 +1034,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "chunked_transfer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" - [[package]] name = "ciborium" version = "0.2.2" @@ -1170,16 +1094,6 @@ dependencies = [ "cc", ] -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - [[package]] name = "compression-codecs" version = "0.4.33" @@ -1522,16 +1436,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" -[[package]] -name = "deflate" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" -dependencies = [ - "adler32", - "gzip-header", -] - [[package]] name = "der" version = "0.6.1" @@ -2204,15 +2108,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "gzip-header" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95cc527b92e6029a62960ad99aa8a6660faa4555fe5f731aab13aa6a921795a2" -dependencies = [ - "crc32fast", -] - [[package]] name = "h2" version = "0.3.27" @@ -3100,7 +2995,6 @@ dependencies = [ "miette", "p256 0.13.2", "rand 0.8.5", - "rouille", "serde", "serde_html_form", "serde_json", @@ -3110,7 +3004,6 @@ dependencies = [ "tokio", "trait-variant", "url", - "webbrowser", ] [[package]] @@ -3140,28 +3033,6 @@ dependencies = [ "trait-variant", ] -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - [[package]] name = "jobserver" version = "0.1.34" @@ -3480,16 +3351,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "mini-moka" version = "0.10.3" @@ -3555,24 +3416,6 @@ dependencies = [ "unsigned-varint 0.8.0", ] -[[package]] -name = "multipart" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" -dependencies = [ - "buf_redux", - "httparse", - "log", - "mime", - "mime_guess", - "quick-error", - "rand 0.8.5", - "safemem", - "tempfile", - "twoway", -] - [[package]] name = "n0-future" version = "0.1.3" @@ -3611,12 +3454,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3748,40 +3585,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "objc2" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" -dependencies = [ - "objc2-encode", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" -dependencies = [ - "bitflags", - "objc2", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -4227,12 +4030,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quinn" version = "0.11.9" @@ -4521,30 +4318,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rouille" -version = "3.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3716fbf57fc1084d7a706adf4e445298d123e4a44294c4e8213caf1b85fcc921" -dependencies = [ - "base64 0.13.1", - "brotli", - "chrono", - "deflate", - "filetime", - "multipart", - "percent-encoding", - "rand 0.8.5", - "serde", - "serde_derive", - "serde_json", - "sha1_smol", - "threadpool", - "time", - "tiny_http", - "url", -] - [[package]] name = "rsa" version = "0.9.9" @@ -4707,12 +4480,6 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - [[package]] name = "same-file" version = "1.0.6" @@ -5011,12 +4778,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - [[package]] name = "sha2" version = "0.10.9" @@ -5673,15 +5434,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - [[package]] name = "time" version = "0.3.44" @@ -5690,9 +5442,7 @@ checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", - "libc", "num-conv", - "num_threads", "powerfmt", "serde", "time-core", @@ -5715,18 +5465,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny_http" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" -dependencies = [ - "ascii", - "chunked_transfer", - "httpdate", - "log", -] - [[package]] name = "tinystr" version = "0.8.2" @@ -6009,15 +5747,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "twoway" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" -dependencies = [ - "memchr", -] - [[package]] name = "typenum" version = "1.19.0" @@ -6318,22 +6047,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webbrowser" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f1243ef785213e3a32fa0396093424a3a6ea566f9948497e5a2309261a4c97" -dependencies = [ - "core-foundation 0.10.1", - "jni", - "log", - "ndk-context", - "objc2", - "objc2-foundation", - "url", - "web-sys", -] - [[package]] name = "webpage" version = "2.0.1" @@ -6561,15 +6274,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -6606,21 +6310,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -6678,12 +6367,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -6702,12 +6385,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -6726,12 +6403,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -6762,12 +6433,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -6786,12 +6451,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -6810,12 +6469,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -6834,12 +6487,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" diff --git a/Cargo.toml b/Cargo.toml index 5b92d1d..e831c9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ bytes = "1.11.0" chrono = { version = "0.4.42", features = ["serde"] } cid = "0.11.1" dotenvy = "0.15.7" -jacquard = "0.9.3" +jacquard = { version = "0.9.3", default-features = false, features = ["api", "api_bluesky", "api_full", "derive", "dns"] } jacquard-axum = "0.9.2" jacquard-repo = "0.9.2" jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] } diff --git a/src/api/feed/timeline.rs b/src/api/feed/timeline.rs index 254142a..f72b5de 100644 --- a/src/api/feed/timeline.rs +++ b/src/api/feed/timeline.rs @@ -11,7 +11,6 @@ use axum::{ use jacquard_repo::storage::BlockStore; use serde::Serialize; use serde_json::{Value, json}; -use sqlx::Row; use tracing::error; #[derive(Serialize)] @@ -153,29 +152,18 @@ pub async fn get_timeline( .into_response(); } - let placeholders: Vec = followed_dids - .iter() - .enumerate() - .map(|(i, _)| format!("${}", i + 1)) - .collect(); - - let posts_query = format!( + let posts_result = sqlx::query!( "SELECT r.record_cid, r.rkey, r.created_at, u.did, u.handle FROM records r JOIN repos rp ON r.repo_id = rp.user_id JOIN users u ON rp.user_id = u.id - WHERE u.did IN ({}) AND r.collection = 'app.bsky.feed.post' + WHERE u.did = ANY($1) AND r.collection = 'app.bsky.feed.post' ORDER BY r.created_at DESC LIMIT 50", - placeholders.join(", ") - ); - - let mut query = sqlx::query(&posts_query); - for did in &followed_dids { - query = query.bind(did); - } - - let posts_result = query.fetch_all(&state.db).await; + &followed_dids + ) + .fetch_all(&state.db) + .await; let posts = match posts_result { Ok(rows) => rows, @@ -192,11 +180,11 @@ pub async fn get_timeline( let mut feed: Vec = Vec::new(); for row in posts { - let record_cid: String = row.get("record_cid"); - let rkey: String = row.get("rkey"); - let created_at: chrono::DateTime = row.get("created_at"); - let author_did: String = row.get("did"); - let author_handle: String = row.get("handle"); + let record_cid: String = row.record_cid; + let rkey: String = row.rkey; + let created_at: chrono::DateTime = row.created_at; + let author_did: String = row.did; + let author_handle: String = row.handle; let cid = match record_cid.parse::() { Ok(c) => c, diff --git a/src/api/repo/meta.rs b/src/api/repo/meta.rs index 32b041a..d6481d2 100644 --- a/src/api/repo/meta.rs +++ b/src/api/repo/meta.rs @@ -7,7 +7,6 @@ use axum::{ }; use serde::Deserialize; use serde_json::json; -use sqlx::Row; #[derive(Deserialize)] pub struct DescribeRepoInput { @@ -19,23 +18,19 @@ pub async fn describe_repo( Query(input): Query, ) -> Response { let user_row = if input.repo.starts_with("did:") { - sqlx::query("SELECT id, handle, did FROM users WHERE did = $1") - .bind(&input.repo) + sqlx::query!("SELECT id, handle, did FROM users WHERE did = $1", input.repo) .fetch_optional(&state.db) .await + .map(|opt| opt.map(|r| (r.id, r.handle, r.did))) } else { - sqlx::query("SELECT id, handle, did FROM users WHERE handle = $1") - .bind(&input.repo) + sqlx::query!("SELECT id, handle, did FROM users WHERE handle = $1", input.repo) .fetch_optional(&state.db) .await + .map(|opt| opt.map(|r| (r.id, r.handle, r.did))) }; let (user_id, handle, did) = match user_row { - Ok(Some(row)) => ( - row.get::("id"), - row.get::("handle"), - row.get::("did"), - ), + Ok(Some((id, handle, did))) => (id, handle, did), _ => { return ( StatusCode::NOT_FOUND, @@ -46,13 +41,12 @@ pub async fn describe_repo( }; let collections_query = - sqlx::query("SELECT DISTINCT collection FROM records WHERE repo_id = $1") - .bind(user_id) + sqlx::query!("SELECT DISTINCT collection FROM records WHERE repo_id = $1", user_id) .fetch_all(&state.db) .await; let collections: Vec = match collections_query { - Ok(rows) => rows.iter().map(|r| r.get("collection")).collect(), + Ok(rows) => rows.iter().map(|r| r.collection.clone()).collect(), Err(_) => Vec::new(), }; diff --git a/src/api/repo/record/batch.rs b/src/api/repo/record/batch.rs index 71ac80c..9b3e7dc 100644 --- a/src/api/repo/record/batch.rs +++ b/src/api/repo/record/batch.rs @@ -15,7 +15,6 @@ use jacquard::types::{ use jacquard_repo::{commit::Commit, mst::Mst, storage::BlockStore}; use serde::{Deserialize, Serialize}; use serde_json::json; -use sqlx::Row; use std::str::FromStr; use std::sync::Arc; use tracing::error; @@ -90,18 +89,18 @@ pub async fn apply_writes( .unwrap_or("") .replace("Bearer ", ""); - let session = sqlx::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" + let session = sqlx::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", + token ) - .bind(&token) .fetch_optional(&state.db) .await .unwrap_or(None); let (did, key_bytes) = match session { Some(row) => ( - row.get::("did"), - row.get::, _>("key_bytes"), + row.did, + row.key_bytes, ), None => { return ( @@ -144,13 +143,12 @@ pub async fn apply_writes( .into_response(); } - let user_query = sqlx::query("SELECT id FROM users WHERE did = $1") - .bind(&did) + let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did) .fetch_optional(&state.db) .await; let user_id: uuid::Uuid = match user_query { - Ok(Some(row)) => row.get("id"), + Ok(Some(row)) => row.id, _ => { return ( StatusCode::INTERNAL_SERVER_ERROR, @@ -160,14 +158,13 @@ pub async fn apply_writes( } }; - let repo_root_query = sqlx::query("SELECT repo_root_cid FROM repos WHERE user_id = $1") - .bind(user_id) + let repo_root_query = sqlx::query!("SELECT repo_root_cid FROM repos WHERE user_id = $1", user_id) .fetch_optional(&state.db) .await; let current_root_cid = match repo_root_query { Ok(Some(row)) => { - let cid_str: String = row.get("repo_root_cid"); + let cid_str: String = row.repo_root_cid; match Cid::from_str(&cid_str) { Ok(c) => c, Err(_) => { @@ -449,9 +446,7 @@ pub async fn apply_writes( } }; - let update_repo = sqlx::query("UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2") - .bind(new_root_cid.to_string()) - .bind(user_id) + let update_repo = sqlx::query!("UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2", new_root_cid.to_string(), user_id) .execute(&state.db) .await; @@ -467,24 +462,24 @@ pub async fn apply_writes( for (collection, rkey, record_cid) in record_ops { match record_cid { Some(cid) => { - let _ = sqlx::query( + let _ = sqlx::query!( "INSERT INTO records (repo_id, collection, rkey, record_cid) VALUES ($1, $2, $3, $4) ON CONFLICT (repo_id, collection, rkey) DO UPDATE SET record_cid = $4, created_at = NOW()", + user_id, + collection, + rkey, + cid ) - .bind(user_id) - .bind(&collection) - .bind(&rkey) - .bind(&cid) .execute(&state.db) .await; } None => { - let _ = sqlx::query( + let _ = sqlx::query!( "DELETE FROM records WHERE repo_id = $1 AND collection = $2 AND rkey = $3", + user_id, + collection, + rkey ) - .bind(user_id) - .bind(&collection) - .bind(&rkey) .execute(&state.db) .await; } diff --git a/src/api/repo/record/delete.rs b/src/api/repo/record/delete.rs index 9f650b4..299ab63 100644 --- a/src/api/repo/record/delete.rs +++ b/src/api/repo/record/delete.rs @@ -14,7 +14,6 @@ use jacquard::types::{ use jacquard_repo::{commit::Commit, mst::Mst, storage::BlockStore}; use serde::Deserialize; use serde_json::json; -use sqlx::Row; use std::str::FromStr; use std::sync::Arc; use tracing::error; @@ -49,18 +48,18 @@ pub async fn delete_record( .unwrap_or("") .replace("Bearer ", ""); - let session = sqlx::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" + let session = sqlx::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", + token ) - .bind(&token) .fetch_optional(&state.db) .await .unwrap_or(None); let (did, key_bytes) = match session { Some(row) => ( - row.get::("did"), - row.get::, _>("key_bytes"), + row.did, + row.key_bytes, ), None => { return ( @@ -83,13 +82,12 @@ pub async fn delete_record( return (StatusCode::FORBIDDEN, Json(json!({"error": "InvalidRepo", "message": "Repo does not match authenticated user"}))).into_response(); } - let user_query = sqlx::query("SELECT id FROM users WHERE did = $1") - .bind(&did) + let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did) .fetch_optional(&state.db) .await; let user_id: uuid::Uuid = match user_query { - Ok(Some(row)) => row.get("id"), + Ok(Some(row)) => row.id, _ => { return ( StatusCode::INTERNAL_SERVER_ERROR, @@ -99,14 +97,13 @@ pub async fn delete_record( } }; - let repo_root_query = sqlx::query("SELECT repo_root_cid FROM repos WHERE user_id = $1") - .bind(user_id) + let repo_root_query = sqlx::query!("SELECT repo_root_cid FROM repos WHERE user_id = $1", user_id) .fetch_optional(&state.db) .await; let current_root_cid = match repo_root_query { Ok(Some(row)) => { - let cid_str: String = row.get("repo_root_cid"); + let cid_str: String = row.repo_root_cid; Cid::from_str(&cid_str).ok() } _ => None, @@ -209,9 +206,7 @@ pub async fn delete_record( } }; - let update_repo = sqlx::query("UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2") - .bind(new_root_cid.to_string()) - .bind(user_id) + let update_repo = sqlx::query!("UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2", new_root_cid.to_string(), user_id) .execute(&state.db) .await; @@ -225,10 +220,7 @@ pub async fn delete_record( } let record_delete = - sqlx::query("DELETE FROM records WHERE repo_id = $1 AND collection = $2 AND rkey = $3") - .bind(user_id) - .bind(&input.collection) - .bind(&input.rkey) + sqlx::query!("DELETE FROM records WHERE repo_id = $1 AND collection = $2 AND rkey = $3", user_id, input.collection, input.rkey) .execute(&state.db) .await; diff --git a/src/api/repo/record/read.rs b/src/api/repo/record/read.rs index 7f3acb5..e1cd268 100644 --- a/src/api/repo/record/read.rs +++ b/src/api/repo/record/read.rs @@ -9,7 +9,6 @@ use cid::Cid; use jacquard_repo::storage::BlockStore; use serde::{Deserialize, Serialize}; use serde_json::json; -use sqlx::Row; use std::str::FromStr; use tracing::error; @@ -25,20 +24,20 @@ pub async fn get_record( State(state): State, Query(input): Query, ) -> Response { - let user_row = if input.repo.starts_with("did:") { - sqlx::query("SELECT id FROM users WHERE did = $1") - .bind(&input.repo) + let user_id_opt = if input.repo.starts_with("did:") { + sqlx::query!("SELECT id FROM users WHERE did = $1", input.repo) .fetch_optional(&state.db) .await + .map(|opt| opt.map(|r| r.id)) } else { - sqlx::query("SELECT id FROM users WHERE handle = $1") - .bind(&input.repo) + sqlx::query!("SELECT id FROM users WHERE handle = $1", input.repo) .fetch_optional(&state.db) .await + .map(|opt| opt.map(|r| r.id)) }; - let user_id: uuid::Uuid = match user_row { - Ok(Some(row)) => row.get("id"), + let user_id: uuid::Uuid = match user_id_opt { + Ok(Some(id)) => id, _ => { return ( StatusCode::NOT_FOUND, @@ -48,17 +47,17 @@ pub async fn get_record( } }; - let record_row = sqlx::query( + let record_row = sqlx::query!( "SELECT record_cid FROM records WHERE repo_id = $1 AND collection = $2 AND rkey = $3", + user_id, + input.collection, + input.rkey ) - .bind(user_id) - .bind(&input.collection) - .bind(&input.rkey) .fetch_optional(&state.db) .await; let record_cid_str: String = match record_row { - Ok(Some(row)) => row.get("record_cid"), + Ok(Some(row)) => row.record_cid, _ => { return ( StatusCode::NOT_FOUND, @@ -143,20 +142,20 @@ pub async fn list_records( State(state): State, Query(input): Query, ) -> Response { - let user_row = if input.repo.starts_with("did:") { - sqlx::query("SELECT id FROM users WHERE did = $1") - .bind(&input.repo) + let user_id_opt = if input.repo.starts_with("did:") { + sqlx::query!("SELECT id FROM users WHERE did = $1", input.repo) .fetch_optional(&state.db) .await + .map(|opt| opt.map(|r| r.id)) } else { - sqlx::query("SELECT id FROM users WHERE handle = $1") - .bind(&input.repo) + sqlx::query!("SELECT id FROM users WHERE handle = $1", input.repo) .fetch_optional(&state.db) .await + .map(|opt| opt.map(|r| r.id)) }; - let user_id: uuid::Uuid = match user_row { - Ok(Some(row)) => row.get("id"), + let user_id: uuid::Uuid = match user_id_opt { + Ok(Some(id)) => id, _ => { return ( StatusCode::NOT_FOUND, @@ -172,30 +171,56 @@ pub async fn list_records( // Simplistic query construction - no sophisticated cursor handling or rkey ranges for now, just basic pagination // TODO: Implement rkeyStart/End and correct cursor logic - let query_str = format!( - "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 {} ORDER BY rkey {} LIMIT {}", - if let Some(_c) = &input.cursor { - if reverse { - "AND rkey < $3" - } else { - "AND rkey > $3" - } + let limit_i64 = limit as i64; + let rows_res = if let Some(cursor) = &input.cursor { + if reverse { + sqlx::query!( + "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 AND rkey < $3 ORDER BY rkey DESC LIMIT $4", + user_id, + input.collection, + cursor, + limit_i64 + ) + .fetch_all(&state.db) + .await + .map(|rows| rows.into_iter().map(|r| (r.rkey, r.record_cid)).collect::>()) } else { - "" - }, - if reverse { "DESC" } else { "ASC" }, - limit - ); + sqlx::query!( + "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 AND rkey > $3 ORDER BY rkey ASC LIMIT $4", + user_id, + input.collection, + cursor, + limit_i64 + ) + .fetch_all(&state.db) + .await + .map(|rows| rows.into_iter().map(|r| (r.rkey, r.record_cid)).collect::>()) + } + } else { + if reverse { + sqlx::query!( + "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 ORDER BY rkey DESC LIMIT $3", + user_id, + input.collection, + limit_i64 + ) + .fetch_all(&state.db) + .await + .map(|rows| rows.into_iter().map(|r| (r.rkey, r.record_cid)).collect::>()) + } else { + sqlx::query!( + "SELECT rkey, record_cid FROM records WHERE repo_id = $1 AND collection = $2 ORDER BY rkey ASC LIMIT $3", + user_id, + input.collection, + limit_i64 + ) + .fetch_all(&state.db) + .await + .map(|rows| rows.into_iter().map(|r| (r.rkey, r.record_cid)).collect::>()) + } + }; - let mut query = sqlx::query(&query_str) - .bind(user_id) - .bind(&input.collection); - - if let Some(c) = &input.cursor { - query = query.bind(c); - } - - let rows = match query.fetch_all(&state.db).await { + let rows = match rows_res { Ok(r) => r, Err(e) => { error!("Error listing records: {:?}", e); @@ -210,9 +235,7 @@ pub async fn list_records( let mut records = Vec::new(); let mut last_rkey = None; - for row in rows { - let rkey: String = row.get("rkey"); - let cid_str: String = row.get("record_cid"); + for (rkey, cid_str) in rows { last_rkey = Some(rkey.clone()); if let Ok(cid) = Cid::from_str(&cid_str) { diff --git a/src/api/repo/record/write.rs b/src/api/repo/record/write.rs index 93ada7f..936e83c 100644 --- a/src/api/repo/record/write.rs +++ b/src/api/repo/record/write.rs @@ -15,7 +15,6 @@ use jacquard::types::{ use jacquard_repo::{commit::Commit, mst::Mst, storage::BlockStore}; use serde::{Deserialize, Serialize}; use serde_json::json; -use sqlx::Row; use std::str::FromStr; use std::sync::Arc; use tracing::error; @@ -58,18 +57,18 @@ pub async fn create_record( .unwrap_or("") .replace("Bearer ", ""); - let session = sqlx::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" + let session = sqlx::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", + token ) - .bind(&token) .fetch_optional(&state.db) .await .unwrap_or(None); let (did, key_bytes) = match session { Some(row) => ( - row.get::("did"), - row.get::, _>("key_bytes"), + row.did, + row.key_bytes, ), None => { return ( @@ -92,13 +91,12 @@ pub async fn create_record( return (StatusCode::FORBIDDEN, Json(json!({"error": "InvalidRepo", "message": "Repo does not match authenticated user"}))).into_response(); } - let user_query = sqlx::query("SELECT id FROM users WHERE did = $1") - .bind(&did) + let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did) .fetch_optional(&state.db) .await; let user_id: uuid::Uuid = match user_query { - Ok(Some(row)) => row.get("id"), + Ok(Some(row)) => row.id, _ => { return ( StatusCode::INTERNAL_SERVER_ERROR, @@ -108,14 +106,13 @@ pub async fn create_record( } }; - let repo_root_query = sqlx::query("SELECT repo_root_cid FROM repos WHERE user_id = $1") - .bind(user_id) + let repo_root_query = sqlx::query!("SELECT repo_root_cid FROM repos WHERE user_id = $1", user_id) .fetch_optional(&state.db) .await; let current_root_cid = match repo_root_query { Ok(Some(row)) => { - let cid_str: String = row.get("repo_root_cid"); + let cid_str: String = row.repo_root_cid; Cid::from_str(&cid_str).ok() } _ => None, @@ -280,9 +277,7 @@ pub async fn create_record( } }; - let update_repo = sqlx::query("UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2") - .bind(new_root_cid.to_string()) - .bind(user_id) + let update_repo = sqlx::query!("UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2", new_root_cid.to_string(), user_id) .execute(&state.db) .await; @@ -295,14 +290,14 @@ pub async fn create_record( .into_response(); } - let record_insert = sqlx::query( + let record_insert = sqlx::query!( "INSERT INTO records (repo_id, collection, rkey, record_cid) VALUES ($1, $2, $3, $4) ON CONFLICT (repo_id, collection, rkey) DO UPDATE SET record_cid = $4, created_at = NOW()", + user_id, + input.collection, + rkey, + record_cid.to_string() ) - .bind(user_id) - .bind(&input.collection) - .bind(&rkey) - .bind(record_cid.to_string()) .execute(&state.db) .await; @@ -362,18 +357,18 @@ pub async fn put_record( .unwrap_or("") .replace("Bearer ", ""); - let session = sqlx::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" + let session = sqlx::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", + token ) - .bind(&token) .fetch_optional(&state.db) .await .unwrap_or(None); let (did, key_bytes) = match session { Some(row) => ( - row.get::("did"), - row.get::, _>("key_bytes"), + row.did, + row.key_bytes, ), None => { return ( @@ -396,13 +391,12 @@ pub async fn put_record( return (StatusCode::FORBIDDEN, Json(json!({"error": "InvalidRepo", "message": "Repo does not match authenticated user"}))).into_response(); } - let user_query = sqlx::query("SELECT id FROM users WHERE did = $1") - .bind(&did) + let user_query = sqlx::query!("SELECT id FROM users WHERE did = $1", did) .fetch_optional(&state.db) .await; let user_id: uuid::Uuid = match user_query { - Ok(Some(row)) => row.get("id"), + Ok(Some(row)) => row.id, _ => { return ( StatusCode::INTERNAL_SERVER_ERROR, @@ -412,14 +406,13 @@ pub async fn put_record( } }; - let repo_root_query = sqlx::query("SELECT repo_root_cid FROM repos WHERE user_id = $1") - .bind(user_id) + let repo_root_query = sqlx::query!("SELECT repo_root_cid FROM repos WHERE user_id = $1", user_id) .fetch_optional(&state.db) .await; let current_root_cid = match repo_root_query { Ok(Some(row)) => { - let cid_str: String = row.get("repo_root_cid"); + let cid_str: String = row.repo_root_cid; Cid::from_str(&cid_str).ok() } _ => None, @@ -637,9 +630,7 @@ pub async fn put_record( } }; - let update_repo = sqlx::query("UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2") - .bind(new_root_cid.to_string()) - .bind(user_id) + let update_repo = sqlx::query!("UPDATE repos SET repo_root_cid = $1 WHERE user_id = $2", new_root_cid.to_string(), user_id) .execute(&state.db) .await; @@ -652,14 +643,14 @@ pub async fn put_record( .into_response(); } - let record_insert = sqlx::query( + let record_insert = sqlx::query!( "INSERT INTO records (repo_id, collection, rkey, record_cid) VALUES ($1, $2, $3, $4) ON CONFLICT (repo_id, collection, rkey) DO UPDATE SET record_cid = $4, created_at = NOW()", + user_id, + input.collection, + rkey, + record_cid.to_string() ) - .bind(user_id) - .bind(&input.collection) - .bind(&rkey) - .bind(record_cid.to_string()) .execute(&state.db) .await;