From: Dessalines Date: Wed, 9 Nov 2022 10:05:00 +0000 (-0500) Subject: Add diesel_async, get rid of blocking function (#2510) X-Git-Url: http://these/git/README.md?a=commitdiff_plain;h=5d837780f5d149cb8d3b861c63a7dc4466a7cbf1;p=lemmy.git Add diesel_async, get rid of blocking function (#2510) * Moving settings to Database. - Moves many settings into the database. Fixes #2285 - Adds a local_site and instance table. Fixes #2365 . Fixes #2368 - Separates SQL update an insert forms, to avoid runtime errors. - Adds TypedBuilder to all the SQL forms, instead of default. * Fix weird clippy issue. * Removing extra lines. * Some fixes from suggestions. * Fixing apub tests. * Using instance creation helper function. * Move forms to their own line. * Trying to fix local_site_data, still broken. * Testing out async * Testing out async 2 * Fixing federation tests. * Trying to fix check features 1. * Starting on adding diesel async. 1/4th done. * Added async to views and schema. * Adding some more async * Compiling now. * Added diesel async. Fixes #2465 * Running clippy --fix * Trying to fix cargo test on drone. * Trying new muslrust. * Trying a custom dns * Trying a custom dns 2 * Trying a custom dns 3 * Trying a custom dns 4 * Trying a custom dns 5 * Trying a custom dns 6 * Trying a custom dns 7 * Addressing PR comments. * Adding check_apub to all verify functions. * Reverting back drone. * Fixing merge * Fix docker images. * Adding missing discussion_languages. * Trying to fix federation tests. * Fix site setup user creation. * Fix clippy * Fix clippy 2 * Test api faster * Try to fix 1 * Try to fix 2 * What are these lines about * Trying to fix 3 * Moving federation test back to top. * Remove logging cat. --- diff --git a/.drone.yml b/.drone.yml index 9f7e2252..fa96258b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -10,8 +10,7 @@ steps: # use minimum supported rust version for most steps - name: prepare repo - image: clux/muslrust:1.59.0 - user: root + image: clux/muslrust:1.64.0 commands: - git fetch --tags - git submodule init @@ -34,7 +33,7 @@ steps: - cargo clippy --workspace --all-features -- -D clippy::unwrap_used - name: cargo test - image: clux/muslrust:1.59.0 + image: clux/muslrust:1.64.0 environment: LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy LEMMY_CONFIG_LOCATION: ../../config/config.hjson @@ -46,20 +45,20 @@ steps: - cargo test --workspace --no-fail-fast --all-features - name: check defaults.hjson updated - image: clux/muslrust:1.59.0 + image: clux/muslrust:1.64.0 commands: - ./scripts/update_config_defaults.sh config/defaults_current.hjson - diff config/defaults.hjson config/defaults_current.hjson - name: check with different features - image: clux/muslrust:1.59.0 + image: clux/muslrust:1.64.0 commands: - cargo install cargo-workspaces - cargo workspaces exec cargo check --no-default-features - cargo workspaces exec cargo check --all-features - name: cargo build - image: clux/muslrust:1.59.0 + image: clux/muslrust:1.64.0 commands: - cargo build - mv target/x86_64-unknown-linux-musl/debug/lemmy_server target/lemmy_server diff --git a/Cargo.lock b/Cargo.lock index 8d50197b..1d6f2940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,7 +12,7 @@ dependencies = [ "actix-web", "anyhow", "async-trait", - "background-jobs 0.13.0", + "background-jobs", "base64", "chrono", "derive_builder 0.11.2", @@ -39,9 +39,9 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07520b54fc0f22ad30b90399b2a2689c6e5c113df0642ca3fa2f7ee823e54126" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -137,7 +137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" dependencies = [ "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "actix-utils" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" dependencies = [ "local-waker", "pin-project-lite", @@ -259,7 +259,7 @@ dependencies = [ "serde_urlencoded", "smallvec", "socket2", - "time 0.3.14", + "time 0.3.15", "url", ] @@ -287,9 +287,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13" dependencies = [ "actix-router", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -298,9 +298,9 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -315,7 +315,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "once_cell", "version_check", ] @@ -338,20 +338,11 @@ dependencies = [ "libc", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "arrayvec" @@ -394,20 +385,20 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] name = "async-trait" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -431,9 +422,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.5.16" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e3356844c4d6a6d6467b8da2cffb4a2820be256f50a3a386c9d152bab31043" +checksum = "acee9fd5073ab6b045a275b3e709c163dd36c90685219cb21804a147b58dba43" dependencies = [ "async-trait", "axum-core", @@ -460,9 +451,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f0c0a60006f2a293d82d571f635042a72edf927539b7685bd62d361963839b" +checksum = "37e5939e02c56fecd5c017c37df4238c0a839fa76b7f97acdd7efb804fd181cc" dependencies = [ "async-trait", "bytes", @@ -474,45 +465,14 @@ dependencies = [ "tower-service", ] -[[package]] -name = "background-jobs" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c301b3ccb60fa2aadb4da111e27b257ddc4f0509848c43c85764dc14f7a49a3" -dependencies = [ - "background-jobs-actix 0.12.0", - "background-jobs-core 0.12.0", -] - [[package]] name = "background-jobs" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793a813f9145c5f3a27b8dcd834c0927de68bbd60d53a369e5894f3cc5759020" dependencies = [ - "background-jobs-actix 0.13.0", - "background-jobs-core 0.13.0", -] - -[[package]] -name = "background-jobs-actix" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65a0dcbc94e0644fcfbaddc19705fae2d6947426682aeab7582d772f4d80b8df" -dependencies = [ - "actix-rt", - "anyhow", - "async-mutex", - "async-trait", - "background-jobs-core 0.12.0", - "num_cpus", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "uuid 0.8.2", + "background-jobs-actix", + "background-jobs-core", ] [[package]] @@ -525,7 +485,7 @@ dependencies = [ "anyhow", "async-mutex", "async-trait", - "background-jobs-core 0.13.0", + "background-jobs-core", "num_cpus", "serde", "serde_json", @@ -533,26 +493,7 @@ dependencies = [ "tokio", "tracing", "tracing-futures", - "uuid 1.1.2", -] - -[[package]] -name = "background-jobs-core" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fe510c99cea8b98c438e81f43c666e9b4cd3630a42a1684ed1d01db4271cfb" -dependencies = [ - "actix-rt", - "anyhow", - "async-mutex", - "async-trait", - "serde", - "serde_json", - "thiserror", - "time 0.3.14", - "tracing", - "tracing-futures", - "uuid 0.8.2", + "uuid", ] [[package]] @@ -568,17 +509,30 @@ dependencies = [ "serde", "serde_json", "thiserror", - "time 0.3.14", + "time 0.3.15", "tracing", "tracing-futures", - "uuid 1.1.2", + "uuid", ] [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bb8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1627eccf3aa91405435ba240be23513eeca466b5dc33866422672264de061582" +dependencies = [ + "async-trait", + "futures-channel", + "futures-util", + "parking_lot", + "tokio", +] [[package]] name = "bcrypt" @@ -588,7 +542,7 @@ checksum = "a7e7c93a3fb23b2fdde989b2c9ec4dd153063ec81f408507f84c090cd91c6641" dependencies = [ "base64", "blowfish", - "getrandom 0.2.7", + "getrandom 0.2.8", "zeroize", ] @@ -646,9 +600,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytemuck" @@ -744,6 +698,16 @@ dependencies = [ "chrono", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -786,7 +750,7 @@ checksum = "e57ff02e8ad8e06ab9731d5dc72dc23bef9200778eae1a89d555d8c42e5d4a86" dependencies = [ "prost 0.11.0", "prost-types 0.11.1", - "tonic 0.8.1", + "tonic 0.8.2", "tracing-core", ] @@ -808,7 +772,7 @@ dependencies = [ "thread_local", "tokio", "tokio-stream", - "tonic 0.8.1", + "tonic 0.8.2", "tracing", "tracing-core", "tracing-subscriber", @@ -822,12 +786,12 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cookie" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05" +checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" dependencies = [ "percent-encoding", - "time 0.3.14", + "time 0.3.15", "version_check", ] @@ -877,12 +841,11 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -895,6 +858,50 @@ dependencies = [ "typenum", ] +[[package]] +name = "cxx" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2 1.0.47", + "quote 1.0.21", + "scratch", + "syn 1.0.103", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7" +dependencies = [ + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.103", +] + [[package]] name = "darling" version = "0.12.4" @@ -933,10 +940,10 @@ checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", "strsim", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -947,10 +954,10 @@ checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", "strsim", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -961,10 +968,10 @@ checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", "strsim", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -975,7 +982,7 @@ checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a" dependencies = [ "darling_core 0.12.4", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -986,7 +993,7 @@ checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core 0.13.4", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -997,7 +1004,7 @@ checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5" dependencies = [ "darling_core 0.14.1", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1038,9 +1045,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5" dependencies = [ "darling 0.12.4", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1050,9 +1057,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" dependencies = [ "darling 0.14.1", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1062,7 +1069,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73" dependencies = [ "derive_builder_core 0.10.2", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1072,7 +1079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" dependencies = [ "derive_builder_core 0.11.2", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1082,10 +1089,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", "rustc_version", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1099,9 +1106,9 @@ dependencies = [ [[package]] name = "diesel" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e2adfd0a7a81070ed7beec0c62636458926326c16fedb77796d41e447b282d" +checksum = "68c186a7418a2aac330bb76cde82f16c36b03a66fb91db32d20214311f9f6545" dependencies = [ "bitflags", "byteorder", @@ -1109,10 +1116,23 @@ dependencies = [ "diesel_derives", "itoa", "pq-sys", - "r2d2", "serde_json", ] +[[package]] +name = "diesel-async" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588383fa6d12fb17edf0fda88942222bbad070d185b5dcc3ac4d8354ce84b583" +dependencies = [ + "async-trait", + "bb8", + "diesel", + "futures", + "tokio", + "tokio-postgres", +] + [[package]] name = "diesel-derive-newtype" version = "2.0.0-rc.0" @@ -1126,14 +1146,14 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a7ab9d7967e6a1a247ea38aedf88ab808b4ac0c159576bc71866ab8f9f9250" +checksum = "143b758c91dbc3fe1fdcb0dba5bd13276c6a66422f2ef5795b58488248a310aa" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1165,6 +1185,7 @@ checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -1215,9 +1236,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6430bef5fcbfa22f3c431f05a14254d45f41ab634cabe09fad82e98d4f9fdc8b" dependencies = [ "darling 0.13.4", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1333,6 +1354,12 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + [[package]] name = "fallible_collections" version = "0.4.5" @@ -1415,9 +1442,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", @@ -1430,9 +1457,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", "futures-sink", @@ -1440,15 +1467,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-executor" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" dependencies = [ "futures-core", "futures-task", @@ -1457,38 +1484,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-macro" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] name = "futures-sink" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-channel", "futures-core", @@ -1525,9 +1552,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -1599,6 +1626,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "hostname" version = "0.3.1" @@ -1632,9 +1668,9 @@ dependencies = [ [[package]] name = "html2text" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617dbbb43af195e64f03eef3b9e412d8374764d88a554332624d83d782da7267" +checksum = "db2a75f4fdb748c0980b4d04f8edafc749bf4b5bfa738bf6c1565c7e6118d6ca" dependencies = [ "html5ever 0.26.0", "markup5ever 0.11.0", @@ -1652,9 +1688,9 @@ dependencies = [ "log", "mac", "markup5ever 0.10.1", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1666,9 +1702,9 @@ dependencies = [ "log", "mac", "markup5ever 0.11.0", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -1814,17 +1850,28 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.50" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd911b35d940d2bd0bea0f9100068e5b97b51a1cbe13d13382f132e0365257a0" +checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" dependencies = [ "android_system_properties", "core-foundation-sys", + "iana-time-zone-haiku", "js-sys", "wasm-bindgen", "winapi", ] +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1854,9 +1901,9 @@ dependencies = [ [[package]] name = "image" -version = "0.24.3" +version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30ca2ecf7666107ff827a8e481de6a132a9b687ed3bb20bb1c144a36c00964" +checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c" dependencies = [ "bytemuck", "byteorder", @@ -1911,9 +1958,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jni" @@ -1993,8 +2040,10 @@ dependencies = [ "lemmy_websocket", "serde", "serde_json", + "serial_test", + "tokio", "tracing", - "uuid 1.1.2", + "uuid", ] [[package]] @@ -2079,9 +2128,10 @@ dependencies = [ "sha2", "strum_macros", "task-local-extensions", + "tokio", "tracing", "url", - "uuid 1.1.2", + "uuid", ] [[package]] @@ -2089,9 +2139,12 @@ name = "lemmy_db_schema" version = "0.16.5" dependencies = [ "activitypub_federation", + "async-trait", + "bb8", "bcrypt", "chrono", "diesel", + "diesel-async", "diesel-derive-newtype", "diesel_ltree", "diesel_migrations", @@ -2104,6 +2157,7 @@ dependencies = [ "sha2", "strum", "strum_macros", + "tokio", "typed-builder", "url", ] @@ -2113,10 +2167,12 @@ name = "lemmy_db_views" version = "0.16.5" dependencies = [ "diesel", + "diesel-async", "diesel_ltree", "lemmy_db_schema", "serde", "serial_test", + "tokio", "tracing", "typed-builder", "url", @@ -2127,6 +2183,7 @@ name = "lemmy_db_views_actor" version = "0.16.5" dependencies = [ "diesel", + "diesel-async", "lemmy_db_schema", "serde", "typed-builder", @@ -2137,6 +2194,7 @@ name = "lemmy_db_views_moderator" version = "0.16.5" dependencies = [ "diesel", + "diesel-async", "lemmy_db_schema", "serde", ] @@ -2178,6 +2236,7 @@ dependencies = [ "clokwerk", "console-subscriber", "diesel", + "diesel-async", "diesel_migrations", "doku", "lemmy_api", @@ -2240,7 +2299,7 @@ dependencies = [ "tracing-error", "typed-builder", "url", - "uuid 1.1.2", + "uuid", ] [[package]] @@ -2251,7 +2310,7 @@ dependencies = [ "actix-web", "actix-web-actors", "anyhow", - "background-jobs 0.12.0", + "background-jobs", "chrono", "diesel", "lemmy_api_common", @@ -2259,7 +2318,7 @@ dependencies = [ "lemmy_db_views", "lemmy_db_views_actor", "lemmy_utils", - "opentelemetry 0.17.0", + "opentelemetry 0.18.0", "rand 0.8.5", "reqwest-middleware", "serde", @@ -2268,7 +2327,7 @@ dependencies = [ "strum_macros", "tokio", "tracing", - "tracing-opentelemetry 0.17.4", + "tracing-opentelemetry 0.18.0", ] [[package]] @@ -2308,9 +2367,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.133" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] [[package]] name = "local-channel" @@ -2342,9 +2410,9 @@ dependencies = [ [[package]] name = "lodepng" -version = "3.7.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff45534ec797452c044fcd47861059eddb501e30a8fd9fdadea7957cdff3ebc7" +checksum = "f0ad39f75bbaa4b10bb6f2316543632a8046a5bcf9c785488d79720b21f044f8" dependencies = [ "crc32fast", "fallible_collections", @@ -2435,6 +2503,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + [[package]] name = "memchr" version = "2.5.0" @@ -2458,7 +2535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a8ff27a350511de30cdabb77147501c36ef02e0451d957abea2f30caffb2b58" dependencies = [ "migrations_internals", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", ] @@ -2502,7 +2579,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -2564,6 +2641,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -2651,9 +2738,9 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -2713,6 +2800,16 @@ dependencies = [ "tokio-stream", ] +[[package]] +name = "opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d6c3d7288a106c0a363e4b0e8d308058d56902adefb16f4936f417ffef086e" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + [[package]] name = "opentelemetry-otlp" version = "0.10.0" @@ -2731,6 +2828,48 @@ dependencies = [ "tonic-build", ] +[[package]] +name = "opentelemetry_api" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22" +dependencies = [ + "fnv", + "futures-channel", + "futures-util", + "indexmap", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113" +dependencies = [ + "async-trait", + "crossbeam-channel", + "dashmap", + "fnv", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "percent-encoding", + "rand 0.8.5", + "thiserror", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.1" @@ -2743,15 +2882,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -2777,9 +2916,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb779fcf4bb850fbbb0edc96ff6cf34fd90c4b1a112ce042653280d9a7364048" +checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a" dependencies = [ "thiserror", "ucd-trie", @@ -2787,9 +2926,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502b62a6d0245378b04ffe0a7fb4f4419a4815fce813bd8a0ec89a56e07d67b1" +checksum = "60b75706b9642ebcb34dab3bc7750f811609a0eb1dd8b88c2d15bf628c1c65b2" dependencies = [ "pest", "pest_generator", @@ -2797,22 +2936,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451e629bf49b750254da26132f1a5a9d11fd8a95a3df51d15c4abd1ba154cb6c" +checksum = "f4f9272122f5979a6511a749af9db9bfc810393f63119970d7085fed1c4ea0db" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] name = "pest_meta" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcec162c71c45e269dfc3fc2916eaeb97feab22993a21bcce4721d08cd7801a6" +checksum = "4c8717927f9b79515e565a64fe46c38b8cd0427e64c40680b14a7365ab09ac8d" dependencies = [ "once_cell", "pest", @@ -2847,6 +2986,15 @@ dependencies = [ "phf_shared 0.10.0", ] +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_shared 0.11.1", +] + [[package]] name = "phf_codegen" version = "0.8.0" @@ -2905,6 +3053,15 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.0.12" @@ -2920,9 +3077,9 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -2955,6 +3112,35 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "postgres-protocol" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878c6cbf956e03af9aa8204b407b9cbf47c072164800aa918c516cd4b056c50c" +dependencies = [ + "base64", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand 0.8.5", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73d946ec7d256b04dfadc4e6a3292324e6f417124750fc5c0950f981b703a0f1" +dependencies = [ + "bytes", + "fallible-iterator", + "postgres-protocol", +] + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -2983,9 +3169,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", "version_check", ] @@ -2995,7 +3181,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", "version_check", ] @@ -3011,9 +3197,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -3066,9 +3252,9 @@ checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -3079,9 +3265,9 @@ checksum = "7345d5f0e08c0536d7ac7229952590239e77abf0a0100a1b1d890add6ea96364" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -3129,7 +3315,7 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", ] [[package]] @@ -3138,17 +3324,6 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fee2dce59f7a43418e3382c766554c614e06a552d53a8f07ef499ea4b332c0f" -[[package]] -name = "r2d2" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" -dependencies = [ - "log", - "parking_lot", - "scheduled-thread-pool", -] - [[package]] name = "radium" version = "0.5.3" @@ -3215,7 +3390,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", ] [[package]] @@ -3251,7 +3426,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "redox_syscall", "thiserror", ] @@ -3425,7 +3600,7 @@ checksum = "6f697b8b3f19bee20f30dc87213d05ce091c43bc733ab1bfc98b0e5cdd9943f3" dependencies = [ "convert_case", "lazy_static", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", "regex", "tinyjson", @@ -3460,9 +3635,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.6" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" dependencies = [ "log", "ring", @@ -3498,16 +3673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", -] - -[[package]] -name = "scheduled-thread-pool" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" -dependencies = [ - "parking_lot", + "windows-sys 0.36.1", ] [[package]] @@ -3516,6 +3682,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + [[package]] name = "sct" version = "0.7.0" @@ -3568,29 +3740,29 @@ checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" [[package]] name = "serde" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "indexmap", "itoa", @@ -3627,9 +3799,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ "darling 0.13.4", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -3653,9 +3825,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b6f5d1c3087fb119617cff2966fe3808a80e5eb59a8c1601d5994d66f4346a5" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -3713,7 +3885,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.14", + "time 0.3.15", ] [[package]] @@ -3733,9 +3905,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smart-default" @@ -3743,9 +3915,9 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -3792,10 +3964,20 @@ checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ "phf_generator 0.10.0", "phf_shared 0.10.0", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", ] +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "strsim" version = "0.10.0" @@ -3815,12 +3997,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.0", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", "rustversion", - "syn 1.0.100", + "syn 1.0.103", ] +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "0.14.9" @@ -3834,11 +4022,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.100" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", "unicode-ident", ] @@ -3889,6 +4077,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.37" @@ -3904,9 +4101,9 @@ version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -3931,9 +4128,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" +checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" dependencies = [ "itoa", "libc", @@ -3971,9 +4168,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.1" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ "autocfg", "bytes", @@ -3981,7 +4178,6 @@ dependencies = [ "memchr", "mio", "num_cpus", - "once_cell", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -4007,9 +4203,9 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -4022,6 +4218,30 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-postgres" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a12c1b3e0704ae7dfc25562629798b29c72e6b1d0a681b6f29ab4ae5e7f7bf" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures-channel", + "futures-util", + "log", + "parking_lot", + "percent-encoding", + "phf 0.11.1", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "socket2", + "tokio", + "tokio-util 0.7.4", +] + [[package]] name = "tokio-rustls" version = "0.23.4" @@ -4035,9 +4255,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6edf2d6bc038a43d31353570e27270603f4648d18f5ed10c0e179abe43255af" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" dependencies = [ "futures-core", "pin-project-lite", @@ -4114,9 +4334,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11cd56bdb54ef93935a6a79dbd1d91f1ebd4c64150fd61654031fd6b8b775c91" +checksum = "55b9af819e54b8f33d453655bef9b9acc171568fb49523078d0cc4e7484200ec" dependencies = [ "async-stream", "async-trait", @@ -4150,10 +4370,10 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "prost-build", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -4197,9 +4417,9 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" [[package]] name = "tower-service" @@ -4209,9 +4429,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "log", @@ -4229,25 +4449,25 @@ dependencies = [ "actix-web", "pin-project", "tracing", - "uuid 1.1.2", + "uuid", ] [[package]] name = "tracing-attributes" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -4311,14 +4531,28 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "tracing-opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ebb87a95ea13271332df069020513ab70bdb5637ca42d6e492dc3bbbad48de" +dependencies = [ + "once_cell", + "opentelemetry 0.18.0", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + [[package]] name = "tracing-subscriber" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ - "ansi_term", "matchers", + "nu-ansi-term", "once_cell", "regex", "sharded-slab", @@ -4347,9 +4581,9 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", ] [[package]] @@ -4381,9 +4615,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-normalization" @@ -4444,21 +4678,11 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom 0.2.7", - "serde", -] - -[[package]] -name = "uuid" -version = "1.1.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" +checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "serde", ] @@ -4538,9 +4762,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", "wasm-bindgen-shared", ] @@ -4572,9 +4796,9 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ - "proc-macro2 1.0.43", + "proc-macro2 1.0.47", "quote 1.0.21", - "syn 1.0.100", + "syn 1.0.103", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4634,9 +4858,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.4" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" dependencies = [ "webpki", ] @@ -4689,43 +4913,100 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "winreg" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index 82962d16..c01d013c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,9 +50,10 @@ lemmy_api_common = { version = "=0.16.5", path = "crates/api_common" } lemmy_websocket = { version = "=0.16.5", path = "./crates/websocket" } lemmy_routes = { version = "=0.16.5", path = "./crates/routes" } activitypub_federation = "0.2.3" -diesel = "2.0.0" +diesel = "2.0.2" diesel_migrations = "2.0.0" -serde = { version = "1.0.145", features = ["derive"] } +diesel-async = "0.1.1" +serde = { version = "1.0.147", features = ["derive"] } actix = "0.13.0" actix-web = { version = "4.2.1", default-features = false, features = ["macros", "rustls"] } tracing = "0.1.36" diff --git a/api_tests/package.json b/api_tests/package.json index 48d87399..82d2f0eb 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -20,7 +20,7 @@ "eslint": "^8.25.0", "eslint-plugin-prettier": "^4.0.0", "jest": "^27.0.6", - "lemmy-js-client": "0.17.0-rc.47", + "lemmy-js-client": "0.17.0-rc.48", "node-fetch": "^2.6.1", "prettier": "^2.7.1", "reflect-metadata": "^0.1.13", diff --git a/api_tests/prepare-drone-federation-test.sh b/api_tests/prepare-drone-federation-test.sh index 3356f0a8..afe18e1d 100755 --- a/api_tests/prepare-drone-federation-test.sh +++ b/api_tests/prepare-drone-federation-test.sh @@ -31,41 +31,35 @@ killall lemmy_server || true echo "$PWD" echo "start alpha" -LEMMY_HOSTNAME=lemmy-alpha:8541 \ - LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_alpha.hjson \ - LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_alpha" \ - LEMMY_HOSTNAME="lemmy-alpha:8541" \ - target/lemmy_server >/tmp/lemmy_alpha.out 2>&1 & +LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_alpha.hjson \ +LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_alpha" \ +target/lemmy_server >/tmp/lemmy_alpha.out 2>&1 & echo "start beta" -LEMMY_HOSTNAME=lemmy-beta:8551 \ - LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_beta.hjson \ - LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_beta" \ - target/lemmy_server >/tmp/lemmy_beta.out 2>&1 & +LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_beta.hjson \ +LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_beta" \ +target/lemmy_server >/tmp/lemmy_beta.out 2>&1 & echo "start gamma" -LEMMY_HOSTNAME=lemmy-gamma:8561 \ - LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_gamma.hjson \ - LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_gamma" \ - target/lemmy_server >/tmp/lemmy_gamma.out 2>&1 & +LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_gamma.hjson \ +LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_gamma" \ +target/lemmy_server >/tmp/lemmy_gamma.out 2>&1 & echo "start delta" # An instance with only an allowlist for beta -LEMMY_HOSTNAME=lemmy-delta:8571 \ - LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_delta.hjson \ - LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_delta" \ - target/lemmy_server >/tmp/lemmy_delta.out 2>&1 & +LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_delta.hjson \ +LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_delta" \ +target/lemmy_server >/tmp/lemmy_delta.out 2>&1 & echo "start epsilon" # An instance who has a blocklist, with lemmy-alpha blocked -LEMMY_HOSTNAME=lemmy-epsilon:8581 \ - LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_epsilon.hjson \ - LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_epsilon" \ - target/lemmy_server >/tmp/lemmy_epsilon.out 2>&1 & +LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_epsilon.hjson \ +LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_epsilon" \ +target/lemmy_server >/tmp/lemmy_epsilon.out 2>&1 & echo "wait for all instances to start" -while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8541/api/v3/site')" != "200" ]]; do sleep 1; done -while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8551/api/v3/site')" != "200" ]]; do sleep 1; done -while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8561/api/v3/site')" != "200" ]]; do sleep 1; done -while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8571/api/v3/site')" != "200" ]]; do sleep 1; done -while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8581/api/v3/site')" != "200" ]]; do sleep 1; done +while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-alpha:8541/api/v3/site')" != "200" ]]; do sleep 1; done +while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-beta:8551/api/v3/site')" != "200" ]]; do sleep 1; done +while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-gamma:8561/api/v3/site')" != "200" ]]; do sleep 1; done +while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-delta:8571/api/v3/site')" != "200" ]]; do sleep 1; done +while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-epsilon:8581/api/v3/site')" != "200" ]]; do sleep 1; done diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 9797ac69..a6b1eef9 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -2373,10 +2373,10 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -lemmy-js-client@0.17.0-rc.47: - version "0.17.0-rc.47" - resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.47.tgz#6094657d2868767532c0e837a31f9af6273b345b" - integrity sha512-Pc1wyr6sX4Z6LS75NVu46WAXeci5G80+Y9ZBXEAmgM+OZGuOCLUq8lAHRvTwr7M0pj0gxo5yP+i3qPVmTPf+EA== +lemmy-js-client@0.17.0-rc.48: + version "0.17.0-rc.48" + resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.48.tgz#6085812d4901b7d12b3fca237d8aced7f5210eac" + integrity sha512-Lz8Nzq/kczQtDj6STlbhxoEarFHtTCoWcWBabyPs6X6em/pfK/cnZqx1mMn7EaBSDUVQ+WL8UNFjQiqjhR4kww== leven@^3.1.0: version "3.1.0" diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 09136b43..51c8808c 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -23,15 +23,19 @@ lemmy_db_views_actor = { version = "=0.16.5", path = "../db_views_actor", featur lemmy_api_common = { version = "=0.16.5", path = "../api_common", features = ["full"] } lemmy_websocket = { version = "=0.16.5", path = "../websocket" } activitypub_federation = "0.2.3" -diesel = "2.0.0" +diesel = "2.0.2" bcrypt = "0.13.0" chrono = { version = "0.4.22", features = ["serde"], default-features = false } -serde_json = { version = "1.0.85", features = ["preserve_order"] } -serde = { version = "1.0.145", features = ["derive"] } +serde_json = { version = "1.0.87", features = ["preserve_order"] } +serde = { version = "1.0.147", features = ["derive"] } actix-web = { version = "4.2.1", default-features = false } -base64 = "0.13.0" -uuid = { version = "1.1.2", features = ["serde", "v4"] } -async-trait = "0.1.57" +base64 = "0.13.1" +uuid = { version = "1.2.1", features = ["serde", "v4"] } +async-trait = "0.1.58" captcha = "0.0.9" -anyhow = "1.0.65" -tracing = "0.1.36" +anyhow = "1.0.66" +tracing = "0.1.37" + +[dev-dependencies] +serial_test = "0.9.0" +tokio = "1.21.2" diff --git a/crates/api/src/comment/like.rs b/crates/api/src/comment/like.rs index 754072ee..6ca87f3c 100644 --- a/crates/api/src/comment/like.rs +++ b/crates/api/src/comment/like.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, CreateCommentLike}, - utils::{blocking, check_community_ban, check_downvotes_enabled, get_local_user_view_from_jwt}, + utils::{check_community_ban, check_downvotes_enabled, get_local_user_view_from_jwt}, }; use lemmy_apub::{ fetcher::post_or_comment::PostOrComment, @@ -36,7 +36,7 @@ impl Perform for CreateCommentLike { websocket_id: Option, ) -> Result { let data: &CreateCommentLike = self; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; @@ -46,10 +46,7 @@ impl Perform for CreateCommentLike { check_downvotes_enabled(data.score, &local_site)?; let comment_id = data.comment_id; - let orig_comment = blocking(context.pool(), move |conn| { - CommentView::read(conn, comment_id, None) - }) - .await??; + let orig_comment = CommentView::read(context.pool(), comment_id, None).await?; check_community_ban( local_user_view.person.id, @@ -59,17 +56,10 @@ impl Perform for CreateCommentLike { .await?; // Add parent poster or commenter to recipients - let comment_reply = blocking(context.pool(), move |conn| { - CommentReply::read_by_comment(conn, comment_id) - }) - .await?; + let comment_reply = CommentReply::read_by_comment(context.pool(), comment_id).await; if let Ok(reply) = comment_reply { let recipient_id = reply.recipient_id; - if let Ok(local_recipient) = blocking(context.pool(), move |conn| { - LocalUserView::read_person(conn, recipient_id) - }) - .await? - { + if let Ok(local_recipient) = LocalUserView::read_person(context.pool(), recipient_id).await { recipient_ids.push(local_recipient.local_user.id); } } @@ -83,10 +73,8 @@ impl Perform for CreateCommentLike { // Remove any likes first let person_id = local_user_view.person.id; - blocking(context.pool(), move |conn| { - CommentLike::remove(conn, person_id, comment_id) - }) - .await??; + + CommentLike::remove(context.pool(), person_id, comment_id).await?; // Only add the like if the score isnt 0 let comment = orig_comment.comment; @@ -94,9 +82,8 @@ impl Perform for CreateCommentLike { let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1); if do_add { let like_form2 = like_form.clone(); - let like = move |conn: &mut _| CommentLike::like(conn, &like_form2); - blocking(context.pool(), like) - .await? + CommentLike::like(context.pool(), &like_form2) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_comment"))?; Vote::send( diff --git a/crates/api/src/comment/save.rs b/crates/api/src/comment/save.rs index e1a26d57..647f0ed5 100644 --- a/crates/api/src/comment/save.rs +++ b/crates/api/src/comment/save.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, SaveComment}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ source::comment::{CommentSaved, CommentSavedForm}, @@ -32,23 +32,18 @@ impl Perform for SaveComment { }; if data.save { - let save_comment = move |conn: &mut _| CommentSaved::save(conn, &comment_saved_form); - blocking(context.pool(), save_comment) - .await? + CommentSaved::save(context.pool(), &comment_saved_form) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_save_comment"))?; } else { - let unsave_comment = move |conn: &mut _| CommentSaved::unsave(conn, &comment_saved_form); - blocking(context.pool(), unsave_comment) - .await? + CommentSaved::unsave(context.pool(), &comment_saved_form) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_save_comment"))?; } let comment_id = data.comment_id; let person_id = local_user_view.person.id; - let comment_view = blocking(context.pool(), move |conn| { - CommentView::read(conn, comment_id, Some(person_id)) - }) - .await??; + let comment_view = CommentView::read(context.pool(), comment_id, Some(person_id)).await?; Ok(CommentResponse { comment_view, diff --git a/crates/api/src/comment_report/create.rs b/crates/api/src/comment_report/create.rs index 5a93fa02..2533aba1 100644 --- a/crates/api/src/comment_report/create.rs +++ b/crates/api/src/comment_report/create.rs @@ -3,7 +3,7 @@ use activitypub_federation::core::object_id::ObjectId; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentReportResponse, CreateCommentReport}, - utils::{blocking, check_community_ban, get_local_user_view_from_jwt}, + utils::{check_community_ban, get_local_user_view_from_jwt}, }; use lemmy_apub::protocol::activities::community::report::Report; use lemmy_db_schema::{ @@ -31,17 +31,14 @@ impl Perform for CreateCommentReport { let data: &CreateCommentReport = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let reason = self.reason.trim(); check_report_reason(reason, &local_site)?; let person_id = local_user_view.person.id; let comment_id = data.comment_id; - let comment_view = blocking(context.pool(), move |conn| { - CommentView::read(conn, comment_id, None) - }) - .await??; + let comment_view = CommentView::read(context.pool(), comment_id, None).await?; check_community_ban(person_id, comment_view.community.id, context.pool()).await?; @@ -52,16 +49,11 @@ impl Perform for CreateCommentReport { reason: reason.to_owned(), }; - let report = blocking(context.pool(), move |conn| { - CommentReport::report(conn, &report_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_report"))?; + let report = CommentReport::report(context.pool(), &report_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_report"))?; - let comment_report_view = blocking(context.pool(), move |conn| { - CommentReportView::read(conn, report.id, person_id) - }) - .await??; + let comment_report_view = CommentReportView::read(context.pool(), report.id, person_id).await?; let res = CommentReportResponse { comment_report_view, diff --git a/crates/api/src/comment_report/list.rs b/crates/api/src/comment_report/list.rs index 3a924aea..4a9041e9 100644 --- a/crates/api/src/comment_report/list.rs +++ b/crates/api/src/comment_report/list.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{ListCommentReports, ListCommentReportsResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_views::comment_report_view::CommentReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -31,19 +31,17 @@ impl Perform for ListCommentReports { let page = data.page; let limit = data.limit; - let comment_reports = blocking(context.pool(), move |conn| { - CommentReportQuery::builder() - .conn(conn) - .my_person_id(person_id) - .admin(admin) - .community_id(community_id) - .unresolved_only(unresolved_only) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + let comment_reports = CommentReportQuery::builder() + .pool(context.pool()) + .my_person_id(person_id) + .admin(admin) + .community_id(community_id) + .unresolved_only(unresolved_only) + .page(page) + .limit(limit) + .build() + .list() + .await?; let res = ListCommentReportsResponse { comment_reports }; diff --git a/crates/api/src/comment_report/resolve.rs b/crates/api/src/comment_report/resolve.rs index c0b8a400..8055e948 100644 --- a/crates/api/src/comment_report/resolve.rs +++ b/crates/api/src/comment_report/resolve.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentReportResponse, ResolveCommentReport}, - utils::{blocking, get_local_user_view_from_jwt, is_mod_or_admin}, + utils::{get_local_user_view_from_jwt, is_mod_or_admin}, }; use lemmy_db_schema::{source::comment_report::CommentReport, traits::Reportable}; use lemmy_db_views::structs::CommentReportView; @@ -26,32 +26,23 @@ impl Perform for ResolveCommentReport { let report_id = data.report_id; let person_id = local_user_view.person.id; - let report = blocking(context.pool(), move |conn| { - CommentReportView::read(conn, report_id, person_id) - }) - .await??; + let report = CommentReportView::read(context.pool(), report_id, person_id).await?; let person_id = local_user_view.person.id; is_mod_or_admin(context.pool(), person_id, report.community.id).await?; - let resolved = data.resolved; - let resolve_fun = move |conn: &mut _| { - if resolved { - CommentReport::resolve(conn, report_id, person_id) - } else { - CommentReport::unresolve(conn, report_id, person_id) - } - }; - - blocking(context.pool(), resolve_fun) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; + if data.resolved { + CommentReport::resolve(context.pool(), report_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; + } else { + CommentReport::unresolve(context.pool(), report_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; + } let report_id = data.report_id; - let comment_report_view = blocking(context.pool(), move |conn| { - CommentReportView::read(conn, report_id, person_id) - }) - .await??; + let comment_report_view = CommentReportView::read(context.pool(), report_id, person_id).await?; let res = CommentReportResponse { comment_report_view, diff --git a/crates/api/src/community/add_mod.rs b/crates/api/src/community/add_mod.rs index f0c5ed17..ff54edda 100644 --- a/crates/api/src/community/add_mod.rs +++ b/crates/api/src/community/add_mod.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{AddModToCommunity, AddModToCommunityResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_mod_or_admin}, + utils::{get_local_user_view_from_jwt, is_mod_or_admin}, }; use lemmy_apub::{ objects::{community::ApubCommunity, person::ApubPerson}, @@ -38,10 +38,7 @@ impl Perform for AddModToCommunity { // Verify that only mods or admins can add mod is_mod_or_admin(context.pool(), local_user_view.person.id, community_id).await?; - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + let community = Community::read(context.pool(), community_id).await?; if local_user_view.person.admin && !community.local { return Err(LemmyError::from_message("not_a_moderator")); } @@ -52,14 +49,12 @@ impl Perform for AddModToCommunity { person_id: data.person_id, }; if data.added { - let join = move |conn: &mut _| CommunityModerator::join(conn, &community_moderator_form); - blocking(context.pool(), join) - .await? + CommunityModerator::join(context.pool(), &community_moderator_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_moderator_already_exists"))?; } else { - let leave = move |conn: &mut _| CommunityModerator::leave(conn, &community_moderator_form); - blocking(context.pool(), leave) - .await? + CommunityModerator::leave(context.pool(), &community_moderator_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_moderator_already_exists"))?; } @@ -70,18 +65,12 @@ impl Perform for AddModToCommunity { community_id: data.community_id, removed: Some(!data.added), }; - blocking(context.pool(), move |conn| { - ModAddCommunity::create(conn, &form) - }) - .await??; + + ModAddCommunity::create(context.pool(), &form).await?; // Send to federated instances let updated_mod_id = data.person_id; - let updated_mod: ApubPerson = blocking(context.pool(), move |conn| { - Person::read(conn, updated_mod_id) - }) - .await?? - .into(); + let updated_mod: ApubPerson = Person::read(context.pool(), updated_mod_id).await?.into(); let community: ApubCommunity = community.into(); if data.added { AddMod::send( @@ -104,10 +93,7 @@ impl Perform for AddModToCommunity { // Note: in case a remote mod is added, this returns the old moderators list, it will only get // updated once we receive an activity from the community (like `Announce/Add/Moderator`) let community_id = data.community_id; - let moderators = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await??; + let moderators = CommunityModeratorView::for_community(context.pool(), community_id).await?; let res = AddModToCommunityResponse { moderators }; context.chat_server().do_send(SendCommunityRoomMessage { diff --git a/crates/api/src/community/ban.rs b/crates/api/src/community/ban.rs index 9ea0c5c9..3b3de914 100644 --- a/crates/api/src/community/ban.rs +++ b/crates/api/src/community/ban.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{BanFromCommunity, BanFromCommunityResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_mod_or_admin, remove_user_data_in_community}, + utils::{get_local_user_view_from_jwt, is_mod_or_admin, remove_user_data_in_community}, }; use lemmy_apub::{ activities::block::SiteOrCommunity, @@ -55,21 +55,12 @@ impl Perform for BanFromCommunity { expires: Some(expires), }; - let community: ApubCommunity = blocking(context.pool(), move |conn: &mut _| { - Community::read(conn, community_id) - }) - .await?? - .into(); - let banned_person: ApubPerson = blocking(context.pool(), move |conn: &mut _| { - Person::read(conn, banned_person_id) - }) - .await?? - .into(); + let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); + let banned_person: ApubPerson = Person::read(context.pool(), banned_person_id).await?.into(); if data.ban { - let ban = move |conn: &mut _| CommunityPersonBan::ban(conn, &community_user_ban_form); - blocking(context.pool(), ban) - .await? + CommunityPersonBan::ban(context.pool(), &community_user_ban_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_user_already_banned"))?; // Also unsubscribe them from the community, if they are subscribed @@ -78,11 +69,10 @@ impl Perform for BanFromCommunity { person_id: banned_person_id, pending: false, }; - blocking(context.pool(), move |conn: &mut _| { - CommunityFollower::unfollow(conn, &community_follower_form) - }) - .await? - .ok(); + + CommunityFollower::unfollow(context.pool(), &community_follower_form) + .await + .ok(); BlockUser::send( &SiteOrCommunity::Community(community), @@ -95,9 +85,8 @@ impl Perform for BanFromCommunity { ) .await?; } else { - let unban = move |conn: &mut _| CommunityPersonBan::unban(conn, &community_user_ban_form); - blocking(context.pool(), unban) - .await? + CommunityPersonBan::unban(context.pool(), &community_user_ban_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_user_already_banned"))?; UndoBlockUser::send( &SiteOrCommunity::Community(community), @@ -123,16 +112,11 @@ impl Perform for BanFromCommunity { banned: Some(data.ban), expires, }; - blocking(context.pool(), move |conn| { - ModBanFromCommunity::create(conn, &form) - }) - .await??; + + ModBanFromCommunity::create(context.pool(), &form).await?; let person_id = data.person_id; - let person_view = blocking(context.pool(), move |conn| { - PersonViewSafe::read(conn, person_id) - }) - .await??; + let person_view = PersonViewSafe::read(context.pool(), person_id).await?; let res = BanFromCommunityResponse { person_view, diff --git a/crates/api/src/community/block.rs b/crates/api/src/community/block.rs index 5f01ac3d..5aaeb831 100644 --- a/crates/api/src/community/block.rs +++ b/crates/api/src/community/block.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{BlockCommunity, BlockCommunityResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_apub::protocol::activities::following::undo_follow::UndoFollowCommunity; use lemmy_db_schema::{ @@ -38,9 +38,8 @@ impl Perform for BlockCommunity { }; if data.block { - let block = move |conn: &mut _| CommunityBlock::block(conn, &community_block_form); - blocking(context.pool(), block) - .await? + CommunityBlock::block(context.pool(), &community_block_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_block_already_exists"))?; // Also, unfollow the community, and send a federated unfollow @@ -49,27 +48,19 @@ impl Perform for BlockCommunity { person_id, pending: false, }; - blocking(context.pool(), move |conn: &mut _| { - CommunityFollower::unfollow(conn, &community_follower_form) - }) - .await? - .ok(); - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + + CommunityFollower::unfollow(context.pool(), &community_follower_form) + .await + .ok(); + let community = Community::read(context.pool(), community_id).await?; UndoFollowCommunity::send(&local_user_view.person.into(), &community.into(), context).await?; } else { - let unblock = move |conn: &mut _| CommunityBlock::unblock(conn, &community_block_form); - blocking(context.pool(), unblock) - .await? + CommunityBlock::unblock(context.pool(), &community_block_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_block_already_exists"))?; } - let community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, community_id, Some(person_id)) - }) - .await??; + let community_view = CommunityView::read(context.pool(), community_id, Some(person_id)).await?; Ok(BlockCommunityResponse { blocked: data.block, diff --git a/crates/api/src/community/follow.rs b/crates/api/src/community/follow.rs index 7a5e3198..8a68646e 100644 --- a/crates/api/src/community/follow.rs +++ b/crates/api/src/community/follow.rs @@ -2,12 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, FollowCommunity}, - utils::{ - blocking, - check_community_ban, - check_community_deleted_or_removed, - get_local_user_view_from_jwt, - }, + utils::{check_community_ban, check_community_deleted_or_removed, get_local_user_view_from_jwt}, }; use lemmy_apub::{ objects::community::ApubCommunity, @@ -39,11 +34,7 @@ impl Perform for FollowCommunity { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let community_id = data.community_id; - let community: ApubCommunity = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await?? - .into(); + let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); let community_follower_form = CommunityFollowerForm { community_id: data.community_id, person_id: local_user_view.person.id, @@ -55,15 +46,12 @@ impl Perform for FollowCommunity { check_community_ban(local_user_view.person.id, community_id, context.pool()).await?; check_community_deleted_or_removed(community_id, context.pool()).await?; - let follow = move |conn: &mut _| CommunityFollower::follow(conn, &community_follower_form); - blocking(context.pool(), follow) - .await? + CommunityFollower::follow(context.pool(), &community_follower_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; } else { - let unfollow = - move |conn: &mut _| CommunityFollower::unfollow(conn, &community_follower_form); - blocking(context.pool(), unfollow) - .await? + CommunityFollower::unfollow(context.pool(), &community_follower_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; } } else if data.follow { @@ -74,19 +62,14 @@ impl Perform for FollowCommunity { } else { UndoFollowCommunity::send(&local_user_view.person.clone().into(), &community, context) .await?; - let unfollow = - move |conn: &mut _| CommunityFollower::unfollow(conn, &community_follower_form); - blocking(context.pool(), unfollow) - .await? + CommunityFollower::unfollow(context.pool(), &community_follower_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; } let community_id = data.community_id; let person_id = local_user_view.person.id; - let community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, community_id, Some(person_id)) - }) - .await??; + let community_view = CommunityView::read(context.pool(), community_id, Some(person_id)).await?; Ok(Self::Response { community_view }) } diff --git a/crates/api/src/community/hide.rs b/crates/api/src/community/hide.rs index 278d492d..111a89d0 100644 --- a/crates/api/src/community/hide.rs +++ b/crates/api/src/community/hide.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, HideCommunity}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_apub::protocol::activities::community::update::UpdateCommunity; use lemmy_db_schema::{ @@ -44,16 +44,11 @@ impl Perform for HideCommunity { }; let community_id = data.community_id; - let updated_community = blocking(context.pool(), move |conn| { - Community::update(conn, community_id, &community_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community_hidden_status"))?; + let updated_community = Community::update(context.pool(), community_id, &community_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community_hidden_status"))?; - blocking(context.pool(), move |conn| { - ModHideCommunity::create(conn, &mod_hide_community_form) - }) - .await??; + ModHideCommunity::create(context.pool(), &mod_hide_community_form).await?; UpdateCommunity::send( updated_community.into(), diff --git a/crates/api/src/community/transfer.rs b/crates/api/src/community/transfer.rs index 36664108..5da0d8e3 100644 --- a/crates/api/src/community/transfer.rs +++ b/crates/api/src/community/transfer.rs @@ -3,7 +3,7 @@ use actix_web::web::Data; use anyhow::Context; use lemmy_api_common::{ community::{GetCommunityResponse, TransferCommunity}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ source::{ @@ -32,14 +32,12 @@ impl Perform for TransferCommunity { let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let admins = blocking(context.pool(), PersonViewSafe::admins).await??; + let admins = PersonViewSafe::admins(context.pool()).await?; // Fetch the community mods let community_id = data.community_id; - let mut community_mods = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await??; + let mut community_mods = + CommunityModeratorView::for_community(context.pool(), community_id).await?; // Make sure transferrer is either the top community mod, or an admin if local_user_view.person.id != community_mods[0].moderator.id @@ -62,10 +60,8 @@ impl Perform for TransferCommunity { // Delete all the mods let community_id = data.community_id; - blocking(context.pool(), move |conn| { - CommunityModerator::delete_for_community(conn, community_id) - }) - .await??; + + CommunityModerator::delete_for_community(context.pool(), community_id).await?; // TODO: this should probably be a bulk operation // Re-add the mods, in the new order @@ -75,9 +71,8 @@ impl Perform for TransferCommunity { person_id: cmod.moderator.id, }; - let join = move |conn: &mut _| CommunityModerator::join(conn, &community_moderator_form); - blocking(context.pool(), join) - .await? + CommunityModerator::join(context.pool(), &community_moderator_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_moderator_already_exists"))?; } @@ -88,25 +83,19 @@ impl Perform for TransferCommunity { community_id: data.community_id, removed: Some(false), }; - blocking(context.pool(), move |conn| { - ModTransferCommunity::create(conn, &form) - }) - .await??; + + ModTransferCommunity::create(context.pool(), &form).await?; let community_id = data.community_id; let person_id = local_user_view.person.id; - let community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, community_id, Some(person_id)) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; + let community_view = CommunityView::read(context.pool(), community_id, Some(person_id)) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; let community_id = data.community_id; - let moderators = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; + let moderators = CommunityModeratorView::for_community(context.pool(), community_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; // Return the jwt Ok(GetCommunityResponse { diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 595ab10f..40026d89 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -253,17 +253,19 @@ mod tests { secret::Secret, }, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use lemmy_utils::{claims::Claims, settings::SETTINGS}; + use serial_test::serial; - #[test] - fn test_should_not_validate_user_token_after_password_change() { - let conn = &mut establish_unpooled_connection(); - let secret = Secret::init(conn).unwrap(); + #[tokio::test] + #[serial] + async fn test_should_not_validate_user_token_after_password_change() { + let pool = &build_db_pool_for_tests().await; + let secret = Secret::init(pool).await.unwrap(); let settings = &SETTINGS.to_owned(); - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("Gerry9812".into()) @@ -271,14 +273,14 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let local_user_form = LocalUserInsertForm::builder() .person_id(inserted_person.id) .password_encrypted("123456".to_string()) .build(); - let inserted_local_user = LocalUser::create(conn, &local_user_form).unwrap(); + let inserted_local_user = LocalUser::create(pool, &local_user_form).await.unwrap(); let jwt = Claims::jwt( inserted_local_user.id.0, @@ -292,11 +294,13 @@ mod tests { // The check should fail, since the validator time is now newer than the jwt issue time let updated_local_user = - LocalUser::update_password(conn, inserted_local_user.id, "password111").unwrap(); + LocalUser::update_password(pool, inserted_local_user.id, "password111") + .await + .unwrap(); let check_after = check_validator_time(&updated_local_user.validator_time, &claims); assert!(check_after.is_err()); - let num_deleted = Person::delete(conn, inserted_person.id).unwrap(); + let num_deleted = Person::delete(pool, inserted_person.id).await.unwrap(); assert_eq!(1, num_deleted); } } diff --git a/crates/api/src/local_user/add_admin.rs b/crates/api/src/local_user/add_admin.rs index 2561906e..ceca80f9 100644 --- a/crates/api/src/local_user/add_admin.rs +++ b/crates/api/src/local_user/add_admin.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{AddAdmin, AddAdminResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_schema::{ source::{ @@ -34,14 +34,12 @@ impl Perform for AddAdmin { let added = data.added; let added_person_id = data.person_id; - let added_admin = blocking(context.pool(), move |conn| { - Person::update( - conn, - added_person_id, - &PersonUpdateForm::builder().admin(Some(added)).build(), - ) - }) - .await? + let added_admin = Person::update( + context.pool(), + added_person_id, + &PersonUpdateForm::builder().admin(Some(added)).build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_user"))?; // Mod tables @@ -51,9 +49,9 @@ impl Perform for AddAdmin { removed: Some(!data.added), }; - blocking(context.pool(), move |conn| ModAdd::create(conn, &form)).await??; + ModAdd::create(context.pool(), &form).await?; - let admins = blocking(context.pool(), PersonViewSafe::admins).await??; + let admins = PersonViewSafe::admins(context.pool()).await?; let res = AddAdminResponse { admins }; diff --git a/crates/api/src/local_user/ban_person.rs b/crates/api/src/local_user/ban_person.rs index f9dc83e0..27814192 100644 --- a/crates/api/src/local_user/ban_person.rs +++ b/crates/api/src/local_user/ban_person.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{BanPerson, BanPersonResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_admin, remove_user_data}, + utils::{get_local_user_view_from_jwt, is_admin, remove_user_data}, }; use lemmy_apub::{ activities::block::SiteOrCommunity, @@ -41,17 +41,15 @@ impl Perform for BanPerson { let banned_person_id = data.person_id; let expires = data.expires.map(naive_from_unix); - let person = blocking(context.pool(), move |conn| { - Person::update( - conn, - banned_person_id, - &PersonUpdateForm::builder() - .banned(Some(ban)) - .ban_expires(Some(expires)) - .build(), - ) - }) - .await? + let person = Person::update( + context.pool(), + banned_person_id, + &PersonUpdateForm::builder() + .banned(Some(ban)) + .ban_expires(Some(expires)) + .build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_user"))?; // Remove their data if that's desired @@ -75,20 +73,12 @@ impl Perform for BanPerson { expires, }; - blocking(context.pool(), move |conn| ModBan::create(conn, &form)).await??; + ModBan::create(context.pool(), &form).await?; let person_id = data.person_id; - let person_view = blocking(context.pool(), move |conn| { - PersonViewSafe::read(conn, person_id) - }) - .await??; + let person_view = PersonViewSafe::read(context.pool(), person_id).await?; - let site = SiteOrCommunity::Site( - blocking(context.pool(), SiteView::read_local) - .await?? - .site - .into(), - ); + let site = SiteOrCommunity::Site(SiteView::read_local(context.pool()).await?.site.into()); // if the action affects a local user, federate to other instances if person.local { if ban { diff --git a/crates/api/src/local_user/block.rs b/crates/api/src/local_user/block.rs index 3f1b36f2..44bd668f 100644 --- a/crates/api/src/local_user/block.rs +++ b/crates/api/src/local_user/block.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{BlockPerson, BlockPersonResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ source::person_block::{PersonBlock, PersonBlockForm}, @@ -39,24 +39,19 @@ impl Perform for BlockPerson { target_id, }; - let target_person_view = blocking(context.pool(), move |conn| { - PersonViewSafe::read(conn, target_id) - }) - .await??; + let target_person_view = PersonViewSafe::read(context.pool(), target_id).await?; if target_person_view.person.admin { return Err(LemmyError::from_message("cant_block_admin")); } if data.block { - let block = move |conn: &mut _| PersonBlock::block(conn, &person_block_form); - blocking(context.pool(), block) - .await? + PersonBlock::block(context.pool(), &person_block_form) + .await .map_err(|e| LemmyError::from_error_message(e, "person_block_already_exists"))?; } else { - let unblock = move |conn: &mut _| PersonBlock::unblock(conn, &person_block_form); - blocking(context.pool(), unblock) - .await? + PersonBlock::unblock(context.pool(), &person_block_form) + .await .map_err(|e| LemmyError::from_error_message(e, "person_block_already_exists"))?; } diff --git a/crates/api/src/local_user/change_password.rs b/crates/api/src/local_user/change_password.rs index 6143fc4f..f13ff9c9 100644 --- a/crates/api/src/local_user/change_password.rs +++ b/crates/api/src/local_user/change_password.rs @@ -3,7 +3,7 @@ use actix_web::web::Data; use bcrypt::verify; use lemmy_api_common::{ person::{ChangePassword, LoginResponse}, - utils::{blocking, get_local_user_view_from_jwt, password_length_check}, + utils::{get_local_user_view_from_jwt, password_length_check}, }; use lemmy_db_schema::source::local_user::LocalUser; use lemmy_utils::{claims::Claims, error::LemmyError, ConnectionId}; @@ -42,10 +42,8 @@ impl Perform for ChangePassword { let local_user_id = local_user_view.local_user.id; let new_password = data.new_password.to_owned(); - let updated_local_user = blocking(context.pool(), move |conn| { - LocalUser::update_password(conn, local_user_id, &new_password) - }) - .await??; + let updated_local_user = + LocalUser::update_password(context.pool(), local_user_id, &new_password).await?; // Return the jwt Ok(LoginResponse { diff --git a/crates/api/src/local_user/change_password_after_reset.rs b/crates/api/src/local_user/change_password_after_reset.rs index cc4c7400..2086a275 100644 --- a/crates/api/src/local_user/change_password_after_reset.rs +++ b/crates/api/src/local_user/change_password_after_reset.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{LoginResponse, PasswordChangeAfterReset}, - utils::{blocking, password_length_check}, + utils::password_length_check, }; use lemmy_db_schema::source::{ local_user::LocalUser, @@ -25,10 +25,9 @@ impl Perform for PasswordChangeAfterReset { // Fetch the user_id from the token let token = data.token.clone(); - let local_user_id = blocking(context.pool(), move |conn| { - PasswordResetRequest::read_from_token(conn, &token).map(|p| p.local_user_id) - }) - .await??; + let local_user_id = PasswordResetRequest::read_from_token(context.pool(), &token) + .await + .map(|p| p.local_user_id)?; password_length_check(&data.password)?; @@ -39,11 +38,9 @@ impl Perform for PasswordChangeAfterReset { // Update the user with the new password let password = data.password.clone(); - let updated_local_user = blocking(context.pool(), move |conn| { - LocalUser::update_password(conn, local_user_id, &password) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_user"))?; + let updated_local_user = LocalUser::update_password(context.pool(), local_user_id, &password) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_user"))?; // Return the jwt Ok(LoginResponse { diff --git a/crates/api/src/local_user/get_captcha.rs b/crates/api/src/local_user/get_captcha.rs index 1d2511f5..c6063efc 100644 --- a/crates/api/src/local_user/get_captcha.rs +++ b/crates/api/src/local_user/get_captcha.rs @@ -2,10 +2,7 @@ use crate::{captcha_as_wav_base64, Perform}; use actix_web::web::Data; use captcha::{gen, Difficulty}; use chrono::Duration; -use lemmy_api_common::{ - person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse}, - utils::blocking, -}; +use lemmy_api_common::person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse}; use lemmy_db_schema::{source::local_site::LocalSite, utils::naive_now}; use lemmy_utils::{error::LemmyError, ConnectionId}; use lemmy_websocket::{messages::CaptchaItem, LemmyContext}; @@ -20,7 +17,7 @@ impl Perform for GetCaptcha { context: &Data, _websocket_id: Option, ) -> Result { - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; if !local_site.captcha_enabled { return Ok(GetCaptchaResponse { ok: None }); diff --git a/crates/api/src/local_user/list_banned.rs b/crates/api/src/local_user/list_banned.rs index 5423bdbe..16df72cc 100644 --- a/crates/api/src/local_user/list_banned.rs +++ b/crates/api/src/local_user/list_banned.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{BannedPersonsResponse, GetBannedPersons}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -24,7 +24,7 @@ impl Perform for GetBannedPersons { // Make sure user is an admin is_admin(&local_user_view)?; - let banned = blocking(context.pool(), PersonViewSafe::banned).await??; + let banned = PersonViewSafe::banned(context.pool()).await?; let res = Self::Response { banned }; diff --git a/crates/api/src/local_user/login.rs b/crates/api/src/local_user/login.rs index 990424c0..61354387 100644 --- a/crates/api/src/local_user/login.rs +++ b/crates/api/src/local_user/login.rs @@ -3,7 +3,7 @@ use actix_web::web::Data; use bcrypt::verify; use lemmy_api_common::{ person::{Login, LoginResponse}, - utils::{blocking, check_registration_application, check_user_valid}, + utils::{check_registration_application, check_user_valid}, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::LocalUserView; @@ -22,15 +22,13 @@ impl Perform for Login { ) -> Result { let data: &Login = self; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; // Fetch that username / email let username_or_email = data.username_or_email.clone(); - let local_user_view = blocking(context.pool(), move |conn| { - LocalUserView::find_by_email_or_name(conn, &username_or_email) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_that_username_or_email"))?; + let local_user_view = LocalUserView::find_by_email_or_name(context.pool(), &username_or_email) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_that_username_or_email"))?; // Verify the password let valid: bool = verify( diff --git a/crates/api/src/local_user/notifications/list_mentions.rs b/crates/api/src/local_user/notifications/list_mentions.rs index b331012b..d231f718 100644 --- a/crates/api/src/local_user/notifications/list_mentions.rs +++ b/crates/api/src/local_user/notifications/list_mentions.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{GetPersonMentions, GetPersonMentionsResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_views_actor::person_mention_view::PersonMentionQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -29,20 +29,18 @@ impl Perform for GetPersonMentions { let person_id = Some(local_user_view.person.id); let show_bot_accounts = Some(local_user_view.local_user.show_bot_accounts); - let mentions = blocking(context.pool(), move |conn| { - PersonMentionQuery::builder() - .conn(conn) - .recipient_id(person_id) - .my_person_id(person_id) - .sort(sort) - .unread_only(unread_only) - .show_bot_accounts(show_bot_accounts) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + let mentions = PersonMentionQuery::builder() + .pool(context.pool()) + .recipient_id(person_id) + .my_person_id(person_id) + .sort(sort) + .unread_only(unread_only) + .show_bot_accounts(show_bot_accounts) + .page(page) + .limit(limit) + .build() + .list() + .await?; Ok(GetPersonMentionsResponse { mentions }) } diff --git a/crates/api/src/local_user/notifications/list_replies.rs b/crates/api/src/local_user/notifications/list_replies.rs index 9a92f625..10222998 100644 --- a/crates/api/src/local_user/notifications/list_replies.rs +++ b/crates/api/src/local_user/notifications/list_replies.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{GetReplies, GetRepliesResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_views_actor::comment_reply_view::CommentReplyQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -29,20 +29,18 @@ impl Perform for GetReplies { let person_id = Some(local_user_view.person.id); let show_bot_accounts = Some(local_user_view.local_user.show_bot_accounts); - let replies = blocking(context.pool(), move |conn| { - CommentReplyQuery::builder() - .conn(conn) - .recipient_id(person_id) - .my_person_id(person_id) - .sort(sort) - .unread_only(unread_only) - .show_bot_accounts(show_bot_accounts) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + let replies = CommentReplyQuery::builder() + .pool(context.pool()) + .recipient_id(person_id) + .my_person_id(person_id) + .sort(sort) + .unread_only(unread_only) + .show_bot_accounts(show_bot_accounts) + .page(page) + .limit(limit) + .build() + .list() + .await?; Ok(GetRepliesResponse { replies }) } diff --git a/crates/api/src/local_user/notifications/mark_all_read.rs b/crates/api/src/local_user/notifications/mark_all_read.rs index b50f87c3..3b8ad0f4 100644 --- a/crates/api/src/local_user/notifications/mark_all_read.rs +++ b/crates/api/src/local_user/notifications/mark_all_read.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{GetRepliesResponse, MarkAllAsRead}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::source::{ comment_reply::CommentReply, @@ -28,25 +28,19 @@ impl Perform for MarkAllAsRead { let person_id = local_user_view.person.id; // Mark all comment_replies as read - blocking(context.pool(), move |conn| { - CommentReply::mark_all_as_read(conn, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; + CommentReply::mark_all_as_read(context.pool(), person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; // Mark all user mentions as read - blocking(context.pool(), move |conn| { - PersonMention::mark_all_as_read(conn, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; + PersonMention::mark_all_as_read(context.pool(), person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; // Mark all private_messages as read - blocking(context.pool(), move |conn| { - PrivateMessage::mark_all_as_read(conn, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_private_message"))?; + PrivateMessage::mark_all_as_read(context.pool(), person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_private_message"))?; Ok(GetRepliesResponse { replies: vec![] }) } diff --git a/crates/api/src/local_user/notifications/mark_mention_read.rs b/crates/api/src/local_user/notifications/mark_mention_read.rs index 134b4311..c42e294a 100644 --- a/crates/api/src/local_user/notifications/mark_mention_read.rs +++ b/crates/api/src/local_user/notifications/mark_mention_read.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{MarkPersonMentionAsRead, PersonMentionResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ source::person_mention::{PersonMention, PersonMentionUpdateForm}, @@ -27,10 +27,7 @@ impl Perform for MarkPersonMentionAsRead { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let person_mention_id = data.person_mention_id; - let read_person_mention = blocking(context.pool(), move |conn| { - PersonMention::read(conn, person_mention_id) - }) - .await??; + let read_person_mention = PersonMention::read(context.pool(), person_mention_id).await?; if local_user_view.person.id != read_person_mention.recipient_id { return Err(LemmyError::from_message("couldnt_update_comment")); @@ -38,18 +35,18 @@ impl Perform for MarkPersonMentionAsRead { let person_mention_id = read_person_mention.id; let read = Some(data.read); - blocking(context.pool(), move |conn| { - PersonMention::update(conn, person_mention_id, &PersonMentionUpdateForm { read }) - }) - .await? + PersonMention::update( + context.pool(), + person_mention_id, + &PersonMentionUpdateForm { read }, + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; let person_mention_id = read_person_mention.id; let person_id = local_user_view.person.id; - let person_mention_view = blocking(context.pool(), move |conn| { - PersonMentionView::read(conn, person_mention_id, Some(person_id)) - }) - .await??; + let person_mention_view = + PersonMentionView::read(context.pool(), person_mention_id, Some(person_id)).await?; Ok(PersonMentionResponse { person_mention_view, diff --git a/crates/api/src/local_user/notifications/mark_reply_read.rs b/crates/api/src/local_user/notifications/mark_reply_read.rs index e270d547..2ec5fd80 100644 --- a/crates/api/src/local_user/notifications/mark_reply_read.rs +++ b/crates/api/src/local_user/notifications/mark_reply_read.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{CommentReplyResponse, MarkCommentReplyAsRead}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ source::comment_reply::{CommentReply, CommentReplyUpdateForm}, @@ -27,10 +27,7 @@ impl Perform for MarkCommentReplyAsRead { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let comment_reply_id = data.comment_reply_id; - let read_comment_reply = blocking(context.pool(), move |conn| { - CommentReply::read(conn, comment_reply_id) - }) - .await??; + let read_comment_reply = CommentReply::read(context.pool(), comment_reply_id).await?; if local_user_view.person.id != read_comment_reply.recipient_id { return Err(LemmyError::from_message("couldnt_update_comment")); @@ -38,18 +35,19 @@ impl Perform for MarkCommentReplyAsRead { let comment_reply_id = read_comment_reply.id; let read = Some(data.read); - blocking(context.pool(), move |conn| { - CommentReply::update(conn, comment_reply_id, &CommentReplyUpdateForm { read }) - }) - .await? + + CommentReply::update( + context.pool(), + comment_reply_id, + &CommentReplyUpdateForm { read }, + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; let comment_reply_id = read_comment_reply.id; let person_id = local_user_view.person.id; - let comment_reply_view = blocking(context.pool(), move |conn| { - CommentReplyView::read(conn, comment_reply_id, Some(person_id)) - }) - .await??; + let comment_reply_view = + CommentReplyView::read(context.pool(), comment_reply_id, Some(person_id)).await?; Ok(CommentReplyResponse { comment_reply_view }) } diff --git a/crates/api/src/local_user/notifications/unread_count.rs b/crates/api/src/local_user/notifications/unread_count.rs index 93307ed5..47d826fd 100644 --- a/crates/api/src/local_user/notifications/unread_count.rs +++ b/crates/api/src/local_user/notifications/unread_count.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{GetUnreadCount, GetUnreadCountResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_views::structs::PrivateMessageView; use lemmy_db_views_actor::structs::{CommentReplyView, PersonMentionView}; @@ -25,20 +25,12 @@ impl Perform for GetUnreadCount { let person_id = local_user_view.person.id; - let replies = blocking(context.pool(), move |conn| { - CommentReplyView::get_unread_replies(conn, person_id) - }) - .await??; + let replies = CommentReplyView::get_unread_replies(context.pool(), person_id).await?; - let mentions = blocking(context.pool(), move |conn| { - PersonMentionView::get_unread_mentions(conn, person_id) - }) - .await??; + let mentions = PersonMentionView::get_unread_mentions(context.pool(), person_id).await?; - let private_messages = blocking(context.pool(), move |conn| { - PrivateMessageView::get_unread_messages(conn, person_id) - }) - .await??; + let private_messages = + PrivateMessageView::get_unread_messages(context.pool(), person_id).await?; let res = Self::Response { replies, diff --git a/crates/api/src/local_user/report_count.rs b/crates/api/src/local_user/report_count.rs index a6556f6c..1372e4ca 100644 --- a/crates/api/src/local_user/report_count.rs +++ b/crates/api/src/local_user/report_count.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{GetReportCount, GetReportCountResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_views::structs::{CommentReportView, PostReportView, PrivateMessageReportView}; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -26,23 +26,14 @@ impl Perform for GetReportCount { let admin = local_user_view.person.admin; let community_id = data.community_id; - let comment_reports = blocking(context.pool(), move |conn| { - CommentReportView::get_report_count(conn, person_id, admin, community_id) - }) - .await??; + let comment_reports = + CommentReportView::get_report_count(context.pool(), person_id, admin, community_id).await?; - let post_reports = blocking(context.pool(), move |conn| { - PostReportView::get_report_count(conn, person_id, admin, community_id) - }) - .await??; + let post_reports = + PostReportView::get_report_count(context.pool(), person_id, admin, community_id).await?; let private_message_reports = if admin && community_id.is_none() { - Some( - blocking(context.pool(), move |conn| { - PrivateMessageReportView::get_report_count(conn) - }) - .await??, - ) + Some(PrivateMessageReportView::get_report_count(context.pool()).await?) } else { None }; diff --git a/crates/api/src/local_user/reset_password.rs b/crates/api/src/local_user/reset_password.rs index dbf959e1..078d55ec 100644 --- a/crates/api/src/local_user/reset_password.rs +++ b/crates/api/src/local_user/reset_password.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{PasswordReset, PasswordResetResponse}, - utils::{blocking, send_password_reset_email}, + utils::send_password_reset_email, }; use lemmy_db_views::structs::LocalUserView; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -22,11 +22,9 @@ impl Perform for PasswordReset { // Fetch that email let email = data.email.to_lowercase(); - let local_user_view = blocking(context.pool(), move |conn| { - LocalUserView::find_by_email(conn, &email) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_that_username_or_email"))?; + let local_user_view = LocalUserView::find_by_email(context.pool(), &email) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_that_username_or_email"))?; // Email the pure token to the user. send_password_reset_email(&local_user_view, context.pool(), context.settings()).await?; diff --git a/crates/api/src/local_user/save_settings.rs b/crates/api/src/local_user/save_settings.rs index eac1eef0..232c6a9b 100644 --- a/crates/api/src/local_user/save_settings.rs +++ b/crates/api/src/local_user/save_settings.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{LoginResponse, SaveUserSettings}, - utils::{blocking, get_local_user_view_from_jwt, send_verification_email}, + utils::{get_local_user_view_from_jwt, send_verification_email}, }; use lemmy_db_schema::{ source::{ @@ -35,7 +35,7 @@ impl Perform for SaveUserSettings { let data: &SaveUserSettings = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let avatar = diesel_option_overwrite_to_url(&data.avatar)?; let banner = diesel_option_overwrite_to_url(&data.banner)?; @@ -97,17 +97,12 @@ impl Perform for SaveUserSettings { .banner(banner) .build(); - blocking(context.pool(), move |conn| { - Person::update(conn, person_id, &person_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "user_already_exists"))?; + Person::update(context.pool(), person_id, &person_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "user_already_exists"))?; if let Some(discussion_languages) = data.discussion_languages.clone() { - blocking(context.pool(), move |conn| { - LocalUserLanguage::update(conn, discussion_languages, local_user_id) - }) - .await??; + LocalUserLanguage::update(context.pool(), discussion_languages, local_user_id).await?; } let local_user_form = LocalUserUpdateForm::builder() @@ -125,10 +120,7 @@ impl Perform for SaveUserSettings { .interface_language(data.interface_language.to_owned()) .build(); - let local_user_res = blocking(context.pool(), move |conn| { - LocalUser::update(conn, local_user_id, &local_user_form) - }) - .await?; + let local_user_res = LocalUser::update(context.pool(), local_user_id, &local_user_form).await; let updated_local_user = match local_user_res { Ok(u) => u, Err(e) => { diff --git a/crates/api/src/local_user/verify_email.rs b/crates/api/src/local_user/verify_email.rs index e4f43af1..73db4bea 100644 --- a/crates/api/src/local_user/verify_email.rs +++ b/crates/api/src/local_user/verify_email.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ person::{VerifyEmail, VerifyEmailResponse}, - utils::{blocking, send_email_verification_success}, + utils::send_email_verification_success, }; use lemmy_db_schema::{ source::{ @@ -25,11 +25,9 @@ impl Perform for VerifyEmail { _websocket_id: Option, ) -> Result { let token = self.token.clone(); - let verification = blocking(context.pool(), move |conn| { - EmailVerification::read_for_token(conn, &token) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "token_not_found"))?; + let verification = EmailVerification::read_for_token(context.pool(), &token) + .await + .map_err(|e| LemmyError::from_error_message(e, "token_not_found"))?; let form = LocalUserUpdateForm::builder() // necessary in case this is a new signup @@ -38,22 +36,14 @@ impl Perform for VerifyEmail { .email(Some(Some(verification.email))) .build(); let local_user_id = verification.local_user_id; - blocking(context.pool(), move |conn| { - LocalUser::update(conn, local_user_id, &form) - }) - .await??; - let local_user_view = blocking(context.pool(), move |conn| { - LocalUserView::read(conn, local_user_id) - }) - .await??; + LocalUser::update(context.pool(), local_user_id, &form).await?; + + let local_user_view = LocalUserView::read(context.pool(), local_user_id).await?; send_email_verification_success(&local_user_view, context.settings())?; - blocking(context.pool(), move |conn| { - EmailVerification::delete_old_tokens_for_local_user(conn, local_user_id) - }) - .await??; + EmailVerification::delete_old_tokens_for_local_user(context.pool(), local_user_id).await?; Ok(VerifyEmailResponse {}) } diff --git a/crates/api/src/post/like.rs b/crates/api/src/post/like.rs index ee29a021..ec2edc33 100644 --- a/crates/api/src/post/like.rs +++ b/crates/api/src/post/like.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ post::{CreatePostLike, PostResponse}, utils::{ - blocking, check_community_ban, check_community_deleted_or_removed, check_downvotes_enabled, @@ -42,16 +41,14 @@ impl Perform for CreatePostLike { let data: &CreatePostLike = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; // Don't do a downvote if site has downvotes disabled check_downvotes_enabled(data.score, &local_site)?; // Check for a community ban let post_id = data.post_id; - let post: ApubPost = blocking(context.pool(), move |conn| Post::read(conn, post_id)) - .await?? - .into(); + let post: ApubPost = Post::read(context.pool(), post_id).await?.into(); check_community_ban(local_user_view.person.id, post.community_id, context.pool()).await?; check_community_deleted_or_removed(post.community_id, context.pool()).await?; @@ -64,10 +61,8 @@ impl Perform for CreatePostLike { // Remove any likes first let person_id = local_user_view.person.id; - blocking(context.pool(), move |conn| { - PostLike::remove(conn, person_id, post_id) - }) - .await??; + + PostLike::remove(context.pool(), person_id, post_id).await?; let community_id = post.community_id; let object = PostOrComment::Post(Box::new(post)); @@ -76,9 +71,8 @@ impl Perform for CreatePostLike { let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1); if do_add { let like_form2 = like_form.clone(); - let like = move |conn: &mut _| PostLike::like(conn, &like_form2); - blocking(context.pool(), like) - .await? + PostLike::like(context.pool(), &like_form2) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_post"))?; Vote::send( diff --git a/crates/api/src/post/lock.rs b/crates/api/src/post/lock.rs index 5ce26c5e..d47088e8 100644 --- a/crates/api/src/post/lock.rs +++ b/crates/api/src/post/lock.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ post::{LockPost, PostResponse}, utils::{ - blocking, check_community_ban, check_community_deleted_or_removed, get_local_user_view_from_jwt, @@ -39,7 +38,7 @@ impl Perform for LockPost { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let post_id = data.post_id; - let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let orig_post = Post::read(context.pool(), post_id).await?; check_community_ban( local_user_view.person.id, @@ -60,14 +59,12 @@ impl Perform for LockPost { // Update the post let post_id = data.post_id; let locked = data.locked; - let updated_post: ApubPost = blocking(context.pool(), move |conn| { - Post::update( - conn, - post_id, - &PostUpdateForm::builder().locked(Some(locked)).build(), - ) - }) - .await?? + let updated_post: ApubPost = Post::update( + context.pool(), + post_id, + &PostUpdateForm::builder().locked(Some(locked)).build(), + ) + .await? .into(); // Mod tables @@ -76,7 +73,7 @@ impl Perform for LockPost { post_id: data.post_id, locked: Some(locked), }; - blocking(context.pool(), move |conn| ModLockPost::create(conn, &form)).await??; + ModLockPost::create(context.pool(), &form).await?; // apub updates CreateOrUpdatePost::send( diff --git a/crates/api/src/post/mark_read.rs b/crates/api/src/post/mark_read.rs index 07659ea8..18f86521 100644 --- a/crates/api/src/post/mark_read.rs +++ b/crates/api/src/post/mark_read.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ post::{MarkPostAsRead, PostResponse}, - utils::{blocking, get_local_user_view_from_jwt, mark_post_as_read, mark_post_as_unread}, + utils::{get_local_user_view_from_jwt, mark_post_as_read, mark_post_as_unread}, }; use lemmy_db_views::structs::PostView; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -33,10 +33,7 @@ impl Perform for MarkPostAsRead { } // Fetch it - let post_view = blocking(context.pool(), move |conn| { - PostView::read(conn, post_id, Some(person_id)) - }) - .await??; + let post_view = PostView::read(context.pool(), post_id, Some(person_id)).await?; let res = Self::Response { post_view }; diff --git a/crates/api/src/post/save.rs b/crates/api/src/post/save.rs index ff41581c..0a240f9e 100644 --- a/crates/api/src/post/save.rs +++ b/crates/api/src/post/save.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ post::{PostResponse, SavePost}, - utils::{blocking, get_local_user_view_from_jwt, mark_post_as_read}, + utils::{get_local_user_view_from_jwt, mark_post_as_read}, }; use lemmy_db_schema::{ source::post::{PostSaved, PostSavedForm}, @@ -32,23 +32,18 @@ impl Perform for SavePost { }; if data.save { - let save = move |conn: &mut _| PostSaved::save(conn, &post_saved_form); - blocking(context.pool(), save) - .await? + PostSaved::save(context.pool(), &post_saved_form) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_save_post"))?; } else { - let unsave = move |conn: &mut _| PostSaved::unsave(conn, &post_saved_form); - blocking(context.pool(), unsave) - .await? + PostSaved::unsave(context.pool(), &post_saved_form) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_save_post"))?; } let post_id = data.post_id; let person_id = local_user_view.person.id; - let post_view = blocking(context.pool(), move |conn| { - PostView::read(conn, post_id, Some(person_id)) - }) - .await??; + let post_view = PostView::read(context.pool(), post_id, Some(person_id)).await?; // Mark the post as read mark_post_as_read(person_id, post_id, context.pool()).await?; diff --git a/crates/api/src/post/sticky.rs b/crates/api/src/post/sticky.rs index 629de9d6..ec4c39a8 100644 --- a/crates/api/src/post/sticky.rs +++ b/crates/api/src/post/sticky.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ post::{PostResponse, StickyPost}, utils::{ - blocking, check_community_ban, check_community_deleted_or_removed, get_local_user_view_from_jwt, @@ -39,7 +38,7 @@ impl Perform for StickyPost { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let post_id = data.post_id; - let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let orig_post = Post::read(context.pool(), post_id).await?; check_community_ban( local_user_view.person.id, @@ -60,14 +59,12 @@ impl Perform for StickyPost { // Update the post let post_id = data.post_id; let stickied = data.stickied; - let updated_post: ApubPost = blocking(context.pool(), move |conn| { - Post::update( - conn, - post_id, - &PostUpdateForm::builder().stickied(Some(stickied)).build(), - ) - }) - .await?? + let updated_post: ApubPost = Post::update( + context.pool(), + post_id, + &PostUpdateForm::builder().stickied(Some(stickied)).build(), + ) + .await? .into(); // Mod tables @@ -76,10 +73,8 @@ impl Perform for StickyPost { post_id: data.post_id, stickied: Some(stickied), }; - blocking(context.pool(), move |conn| { - ModStickyPost::create(conn, &form) - }) - .await??; + + ModStickyPost::create(context.pool(), &form).await?; // Apub updates // TODO stickied should pry work like locked for ease of use diff --git a/crates/api/src/post_report/create.rs b/crates/api/src/post_report/create.rs index 24379f46..ca4113a3 100644 --- a/crates/api/src/post_report/create.rs +++ b/crates/api/src/post_report/create.rs @@ -3,7 +3,7 @@ use activitypub_federation::core::object_id::ObjectId; use actix_web::web::Data; use lemmy_api_common::{ post::{CreatePostReport, PostReportResponse}, - utils::{blocking, check_community_ban, get_local_user_view_from_jwt}, + utils::{check_community_ban, get_local_user_view_from_jwt}, }; use lemmy_apub::protocol::activities::community::report::Report; use lemmy_db_schema::{ @@ -31,17 +31,14 @@ impl Perform for CreatePostReport { let data: &CreatePostReport = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let reason = self.reason.trim(); check_report_reason(reason, &local_site)?; let person_id = local_user_view.person.id; let post_id = data.post_id; - let post_view = blocking(context.pool(), move |conn| { - PostView::read(conn, post_id, None) - }) - .await??; + let post_view = PostView::read(context.pool(), post_id, None).await?; check_community_ban(person_id, post_view.community.id, context.pool()).await?; @@ -54,16 +51,11 @@ impl Perform for CreatePostReport { reason: reason.to_owned(), }; - let report = blocking(context.pool(), move |conn| { - PostReport::report(conn, &report_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_report"))?; + let report = PostReport::report(context.pool(), &report_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_report"))?; - let post_report_view = blocking(context.pool(), move |conn| { - PostReportView::read(conn, report.id, person_id) - }) - .await??; + let post_report_view = PostReportView::read(context.pool(), report.id, person_id).await?; let res = PostReportResponse { post_report_view }; diff --git a/crates/api/src/post_report/list.rs b/crates/api/src/post_report/list.rs index 3a4d9dcc..7a79f04b 100644 --- a/crates/api/src/post_report/list.rs +++ b/crates/api/src/post_report/list.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ post::{ListPostReports, ListPostReportsResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_views::post_report_view::PostReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -31,19 +31,17 @@ impl Perform for ListPostReports { let page = data.page; let limit = data.limit; - let post_reports = blocking(context.pool(), move |conn| { - PostReportQuery::builder() - .conn(conn) - .my_person_id(person_id) - .admin(admin) - .community_id(community_id) - .unresolved_only(unresolved_only) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + let post_reports = PostReportQuery::builder() + .pool(context.pool()) + .my_person_id(person_id) + .admin(admin) + .community_id(community_id) + .unresolved_only(unresolved_only) + .page(page) + .limit(limit) + .build() + .list() + .await?; let res = ListPostReportsResponse { post_reports }; diff --git a/crates/api/src/post_report/resolve.rs b/crates/api/src/post_report/resolve.rs index 120a76f1..687bdcce 100644 --- a/crates/api/src/post_report/resolve.rs +++ b/crates/api/src/post_report/resolve.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ post::{PostReportResponse, ResolvePostReport}, - utils::{blocking, get_local_user_view_from_jwt, is_mod_or_admin}, + utils::{get_local_user_view_from_jwt, is_mod_or_admin}, }; use lemmy_db_schema::{source::post_report::PostReport, traits::Reportable}; use lemmy_db_views::structs::PostReportView; @@ -26,31 +26,22 @@ impl Perform for ResolvePostReport { let report_id = data.report_id; let person_id = local_user_view.person.id; - let report = blocking(context.pool(), move |conn| { - PostReportView::read(conn, report_id, person_id) - }) - .await??; + let report = PostReportView::read(context.pool(), report_id, person_id).await?; let person_id = local_user_view.person.id; is_mod_or_admin(context.pool(), person_id, report.community.id).await?; - let resolved = data.resolved; - let resolve_fun = move |conn: &mut _| { - if resolved { - PostReport::resolve(conn, report_id, person_id) - } else { - PostReport::unresolve(conn, report_id, person_id) - } - }; - - blocking(context.pool(), resolve_fun) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; - - let post_report_view = blocking(context.pool(), move |conn| { - PostReportView::read(conn, report_id, person_id) - }) - .await??; + if data.resolved { + PostReport::resolve(context.pool(), report_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; + } else { + PostReport::unresolve(context.pool(), report_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; + } + + let post_report_view = PostReportView::read(context.pool(), report_id, person_id).await?; let res = PostReportResponse { post_report_view }; diff --git a/crates/api/src/private_message/mark_read.rs b/crates/api/src/private_message/mark_read.rs index 6a5737ce..0b7bb676 100644 --- a/crates/api/src/private_message/mark_read.rs +++ b/crates/api/src/private_message/mark_read.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ private_message::{MarkPrivateMessageAsRead, PrivateMessageResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ source::private_message::{PrivateMessage, PrivateMessageUpdateForm}, @@ -27,10 +27,7 @@ impl Perform for MarkPrivateMessageAsRead { // Checking permissions let private_message_id = data.private_message_id; - let orig_private_message = blocking(context.pool(), move |conn| { - PrivateMessage::read(conn, private_message_id) - }) - .await??; + let orig_private_message = PrivateMessage::read(context.pool(), private_message_id).await?; if local_user_view.person.id != orig_private_message.recipient_id { return Err(LemmyError::from_message("couldnt_update_private_message")); } @@ -38,14 +35,12 @@ impl Perform for MarkPrivateMessageAsRead { // Doing the update let private_message_id = data.private_message_id; let read = data.read; - blocking(context.pool(), move |conn| { - PrivateMessage::update( - conn, - private_message_id, - &PrivateMessageUpdateForm::builder().read(Some(read)).build(), - ) - }) - .await? + PrivateMessage::update( + context.pool(), + private_message_id, + &PrivateMessageUpdateForm::builder().read(Some(read)).build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_private_message"))?; // No need to send an apub update diff --git a/crates/api/src/private_message_report/create.rs b/crates/api/src/private_message_report/create.rs index 8e661b79..490fd55b 100644 --- a/crates/api/src/private_message_report/create.rs +++ b/crates/api/src/private_message_report/create.rs @@ -2,7 +2,7 @@ use crate::{check_report_reason, Perform}; use actix_web::web::Data; use lemmy_api_common::{ private_message::{CreatePrivateMessageReport, PrivateMessageReportResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ newtypes::CommunityId, @@ -29,17 +29,14 @@ impl Perform for CreatePrivateMessageReport { ) -> Result { let local_user_view = get_local_user_view_from_jwt(&self.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let reason = self.reason.trim(); check_report_reason(reason, &local_site)?; let person_id = local_user_view.person.id; let private_message_id = self.private_message_id; - let private_message = blocking(context.pool(), move |conn| { - PrivateMessage::read(conn, private_message_id) - }) - .await??; + let private_message = PrivateMessage::read(context.pool(), private_message_id).await?; let report_form = PrivateMessageReportForm { creator_id: person_id, @@ -48,16 +45,12 @@ impl Perform for CreatePrivateMessageReport { reason: reason.to_owned(), }; - let report = blocking(context.pool(), move |conn| { - PrivateMessageReport::report(conn, &report_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_report"))?; + let report = PrivateMessageReport::report(context.pool(), &report_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_report"))?; - let private_message_report_view = blocking(context.pool(), move |conn| { - PrivateMessageReportView::read(conn, report.id) - }) - .await??; + let private_message_report_view = + PrivateMessageReportView::read(context.pool(), report.id).await?; let res = PrivateMessageReportResponse { private_message_report_view, diff --git a/crates/api/src/private_message_report/list.rs b/crates/api/src/private_message_report/list.rs index 6e530309..0279cb83 100644 --- a/crates/api/src/private_message_report/list.rs +++ b/crates/api/src/private_message_report/list.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ private_message::{ListPrivateMessageReports, ListPrivateMessageReportsResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_views::private_message_report_view::PrivateMessageReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -26,16 +26,14 @@ impl Perform for ListPrivateMessageReports { let unresolved_only = self.unresolved_only; let page = self.page; let limit = self.limit; - let private_message_reports = blocking(context.pool(), move |conn| { - PrivateMessageReportQuery::builder() - .conn(conn) - .unresolved_only(unresolved_only) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + let private_message_reports = PrivateMessageReportQuery::builder() + .pool(context.pool()) + .unresolved_only(unresolved_only) + .page(page) + .limit(limit) + .build() + .list() + .await?; let res = ListPrivateMessageReportsResponse { private_message_reports, diff --git a/crates/api/src/private_message_report/resolve.rs b/crates/api/src/private_message_report/resolve.rs index 03aab70b..a7af798a 100644 --- a/crates/api/src/private_message_report/resolve.rs +++ b/crates/api/src/private_message_report/resolve.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ private_message::{PrivateMessageReportResponse, ResolvePrivateMessageReport}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_schema::{ newtypes::CommunityId, @@ -28,25 +28,20 @@ impl Perform for ResolvePrivateMessageReport { is_admin(&local_user_view)?; - let resolved = self.resolved; let report_id = self.report_id; let person_id = local_user_view.person.id; - let resolve_fn = move |conn: &mut _| { - if resolved { - PrivateMessageReport::resolve(conn, report_id, person_id) - } else { - PrivateMessageReport::unresolve(conn, report_id, person_id) - } - }; - - blocking(context.pool(), resolve_fn) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; - - let private_message_report_view = blocking(context.pool(), move |conn| { - PrivateMessageReportView::read(conn, report_id) - }) - .await??; + if self.resolved { + PrivateMessageReport::resolve(context.pool(), report_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; + } else { + PrivateMessageReport::unresolve(context.pool(), report_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?; + } + + let private_message_report_view = + PrivateMessageReportView::read(context.pool(), report_id).await?; let res = PrivateMessageReportResponse { private_message_report_view, diff --git a/crates/api/src/site/leave_admin.rs b/crates/api/src/site/leave_admin.rs index 9ba48f65..aee747be 100644 --- a/crates/api/src/site/leave_admin.rs +++ b/crates/api/src/site/leave_admin.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ site::{GetSiteResponse, LeaveAdmin}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_schema::{ source::{ @@ -35,20 +35,18 @@ impl Perform for LeaveAdmin { is_admin(&local_user_view)?; // Make sure there isn't just one admin (so if one leaves, there will still be one left) - let admins = blocking(context.pool(), PersonViewSafe::admins).await??; + let admins = PersonViewSafe::admins(context.pool()).await?; if admins.len() == 1 { return Err(LemmyError::from_message("cannot_leave_admin")); } let person_id = local_user_view.person.id; - blocking(context.pool(), move |conn| { - Person::update( - conn, - person_id, - &PersonUpdateForm::builder().admin(Some(false)).build(), - ) - }) - .await??; + Person::update( + context.pool(), + person_id, + &PersonUpdateForm::builder().admin(Some(false)).build(), + ) + .await?; // Mod tables let form = ModAddForm { @@ -57,14 +55,14 @@ impl Perform for LeaveAdmin { removed: Some(true), }; - blocking(context.pool(), move |conn| ModAdd::create(conn, &form)).await??; + ModAdd::create(context.pool(), &form).await?; // Reread site and admins - let site_view = blocking(context.pool(), SiteView::read_local).await??; - let admins = blocking(context.pool(), PersonViewSafe::admins).await??; + let site_view = SiteView::read_local(context.pool()).await?; + let admins = PersonViewSafe::admins(context.pool()).await?; - let all_languages = blocking(context.pool(), Language::read_all).await??; - let discussion_languages = blocking(context.pool(), SiteLanguage::read_local).await??; + let all_languages = Language::read_all(context.pool()).await?; + let discussion_languages = SiteLanguage::read_local(context.pool()).await?; Ok(GetSiteResponse { site_view, diff --git a/crates/api/src/site/mod_log.rs b/crates/api/src/site/mod_log.rs index 6241c509..f1ab9f45 100644 --- a/crates/api/src/site/mod_log.rs +++ b/crates/api/src/site/mod_log.rs @@ -2,13 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ site::{GetModlog, GetModlogResponse}, - utils::{ - blocking, - check_private_instance, - get_local_user_view_from_jwt_opt, - is_admin, - is_mod_or_admin, - }, + utils::{check_private_instance, get_local_user_view_from_jwt_opt, is_admin, is_mod_or_admin}, }; use lemmy_db_schema::{ newtypes::{CommunityId, PersonId}, @@ -52,7 +46,7 @@ impl Perform for GetModlog { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; @@ -88,81 +82,43 @@ impl Perform for GetModlog { hide_modlog_names, }; let removed_posts = match type_ { - All | ModRemovePost => { - blocking(context.pool(), move |conn| { - ModRemovePostView::list(conn, params) - }) - .await?? - } + All | ModRemovePost => ModRemovePostView::list(context.pool(), params).await?, _ => Default::default(), }; let locked_posts = match type_ { - All | ModLockPost => { - blocking(context.pool(), move |conn| { - ModLockPostView::list(conn, params) - }) - .await?? - } + All | ModLockPost => ModLockPostView::list(context.pool(), params).await?, _ => Default::default(), }; let stickied_posts = match type_ { - All | ModStickyPost => { - blocking(context.pool(), move |conn| { - ModStickyPostView::list(conn, params) - }) - .await?? - } + All | ModStickyPost => ModStickyPostView::list(context.pool(), params).await?, _ => Default::default(), }; let removed_comments = match type_ { - All | ModRemoveComment => { - blocking(context.pool(), move |conn| { - ModRemoveCommentView::list(conn, params) - }) - .await?? - } + All | ModRemoveComment => ModRemoveCommentView::list(context.pool(), params).await?, _ => Default::default(), }; let banned_from_community = match type_ { - All | ModBanFromCommunity => { - blocking(context.pool(), move |conn| { - ModBanFromCommunityView::list(conn, params) - }) - .await?? - } + All | ModBanFromCommunity => ModBanFromCommunityView::list(context.pool(), params).await?, _ => Default::default(), }; let added_to_community = match type_ { - All | ModAddCommunity => { - blocking(context.pool(), move |conn| { - ModAddCommunityView::list(conn, params) - }) - .await?? - } + All | ModAddCommunity => ModAddCommunityView::list(context.pool(), params).await?, _ => Default::default(), }; let transferred_to_community = match type_ { - All | ModTransferCommunity => { - blocking(context.pool(), move |conn| { - ModTransferCommunityView::list(conn, params) - }) - .await?? - } + All | ModTransferCommunity => ModTransferCommunityView::list(context.pool(), params).await?, _ => Default::default(), }; let hidden_communities = match type_ { All | ModHideCommunity if other_person_id.is_none() => { - blocking(context.pool(), move |conn| { - ModHideCommunityView::list(conn, params) - }) - .await?? + ModHideCommunityView::list(context.pool(), params).await? } _ => Default::default(), }; @@ -177,49 +133,46 @@ impl Perform for GetModlog { admin_purged_posts, admin_purged_comments, ) = if data.community_id.is_none() { - blocking(context.pool(), move |conn| { - Ok(( - match type_ { - All | ModBan => ModBanView::list(conn, params)?, - _ => Default::default(), - }, - match type_ { - All | ModAdd => ModAddView::list(conn, params)?, - _ => Default::default(), - }, - match type_ { - All | ModRemoveCommunity if other_person_id.is_none() => { - ModRemoveCommunityView::list(conn, params)? - } - _ => Default::default(), - }, - match type_ { - All | AdminPurgePerson if other_person_id.is_none() => { - AdminPurgePersonView::list(conn, params)? - } - _ => Default::default(), - }, - match type_ { - All | AdminPurgeCommunity if other_person_id.is_none() => { - AdminPurgeCommunityView::list(conn, params)? - } - _ => Default::default(), - }, - match type_ { - All | AdminPurgePost if other_person_id.is_none() => { - AdminPurgePostView::list(conn, params)? - } - _ => Default::default(), - }, - match type_ { - All | AdminPurgeComment if other_person_id.is_none() => { - AdminPurgeCommentView::list(conn, params)? - } - _ => Default::default(), - }, - )) as Result<_, LemmyError> - }) - .await?? + ( + match type_ { + All | ModBan => ModBanView::list(context.pool(), params).await?, + _ => Default::default(), + }, + match type_ { + All | ModAdd => ModAddView::list(context.pool(), params).await?, + _ => Default::default(), + }, + match type_ { + All | ModRemoveCommunity if other_person_id.is_none() => { + ModRemoveCommunityView::list(context.pool(), params).await? + } + _ => Default::default(), + }, + match type_ { + All | AdminPurgePerson if other_person_id.is_none() => { + AdminPurgePersonView::list(context.pool(), params).await? + } + _ => Default::default(), + }, + match type_ { + All | AdminPurgeCommunity if other_person_id.is_none() => { + AdminPurgeCommunityView::list(context.pool(), params).await? + } + _ => Default::default(), + }, + match type_ { + All | AdminPurgePost if other_person_id.is_none() => { + AdminPurgePostView::list(context.pool(), params).await? + } + _ => Default::default(), + }, + match type_ { + All | AdminPurgeComment if other_person_id.is_none() => { + AdminPurgeCommentView::list(context.pool(), params).await? + } + _ => Default::default(), + }, + ) } else { Default::default() }; diff --git a/crates/api/src/site/purge/comment.rs b/crates/api/src/site/purge/comment.rs index e8509318..fa4b508a 100644 --- a/crates/api/src/site/purge/comment.rs +++ b/crates/api/src/site/purge/comment.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ site::{PurgeComment, PurgeItemResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_schema::{ source::{ @@ -34,16 +34,13 @@ impl Perform for PurgeComment { let comment_id = data.comment_id; // Read the comment to get the post_id - let comment = blocking(context.pool(), move |conn| Comment::read(conn, comment_id)).await??; + let comment = Comment::read(context.pool(), comment_id).await?; let post_id = comment.post_id; // TODO read comments for pictrs images and purge them - blocking(context.pool(), move |conn| { - Comment::delete(conn, comment_id) - }) - .await??; + Comment::delete(context.pool(), comment_id).await?; // Mod tables let reason = data.reason.to_owned(); @@ -53,10 +50,7 @@ impl Perform for PurgeComment { post_id, }; - blocking(context.pool(), move |conn| { - AdminPurgeComment::create(conn, &form) - }) - .await??; + AdminPurgeComment::create(context.pool(), &form).await?; Ok(PurgeItemResponse { success: true }) } diff --git a/crates/api/src/site/purge/community.rs b/crates/api/src/site/purge/community.rs index 5f1e3888..33781834 100644 --- a/crates/api/src/site/purge/community.rs +++ b/crates/api/src/site/purge/community.rs @@ -3,7 +3,7 @@ use actix_web::web::Data; use lemmy_api_common::{ request::purge_image_from_pictrs, site::{PurgeCommunity, PurgeItemResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_admin, purge_image_posts_for_community}, + utils::{get_local_user_view_from_jwt, is_admin, purge_image_posts_for_community}, }; use lemmy_db_schema::{ source::{ @@ -35,10 +35,7 @@ impl Perform for PurgeCommunity { let community_id = data.community_id; // Read the community to get its images - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + let community = Community::read(context.pool(), community_id).await?; if let Some(banner) = community.banner { purge_image_from_pictrs(context.client(), context.settings(), &banner) @@ -60,10 +57,7 @@ impl Perform for PurgeCommunity { ) .await?; - blocking(context.pool(), move |conn| { - Community::delete(conn, community_id) - }) - .await??; + Community::delete(context.pool(), community_id).await?; // Mod tables let reason = data.reason.to_owned(); @@ -72,10 +66,7 @@ impl Perform for PurgeCommunity { reason, }; - blocking(context.pool(), move |conn| { - AdminPurgeCommunity::create(conn, &form) - }) - .await??; + AdminPurgeCommunity::create(context.pool(), &form).await?; Ok(PurgeItemResponse { success: true }) } diff --git a/crates/api/src/site/purge/person.rs b/crates/api/src/site/purge/person.rs index 350b9a47..6ac30276 100644 --- a/crates/api/src/site/purge/person.rs +++ b/crates/api/src/site/purge/person.rs @@ -3,7 +3,7 @@ use actix_web::web::Data; use lemmy_api_common::{ request::purge_image_from_pictrs, site::{PurgeItemResponse, PurgePerson}, - utils::{blocking, get_local_user_view_from_jwt, is_admin, purge_image_posts_for_person}, + utils::{get_local_user_view_from_jwt, is_admin, purge_image_posts_for_person}, }; use lemmy_db_schema::{ source::{ @@ -34,7 +34,7 @@ impl Perform for PurgePerson { // Read the person to get their images let person_id = data.person_id; - let person = blocking(context.pool(), move |conn| Person::read(conn, person_id)).await??; + let person = Person::read(context.pool(), person_id).await?; if let Some(banner) = person.banner { purge_image_from_pictrs(context.client(), context.settings(), &banner) @@ -56,7 +56,7 @@ impl Perform for PurgePerson { ) .await?; - blocking(context.pool(), move |conn| Person::delete(conn, person_id)).await??; + Person::delete(context.pool(), person_id).await?; // Mod tables let reason = data.reason.to_owned(); @@ -65,10 +65,7 @@ impl Perform for PurgePerson { reason, }; - blocking(context.pool(), move |conn| { - AdminPurgePerson::create(conn, &form) - }) - .await??; + AdminPurgePerson::create(context.pool(), &form).await?; Ok(PurgeItemResponse { success: true }) } diff --git a/crates/api/src/site/purge/post.rs b/crates/api/src/site/purge/post.rs index b7e13ade..ca10bb8c 100644 --- a/crates/api/src/site/purge/post.rs +++ b/crates/api/src/site/purge/post.rs @@ -3,7 +3,7 @@ use actix_web::web::Data; use lemmy_api_common::{ request::purge_image_from_pictrs, site::{PurgeItemResponse, PurgePost}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_schema::{ source::{ @@ -35,7 +35,7 @@ impl Perform for PurgePost { let post_id = data.post_id; // Read the post to get the community_id - let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let post = Post::read(context.pool(), post_id).await?; // Purge image if let Some(url) = post.url { @@ -52,7 +52,7 @@ impl Perform for PurgePost { let community_id = post.community_id; - blocking(context.pool(), move |conn| Post::delete(conn, post_id)).await??; + Post::delete(context.pool(), post_id).await?; // Mod tables let reason = data.reason.to_owned(); @@ -62,10 +62,7 @@ impl Perform for PurgePost { community_id, }; - blocking(context.pool(), move |conn| { - AdminPurgePost::create(conn, &form) - }) - .await??; + AdminPurgePost::create(context.pool(), &form).await?; Ok(PurgeItemResponse { success: true }) } diff --git a/crates/api/src/site/registration_applications/approve.rs b/crates/api/src/site/registration_applications/approve.rs index 129e92b7..bb125259 100644 --- a/crates/api/src/site/registration_applications/approve.rs +++ b/crates/api/src/site/registration_applications/approve.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ site::{ApproveRegistrationApplication, RegistrationApplicationResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_admin, send_application_approved_email}, + utils::{get_local_user_view_from_jwt, is_admin, send_application_approved_email}, }; use lemmy_db_schema::{ source::{ @@ -41,10 +41,8 @@ impl Perform for ApproveRegistrationApplication { deny_reason, }; - let registration_application = blocking(context.pool(), move |conn| { - RegistrationApplication::update(conn, app_id, &app_form) - }) - .await??; + let registration_application = + RegistrationApplication::update(context.pool(), app_id, &app_form).await?; // Update the local_user row let local_user_form = LocalUserUpdateForm::builder() @@ -52,16 +50,10 @@ impl Perform for ApproveRegistrationApplication { .build(); let approved_user_id = registration_application.local_user_id; - blocking(context.pool(), move |conn| { - LocalUser::update(conn, approved_user_id, &local_user_form) - }) - .await??; + LocalUser::update(context.pool(), approved_user_id, &local_user_form).await?; if data.approve { - let approved_local_user_view = blocking(context.pool(), move |conn| { - LocalUserView::read(conn, approved_user_id) - }) - .await??; + let approved_local_user_view = LocalUserView::read(context.pool(), approved_user_id).await?; if approved_local_user_view.local_user.email.is_some() { send_application_approved_email(&approved_local_user_view, context.settings())?; @@ -69,10 +61,8 @@ impl Perform for ApproveRegistrationApplication { } // Read the view - let registration_application = blocking(context.pool(), move |conn| { - RegistrationApplicationView::read(conn, app_id) - }) - .await??; + let registration_application = + RegistrationApplicationView::read(context.pool(), app_id).await?; Ok(Self::Response { registration_application, diff --git a/crates/api/src/site/registration_applications/list.rs b/crates/api/src/site/registration_applications/list.rs index 9329151b..3d9ed326 100644 --- a/crates/api/src/site/registration_applications/list.rs +++ b/crates/api/src/site/registration_applications/list.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ site::{ListRegistrationApplications, ListRegistrationApplicationsResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::registration_application_view::RegistrationApplicationQuery; @@ -22,7 +22,7 @@ impl Perform for ListRegistrationApplications { let data = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; // Make sure user is an admin is_admin(&local_user_view)?; @@ -32,17 +32,15 @@ impl Perform for ListRegistrationApplications { let page = data.page; let limit = data.limit; - let registration_applications = blocking(context.pool(), move |conn| { - RegistrationApplicationQuery::builder() - .conn(conn) - .unread_only(unread_only) - .verified_email_only(Some(verified_email_only)) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + let registration_applications = RegistrationApplicationQuery::builder() + .pool(context.pool()) + .unread_only(unread_only) + .verified_email_only(Some(verified_email_only)) + .page(page) + .limit(limit) + .build() + .list() + .await?; let res = Self::Response { registration_applications, diff --git a/crates/api/src/site/registration_applications/unread_count.rs b/crates/api/src/site/registration_applications/unread_count.rs index 32db67bb..7fb8906a 100644 --- a/crates/api/src/site/registration_applications/unread_count.rs +++ b/crates/api/src/site/registration_applications/unread_count.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ site::{GetUnreadRegistrationApplicationCount, GetUnreadRegistrationApplicationCountResponse}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::RegistrationApplicationView; @@ -21,17 +21,15 @@ impl Perform for GetUnreadRegistrationApplicationCount { let data = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; // Only let admins do this is_admin(&local_user_view)?; let verified_email_only = local_site.require_email_verification; - let registration_applications = blocking(context.pool(), move |conn| { - RegistrationApplicationView::get_unread_count(conn, verified_email_only) - }) - .await??; + let registration_applications = + RegistrationApplicationView::get_unread_count(context.pool(), verified_email_only).await?; Ok(Self::Response { registration_applications, diff --git a/crates/api/src/site/resolve_object.rs b/crates/api/src/site/resolve_object.rs index 5d322eec..816522c7 100644 --- a/crates/api/src/site/resolve_object.rs +++ b/crates/api/src/site/resolve_object.rs @@ -3,7 +3,7 @@ use actix_web::web::Data; use diesel::NotFound; use lemmy_api_common::{ site::{ResolveObject, ResolveObjectResponse}, - utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt}, + utils::{check_private_instance, get_local_user_view_from_jwt_opt}, }; use lemmy_apub::fetcher::search::{search_query_to_object_id, SearchableObjects}; use lemmy_db_schema::{newtypes::PersonId, source::local_site::LocalSite, utils::DbPool}; @@ -25,7 +25,7 @@ impl Perform for ResolveObject { let local_user_view = get_local_user_view_from_jwt_opt(self.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; let res = search_query_to_object_id(&self.q, local_user_view.is_none(), context) @@ -53,20 +53,19 @@ async fn convert_response( match object { Person(p) => { removed_or_deleted = p.deleted; - res.person = Some(blocking(pool, move |conn| PersonViewSafe::read(conn, p.id)).await??) + res.person = Some(PersonViewSafe::read(pool, p.id).await?) } Community(c) => { removed_or_deleted = c.deleted || c.removed; - res.community = - Some(blocking(pool, move |conn| CommunityView::read(conn, c.id, user_id)).await??) + res.community = Some(CommunityView::read(pool, c.id, user_id).await?) } Post(p) => { removed_or_deleted = p.deleted || p.removed; - res.post = Some(blocking(pool, move |conn| PostView::read(conn, p.id, user_id)).await??) + res.post = Some(PostView::read(pool, p.id, user_id).await?) } Comment(c) => { removed_or_deleted = c.deleted || c.removed; - res.comment = Some(blocking(pool, move |conn| CommentView::read(conn, c.id, user_id)).await??) + res.comment = Some(CommentView::read(pool, c.id, user_id).await?) } }; // if the object was deleted from database, dont return it diff --git a/crates/api/src/site/search.rs b/crates/api/src/site/search.rs index 6c02f9ac..970cb500 100644 --- a/crates/api/src/site/search.rs +++ b/crates/api/src/site/search.rs @@ -2,7 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ site::{Search, SearchResponse}, - utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt}, + utils::{check_private_instance, get_local_user_view_from_jwt_opt}, }; use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity}; use lemmy_db_schema::{ @@ -31,7 +31,7 @@ impl Perform for Search { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; @@ -63,68 +63,60 @@ impl Perform for Search { let creator_id = data.creator_id; match search_type { SearchType::Posts => { - posts = blocking(context.pool(), move |conn| { - PostQuery::builder() - .conn(conn) - .sort(sort) - .listing_type(listing_type) - .community_id(community_id) - .community_actor_id(community_actor_id) - .creator_id(creator_id) - .local_user(local_user.as_ref()) - .search_term(Some(q)) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + posts = PostQuery::builder() + .pool(context.pool()) + .sort(sort) + .listing_type(listing_type) + .community_id(community_id) + .community_actor_id(community_actor_id) + .creator_id(creator_id) + .local_user(local_user.as_ref()) + .search_term(Some(q)) + .page(page) + .limit(limit) + .build() + .list() + .await?; } SearchType::Comments => { - comments = blocking(context.pool(), move |conn| { - CommentQuery::builder() - .conn(conn) - .sort(sort.map(post_to_comment_sort_type)) - .listing_type(listing_type) - .search_term(Some(q)) - .community_id(community_id) - .community_actor_id(community_actor_id) - .creator_id(creator_id) - .local_user(local_user.as_ref()) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + comments = CommentQuery::builder() + .pool(context.pool()) + .sort(sort.map(post_to_comment_sort_type)) + .listing_type(listing_type) + .search_term(Some(q)) + .community_id(community_id) + .community_actor_id(community_actor_id) + .creator_id(creator_id) + .local_user(local_user.as_ref()) + .page(page) + .limit(limit) + .build() + .list() + .await?; } SearchType::Communities => { - communities = blocking(context.pool(), move |conn| { - CommunityQuery::builder() - .conn(conn) - .sort(sort) - .listing_type(listing_type) - .search_term(Some(q)) - .local_user(local_user.as_ref()) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + communities = CommunityQuery::builder() + .pool(context.pool()) + .sort(sort) + .listing_type(listing_type) + .search_term(Some(q)) + .local_user(local_user.as_ref()) + .page(page) + .limit(limit) + .build() + .list() + .await?; } SearchType::Users => { - users = blocking(context.pool(), move |conn| { - PersonQuery::builder() - .conn(conn) - .sort(sort) - .search_term(Some(q)) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + users = PersonQuery::builder() + .pool(context.pool()) + .sort(sort) + .search_term(Some(q)) + .page(page) + .limit(limit) + .build() + .list() + .await?; } SearchType::All => { // If the community or creator is included, dont search communities or users @@ -133,62 +125,56 @@ impl Perform for Search { let community_actor_id_2 = community_actor_id.to_owned(); let local_user_ = local_user.clone(); - posts = blocking(context.pool(), move |conn| { - PostQuery::builder() - .conn(conn) - .sort(sort) - .listing_type(listing_type) - .community_id(community_id) - .community_actor_id(community_actor_id_2) - .creator_id(creator_id) - .local_user(local_user_.as_ref()) - .search_term(Some(q)) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + posts = PostQuery::builder() + .pool(context.pool()) + .sort(sort) + .listing_type(listing_type) + .community_id(community_id) + .community_actor_id(community_actor_id_2) + .creator_id(creator_id) + .local_user(local_user_.as_ref()) + .search_term(Some(q)) + .page(page) + .limit(limit) + .build() + .list() + .await?; let q = data.q.to_owned(); let community_actor_id = community_actor_id.to_owned(); let local_user_ = local_user.clone(); - comments = blocking(context.pool(), move |conn| { - CommentQuery::builder() - .conn(conn) - .sort(sort.map(post_to_comment_sort_type)) - .listing_type(listing_type) - .search_term(Some(q)) - .community_id(community_id) - .community_actor_id(community_actor_id) - .creator_id(creator_id) - .local_user(local_user_.as_ref()) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + comments = CommentQuery::builder() + .pool(context.pool()) + .sort(sort.map(post_to_comment_sort_type)) + .listing_type(listing_type) + .search_term(Some(q)) + .community_id(community_id) + .community_actor_id(community_actor_id) + .creator_id(creator_id) + .local_user(local_user_.as_ref()) + .page(page) + .limit(limit) + .build() + .list() + .await?; let q = data.q.to_owned(); communities = if community_or_creator_included { vec![] } else { - blocking(context.pool(), move |conn| { - CommunityQuery::builder() - .conn(conn) - .sort(sort) - .listing_type(listing_type) - .search_term(Some(q)) - .local_user(local_user.as_ref()) - .page(page) - .limit(limit) - .build() - .list() - }) - .await?? + CommunityQuery::builder() + .pool(context.pool()) + .sort(sort) + .listing_type(listing_type) + .search_term(Some(q)) + .local_user(local_user.as_ref()) + .page(page) + .limit(limit) + .build() + .list() + .await? }; let q = data.q.to_owned(); @@ -196,35 +182,31 @@ impl Perform for Search { users = if community_or_creator_included { vec![] } else { - blocking(context.pool(), move |conn| { - PersonQuery::builder() - .conn(conn) - .sort(sort) - .search_term(Some(q)) - .page(page) - .limit(limit) - .build() - .list() - }) - .await?? - }; - } - SearchType::Url => { - posts = blocking(context.pool(), move |conn| { - PostQuery::builder() - .conn(conn) + PersonQuery::builder() + .pool(context.pool()) .sort(sort) - .listing_type(listing_type) - .community_id(community_id) - .community_actor_id(community_actor_id) - .creator_id(creator_id) - .url_search(Some(q)) + .search_term(Some(q)) .page(page) .limit(limit) .build() .list() - }) - .await??; + .await? + }; + } + SearchType::Url => { + posts = PostQuery::builder() + .pool(context.pool()) + .sort(sort) + .listing_type(listing_type) + .community_id(community_id) + .community_actor_id(community_actor_id) + .creator_id(creator_id) + .url_search(Some(q)) + .page(page) + .limit(limit) + .build() + .list() + .await?; } }; diff --git a/crates/api_common/Cargo.toml b/crates/api_common/Cargo.toml index 406517cd..7bd38b6a 100644 --- a/crates/api_common/Cargo.toml +++ b/crates/api_common/Cargo.toml @@ -24,11 +24,11 @@ lemmy_db_views_moderator = { version = "=0.16.5", path = "../db_views_moderator" lemmy_db_views_actor = { version = "=0.16.5", path = "../db_views_actor" } lemmy_db_schema = { version = "=0.16.5", path = "../db_schema", default-features = false } lemmy_utils = { version = "=0.16.5", path = "../utils", optional = true } -serde = { version = "1.0.145", features = ["derive"] } +serde = { version = "1.0.147", features = ["derive"] } url = "2.3.1" actix-web = { version = "4.2.1", default-features = false, features = ["cookies"], optional = true } chrono = { version = "0.4.22", features = ["serde"], optional = true } -diesel = { version = "2.0.0", optional = true } +diesel = { version = "2.0.2", optional = true } tracing = { version = "0.1.36", optional = true } rosetta-i18n = { version = "0.1.2", optional = true } percent-encoding = { version = "2.2.0", optional = true } diff --git a/crates/api_common/src/site.rs b/crates/api_common/src/site.rs index 88e1c3ac..e4619e64 100644 --- a/crates/api_common/src/site.rs +++ b/crates/api_common/src/site.rs @@ -125,10 +125,10 @@ pub struct CreateSite { pub private_instance: Option, pub default_theme: Option, pub default_post_listing_type: Option, + pub legal_information: Option, pub application_email_admins: Option, - pub auth: Sensitive, pub hide_modlog_mod_names: Option, - pub legal_information: Option, + pub discussion_languages: Option>, pub slur_filter_regex: Option, pub actor_name_max_length: Option, pub rate_limit_message: Option, @@ -152,6 +152,7 @@ pub struct CreateSite { pub captcha_difficulty: Option, pub allowed_instances: Option>, pub blocked_instances: Option>, + pub auth: Sensitive, } #[derive(Debug, Serialize, Deserialize, Clone, Default)] diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index 8c341c44..a65845cc 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -44,33 +44,13 @@ use rosetta_i18n::{Language, LanguageId}; use std::str::FromStr; use tracing::warn; -pub async fn blocking(pool: &DbPool, f: F) -> Result -where - F: FnOnce(&mut diesel::PgConnection) -> T + Send + 'static, - T: Send + 'static, -{ - let pool = pool.clone(); - let blocking_span = tracing::info_span!("blocking operation"); - actix_web::web::block(move || { - let entered = blocking_span.enter(); - let mut conn = pool.get()?; - let res = (f)(&mut conn); - drop(entered); - Ok(res) as Result - }) - .await? -} - #[tracing::instrument(skip_all)] pub async fn is_mod_or_admin( pool: &DbPool, person_id: PersonId, community_id: CommunityId, ) -> Result<(), LemmyError> { - let is_mod_or_admin = blocking(pool, move |conn| { - CommunityView::is_mod_or_admin(conn, person_id, community_id) - }) - .await?; + let is_mod_or_admin = CommunityView::is_mod_or_admin(pool, person_id, community_id).await?; if !is_mod_or_admin { return Err(LemmyError::from_message("not_a_mod_or_admin")); } @@ -86,8 +66,8 @@ pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> { #[tracing::instrument(skip_all)] pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result { - blocking(pool, move |conn| Post::read(conn, post_id)) - .await? + Post::read(pool, post_id) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post")) } @@ -99,11 +79,9 @@ pub async fn mark_post_as_read( ) -> Result { let post_read_form = PostReadForm { post_id, person_id }; - blocking(pool, move |conn| { - PostRead::mark_as_read(conn, &post_read_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_mark_post_as_read")) + PostRead::mark_as_read(pool, &post_read_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_mark_post_as_read")) } #[tracing::instrument(skip_all)] @@ -114,11 +92,9 @@ pub async fn mark_post_as_unread( ) -> Result { let post_read_form = PostReadForm { post_id, person_id }; - blocking(pool, move |conn| { - PostRead::mark_as_unread(conn, &post_read_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_mark_post_as_read")) + PostRead::mark_as_unread(pool, &post_read_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_mark_post_as_read")) } #[tracing::instrument(skip_all)] @@ -131,8 +107,7 @@ pub async fn get_local_user_view_from_jwt( .map_err(|e| e.with_message("not_logged_in"))? .claims; let local_user_id = LocalUserId(claims.sub); - let local_user_view = - blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??; + let local_user_view = LocalUserView::read(pool, local_user_id).await?; check_user_valid( local_user_view.person.banned, local_user_view.person.ban_expires, @@ -181,10 +156,7 @@ pub async fn get_local_user_settings_view_from_jwt_opt( .map_err(|e| e.with_message("not_logged_in"))? .claims; let local_user_id = LocalUserId(claims.sub); - let local_user_view = blocking(pool, move |conn| { - LocalUserSettingsView::read(conn, local_user_id) - }) - .await??; + let local_user_view = LocalUserSettingsView::read(pool, local_user_id).await?; check_user_valid( local_user_view.person.banned, local_user_view.person.ban_expires, @@ -222,9 +194,10 @@ pub async fn check_community_ban( community_id: CommunityId, pool: &DbPool, ) -> Result<(), LemmyError> { - let is_banned = - move |conn: &mut _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok(); - if blocking(pool, is_banned).await? { + let is_banned = CommunityPersonBanView::get(pool, person_id, community_id) + .await + .is_ok(); + if is_banned { Err(LemmyError::from_message("community_ban")) } else { Ok(()) @@ -236,8 +209,8 @@ pub async fn check_community_deleted_or_removed( community_id: CommunityId, pool: &DbPool, ) -> Result<(), LemmyError> { - let community = blocking(pool, move |conn| Community::read(conn, community_id)) - .await? + let community = Community::read(pool, community_id) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; if community.deleted || community.removed { Err(LemmyError::from_message("deleted")) @@ -260,8 +233,10 @@ pub async fn check_person_block( potential_blocker_id: PersonId, pool: &DbPool, ) -> Result<(), LemmyError> { - let is_blocked = move |conn: &mut _| PersonBlock::read(conn, potential_blocker_id, my_id).is_ok(); - if blocking(pool, is_blocked).await? { + let is_blocked = PersonBlock::read(pool, potential_blocker_id, my_id) + .await + .is_ok(); + if is_blocked { Err(LemmyError::from_message("person_block")) } else { Ok(()) @@ -294,9 +269,9 @@ pub async fn build_federated_instances( ) -> Result, LemmyError> { if local_site.federation_enabled { // TODO I hate that this requires 3 queries - let linked = blocking(pool, Instance::linked).await??; - let allowed = blocking(pool, Instance::allowlist).await??; - let blocked = blocking(pool, Instance::blocklist).await??; + let linked = Instance::linked(pool).await?; + let allowed = Instance::allowlist(pool).await?; + let blocked = Instance::blocklist(pool).await?; // These can return empty vectors, so convert them to options let allowed = (!allowed.is_empty()).then(|| allowed); @@ -374,10 +349,7 @@ pub async fn send_password_reset_email( // Insert the row let token2 = token.clone(); let local_user_id = user.local_user.id; - blocking(pool, move |conn| { - PasswordResetRequest::create_token(conn, local_user_id, &token2) - }) - .await??; + PasswordResetRequest::create_token(pool, local_user_id, &token2).await?; let email = &user.local_user.email.to_owned().expect("email"); let lang = get_interface_language(user); @@ -405,7 +377,7 @@ pub async fn send_verification_email( settings.get_protocol_and_hostname(), &form.verification_token ); - blocking(pool, move |conn| EmailVerification::create(conn, &form)).await??; + EmailVerification::create(pool, &form).await?; let lang = get_interface_language(user); let subject = lang.verify_email_subject(&settings.hostname); @@ -491,10 +463,7 @@ pub async fn send_new_applicant_email_to_admins( settings: &Settings, ) -> Result<(), LemmyError> { // Collect the admins with emails - let admins = blocking(pool, move |conn| { - LocalUserSettingsView::list_admins_with_emails(conn) - }) - .await??; + let admins = LocalUserSettingsView::list_admins_with_emails(pool).await?; let applications_link = &format!( "{}/registration_applications", @@ -522,10 +491,7 @@ pub async fn check_registration_application( { // Fetch the registration, see if its denied let local_user_id = local_user_view.local_user.id; - let registration = blocking(pool, move |conn| { - RegistrationApplication::find_by_local_user_id(conn, local_user_id) - }) - .await??; + let registration = RegistrationApplication::find_by_local_user_id(pool, local_user_id).await?; if let Some(deny_reason) = registration.deny_reason { let lang = get_interface_language(local_user_view); let registration_denied_message = format!("{}: {}", lang.registration_denied(), &deny_reason); @@ -554,10 +520,7 @@ pub async fn purge_image_posts_for_person( settings: &Settings, client: &ClientWithMiddleware, ) -> Result<(), LemmyError> { - let posts = blocking(pool, move |conn: &mut _| { - Post::fetch_pictrs_posts_for_creator(conn, banned_person_id) - }) - .await??; + let posts = Post::fetch_pictrs_posts_for_creator(pool, banned_person_id).await?; for post in posts { if let Some(url) = post.url { purge_image_from_pictrs(client, settings, &url).await.ok(); @@ -569,10 +532,7 @@ pub async fn purge_image_posts_for_person( } } - blocking(pool, move |conn| { - Post::remove_pictrs_post_images_and_thumbnails_for_creator(conn, banned_person_id) - }) - .await??; + Post::remove_pictrs_post_images_and_thumbnails_for_creator(pool, banned_person_id).await?; Ok(()) } @@ -583,10 +543,7 @@ pub async fn purge_image_posts_for_community( settings: &Settings, client: &ClientWithMiddleware, ) -> Result<(), LemmyError> { - let posts = blocking(pool, move |conn: &mut _| { - Post::fetch_pictrs_posts_for_community(conn, banned_community_id) - }) - .await??; + let posts = Post::fetch_pictrs_posts_for_community(pool, banned_community_id).await?; for post in posts { if let Some(url) = post.url { purge_image_from_pictrs(client, settings, &url).await.ok(); @@ -598,10 +555,7 @@ pub async fn purge_image_posts_for_community( } } - blocking(pool, move |conn| { - Post::remove_pictrs_post_images_and_thumbnails_for_community(conn, banned_community_id) - }) - .await??; + Post::remove_pictrs_post_images_and_thumbnails_for_community(pool, banned_community_id).await?; Ok(()) } @@ -613,7 +567,7 @@ pub async fn remove_user_data( client: &ClientWithMiddleware, ) -> Result<(), LemmyError> { // Purge user images - let person = blocking(pool, move |conn| Person::read(conn, banned_person_id)).await??; + let person = Person::read(pool, banned_person_id).await?; if let Some(avatar) = person.avatar { purge_image_from_pictrs(client, settings, &avatar) .await @@ -626,23 +580,18 @@ pub async fn remove_user_data( } // Update the fields to None - blocking(pool, move |conn| { - Person::update( - conn, - banned_person_id, - &PersonUpdateForm::builder() - .avatar(Some(None)) - .banner(Some(None)) - .build(), - ) - }) - .await??; + Person::update( + pool, + banned_person_id, + &PersonUpdateForm::builder() + .avatar(Some(None)) + .banner(Some(None)) + .build(), + ) + .await?; // Posts - blocking(pool, move |conn: &mut _| { - Post::update_removed_for_creator(conn, banned_person_id, None, true) - }) - .await??; + Post::update_removed_for_creator(pool, banned_person_id, None, true).await?; // Purge image posts purge_image_posts_for_person(banned_person_id, pool, settings, client).await?; @@ -650,10 +599,7 @@ pub async fn remove_user_data( // Communities // Remove all communities where they're the top mod // for now, remove the communities manually - let first_mod_communities = blocking(pool, move |conn: &mut _| { - CommunityModeratorView::get_community_first_mods(conn) - }) - .await??; + let first_mod_communities = CommunityModeratorView::get_community_first_mods(pool).await?; // Filter to only this banned users top communities let banned_user_first_communities: Vec = first_mod_communities @@ -663,14 +609,12 @@ pub async fn remove_user_data( for first_mod_community in banned_user_first_communities { let community_id = first_mod_community.community.id; - blocking(pool, move |conn| { - Community::update( - conn, - community_id, - &CommunityUpdateForm::builder().removed(Some(true)).build(), - ) - }) - .await??; + Community::update( + pool, + community_id, + &CommunityUpdateForm::builder().removed(Some(true)).build(), + ) + .await?; // Delete the community images if let Some(icon) = first_mod_community.community.icon { @@ -682,24 +626,19 @@ pub async fn remove_user_data( .ok(); } // Update the fields to None - blocking(pool, move |conn| { - Community::update( - conn, - community_id, - &CommunityUpdateForm::builder() - .icon(Some(None)) - .banner(Some(None)) - .build(), - ) - }) - .await??; + Community::update( + pool, + community_id, + &CommunityUpdateForm::builder() + .icon(Some(None)) + .banner(Some(None)) + .build(), + ) + .await?; } // Comments - blocking(pool, move |conn: &mut _| { - Comment::update_removed_for_creator(conn, banned_person_id, true) - }) - .await??; + Comment::update_removed_for_creator(pool, banned_person_id, true).await?; Ok(()) } @@ -710,34 +649,27 @@ pub async fn remove_user_data_in_community( pool: &DbPool, ) -> Result<(), LemmyError> { // Posts - blocking(pool, move |conn| { - Post::update_removed_for_creator(conn, banned_person_id, Some(community_id), true) - }) - .await??; + Post::update_removed_for_creator(pool, banned_person_id, Some(community_id), true).await?; // Comments // TODO Diesel doesn't allow updates with joins, so this has to be a loop - let comments = blocking(pool, move |conn| { - CommentQuery::builder() - .conn(conn) - .creator_id(Some(banned_person_id)) - .community_id(Some(community_id)) - .limit(Some(i64::MAX)) - .build() - .list() - }) - .await??; + let comments = CommentQuery::builder() + .pool(pool) + .creator_id(Some(banned_person_id)) + .community_id(Some(community_id)) + .limit(Some(i64::MAX)) + .build() + .list() + .await?; for comment_view in &comments { let comment_id = comment_view.comment.id; - blocking(pool, move |conn| { - Comment::update( - conn, - comment_id, - &CommentUpdateForm::builder().removed(Some(true)).build(), - ) - }) - .await??; + Comment::update( + pool, + comment_id, + &CommentUpdateForm::builder().removed(Some(true)).build(), + ) + .await?; } Ok(()) @@ -750,7 +682,7 @@ pub async fn delete_user_account( client: &ClientWithMiddleware, ) -> Result<(), LemmyError> { // Delete their images - let person = blocking(pool, move |conn| Person::read(conn, person_id)).await??; + let person = Person::read(pool, person_id).await?; if let Some(avatar) = person.avatar { purge_image_from_pictrs(client, settings, &avatar) .await @@ -764,21 +696,19 @@ pub async fn delete_user_account( // No need to update avatar and banner, those are handled in Person::delete_account // Comments - let permadelete = move |conn: &mut _| Comment::permadelete_for_creator(conn, person_id); - blocking(pool, permadelete) - .await? + Comment::permadelete_for_creator(pool, person_id) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; // Posts - let permadelete = move |conn: &mut _| Post::permadelete_for_creator(conn, person_id); - blocking(pool, permadelete) - .await? + Post::permadelete_for_creator(pool, person_id) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_post"))?; // Purge image posts purge_image_posts_for_person(person_id, pool, settings, client).await?; - blocking(pool, move |conn| Person::delete_account(conn, person_id)).await??; + Person::delete_account(pool, person_id).await?; Ok(()) } diff --git a/crates/api_crud/Cargo.toml b/crates/api_crud/Cargo.toml index 6608f22c..aa1ec1a0 100644 --- a/crates/api_crud/Cargo.toml +++ b/crates/api_crud/Cargo.toml @@ -18,10 +18,10 @@ lemmy_api_common = { version = "=0.16.5", path = "../api_common", features = ["f lemmy_websocket = { version = "=0.16.5", path = "../websocket" } activitypub_federation = "0.2.3" bcrypt = "0.13.0" -serde_json = { version = "1.0.85", features = ["preserve_order"] } -serde = { version = "1.0.145", features = ["derive"] } +serde_json = { version = "1.0.87", features = ["preserve_order"] } +serde = { version = "1.0.147", features = ["derive"] } actix-web = { version = "4.2.1", default-features = false } tracing = "0.1.36" url = { version = "2.3.1", features = ["serde"] } -async-trait = "0.1.57" +async-trait = "0.1.58" webmention = "0.4.0" diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index ef13e54d..ff91baf2 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, CreateComment}, utils::{ - blocking, check_community_ban, check_community_deleted_or_removed, check_post_deleted_or_removed, @@ -52,7 +51,7 @@ impl PerformCrud for CreateComment { let data: &CreateComment = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let content_slurs_removed = remove_slurs( &data.content.to_owned(), @@ -75,9 +74,7 @@ impl PerformCrud for CreateComment { // Fetch the parent, if it exists let parent_opt = if let Some(parent_id) = data.parent_id { - blocking(context.pool(), move |conn| Comment::read(conn, parent_id)) - .await? - .ok() + Comment::read(context.pool(), parent_id).await.ok() } else { None }; @@ -97,10 +94,12 @@ impl PerformCrud for CreateComment { .unwrap_or(post.language_id); let language_id = data.language_id.unwrap_or(parent_language); - blocking(context.pool(), move |conn| { - CommunityLanguage::is_allowed_community_language(conn, Some(language_id), community_id) - }) - .await??; + CommunityLanguage::is_allowed_community_language( + context.pool(), + Some(language_id), + community_id, + ) + .await?; let comment_form = CommentInsertForm::builder() .content(content_slurs_removed.to_owned()) @@ -112,31 +111,26 @@ impl PerformCrud for CreateComment { // Create the comment let comment_form2 = comment_form.clone(); let parent_path = parent_opt.to_owned().map(|t| t.path); - let inserted_comment = blocking(context.pool(), move |conn| { - Comment::create(conn, &comment_form2, parent_path.as_ref()) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_comment"))?; + let inserted_comment = Comment::create(context.pool(), &comment_form2, parent_path.as_ref()) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_comment"))?; // Necessary to update the ap_id let inserted_comment_id = inserted_comment.id; let protocol_and_hostname = context.settings().get_protocol_and_hostname(); - let updated_comment: Comment = - blocking(context.pool(), move |conn| -> Result { - let apub_id = generate_local_apub_endpoint( - EndpointType::Comment, - &inserted_comment_id.to_string(), - &protocol_and_hostname, - )?; - Ok(Comment::update( - conn, - inserted_comment_id, - &CommentUpdateForm::builder().ap_id(Some(apub_id)).build(), - )?) - }) - .await? - .map_err(|e| e.with_message("couldnt_create_comment"))?; + let apub_id = generate_local_apub_endpoint( + EndpointType::Comment, + &inserted_comment_id.to_string(), + &protocol_and_hostname, + )?; + let updated_comment = Comment::update( + context.pool(), + inserted_comment_id, + &CommentUpdateForm::builder().ap_id(Some(apub_id)).build(), + ) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_comment"))?; // Scan the comment for user mentions, add those rows let post_id = post.id; @@ -159,9 +153,8 @@ impl PerformCrud for CreateComment { score: 1, }; - let like = move |conn: &mut _| CommentLike::like(conn, &like_form); - blocking(context.pool(), like) - .await? + CommentLike::like(context.pool(), &like_form) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_comment"))?; let apub_comment: ApubComment = updated_comment.into(); @@ -177,33 +170,28 @@ impl PerformCrud for CreateComment { // If its a reply, mark the parent as read if let Some(parent) = parent_opt { let parent_id = parent.id; - let comment_reply = blocking(context.pool(), move |conn| { - CommentReply::read_by_comment(conn, parent_id) - }) - .await?; + let comment_reply = CommentReply::read_by_comment(context.pool(), parent_id).await; if let Ok(reply) = comment_reply { - blocking(context.pool(), move |conn| { - CommentReply::update(conn, reply.id, &CommentReplyUpdateForm { read: Some(true) }) - }) - .await? + CommentReply::update( + context.pool(), + reply.id, + &CommentReplyUpdateForm { read: Some(true) }, + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_replies"))?; } // If the parent has PersonMentions mark them as read too let person_id = local_user_view.person.id; - let person_mention = blocking(context.pool(), move |conn| { - PersonMention::read_by_comment_and_person(conn, parent_id, person_id) - }) - .await?; + let person_mention = + PersonMention::read_by_comment_and_person(context.pool(), parent_id, person_id).await; if let Ok(mention) = person_mention { - blocking(context.pool(), move |conn| { - PersonMention::update( - conn, - mention.id, - &PersonMentionUpdateForm { read: Some(true) }, - ) - }) - .await? + PersonMention::update( + context.pool(), + mention.id, + &PersonMentionUpdateForm { read: Some(true) }, + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_person_mentions"))?; } } diff --git a/crates/api_crud/src/comment/delete.rs b/crates/api_crud/src/comment/delete.rs index 407d11cc..549d2f36 100644 --- a/crates/api_crud/src/comment/delete.rs +++ b/crates/api_crud/src/comment/delete.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, DeleteComment}, - utils::{blocking, check_community_ban, get_local_user_view_from_jwt}, + utils::{check_community_ban, get_local_user_view_from_jwt}, }; use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ @@ -36,10 +36,7 @@ impl PerformCrud for DeleteComment { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let comment_id = data.comment_id; - let orig_comment = blocking(context.pool(), move |conn| { - CommentView::read(conn, comment_id, None) - }) - .await??; + let orig_comment = CommentView::read(context.pool(), comment_id, None).await?; // Dont delete it if its already been deleted. if orig_comment.comment.deleted == data.deleted { @@ -60,18 +57,16 @@ impl PerformCrud for DeleteComment { // Do the delete let deleted = data.deleted; - let updated_comment = blocking(context.pool(), move |conn| { - Comment::update( - conn, - comment_id, - &CommentUpdateForm::builder().deleted(Some(deleted)).build(), - ) - }) - .await? + let updated_comment = Comment::update( + context.pool(), + comment_id, + &CommentUpdateForm::builder().deleted(Some(deleted)).build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; let post_id = updated_comment.post_id; - let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let post = Post::read(context.pool(), post_id).await?; let recipient_ids = send_local_notifs( vec![], &updated_comment, @@ -94,10 +89,7 @@ impl PerformCrud for DeleteComment { .await?; // Send the apub message - let community = blocking(context.pool(), move |conn| { - Community::read(conn, orig_comment.post.community_id) - }) - .await??; + let community = Community::read(context.pool(), orig_comment.post.community_id).await?; let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into())); send_apub_delete_in_community( local_user_view.person, diff --git a/crates/api_crud/src/comment/list.rs b/crates/api_crud/src/comment/list.rs index 9ab7d6d0..22a6a3ac 100644 --- a/crates/api_crud/src/comment/list.rs +++ b/crates/api_crud/src/comment/list.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ comment::{GetComments, GetCommentsResponse}, utils::{ - blocking, check_private_instance, get_local_user_view_from_jwt_opt, listing_type_with_site_default, @@ -32,7 +31,7 @@ impl PerformCrud for GetComments { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; let community_id = data.community_id; @@ -55,11 +54,7 @@ impl PerformCrud for GetComments { // If a parent_id is given, fetch the comment to get the path let parent_path = if let Some(parent_id) = parent_id { - Some( - blocking(context.pool(), move |conn| Comment::read(conn, parent_id)) - .await?? - .path, - ) + Some(Comment::read(context.pool(), parent_id).await?.path) } else { None }; @@ -67,25 +62,23 @@ impl PerformCrud for GetComments { let parent_path_cloned = parent_path.to_owned(); let post_id = data.post_id; let local_user = local_user_view.map(|l| l.local_user); - let mut comments = blocking(context.pool(), move |conn| { - CommentQuery::builder() - .conn(conn) - .listing_type(Some(listing_type)) - .sort(sort) - .max_depth(max_depth) - .saved_only(saved_only) - .community_id(community_id) - .community_actor_id(community_actor_id) - .parent_path(parent_path_cloned) - .post_id(post_id) - .local_user(local_user.as_ref()) - .page(page) - .limit(limit) - .build() - .list() - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_get_comments"))?; + let mut comments = CommentQuery::builder() + .pool(context.pool()) + .listing_type(Some(listing_type)) + .sort(sort) + .max_depth(max_depth) + .saved_only(saved_only) + .community_id(community_id) + .community_actor_id(community_actor_id) + .parent_path(parent_path_cloned) + .post_id(post_id) + .local_user(local_user.as_ref()) + .page(page) + .limit(limit) + .build() + .list() + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_get_comments"))?; // Blank out deleted or removed info for cv in comments diff --git a/crates/api_crud/src/comment/read.rs b/crates/api_crud/src/comment/read.rs index a4868c09..7d5779ff 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, GetComment}, - utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt}, + utils::{check_private_instance, get_local_user_view_from_jwt_opt}, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::CommentView; @@ -23,17 +23,15 @@ impl PerformCrud for GetComment { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; let person_id = local_user_view.map(|u| u.person.id); let id = data.id; - let comment_view = blocking(context.pool(), move |conn| { - CommentView::read(conn, id, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_comment"))?; + let comment_view = CommentView::read(context.pool(), id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_comment"))?; Ok(Self::Response { comment_view, diff --git a/crates/api_crud/src/comment/remove.rs b/crates/api_crud/src/comment/remove.rs index 3b94fd47..c866eca3 100644 --- a/crates/api_crud/src/comment/remove.rs +++ b/crates/api_crud/src/comment/remove.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, RemoveComment}, - utils::{blocking, check_community_ban, get_local_user_view_from_jwt, is_mod_or_admin}, + utils::{check_community_ban, get_local_user_view_from_jwt, is_mod_or_admin}, }; use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ @@ -37,10 +37,7 @@ impl PerformCrud for RemoveComment { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let comment_id = data.comment_id; - let orig_comment = blocking(context.pool(), move |conn| { - CommentView::read(conn, comment_id, None) - }) - .await??; + let orig_comment = CommentView::read(context.pool(), comment_id, None).await?; check_community_ban( local_user_view.person.id, @@ -59,14 +56,12 @@ impl PerformCrud for RemoveComment { // Do the remove let removed = data.removed; - let updated_comment = blocking(context.pool(), move |conn| { - Comment::update( - conn, - comment_id, - &CommentUpdateForm::builder().removed(Some(removed)).build(), - ) - }) - .await? + let updated_comment = Comment::update( + context.pool(), + comment_id, + &CommentUpdateForm::builder().removed(Some(removed)).build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; // Mod tables @@ -76,13 +71,10 @@ impl PerformCrud for RemoveComment { removed: Some(removed), reason: data.reason.to_owned(), }; - blocking(context.pool(), move |conn| { - ModRemoveComment::create(conn, &form) - }) - .await??; + ModRemoveComment::create(context.pool(), &form).await?; let post_id = updated_comment.post_id; - let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let post = Post::read(context.pool(), post_id).await?; let recipient_ids = send_local_notifs( vec![], &updated_comment, @@ -105,10 +97,7 @@ impl PerformCrud for RemoveComment { .await?; // Send the apub message - let community = blocking(context.pool(), move |conn| { - Community::read(conn, orig_comment.post.community_id) - }) - .await??; + let community = Community::read(context.pool(), orig_comment.post.community_id).await?; let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into())); send_apub_delete_in_community( local_user_view.person, diff --git a/crates/api_crud/src/comment/update.rs b/crates/api_crud/src/comment/update.rs index 9678765e..ef8aabb0 100644 --- a/crates/api_crud/src/comment/update.rs +++ b/crates/api_crud/src/comment/update.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, EditComment}, utils::{ - blocking, check_community_ban, check_community_deleted_or_removed, check_post_deleted_or_removed, @@ -49,13 +48,10 @@ impl PerformCrud for EditComment { let data: &EditComment = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let comment_id = data.comment_id; - let orig_comment = blocking(context.pool(), move |conn| { - CommentView::read(conn, comment_id, None) - }) - .await??; + let orig_comment = CommentView::read(context.pool(), comment_id, None).await?; // TODO is this necessary? It should really only need to check on create check_community_ban( @@ -83,10 +79,12 @@ impl PerformCrud for EditComment { } let language_id = self.language_id; - blocking(context.pool(), move |conn| { - CommunityLanguage::is_allowed_community_language(conn, language_id, orig_comment.community.id) - }) - .await??; + CommunityLanguage::is_allowed_community_language( + context.pool(), + language_id, + orig_comment.community.id, + ) + .await?; // Update the Content let content_slurs_removed = data @@ -99,11 +97,9 @@ impl PerformCrud for EditComment { .distinguished(data.distinguished) .language_id(data.language_id) .build(); - let updated_comment = blocking(context.pool(), move |conn| { - Comment::update(conn, comment_id, &form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; + let updated_comment = Comment::update(context.pool(), comment_id, &form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?; // Do the mentions / recipients let updated_comment_content = updated_comment.content.to_owned(); diff --git a/crates/api_crud/src/community/create.rs b/crates/api_crud/src/community/create.rs index 63cdc3af..128870ea 100644 --- a/crates/api_crud/src/community/create.rs +++ b/crates/api_crud/src/community/create.rs @@ -3,7 +3,7 @@ use activitypub_federation::core::{object_id::ObjectId, signatures::generate_act use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, CreateCommunity}, - utils::{blocking, get_local_user_view_from_jwt, is_admin, local_site_to_slur_regex}, + utils::{get_local_user_view_from_jwt, is_admin, local_site_to_slur_regex}, }; use lemmy_apub::{ generate_followers_url, @@ -47,7 +47,7 @@ impl PerformCrud for CreateCommunity { let data: &CreateCommunity = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let site_view = blocking(context.pool(), SiteView::read_local).await??; + let site_view = SiteView::read_local(context.pool()).await?; let local_site = site_view.local_site; if local_site.community_creation_admin_only && is_admin(&local_user_view).is_err() { @@ -101,11 +101,9 @@ impl PerformCrud for CreateCommunity { .instance_id(site_view.site.instance_id) .build(); - let inserted_community = blocking(context.pool(), move |conn| { - Community::create(conn, &community_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "community_already_exists"))?; + let inserted_community = Community::create(context.pool(), &community_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "community_already_exists"))?; // The community creator becomes a moderator let community_moderator_form = CommunityModeratorForm { @@ -113,9 +111,8 @@ impl PerformCrud for CreateCommunity { person_id: local_user_view.person.id, }; - let join = move |conn: &mut _| CommunityModerator::join(conn, &community_moderator_form); - blocking(context.pool(), join) - .await? + CommunityModerator::join(context.pool(), &community_moderator_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_moderator_already_exists"))?; // Follow your own community @@ -125,16 +122,13 @@ impl PerformCrud for CreateCommunity { pending: false, }; - let follow = move |conn: &mut _| CommunityFollower::follow(conn, &community_follower_form); - blocking(context.pool(), follow) - .await? + CommunityFollower::follow(context.pool(), &community_follower_form) + .await .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; let person_id = local_user_view.person.id; - let community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, inserted_community.id, Some(person_id)) - }) - .await??; + let community_view = + CommunityView::read(context.pool(), inserted_community.id, Some(person_id)).await?; Ok(CommunityResponse { community_view }) } diff --git a/crates/api_crud/src/community/delete.rs b/crates/api_crud/src/community/delete.rs index dff00696..41f14b52 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, DeleteCommunity}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ @@ -29,10 +29,8 @@ impl PerformCrud for DeleteCommunity { // Fetch the community mods let community_id = data.community_id; - let community_mods = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await??; + let community_mods = + CommunityModeratorView::for_community(context.pool(), community_id).await?; // Make sure deleter is the top mod if local_user_view.person.id != community_mods[0].moderator.id { @@ -42,16 +40,14 @@ impl PerformCrud for DeleteCommunity { // Do the delete let community_id = data.community_id; let deleted = data.deleted; - let updated_community = blocking(context.pool(), move |conn| { - Community::update( - conn, - community_id, - &CommunityUpdateForm::builder() - .deleted(Some(deleted)) - .build(), - ) - }) - .await? + let updated_community = Community::update( + context.pool(), + community_id, + &CommunityUpdateForm::builder() + .deleted(Some(deleted)) + .build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community"))?; let res = send_community_ws_message( diff --git a/crates/api_crud/src/community/list.rs b/crates/api_crud/src/community/list.rs index dcf5886a..ab95739a 100644 --- a/crates/api_crud/src/community/list.rs +++ b/crates/api_crud/src/community/list.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{ListCommunities, ListCommunitiesResponse}, - utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt}, + utils::{check_private_instance, get_local_user_view_from_jwt_opt}, }; use lemmy_db_schema::{source::local_site::LocalSite, traits::DeleteableOrRemoveable}; use lemmy_db_views_actor::community_view::CommunityQuery; @@ -23,7 +23,7 @@ impl PerformCrud for ListCommunities { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; @@ -34,18 +34,16 @@ impl PerformCrud for ListCommunities { let page = data.page; let limit = data.limit; let local_user = local_user_view.map(|l| l.local_user); - let mut communities = blocking(context.pool(), move |conn| { - CommunityQuery::builder() - .conn(conn) - .listing_type(listing_type) - .sort(sort) - .local_user(local_user.as_ref()) - .page(page) - .limit(limit) - .build() - .list() - }) - .await??; + let mut communities = CommunityQuery::builder() + .pool(context.pool()) + .listing_type(listing_type) + .sort(sort) + .local_user(local_user.as_ref()) + .page(page) + .limit(limit) + .build() + .list() + .await?; // Blank out deleted or removed info for non-logged in users if person_id.is_none() { diff --git a/crates/api_crud/src/community/read.rs b/crates/api_crud/src/community/read.rs index 595f3e2b..b42ad49f 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/api_crud/src/community/read.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{GetCommunity, GetCommunityResponse}, - utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt}, + utils::{check_private_instance, get_local_user_view_from_jwt_opt}, }; use lemmy_apub::{ fetcher::resolve_actor_identifier, @@ -36,7 +36,7 @@ impl PerformCrud for GetCommunity { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; if data.name.is_none() && data.id.is_none() { return Err(LemmyError::from_message("no_id_given")); @@ -57,11 +57,9 @@ impl PerformCrud for GetCommunity { } }; - let mut community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, community_id, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; + let mut community_view = CommunityView::read(context.pool(), community_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; // Blank out deleted or removed info for non-logged in users if person_id.is_none() && (community_view.community.deleted || community_view.community.removed) @@ -69,11 +67,9 @@ impl PerformCrud for GetCommunity { community_view.community = community_view.community.blank_out_deleted_or_removed_info(); } - let moderators: Vec = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; + let moderators = CommunityModeratorView::for_community(context.pool(), community_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; let online = context .chat_server() @@ -82,10 +78,7 @@ impl PerformCrud for GetCommunity { .unwrap_or(1); let site_id = instance_actor_id_from_url(community_view.community.actor_id.clone().into()); - let mut site: Option = blocking(context.pool(), move |conn| { - Site::read_from_apub_id(conn, site_id) - }) - .await??; + let mut site = Site::read_from_apub_id(context.pool(), site_id).await?; // no need to include metadata for local site (its already available through other endpoints). // this also prevents us from leaking the federation private key. if let Some(s) = &site { @@ -95,15 +88,9 @@ impl PerformCrud for GetCommunity { } let community_id = community_view.community.id; - let discussion_languages = blocking(context.pool(), move |conn| { - CommunityLanguage::read(conn, community_id) - }) - .await??; + let discussion_languages = CommunityLanguage::read(context.pool(), community_id).await?; let default_post_language = if let Some(user) = local_user_view { - blocking(context.pool(), move |conn| { - default_post_language(conn, community_id, user.local_user.id) - }) - .await?? + default_post_language(context.pool(), community_id, user.local_user.id).await? } else { None }; diff --git a/crates/api_crud/src/community/remove.rs b/crates/api_crud/src/community/remove.rs index be486144..ab747354 100644 --- a/crates/api_crud/src/community/remove.rs +++ b/crates/api_crud/src/community/remove.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, RemoveCommunity}, - utils::{blocking, get_local_user_view_from_jwt, is_admin}, + utils::{get_local_user_view_from_jwt, is_admin}, }; use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ @@ -35,16 +35,14 @@ impl PerformCrud for RemoveCommunity { // Do the remove let community_id = data.community_id; let removed = data.removed; - let updated_community = blocking(context.pool(), move |conn| { - Community::update( - conn, - community_id, - &CommunityUpdateForm::builder() - .removed(Some(removed)) - .build(), - ) - }) - .await? + let updated_community = Community::update( + context.pool(), + community_id, + &CommunityUpdateForm::builder() + .removed(Some(removed)) + .build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community"))?; // Mod tables @@ -56,10 +54,7 @@ impl PerformCrud for RemoveCommunity { reason: data.reason.to_owned(), expires, }; - blocking(context.pool(), move |conn| { - ModRemoveCommunity::create(conn, &form) - }) - .await??; + ModRemoveCommunity::create(context.pool(), &form).await?; let res = send_community_ws_message( data.community_id, diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index 82ae4cc8..feb8bc8f 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -2,11 +2,11 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, EditCommunity}, - utils::{blocking, get_local_user_view_from_jwt, local_site_to_slur_regex}, + utils::{get_local_user_view_from_jwt, local_site_to_slur_regex}, }; use lemmy_apub::protocol::activities::community::update::UpdateCommunity; use lemmy_db_schema::{ - newtypes::{LanguageId, PersonId}, + newtypes::PersonId, source::{ actor_language::{CommunityLanguage, SiteLanguage}, community::{Community, CommunityUpdateForm}, @@ -32,7 +32,7 @@ impl PerformCrud for EditCommunity { let data: &EditCommunity = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let icon = diesel_option_overwrite_to_url(&data.icon)?; let banner = diesel_option_overwrite_to_url(&data.banner)?; @@ -44,29 +44,23 @@ impl PerformCrud for EditCommunity { // Verify its a mod (only mods can edit it) let community_id = data.community_id; - let mods: Vec = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - .map(|v| v.into_iter().map(|m| m.moderator.id).collect()) - }) - .await??; + let mods: Vec = CommunityModeratorView::for_community(context.pool(), community_id) + .await + .map(|v| v.into_iter().map(|m| m.moderator.id).collect())?; if !mods.contains(&local_user_view.person.id) { return Err(LemmyError::from_message("not_a_moderator")); } let community_id = data.community_id; if let Some(languages) = data.discussion_languages.clone() { - let site_languages: Vec = - blocking(context.pool(), SiteLanguage::read_local).await??; + let site_languages = SiteLanguage::read_local(context.pool()).await?; // check that community languages are a subset of site languages // https://stackoverflow.com/a/64227550 let is_subset = languages.iter().all(|item| site_languages.contains(item)); if !is_subset { return Err(LemmyError::from_message("language_not_allowed")); } - blocking(context.pool(), move |conn| { - CommunityLanguage::update(conn, languages, community_id) - }) - .await??; + CommunityLanguage::update(context.pool(), languages, community_id).await?; } let community_form = CommunityUpdateForm::builder() @@ -79,11 +73,9 @@ impl PerformCrud for EditCommunity { .build(); let community_id = data.community_id; - let updated_community = blocking(context.pool(), move |conn| { - Community::update(conn, community_id, &community_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community"))?; + let updated_community = Community::update(context.pool(), community_id, &community_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community"))?; UpdateCommunity::send( updated_community.into(), diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index 2c7f605b..46804441 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -4,7 +4,6 @@ use lemmy_api_common::{ post::{CreatePost, PostResponse}, request::fetch_site_data, utils::{ - blocking, check_community_ban, check_community_deleted_or_removed, get_local_user_view_from_jwt, @@ -53,7 +52,7 @@ impl PerformCrud for CreatePost { let data: &CreatePost = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let slur_regex = local_site_to_slur_regex(&local_site); check_slurs(&data.name, &slur_regex)?; @@ -71,15 +70,14 @@ impl PerformCrud for CreatePost { check_community_deleted_or_removed(data.community_id, context.pool()).await?; let community_id = data.community_id; - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + let community = Community::read(context.pool(), community_id).await?; if community.posting_restricted_to_mods { let community_id = data.community_id; - let is_mod = blocking(context.pool(), move |conn| { - CommunityView::is_mod_or_admin(conn, local_user_view.local_user.person_id, community_id) - }) + let is_mod = CommunityView::is_mod_or_admin( + context.pool(), + local_user_view.local_user.person_id, + community_id, + ) .await?; if !is_mod { return Err(LemmyError::from_message("only_mods_can_post_in_community")); @@ -96,16 +94,11 @@ impl PerformCrud for CreatePost { let language_id = match data.language_id { Some(lid) => Some(lid), None => { - blocking(context.pool(), move |conn| { - default_post_language(conn, community_id, local_user_view.local_user.id) - }) - .await?? + default_post_language(context.pool(), community_id, local_user_view.local_user.id).await? } }; - blocking(context.pool(), move |conn| { - CommunityLanguage::is_allowed_community_language(conn, language_id, community_id) - }) - .await??; + CommunityLanguage::is_allowed_community_language(context.pool(), language_id, community_id) + .await?; let post_form = PostInsertForm::builder() .name(data.name.trim().to_owned()) @@ -121,36 +114,33 @@ impl PerformCrud for CreatePost { .thumbnail_url(thumbnail_url) .build(); - let inserted_post = - match blocking(context.pool(), move |conn| Post::create(conn, &post_form)).await? { - Ok(post) => post, - Err(e) => { - let err_type = if e.to_string() == "value too long for type character varying(200)" { - "post_title_too_long" - } else { - "couldnt_create_post" - }; + let inserted_post = match Post::create(context.pool(), &post_form).await { + Ok(post) => post, + Err(e) => { + let err_type = if e.to_string() == "value too long for type character varying(200)" { + "post_title_too_long" + } else { + "couldnt_create_post" + }; - return Err(LemmyError::from_error_message(e, err_type)); - } - }; + return Err(LemmyError::from_error_message(e, err_type)); + } + }; let inserted_post_id = inserted_post.id; let protocol_and_hostname = context.settings().get_protocol_and_hostname(); - let updated_post = blocking(context.pool(), move |conn| -> Result { - let apub_id = generate_local_apub_endpoint( - EndpointType::Post, - &inserted_post_id.to_string(), - &protocol_and_hostname, - )?; - Ok(Post::update( - conn, - inserted_post_id, - &PostUpdateForm::builder().ap_id(Some(apub_id)).build(), - )?) - }) - .await? - .map_err(|e| e.with_message("couldnt_create_post"))?; + let apub_id = generate_local_apub_endpoint( + EndpointType::Post, + &inserted_post_id.to_string(), + &protocol_and_hostname, + )?; + let updated_post = Post::update( + context.pool(), + inserted_post_id, + &PostUpdateForm::builder().ap_id(Some(apub_id)).build(), + ) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_post"))?; // They like their own post by default let person_id = local_user_view.person.id; @@ -161,9 +151,8 @@ impl PerformCrud for CreatePost { score: 1, }; - let like = move |conn: &mut _| PostLike::like(conn, &like_form); - blocking(context.pool(), like) - .await? + PostLike::like(context.pool(), &like_form) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_post"))?; // Mark the post as read diff --git a/crates/api_crud/src/post/delete.rs b/crates/api_crud/src/post/delete.rs index 78e2f49a..a0b93008 100644 --- a/crates/api_crud/src/post/delete.rs +++ b/crates/api_crud/src/post/delete.rs @@ -2,12 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ post::{DeletePost, PostResponse}, - utils::{ - blocking, - check_community_ban, - check_community_deleted_or_removed, - get_local_user_view_from_jwt, - }, + utils::{check_community_ban, check_community_deleted_or_removed, get_local_user_view_from_jwt}, }; use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ @@ -35,7 +30,7 @@ impl PerformCrud for DeletePost { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let post_id = data.post_id; - let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let orig_post = Post::read(context.pool(), post_id).await?; // Dont delete it if its already been deleted. if orig_post.deleted == data.deleted { @@ -58,14 +53,12 @@ impl PerformCrud for DeletePost { // Update the post let post_id = data.post_id; let deleted = data.deleted; - let updated_post = blocking(context.pool(), move |conn| { - Post::update( - conn, - post_id, - &PostUpdateForm::builder().deleted(Some(deleted)).build(), - ) - }) - .await??; + let updated_post = Post::update( + context.pool(), + post_id, + &PostUpdateForm::builder().deleted(Some(deleted)).build(), + ) + .await?; let res = send_post_ws_message( data.post_id, @@ -77,10 +70,7 @@ impl PerformCrud for DeletePost { .await?; // apub updates - let community = blocking(context.pool(), move |conn| { - Community::read(conn, orig_post.community_id) - }) - .await??; + let community = Community::read(context.pool(), orig_post.community_id).await?; let deletable = DeletableObjects::Post(Box::new(updated_post.into())); send_apub_delete_in_community( local_user_view.person, diff --git a/crates/api_crud/src/post/list.rs b/crates/api_crud/src/post/list.rs index f7f7b2cc..c3d20d3d 100644 --- a/crates/api_crud/src/post/list.rs +++ b/crates/api_crud/src/post/list.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ post::{GetPosts, GetPostsResponse}, utils::{ - blocking, check_private_instance, get_local_user_view_from_jwt_opt, listing_type_with_site_default, @@ -32,7 +31,7 @@ impl PerformCrud for GetPosts { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; @@ -54,22 +53,20 @@ impl PerformCrud for GetPosts { }; let saved_only = data.saved_only; - let mut posts = blocking(context.pool(), move |conn| { - PostQuery::builder() - .conn(conn) - .local_user(local_user_view.map(|l| l.local_user).as_ref()) - .listing_type(Some(listing_type)) - .sort(sort) - .community_id(community_id) - .community_actor_id(community_actor_id) - .saved_only(saved_only) - .page(page) - .limit(limit) - .build() - .list() - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_get_posts"))?; + let mut posts = PostQuery::builder() + .pool(context.pool()) + .local_user(local_user_view.map(|l| l.local_user).as_ref()) + .listing_type(Some(listing_type)) + .sort(sort) + .community_id(community_id) + .community_actor_id(community_actor_id) + .saved_only(saved_only) + .page(page) + .limit(limit) + .build() + .list() + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_get_posts"))?; // Blank out deleted or removed info for non-logged in users if !is_logged_in { diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index 746b8470..5e2582a0 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ post::{GetPost, GetPostResponse}, - utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt, mark_post_as_read}, + utils::{check_private_instance, get_local_user_view_from_jwt_opt, mark_post_as_read}, }; use lemmy_db_schema::{ aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm}, @@ -28,7 +28,7 @@ impl PerformCrud for GetPost { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; @@ -38,19 +38,17 @@ impl PerformCrud for GetPost { let post_id = if let Some(id) = data.id { id } else if let Some(comment_id) = data.comment_id { - blocking(context.pool(), move |conn| Comment::read(conn, comment_id)) - .await? + Comment::read(context.pool(), comment_id) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))? .post_id } else { Err(LemmyError::from_message("couldnt_find_post"))? }; - let mut post_view = blocking(context.pool(), move |conn| { - PostView::read(conn, post_id, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?; + let mut post_view = PostView::read(context.pool(), post_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?; // Mark the post as read let post_id = post_view.post.id; @@ -60,11 +58,9 @@ impl PerformCrud for GetPost { // Necessary for the sidebar subscribed let community_id = post_view.community.id; - let mut community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, community_id, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; + let mut community_view = CommunityView::read(context.pool(), community_id, person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; // Insert into PersonPostAggregates // to update the read_comments count @@ -76,11 +72,9 @@ impl PerformCrud for GetPost { read_comments, ..PersonPostAggregatesForm::default() }; - blocking(context.pool(), move |conn| { - PersonPostAggregates::upsert(conn, &person_post_agg_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?; + PersonPostAggregates::upsert(context.pool(), &person_post_agg_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?; } // Blank out deleted or removed info for non-logged in users @@ -94,10 +88,7 @@ impl PerformCrud for GetPost { } } - let moderators = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await??; + let moderators = CommunityModeratorView::for_community(context.pool(), community_id).await?; let online = context .chat_server() diff --git a/crates/api_crud/src/post/remove.rs b/crates/api_crud/src/post/remove.rs index d646a008..8850349c 100644 --- a/crates/api_crud/src/post/remove.rs +++ b/crates/api_crud/src/post/remove.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ post::{PostResponse, RemovePost}, - utils::{blocking, check_community_ban, get_local_user_view_from_jwt, is_mod_or_admin}, + utils::{check_community_ban, get_local_user_view_from_jwt, is_mod_or_admin}, }; use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ @@ -31,7 +31,7 @@ impl PerformCrud for RemovePost { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let post_id = data.post_id; - let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let orig_post = Post::read(context.pool(), post_id).await?; check_community_ban( local_user_view.person.id, @@ -51,14 +51,12 @@ impl PerformCrud for RemovePost { // Update the post let post_id = data.post_id; let removed = data.removed; - let updated_post = blocking(context.pool(), move |conn| { - Post::update( - conn, - post_id, - &PostUpdateForm::builder().removed(Some(removed)).build(), - ) - }) - .await??; + let updated_post = Post::update( + context.pool(), + post_id, + &PostUpdateForm::builder().removed(Some(removed)).build(), + ) + .await?; // Mod tables let form = ModRemovePostForm { @@ -67,10 +65,7 @@ impl PerformCrud for RemovePost { removed: Some(removed), reason: data.reason.to_owned(), }; - blocking(context.pool(), move |conn| { - ModRemovePost::create(conn, &form) - }) - .await??; + ModRemovePost::create(context.pool(), &form).await?; let res = send_post_ws_message( data.post_id, @@ -82,10 +77,7 @@ impl PerformCrud for RemovePost { .await?; // apub updates - let community = blocking(context.pool(), move |conn| { - Community::read(conn, orig_post.community_id) - }) - .await??; + let community = Community::read(context.pool(), orig_post.community_id).await?; let deletable = DeletableObjects::Post(Box::new(updated_post.into())); send_apub_delete_in_community( local_user_view.person, diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index ab9993e6..ff6a10f0 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -4,7 +4,6 @@ use lemmy_api_common::{ post::{EditPost, PostResponse}, request::fetch_site_data, utils::{ - blocking, check_community_ban, check_community_deleted_or_removed, get_local_user_view_from_jwt, @@ -44,7 +43,7 @@ impl PerformCrud for EditPost { let data: &EditPost = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let data_url = data.url.as_ref(); @@ -64,7 +63,7 @@ impl PerformCrud for EditPost { } let post_id = data.post_id; - let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let orig_post = Post::read(context.pool(), post_id).await?; check_community_ban( local_user_view.person.id, @@ -88,10 +87,12 @@ impl PerformCrud for EditPost { .unwrap_or_default(); let language_id = self.language_id; - blocking(context.pool(), move |conn| { - CommunityLanguage::is_allowed_community_language(conn, language_id, orig_post.community_id) - }) - .await??; + CommunityLanguage::is_allowed_community_language( + context.pool(), + language_id, + orig_post.community_id, + ) + .await?; let post_form = PostUpdateForm::builder() .name(data.name.to_owned()) @@ -106,10 +107,7 @@ impl PerformCrud for EditPost { .build(); let post_id = data.post_id; - let res = blocking(context.pool(), move |conn| { - Post::update(conn, post_id, &post_form) - }) - .await?; + let res = Post::update(context.pool(), post_id, &post_form).await; let updated_post: Post = match res { Ok(post) => post, Err(e) => { diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index 9eeea66d..c0b784ab 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ private_message::{CreatePrivateMessage, PrivateMessageResponse}, utils::{ - blocking, check_person_block, get_interface_language, get_local_user_view_from_jwt, @@ -43,7 +42,7 @@ impl PerformCrud for CreatePrivateMessage { let data: &CreatePrivateMessage = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; let content_slurs_removed = remove_slurs( &data.content.to_owned(), @@ -58,41 +57,33 @@ impl PerformCrud for CreatePrivateMessage { .recipient_id(data.recipient_id) .build(); - let inserted_private_message = match blocking(context.pool(), move |conn| { - PrivateMessage::create(conn, &private_message_form) - }) - .await? - { - Ok(private_message) => private_message, - Err(e) => { - return Err(LemmyError::from_error_message( - e, - "couldnt_create_private_message", - )); - } - }; + let inserted_private_message = + match PrivateMessage::create(context.pool(), &private_message_form).await { + Ok(private_message) => private_message, + Err(e) => { + return Err(LemmyError::from_error_message( + e, + "couldnt_create_private_message", + )); + } + }; let inserted_private_message_id = inserted_private_message.id; let protocol_and_hostname = context.settings().get_protocol_and_hostname(); - let updated_private_message = blocking( + let apub_id = generate_local_apub_endpoint( + EndpointType::PrivateMessage, + &inserted_private_message_id.to_string(), + &protocol_and_hostname, + )?; + let updated_private_message = PrivateMessage::update( context.pool(), - move |conn| -> Result { - let apub_id = generate_local_apub_endpoint( - EndpointType::PrivateMessage, - &inserted_private_message_id.to_string(), - &protocol_and_hostname, - )?; - Ok(PrivateMessage::update( - conn, - inserted_private_message.id, - &PrivateMessageUpdateForm::builder() - .ap_id(Some(apub_id)) - .build(), - )?) - }, + inserted_private_message.id, + &PrivateMessageUpdateForm::builder() + .ap_id(Some(apub_id)) + .build(), ) - .await? - .map_err(|e| e.with_message("couldnt_create_private_message"))?; + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_private_message"))?; CreateOrUpdatePrivateMessage::send( updated_private_message.into(), @@ -113,10 +104,7 @@ impl PerformCrud for CreatePrivateMessage { // Send email to the local recipient, if one exists if res.private_message_view.recipient.local { let recipient_id = data.recipient_id; - let local_recipient = blocking(context.pool(), move |conn| { - LocalUserView::read_person(conn, recipient_id) - }) - .await??; + let local_recipient = LocalUserView::read_person(context.pool(), recipient_id).await?; let lang = get_interface_language(&local_recipient); let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname()); send_email_to_user( diff --git a/crates/api_crud/src/private_message/delete.rs b/crates/api_crud/src/private_message/delete.rs index 8a348223..51cded6d 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ private_message::{DeletePrivateMessage, PrivateMessageResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_apub::activities::deletion::send_apub_delete_private_message; use lemmy_db_schema::{ @@ -28,10 +28,7 @@ impl PerformCrud for DeletePrivateMessage { // Checking permissions let private_message_id = data.private_message_id; - let orig_private_message = blocking(context.pool(), move |conn| { - PrivateMessage::read(conn, private_message_id) - }) - .await??; + let orig_private_message = PrivateMessage::read(context.pool(), private_message_id).await?; if local_user_view.person.id != orig_private_message.creator_id { return Err(LemmyError::from_message("no_private_message_edit_allowed")); } @@ -39,16 +36,14 @@ impl PerformCrud for DeletePrivateMessage { // Doing the update let private_message_id = data.private_message_id; let deleted = data.deleted; - let updated_private_message = blocking(context.pool(), move |conn| { - PrivateMessage::update( - conn, - private_message_id, - &PrivateMessageUpdateForm::builder() - .deleted(Some(deleted)) - .build(), - ) - }) - .await? + let updated_private_message = PrivateMessage::update( + context.pool(), + private_message_id, + &PrivateMessageUpdateForm::builder() + .deleted(Some(deleted)) + .build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_private_message"))?; // Send the apub update diff --git a/crates/api_crud/src/private_message/read.rs b/crates/api_crud/src/private_message/read.rs index cc03c318..7e336c3b 100644 --- a/crates/api_crud/src/private_message/read.rs +++ b/crates/api_crud/src/private_message/read.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ private_message::{GetPrivateMessages, PrivateMessagesResponse}, - utils::{blocking, get_local_user_view_from_jwt}, + utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::traits::DeleteableOrRemoveable; use lemmy_db_views::private_message_view::PrivateMessageQuery; @@ -27,17 +27,15 @@ impl PerformCrud for GetPrivateMessages { let page = data.page; let limit = data.limit; let unread_only = data.unread_only; - let mut messages = blocking(context.pool(), move |conn| { - PrivateMessageQuery::builder() - .conn(conn) - .recipient_id(person_id) - .page(page) - .limit(limit) - .unread_only(unread_only) - .build() - .list() - }) - .await??; + let mut messages = PrivateMessageQuery::builder() + .pool(context.pool()) + .recipient_id(person_id) + .page(page) + .limit(limit) + .unread_only(unread_only) + .build() + .list() + .await?; // Messages sent by ourselves should be marked as read. The `read` column in database is only // for the recipient, and shouldnt be exposed to sender. diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index 9782b64c..dfe06e8e 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ private_message::{EditPrivateMessage, PrivateMessageResponse}, - utils::{blocking, get_local_user_view_from_jwt, local_site_to_slur_regex}, + utils::{get_local_user_view_from_jwt, local_site_to_slur_regex}, }; use lemmy_apub::protocol::activities::{ create_or_update::private_message::CreateOrUpdatePrivateMessage, @@ -32,14 +32,11 @@ impl PerformCrud for EditPrivateMessage { let data: &EditPrivateMessage = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; // Checking permissions let private_message_id = data.private_message_id; - let orig_private_message = blocking(context.pool(), move |conn| { - PrivateMessage::read(conn, private_message_id) - }) - .await??; + let orig_private_message = PrivateMessage::read(context.pool(), private_message_id).await?; if local_user_view.person.id != orig_private_message.creator_id { return Err(LemmyError::from_message("no_private_message_edit_allowed")); } @@ -47,17 +44,15 @@ impl PerformCrud for EditPrivateMessage { // Doing the update let content_slurs_removed = remove_slurs(&data.content, &local_site_to_slur_regex(&local_site)); let private_message_id = data.private_message_id; - let updated_private_message = blocking(context.pool(), move |conn| { - PrivateMessage::update( - conn, - private_message_id, - &PrivateMessageUpdateForm::builder() - .content(Some(content_slurs_removed)) - .updated(Some(Some(naive_now()))) - .build(), - ) - }) - .await? + let updated_private_message = PrivateMessage::update( + context.pool(), + private_message_id, + &PrivateMessageUpdateForm::builder() + .content(Some(content_slurs_removed)) + .updated(Some(Some(naive_now()))) + .build(), + ) + .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_private_message"))?; // Send the apub update diff --git a/crates/api_crud/src/site/create.rs b/crates/api_crud/src/site/create.rs index 5340c657..7a9b0484 100644 --- a/crates/api_crud/src/site/create.rs +++ b/crates/api_crud/src/site/create.rs @@ -4,7 +4,6 @@ use actix_web::web::Data; use lemmy_api_common::{ site::{CreateSite, SiteResponse}, utils::{ - blocking, get_local_user_view_from_jwt, is_admin, local_site_to_slur_regex, @@ -43,7 +42,7 @@ impl PerformCrud for CreateSite { ) -> Result { let data: &CreateSite = self; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; if local_site.site_setup { return Err(LemmyError::from_message("site_already_exists")); @@ -88,10 +87,8 @@ impl PerformCrud for CreateSite { .build(); let site_id = local_site.site_id; - blocking(context.pool(), move |conn| { - Site::update(conn, site_id, &site_form) - }) - .await??; + + Site::update(context.pool(), site_id, &site_form).await?; let local_site_form = LocalSiteUpdateForm::builder() // Set the site setup to true @@ -120,10 +117,8 @@ impl PerformCrud for CreateSite { .captcha_enabled(data.captcha_enabled) .captcha_difficulty(data.captcha_difficulty.to_owned()) .build(); - blocking(context.pool(), move |conn| { - LocalSite::update(conn, &local_site_form) - }) - .await??; + + LocalSite::update(context.pool(), &local_site_form).await?; let local_site_rate_limit_form = LocalSiteRateLimitUpdateForm::builder() .message(data.rate_limit_message) @@ -140,12 +135,9 @@ impl PerformCrud for CreateSite { .search_per_second(data.rate_limit_search_per_second) .build(); - blocking(context.pool(), move |conn| { - LocalSiteRateLimit::update(conn, &local_site_rate_limit_form) - }) - .await??; + LocalSiteRateLimit::update(context.pool(), &local_site_rate_limit_form).await?; - let site_view = blocking(context.pool(), SiteView::read_local).await??; + let site_view = SiteView::read_local(context.pool()).await?; Ok(SiteResponse { site_view }) } diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index 226e24f3..2f4203a0 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ site::{GetSite, GetSiteResponse, MyUserInfo}, - utils::{blocking, build_federated_instances, get_local_user_settings_view_from_jwt_opt}, + utils::{build_federated_instances, get_local_user_settings_view_from_jwt_opt}, }; use lemmy_db_schema::source::{actor_language::SiteLanguage, language::Language}; use lemmy_db_views::structs::{LocalUserDiscussionLanguageView, SiteView}; @@ -28,9 +28,9 @@ impl PerformCrud for GetSite { ) -> Result { let data: &GetSite = self; - let site_view = blocking(context.pool(), SiteView::read_local).await??; + let site_view = SiteView::read_local(context.pool()).await?; - let admins = blocking(context.pool(), PersonViewSafe::admins).await??; + let admins = PersonViewSafe::admins(context.pool()).await?; let online = context .chat_server() @@ -49,37 +49,28 @@ impl PerformCrud for GetSite { let person_id = local_user_view.person.id; let local_user_id = local_user_view.local_user.id; - let follows = blocking(context.pool(), move |conn| { - CommunityFollowerView::for_person(conn, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; + let follows = CommunityFollowerView::for_person(context.pool(), person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; let person_id = local_user_view.person.id; - let community_blocks = blocking(context.pool(), move |conn| { - CommunityBlockView::for_person(conn, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; + let community_blocks = CommunityBlockView::for_person(context.pool(), person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; let person_id = local_user_view.person.id; - let person_blocks = blocking(context.pool(), move |conn| { - PersonBlockView::for_person(conn, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; + let person_blocks = PersonBlockView::for_person(context.pool(), person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; - let moderates = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_person(conn, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; + let moderates = CommunityModeratorView::for_person(context.pool(), person_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; - let discussion_languages = blocking(context.pool(), move |conn| { - LocalUserDiscussionLanguageView::read_languages(conn, local_user_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; + let discussion_languages = + LocalUserDiscussionLanguageView::read_languages(context.pool(), local_user_id) + .await + .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?; Some(MyUserInfo { local_user_view, @@ -96,8 +87,8 @@ impl PerformCrud for GetSite { let federated_instances = build_federated_instances(&site_view.local_site, context.pool()).await?; - let all_languages = blocking(context.pool(), Language::read_all).await??; - let discussion_languages = blocking(context.pool(), SiteLanguage::read_local).await??; + let all_languages = Language::read_all(context.pool()).await?; + let discussion_languages = SiteLanguage::read_local(context.pool()).await?; Ok(GetSiteResponse { site_view, diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index 2f050395..5f22d9f2 100644 --- a/crates/api_crud/src/site/update.rs +++ b/crates/api_crud/src/site/update.rs @@ -3,7 +3,6 @@ use actix_web::web::Data; use lemmy_api_common::{ site::{EditSite, SiteResponse}, utils::{ - blocking, get_local_user_view_from_jwt, is_admin, local_site_to_slur_regex, @@ -46,7 +45,7 @@ impl PerformCrud for EditSite { let data: &EditSite = self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; // Make sure user is an admin is_admin(&local_user_view)?; @@ -75,11 +74,8 @@ impl PerformCrud for EditSite { let site_id = local_site.site_id; if let Some(discussion_languages) = data.discussion_languages.clone() { - blocking(context.pool(), move |conn| { - let site = Site::read(conn, site_id)?; - SiteLanguage::update(conn, discussion_languages, &site) - }) - .await??; + let site = Site::read(context.pool(), site_id).await?; + SiteLanguage::update(context.pool(), discussion_languages.clone(), &site).await?; } let name = data.name.to_owned(); @@ -92,13 +88,11 @@ impl PerformCrud for EditSite { .updated(Some(Some(naive_now()))) .build(); - blocking(context.pool(), move |conn| { - Site::update(conn, local_site.site_id, &site_form) - }) - .await - // Ignore errors for all these, so as to not throw errors if no update occurs - // Diesel will throw an error for empty update forms - .ok(); + Site::update(context.pool(), site_id, &site_form) + .await + // Ignore errors for all these, so as to not throw errors if no update occurs + // Diesel will throw an error for empty update forms + .ok(); let local_site_form = LocalSiteUpdateForm::builder() .enable_downvotes(data.enable_downvotes) @@ -126,11 +120,9 @@ impl PerformCrud for EditSite { .captcha_difficulty(data.captcha_difficulty.to_owned()) .build(); - let update_local_site = blocking(context.pool(), move |conn| { - LocalSite::update(conn, &local_site_form) - }) - .await - .ok(); + let update_local_site = LocalSite::update(context.pool(), &local_site_form) + .await + .ok(); let local_site_rate_limit_form = LocalSiteRateLimitUpdateForm::builder() .message(data.rate_limit_message) @@ -147,23 +139,15 @@ impl PerformCrud for EditSite { .search_per_second(data.rate_limit_search_per_second) .build(); - blocking(context.pool(), move |conn| { - LocalSiteRateLimit::update(conn, &local_site_rate_limit_form) - }) - .await - .ok(); + LocalSiteRateLimit::update(context.pool(), &local_site_rate_limit_form) + .await + .ok(); // Replace the blocked and allowed instances let allowed = data.allowed_instances.to_owned(); - blocking(context.pool(), move |conn| { - FederationAllowList::replace(conn, allowed) - }) - .await??; + FederationAllowList::replace(context.pool(), allowed).await?; let blocked = data.blocked_instances.to_owned(); - blocking(context.pool(), move |conn| { - FederationBlockList::replace(conn, blocked) - }) - .await??; + FederationBlockList::replace(context.pool(), blocked).await?; // TODO can't think of a better way to do this. // If the server suddenly requires email verification, or required applications, no old users @@ -172,39 +156,25 @@ impl PerformCrud for EditSite { let new_require_application = update_local_site .as_ref() - .map(|ols| { - ols - .as_ref() - .map(|ls| ls.require_application) - .unwrap_or(false) - }) + .map(|ols| ols.require_application) .unwrap_or(false); if !local_site.require_application && new_require_application { - blocking(context.pool(), move |conn| { - LocalUser::set_all_users_registration_applications_accepted(conn) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_set_all_registrations_accepted"))?; + LocalUser::set_all_users_registration_applications_accepted(context.pool()) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_set_all_registrations_accepted"))?; } let new_require_email_verification = update_local_site .as_ref() - .map(|ols| { - ols - .as_ref() - .map(|ls| ls.require_email_verification) - .unwrap_or(false) - }) + .map(|ols| ols.require_email_verification) .unwrap_or(false); if !local_site.require_email_verification && new_require_email_verification { - blocking(context.pool(), move |conn| { - LocalUser::set_all_users_email_verified(conn) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_set_all_email_verified"))?; + LocalUser::set_all_users_email_verified(context.pool()) + .await + .map_err(|e| LemmyError::from_error_message(e, "couldnt_set_all_email_verified"))?; } - let site_view = blocking(context.pool(), SiteView::read_local).await??; + let site_view = SiteView::read_local(context.pool()).await?; let res = SiteResponse { site_view }; diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index 88bc43d0..7cd34fc4 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -4,7 +4,6 @@ use actix_web::web::Data; use lemmy_api_common::{ person::{LoginResponse, Register}, utils::{ - blocking, honeypot_check, local_site_to_slur_regex, password_length_check, @@ -28,7 +27,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_db_views::structs::{LocalUserView, SiteView}; -use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{ claims::Claims, error::LemmyError, @@ -49,7 +47,7 @@ impl PerformCrud for Register { ) -> Result { let data: &Register = self; - let site_view = blocking(context.pool(), SiteView::read_local).await??; + let site_view = SiteView::read_local(context.pool()).await?; let local_site = site_view.local_site; if !local_site.open_registration { @@ -63,7 +61,7 @@ impl PerformCrud for Register { return Err(LemmyError::from_message("email_required")); } - if local_site.require_application && data.answer.is_none() { + if local_site.site_setup && local_site.require_application && data.answer.is_none() { return Err(LemmyError::from_message( "registration_application_answer_required", )); @@ -74,14 +72,8 @@ impl PerformCrud for Register { return Err(LemmyError::from_message("passwords_dont_match")); } - // Check if there are admins. False if admins exist - let no_admins = blocking(context.pool(), move |conn| { - PersonViewSafe::admins(conn).map(|a| a.is_empty()) - }) - .await??; - - // If its not the admin, check the captcha - if !no_admins && local_site.captcha_enabled { + // If the site is set up, check the captcha + if local_site.site_setup && local_site.captcha_enabled { let check = context .chat_server() .send(CheckCaptcha { @@ -124,16 +116,15 @@ impl PerformCrud for Register { .public_key(actor_keypair.public_key) .inbox_url(Some(generate_inbox_url(&actor_id)?)) .shared_inbox_url(Some(generate_shared_inbox_url(&actor_id)?)) - .admin(Some(no_admins)) + // If its the initial site setup, they are an admin + .admin(Some(!local_site.site_setup)) .instance_id(site_view.site.instance_id) .build(); // insert the person - let inserted_person = blocking(context.pool(), move |conn| { - Person::create(conn, &person_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "user_already_exists"))?; + let inserted_person = Person::create(context.pool(), &person_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "user_already_exists"))?; // Create the local user let local_user_form = LocalUserInsertForm::builder() @@ -143,11 +134,7 @@ impl PerformCrud for Register { .show_nsfw(Some(data.show_nsfw)) .build(); - let inserted_local_user = match blocking(context.pool(), move |conn| { - LocalUser::create(conn, &local_user_form) - }) - .await? - { + let inserted_local_user = match LocalUser::create(context.pool(), &local_user_form).await { Ok(lu) => lu, Err(e) => { let err_type = if e.to_string() @@ -159,16 +146,13 @@ impl PerformCrud for Register { }; // If the local user creation errored, then delete that person - blocking(context.pool(), move |conn| { - Person::delete(conn, inserted_person.id) - }) - .await??; + Person::delete(context.pool(), inserted_person.id).await?; return Err(LemmyError::from_error_message(e, err_type)); } }; - if local_site.require_application { + if local_site.site_setup && local_site.require_application { // Create the registration application let form = RegistrationApplicationInsertForm { local_user_id: inserted_local_user.id, @@ -176,10 +160,7 @@ impl PerformCrud for Register { answer: data.answer.to_owned().expect("must have an answer"), }; - blocking(context.pool(), move |conn| { - RegistrationApplication::create(conn, &form) - }) - .await??; + RegistrationApplication::create(context.pool(), &form).await?; } // Email the admins @@ -194,8 +175,10 @@ impl PerformCrud for Register { verify_email_sent: false, }; - // Log the user in directly if email verification and application aren't required - if !local_site.require_application && !local_site.require_email_verification { + // Log the user in directly if the site is not setup, or email verification and application aren't required + if !local_site.site_setup + || (!local_site.require_application && !local_site.require_email_verification) + { login_response.jwt = Some( Claims::jwt( inserted_local_user.id.0, diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index 5e6355ce..0352b07a 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -2,7 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ person::{GetPersonDetails, GetPersonDetailsResponse}, - utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt}, + utils::{check_private_instance, get_local_user_view_from_jwt_opt}, }; use lemmy_apub::{fetcher::resolve_actor_identifier, objects::person::ApubPerson}; use lemmy_db_schema::{ @@ -34,7 +34,7 @@ impl PerformCrud for GetPersonDetails { let local_user_view = get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) .await?; - let local_site = blocking(context.pool(), LocalSite::read).await??; + let local_site = LocalSite::read(context.pool()).await?; check_private_instance(&local_user_view, &local_site)?; @@ -56,10 +56,7 @@ impl PerformCrud for GetPersonDetails { // You don't need to return settings for the user, since this comes back with GetSite // `my_user` - let person_view = blocking(context.pool(), move |conn| { - PersonViewSafe::read(conn, person_details_id) - }) - .await??; + let person_view = PersonViewSafe::read(context.pool(), person_details_id).await?; let sort = data.sort; let page = data.page; @@ -69,57 +66,50 @@ impl PerformCrud for GetPersonDetails { let local_user = local_user_view.map(|l| l.local_user); let local_user_clone = local_user.to_owned(); - let posts = blocking(context.pool(), move |conn| { - let posts_query = PostQuery::builder() - .conn(conn) - .sort(sort) - .saved_only(saved_only) - .local_user(local_user.as_ref()) - .community_id(community_id) - .page(page) - .limit(limit); + let posts_query = PostQuery::builder() + .pool(context.pool()) + .sort(sort) + .saved_only(saved_only) + .local_user(local_user.as_ref()) + .community_id(community_id) + .page(page) + .limit(limit); - // If its saved only, you don't care what creator it was - // Or, if its not saved, then you only want it for that specific creator - if !saved_only.unwrap_or(false) { - posts_query - .creator_id(Some(person_details_id)) - .build() - .list() - } else { - posts_query.build().list() - } - }) - .await??; + // If its saved only, you don't care what creator it was + // Or, if its not saved, then you only want it for that specific creator + let posts = if !saved_only.unwrap_or(false) { + posts_query + .creator_id(Some(person_details_id)) + .build() + .list() + } else { + posts_query.build().list() + } + .await?; - let comments = blocking(context.pool(), move |conn| { - let comments_query = CommentQuery::builder() - .conn(conn) - .local_user(local_user_clone.as_ref()) - .sort(sort.map(post_to_comment_sort_type)) - .saved_only(saved_only) - .show_deleted_and_removed(Some(false)) - .community_id(community_id) - .page(page) - .limit(limit); + let comments_query = CommentQuery::builder() + .pool(context.pool()) + .local_user(local_user_clone.as_ref()) + .sort(sort.map(post_to_comment_sort_type)) + .saved_only(saved_only) + .show_deleted_and_removed(Some(false)) + .community_id(community_id) + .page(page) + .limit(limit); - // If its saved only, you don't care what creator it was - // Or, if its not saved, then you only want it for that specific creator - if !saved_only.unwrap_or(false) { - comments_query - .creator_id(Some(person_details_id)) - .build() - .list() - } else { - comments_query.build().list() - } - }) - .await??; + // If its saved only, you don't care what creator it was + // Or, if its not saved, then you only want it for that specific creator + let comments = if !saved_only.unwrap_or(false) { + comments_query + .creator_id(Some(person_details_id)) + .build() + .list() + } else { + comments_query.build().list() + } + .await?; - let moderates = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_person(conn, person_details_id) - }) - .await??; + let moderates = CommunityModeratorView::for_person(context.pool(), person_details_id).await?; // Return the jwt Ok(GetPersonDetailsResponse { diff --git a/crates/apub/Cargo.toml b/crates/apub/Cargo.toml index 81967ee9..3fdd062a 100644 --- a/crates/apub/Cargo.toml +++ b/crates/apub/Cargo.toml @@ -21,11 +21,11 @@ lemmy_db_views_actor = { version = "=0.16.5", path = "../db_views_actor", featur lemmy_api_common = { version = "=0.16.5", path = "../api_common", features = ["full"] } lemmy_websocket = { version = "=0.16.5", path = "../websocket" } activitypub_federation = "0.2.3" -diesel = "2.0.0" +diesel = "2.0.2" activitystreams-kinds = "0.2.1" chrono = { version = "0.4.22", features = ["serde"], default-features = false } -serde_json = { version = "1.0.85", features = ["preserve_order"] } -serde = { version = "1.0.145", features = ["derive"] } +serde_json = { version = "1.0.87", features = ["preserve_order"] } +serde = { version = "1.0.147", features = ["derive"] } serde_with = "1.14.0" actix = "0.13.0" actix-web = { version = "4.2.1", default-features = false } @@ -35,15 +35,16 @@ strum_macros = "0.24.3" url = { version = "2.3.1", features = ["serde"] } http = "0.2.8" http-signature-normalization-actix = { version = "0.6.1", default-features = false, features = ["server", "sha-2"] } -futures = "0.3.24" +futures = "0.3.25" itertools = "0.10.5" -uuid = { version = "1.1.2", features = ["serde", "v4"] } +uuid = { version = "1.2.1", features = ["serde", "v4"] } sha2 = "0.10.6" -async-trait = "0.1.57" -anyhow = "1.0.65" +async-trait = "0.1.58" +anyhow = "1.0.66" reqwest = { version = "0.11.12", features = ["json"] } html2md = "0.2.13" once_cell = "1.15.0" +tokio = "1.21.2" [dev-dependencies] serial_test = "0.9.0" diff --git a/crates/apub/src/activities/block/block_user.rs b/crates/apub/src/activities/block/block_user.rs index bef3b6a2..54084707 100644 --- a/crates/apub/src/activities/block/block_user.rs +++ b/crates/apub/src/activities/block/block_user.rs @@ -23,7 +23,7 @@ use activitypub_federation::{ use activitystreams_kinds::{activity::BlockType, public}; use anyhow::anyhow; use chrono::NaiveDateTime; -use lemmy_api_common::utils::{blocking, remove_user_data, remove_user_data_in_community}; +use lemmy_api_common::utils::{remove_user_data, remove_user_data_in_community}; use lemmy_db_schema::{ source::{ community::{ @@ -126,7 +126,7 @@ impl ActivityHandler for BlockUser { verify_is_public(&self.to, &self.cc)?; match self .target - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await? { SiteOrCommunity::Site(site) => { @@ -164,29 +164,27 @@ impl ActivityHandler for BlockUser { let expires = self.expires.map(|u| u.naive_local()); let mod_person = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let blocked_person = self .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let target = self .target - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; match target { SiteOrCommunity::Site(_site) => { - let blocked_person = blocking(context.pool(), move |conn| { - Person::update( - conn, - blocked_person.id, - &PersonUpdateForm::builder() - .banned(Some(true)) - .ban_expires(Some(expires)) - .build(), - ) - }) - .await??; + let blocked_person = Person::update( + context.pool(), + blocked_person.id, + &PersonUpdateForm::builder() + .banned(Some(true)) + .ban_expires(Some(expires)) + .build(), + ) + .await?; if self.remove_data.unwrap_or(false) { remove_user_data( blocked_person.id, @@ -205,7 +203,7 @@ impl ActivityHandler for BlockUser { banned: Some(true), expires, }; - blocking(context.pool(), move |conn| ModBan::create(conn, &form)).await??; + ModBan::create(context.pool(), &form).await?; } SiteOrCommunity::Community(community) => { let community_user_ban_form = CommunityPersonBanForm { @@ -213,10 +211,7 @@ impl ActivityHandler for BlockUser { person_id: blocked_person.id, expires: Some(expires), }; - blocking(context.pool(), move |conn| { - CommunityPersonBan::ban(conn, &community_user_ban_form) - }) - .await??; + CommunityPersonBan::ban(context.pool(), &community_user_ban_form).await?; // Also unsubscribe them from the community, if they are subscribed let community_follower_form = CommunityFollowerForm { @@ -224,11 +219,9 @@ impl ActivityHandler for BlockUser { person_id: blocked_person.id, pending: false, }; - blocking(context.pool(), move |conn: &mut _| { - CommunityFollower::unfollow(conn, &community_follower_form) - }) - .await? - .ok(); + CommunityFollower::unfollow(context.pool(), &community_follower_form) + .await + .ok(); if self.remove_data.unwrap_or(false) { remove_user_data_in_community(community.id, blocked_person.id, context.pool()).await?; @@ -243,10 +236,7 @@ impl ActivityHandler for BlockUser { banned: Some(true), expires, }; - blocking(context.pool(), move |conn| { - ModBanFromCommunity::create(conn, &form) - }) - .await??; + ModBanFromCommunity::create(context.pool(), &form).await?; } } @@ -264,7 +254,7 @@ impl GetCommunity for BlockUser { ) -> Result { let target = self .target - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; match target { SiteOrCommunity::Community(c) => Ok(c), diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 386260de..bc2ea77f 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -5,7 +5,6 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, traits::ApubObject}; use chrono::NaiveDateTime; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{source::site::Site, utils::DbPool}; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -116,8 +115,8 @@ impl SiteOrCommunity { async fn generate_cc(target: &SiteOrCommunity, pool: &DbPool) -> Result, LemmyError> { Ok(match target { - SiteOrCommunity::Site(_) => blocking(pool, Site::read_remote_sites) - .await?? + SiteOrCommunity::Site(_) => Site::read_remote_sites(pool) + .await? .into_iter() .map(|s| s.actor_id.into()) .collect(), diff --git a/crates/apub/src/activities/block/undo_block_user.rs b/crates/apub/src/activities/block/undo_block_user.rs index cd9784f3..f18516f9 100644 --- a/crates/apub/src/activities/block/undo_block_user.rs +++ b/crates/apub/src/activities/block/undo_block_user.rs @@ -19,7 +19,6 @@ use activitypub_federation::{ utils::verify_domains_match, }; use activitystreams_kinds::{activity::UndoType, public}; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ community::{CommunityPersonBan, CommunityPersonBanForm}, @@ -102,7 +101,7 @@ impl ActivityHandler for UndoBlockUser { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let instance = local_instance(context); + let instance = local_instance(context).await; let expires = self.object.expires.map(|u| u.naive_local()); let mod_person = self .actor @@ -120,17 +119,15 @@ impl ActivityHandler for UndoBlockUser { .await? { SiteOrCommunity::Site(_site) => { - let blocked_person = blocking(context.pool(), move |conn| { - Person::update( - conn, - blocked_person.id, - &PersonUpdateForm::builder() - .banned(Some(false)) - .ban_expires(Some(expires)) - .build(), - ) - }) - .await??; + let blocked_person = Person::update( + context.pool(), + blocked_person.id, + &PersonUpdateForm::builder() + .banned(Some(false)) + .ban_expires(Some(expires)) + .build(), + ) + .await?; // write mod log let form = ModBanForm { @@ -140,7 +137,7 @@ impl ActivityHandler for UndoBlockUser { banned: Some(false), expires, }; - blocking(context.pool(), move |conn| ModBan::create(conn, &form)).await??; + ModBan::create(context.pool(), &form).await?; } SiteOrCommunity::Community(community) => { let community_user_ban_form = CommunityPersonBanForm { @@ -148,10 +145,7 @@ impl ActivityHandler for UndoBlockUser { person_id: blocked_person.id, expires: None, }; - blocking(context.pool(), move |conn: &mut _| { - CommunityPersonBan::unban(conn, &community_user_ban_form) - }) - .await??; + CommunityPersonBan::unban(context.pool(), &community_user_ban_form).await?; // write to mod log let form = ModBanFromCommunityForm { @@ -162,10 +156,7 @@ impl ActivityHandler for UndoBlockUser { banned: Some(false), expires, }; - blocking(context.pool(), move |conn| { - ModBanFromCommunity::create(conn, &form) - }) - .await??; + ModBanFromCommunity::create(context.pool(), &form).await?; } } diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index 4dbd463b..ba78ec3b 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -24,7 +24,6 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::{activity::AddType, public}; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ community::{CommunityModerator, CommunityModeratorForm}, @@ -108,30 +107,25 @@ impl ActivityHandler for AddMod { let community = self.get_community(context, request_counter).await?; let new_mod = self .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; // If we had to refetch the community while parsing the activity, then the new mod has already // been added. Skip it here as it would result in a duplicate key error. let new_mod_id = new_mod.id; - let moderated_communities = blocking(context.pool(), move |conn| { - CommunityModerator::get_person_moderated_communities(conn, new_mod_id) - }) - .await??; + let moderated_communities = + CommunityModerator::get_person_moderated_communities(context.pool(), new_mod_id).await?; if !moderated_communities.contains(&community.id) { let form = CommunityModeratorForm { community_id: community.id, person_id: new_mod.id, }; - blocking(context.pool(), move |conn| { - CommunityModerator::join(conn, &form) - }) - .await??; + CommunityModerator::join(context.pool(), &form).await?; // write mod log let actor = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let form = ModAddCommunityForm { mod_person_id: actor.id, @@ -139,10 +133,7 @@ impl ActivityHandler for AddMod { community_id: community.id, removed: Some(false), }; - blocking(context.pool(), move |conn| { - ModAddCommunity::create(conn, &form) - }) - .await??; + ModAddCommunity::create(context.pool(), &form).await?; } // TODO: send websocket notification about added mod Ok(()) diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 85062571..4d96ca4c 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -46,6 +46,6 @@ async fn get_community_from_moderators_url( ) -> Result { let community_id = Url::parse(&moderators.to_string().replace("/moderators", ""))?; ObjectId::new(community_id) - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await } diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs index ede6a008..82c499e4 100644 --- a/crates/apub/src/activities/community/remove_mod.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -24,7 +24,6 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::{activity::RemoveType, public}; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ community::{CommunityModerator, CommunityModeratorForm}, @@ -108,22 +107,19 @@ impl ActivityHandler for RemoveMod { let community = self.get_community(context, request_counter).await?; let remove_mod = self .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let form = CommunityModeratorForm { community_id: community.id, person_id: remove_mod.id, }; - blocking(context.pool(), move |conn| { - CommunityModerator::leave(conn, &form) - }) - .await??; + CommunityModerator::leave(context.pool(), &form).await?; // write mod log let actor = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let form = ModAddCommunityForm { mod_person_id: actor.id, @@ -131,10 +127,7 @@ impl ActivityHandler for RemoveMod { community_id: community.id, removed: Some(true), }; - blocking(context.pool(), move |conn| { - ModAddCommunity::create(conn, &form) - }) - .await??; + ModAddCommunity::create(context.pool(), &form).await?; // TODO: send websocket notification about removed mod Ok(()) diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index c3b50abf..33322bf3 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -12,7 +12,7 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::activity::FlagType; -use lemmy_api_common::{comment::CommentReportResponse, post::PostReportResponse, utils::blocking}; +use lemmy_api_common::{comment::CommentReportResponse, post::PostReportResponse}; use lemmy_db_schema::{ source::{ comment_report::{CommentReport, CommentReportForm}, @@ -75,7 +75,7 @@ impl ActivityHandler for Report { request_counter: &mut i32, ) -> Result<(), LemmyError> { let community = self.to[0] - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; Ok(()) @@ -89,11 +89,11 @@ impl ActivityHandler for Report { ) -> Result<(), LemmyError> { let actor = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; match self .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await? { PostOrComment::Post(post) => { @@ -106,15 +106,9 @@ impl ActivityHandler for Report { original_post_body: post.body.clone(), }; - let report = blocking(context.pool(), move |conn| { - PostReport::report(conn, &report_form) - }) - .await??; + let report = PostReport::report(context.pool(), &report_form).await?; - let post_report_view = blocking(context.pool(), move |conn| { - PostReportView::read(conn, report.id, actor.id) - }) - .await??; + let post_report_view = PostReportView::read(context.pool(), report.id, actor.id).await?; context.chat_server().do_send(SendModRoomMessage { op: UserOperation::CreateCommentReport, @@ -131,15 +125,10 @@ impl ActivityHandler for Report { reason: self.summary, }; - let report = blocking(context.pool(), move |conn| { - CommentReport::report(conn, &report_form) - }) - .await??; + let report = CommentReport::report(context.pool(), &report_form).await?; - let comment_report_view = blocking(context.pool(), move |conn| { - CommentReportView::read(conn, report.id, actor.id) - }) - .await??; + let comment_report_view = + CommentReportView::read(context.pool(), report.id, actor.id).await?; let community_id = comment_report_view.community.id; context.chat_server().do_send(SendModRoomMessage { diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index def4d7a4..f19aafec 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -18,7 +18,6 @@ use activitypub_federation::{ traits::{ActivityHandler, ApubObject}, }; use activitystreams_kinds::{activity::UpdateType, public}; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{source::community::Community, traits::Crud}; use lemmy_utils::error::LemmyError; use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; @@ -100,10 +99,8 @@ impl ActivityHandler for UpdateCommunity { let community_update_form = self.object.into_update_form(); - let updated_community = blocking(context.pool(), move |conn| { - Community::update(conn, community.id, &community_update_form) - }) - .await??; + let updated_community = + Community::update(context.pool(), community.id, &community_update_form).await?; send_community_ws_message( updated_community.id, @@ -127,7 +124,7 @@ impl GetCommunity for UpdateCommunity { ) -> Result { let cid = ObjectId::new(self.object.id.clone()); cid - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await } } diff --git a/crates/apub/src/activities/create_or_update/comment.rs b/crates/apub/src/activities/create_or_update/comment.rs index dad6ada9..1c6ce511 100644 --- a/crates/apub/src/activities/create_or_update/comment.rs +++ b/crates/apub/src/activities/create_or_update/comment.rs @@ -21,7 +21,7 @@ use activitypub_federation::{ utils::verify_domains_match, }; use activitystreams_kinds::public; -use lemmy_api_common::utils::{blocking, check_post_deleted_or_removed}; +use lemmy_api_common::utils::check_post_deleted_or_removed; use lemmy_db_schema::{ source::{ comment::{CommentLike, CommentLikeForm}, @@ -45,13 +45,9 @@ impl CreateOrUpdateComment { ) -> Result<(), LemmyError> { // TODO: might be helpful to add a comment method to retrieve community directly let post_id = comment.post_id; - let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let post = Post::read(context.pool(), post_id).await?; let community_id = post.community_id; - let community: ApubCommunity = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await?? - .into(); + let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); let id = generate_activity_id( kind.clone(), @@ -86,7 +82,7 @@ impl CreateOrUpdateComment { let mut inboxes = vec![]; for t in tagged_users { let person = t - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; inboxes.push(person.shared_inbox_or_inbox()); } @@ -143,10 +139,7 @@ impl ActivityHandler for CreateOrUpdateComment { person_id: comment.creator_id, score: 1, }; - blocking(context.pool(), move |conn: &mut _| { - CommentLike::like(conn, &like_form) - }) - .await??; + CommentLike::like(context.pool(), &like_form).await?; let do_send_email = self.kind == CreateOrUpdateType::Create; let recipients = get_comment_notif_recipients( @@ -178,10 +171,7 @@ impl GetCommunity for CreateOrUpdateComment { request_counter: &mut i32, ) -> Result { let post = self.object.get_parents(context, request_counter).await?.0; - let community = blocking(context.pool(), move |conn| { - Community::read(conn, post.community_id) - }) - .await??; + let community = Community::read(context.pool(), post.community_id).await?; Ok(community.into()) } } diff --git a/crates/apub/src/activities/create_or_update/mod.rs b/crates/apub/src/activities/create_or_update/mod.rs index c0854089..a41912da 100644 --- a/crates/apub/src/activities/create_or_update/mod.rs +++ b/crates/apub/src/activities/create_or_update/mod.rs @@ -1,6 +1,5 @@ use crate::{local_instance, objects::person::ApubPerson}; use activitypub_federation::core::object_id::ObjectId; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ newtypes::LocalUserId, source::{comment::Comment, post::Post}, @@ -22,9 +21,9 @@ async fn get_comment_notif_recipients( request_counter: &mut i32, ) -> Result, LemmyError> { let post_id = comment.post_id; - let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let post = Post::read(context.pool(), post_id).await?; let actor = actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; // Note: diff --git a/crates/apub/src/activities/create_or_update/post.rs b/crates/apub/src/activities/create_or_update/post.rs index d9d7b854..09e9ae0d 100644 --- a/crates/apub/src/activities/create_or_update/post.rs +++ b/crates/apub/src/activities/create_or_update/post.rs @@ -19,7 +19,6 @@ use activitypub_federation::{ utils::{verify_domains_match, verify_urls_match}, }; use activitystreams_kinds::public; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ community::Community, @@ -62,11 +61,7 @@ impl CreateOrUpdatePost { context: &LemmyContext, ) -> Result<(), LemmyError> { let community_id = post.community_id; - let community: ApubCommunity = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await?? - .into(); + let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); let create_or_update = CreateOrUpdatePost::new(post, actor, &community, kind, context).await?; let activity = AnnouncableActivities::CreateOrUpdatePost(Box::new(create_or_update)); @@ -149,10 +144,7 @@ impl ActivityHandler for CreateOrUpdatePost { person_id: post.creator_id, score: 1, }; - blocking(context.pool(), move |conn: &mut _| { - PostLike::like(conn, &like_form) - }) - .await??; + PostLike::like(context.pool(), &like_form).await?; let notif_type = match self.kind { CreateOrUpdateType::Create => UserOperationCrud::CreatePost, diff --git a/crates/apub/src/activities/create_or_update/private_message.rs b/crates/apub/src/activities/create_or_update/private_message.rs index 9ad54769..523135db 100644 --- a/crates/apub/src/activities/create_or_update/private_message.rs +++ b/crates/apub/src/activities/create_or_update/private_message.rs @@ -13,7 +13,6 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor, ApubObject}, utils::verify_domains_match, }; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{source::person::Person, traits::Crud}; use lemmy_utils::error::LemmyError; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; @@ -28,10 +27,7 @@ impl CreateOrUpdatePrivateMessage { context: &LemmyContext, ) -> Result<(), LemmyError> { let recipient_id = private_message.recipient_id; - let recipient: ApubPerson = - blocking(context.pool(), move |conn| Person::read(conn, recipient_id)) - .await?? - .into(); + let recipient: ApubPerson = Person::read(context.pool(), recipient_id).await?.into(); let id = generate_activity_id( kind.clone(), diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs index ca93b89f..0124f233 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -11,7 +11,6 @@ use crate::{ use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler}; use activitystreams_kinds::activity::DeleteType; use anyhow::anyhow; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ comment::{Comment, CommentUpdateForm}, @@ -76,7 +75,7 @@ impl ActivityHandler for Delete { receive_remove_action( &self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?, self.object.id(), reason, @@ -145,18 +144,13 @@ pub(in crate::activities) async fn receive_remove_action( reason, expires: None, }; - blocking(context.pool(), move |conn| { - ModRemoveCommunity::create(conn, &form) - }) - .await??; - let deleted_community = blocking(context.pool(), move |conn| { - Community::update( - conn, - community.id, - &CommunityUpdateForm::builder().removed(Some(true)).build(), - ) - }) - .await??; + ModRemoveCommunity::create(context.pool(), &form).await?; + let deleted_community = Community::update( + context.pool(), + community.id, + &CommunityUpdateForm::builder().removed(Some(true)).build(), + ) + .await?; send_community_ws_message(deleted_community.id, RemoveCommunity, None, None, context).await?; } @@ -167,18 +161,13 @@ pub(in crate::activities) async fn receive_remove_action( removed: Some(true), reason, }; - blocking(context.pool(), move |conn| { - ModRemovePost::create(conn, &form) - }) - .await??; - let removed_post = blocking(context.pool(), move |conn| { - Post::update( - conn, - post.id, - &PostUpdateForm::builder().removed(Some(true)).build(), - ) - }) - .await??; + ModRemovePost::create(context.pool(), &form).await?; + let removed_post = Post::update( + context.pool(), + post.id, + &PostUpdateForm::builder().removed(Some(true)).build(), + ) + .await?; send_post_ws_message(removed_post.id, RemovePost, None, None, context).await?; } @@ -189,18 +178,13 @@ pub(in crate::activities) async fn receive_remove_action( removed: Some(true), reason, }; - blocking(context.pool(), move |conn| { - ModRemoveComment::create(conn, &form) - }) - .await??; - let removed_comment = blocking(context.pool(), move |conn| { - Comment::update( - conn, - comment.id, - &CommentUpdateForm::builder().removed(Some(true)).build(), - ) - }) - .await??; + ModRemoveComment::create(context.pool(), &form).await?; + let removed_comment = Comment::update( + context.pool(), + comment.id, + &CommentUpdateForm::builder().removed(Some(true)).build(), + ) + .await?; send_comment_ws_message_simple(removed_comment.id, RemoveComment, context).await?; } @@ -220,7 +204,7 @@ impl GetCommunity for Delete { let community_id = match DeletableObjects::read_from_db(self.object.id(), context).await? { DeletableObjects::Community(c) => c.id, DeletableObjects::Comment(c) => { - let post = blocking(context.pool(), move |conn| Post::read(conn, c.post_id)).await??; + let post = Post::read(context.pool(), c.post_id).await?; post.community_id } DeletableObjects::Post(p) => p.community_id, @@ -228,10 +212,7 @@ impl GetCommunity for Delete { return Err(anyhow!("Private message is not part of community").into()) } }; - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + let community = Community::read(context.pool(), community_id).await?; Ok(community.into()) } } diff --git a/crates/apub/src/activities/deletion/delete_user.rs b/crates/apub/src/activities/deletion/delete_user.rs index 9570d85d..08d9d395 100644 --- a/crates/apub/src/activities/deletion/delete_user.rs +++ b/crates/apub/src/activities/deletion/delete_user.rs @@ -49,7 +49,7 @@ impl ActivityHandler for DeleteUser { ) -> Result<(), LemmyError> { let actor = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; delete_user_account( actor.id, diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs index 0a131c40..73a7edb6 100644 --- a/crates/apub/src/activities/deletion/mod.rs +++ b/crates/apub/src/activities/deletion/mod.rs @@ -25,7 +25,6 @@ use activitypub_federation::{ utils::verify_domains_match, }; use activitystreams_kinds::public; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ comment::{Comment, CommentUpdateForm}, @@ -84,10 +83,7 @@ pub async fn send_apub_delete_private_message( context: &LemmyContext, ) -> Result<(), LemmyError> { let recipient_id = pm.recipient_id; - let recipient: ApubPerson = - blocking(context.pool(), move |conn| Person::read(conn, recipient_id)) - .await?? - .into(); + let recipient: ApubPerson = Person::read(context.pool(), recipient_id).await?.into(); let deletable = DeletableObjects::PrivateMessage(Box::new(pm.into())); let inbox = vec![recipient.shared_inbox_or_inbox()]; @@ -229,7 +225,7 @@ async fn receive_delete_action( DeletableObjects::Community(community) => { if community.local { let mod_: Person = actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await? .deref() .clone(); @@ -238,16 +234,14 @@ async fn receive_delete_action( send_apub_delete_in_community(mod_, c, object, None, true, context).await?; } - let community = blocking(context.pool(), move |conn| { - Community::update( - conn, - community.id, - &CommunityUpdateForm::builder() - .deleted(Some(deleted)) - .build(), - ) - }) - .await??; + let community = Community::update( + context.pool(), + community.id, + &CommunityUpdateForm::builder() + .deleted(Some(deleted)) + .build(), + ) + .await?; send_community_ws_message( community.id, UserOperationCrud::DeleteCommunity, @@ -259,14 +253,12 @@ async fn receive_delete_action( } DeletableObjects::Post(post) => { if deleted != post.deleted { - let deleted_post = blocking(context.pool(), move |conn| { - Post::update( - conn, - post.id, - &PostUpdateForm::builder().deleted(Some(deleted)).build(), - ) - }) - .await??; + let deleted_post = Post::update( + context.pool(), + post.id, + &PostUpdateForm::builder().deleted(Some(deleted)).build(), + ) + .await?; send_post_ws_message( deleted_post.id, UserOperationCrud::DeletePost, @@ -279,14 +271,12 @@ async fn receive_delete_action( } DeletableObjects::Comment(comment) => { if deleted != comment.deleted { - let deleted_comment = blocking(context.pool(), move |conn| { - Comment::update( - conn, - comment.id, - &CommentUpdateForm::builder().deleted(Some(deleted)).build(), - ) - }) - .await??; + let deleted_comment = Comment::update( + context.pool(), + comment.id, + &CommentUpdateForm::builder().deleted(Some(deleted)).build(), + ) + .await?; send_comment_ws_message_simple( deleted_comment.id, UserOperationCrud::DeleteComment, @@ -296,16 +286,14 @@ async fn receive_delete_action( } } DeletableObjects::PrivateMessage(pm) => { - let deleted_private_message = blocking(context.pool(), move |conn| { - PrivateMessage::update( - conn, - pm.id, - &PrivateMessageUpdateForm::builder() - .deleted(Some(deleted)) - .build(), - ) - }) - .await??; + let deleted_private_message = PrivateMessage::update( + context.pool(), + pm.id, + &PrivateMessageUpdateForm::builder() + .deleted(Some(deleted)) + .build(), + ) + .await?; send_pm_ws_message( deleted_private_message.id, diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs index 1576e944..29f75e6d 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -10,7 +10,6 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler}; use activitystreams_kinds::activity::UndoType; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ comment::{Comment, CommentUpdateForm}, @@ -75,7 +74,7 @@ impl ActivityHandler for UndoDelete { UndoDelete::receive_undo_remove_action( &self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?, self.object.object.id(), context, @@ -143,18 +142,13 @@ impl UndoDelete { reason: None, expires: None, }; - blocking(context.pool(), move |conn| { - ModRemoveCommunity::create(conn, &form) - }) - .await??; - let deleted_community = blocking(context.pool(), move |conn| { - Community::update( - conn, - community.id, - &CommunityUpdateForm::builder().removed(Some(false)).build(), - ) - }) - .await??; + ModRemoveCommunity::create(context.pool(), &form).await?; + let deleted_community = Community::update( + context.pool(), + community.id, + &CommunityUpdateForm::builder().removed(Some(false)).build(), + ) + .await?; send_community_ws_message(deleted_community.id, EditCommunity, None, None, context).await?; } DeletableObjects::Post(post) => { @@ -164,18 +158,13 @@ impl UndoDelete { removed: Some(false), reason: None, }; - blocking(context.pool(), move |conn| { - ModRemovePost::create(conn, &form) - }) - .await??; - let removed_post = blocking(context.pool(), move |conn| { - Post::update( - conn, - post.id, - &PostUpdateForm::builder().removed(Some(false)).build(), - ) - }) - .await??; + ModRemovePost::create(context.pool(), &form).await?; + let removed_post = Post::update( + context.pool(), + post.id, + &PostUpdateForm::builder().removed(Some(false)).build(), + ) + .await?; send_post_ws_message(removed_post.id, EditPost, None, None, context).await?; } DeletableObjects::Comment(comment) => { @@ -185,18 +174,13 @@ impl UndoDelete { removed: Some(false), reason: None, }; - blocking(context.pool(), move |conn| { - ModRemoveComment::create(conn, &form) - }) - .await??; - let removed_comment = blocking(context.pool(), move |conn| { - Comment::update( - conn, - comment.id, - &CommentUpdateForm::builder().removed(Some(false)).build(), - ) - }) - .await??; + ModRemoveComment::create(context.pool(), &form).await?; + let removed_comment = Comment::update( + context.pool(), + comment.id, + &CommentUpdateForm::builder().removed(Some(false)).build(), + ) + .await?; send_comment_ws_message_simple(removed_comment.id, EditComment, context).await?; } DeletableObjects::PrivateMessage(_) => unimplemented!(), diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index f964da08..55a37449 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -11,7 +11,7 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::activity::AcceptType; -use lemmy_api_common::{community::CommunityResponse, utils::blocking}; +use lemmy_api_common::community::CommunityResponse; use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable}; use lemmy_db_views::structs::LocalUserView; use lemmy_db_views_actor::structs::CommunityView; @@ -30,7 +30,7 @@ impl AcceptFollowCommunity { let person = follow .actor .clone() - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let accept = AcceptFollowCommunity { actor: ObjectId::new(community.actor_id()), @@ -80,35 +80,27 @@ impl ActivityHandler for AcceptFollowCommunity { ) -> Result<(), LemmyError> { let community = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let person = self .object .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; // This will throw an error if no follow was requested let community_id = community.id; let person_id = person.id; - blocking(context.pool(), move |conn| { - CommunityFollower::follow_accepted(conn, community_id, person_id) - }) - .await??; + CommunityFollower::follow_accepted(context.pool(), community_id, person_id).await?; // Send the Subscribed message over websocket // Re-read the community_view to get the new SubscribedType - let community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, community_id, Some(person_id)) - }) - .await??; + let community_view = CommunityView::read(context.pool(), community_id, Some(person_id)).await?; // Get the local_user_id - let local_recipient_id = blocking(context.pool(), move |conn| { - LocalUserView::read_person(conn, person_id) - }) - .await?? - .local_user - .id; + let local_recipient_id = LocalUserView::read_person(context.pool(), person_id) + .await? + .local_user + .id; let response = CommunityResponse { community_view }; diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index b0ae72c7..57390b7f 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -16,7 +16,6 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::activity::FollowType; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::community::{CommunityFollower, CommunityFollowerForm}, traits::Followable, @@ -54,10 +53,9 @@ impl FollowCommunity { person_id: actor.id, pending: true, }; - blocking(context.pool(), move |conn| { - CommunityFollower::follow(conn, &community_follower_form).ok() - }) - .await?; + CommunityFollower::follow(context.pool(), &community_follower_form) + .await + .ok(); let follow = FollowCommunity::new(actor, community, context)?; let inbox = vec![community.shared_inbox_or_inbox()]; @@ -87,7 +85,7 @@ impl ActivityHandler for FollowCommunity { verify_person(&self.actor, context, request_counter).await?; let community = self .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; Ok(()) @@ -101,11 +99,11 @@ impl ActivityHandler for FollowCommunity { ) -> Result<(), LemmyError> { let person = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let community = self .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let community_follower_form = CommunityFollowerForm { community_id: community.id, @@ -114,10 +112,9 @@ impl ActivityHandler for FollowCommunity { }; // This will fail if they're already a follower, but ignore the error. - blocking(context.pool(), move |conn| { - CommunityFollower::follow(conn, &community_follower_form).ok() - }) - .await?; + CommunityFollower::follow(context.pool(), &community_follower_form) + .await + .ok(); AcceptFollowCommunity::send(self, context, request_counter).await } diff --git a/crates/apub/src/activities/following/undo_follow.rs b/crates/apub/src/activities/following/undo_follow.rs index 94b0b68e..221d8184 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -12,7 +12,6 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::activity::UndoType; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::community::{CommunityFollower, CommunityFollowerForm}, traits::Followable, @@ -77,12 +76,12 @@ impl ActivityHandler for UndoFollowCommunity { ) -> Result<(), LemmyError> { let person = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let community = self .object .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let community_follower_form = CommunityFollowerForm { @@ -92,10 +91,9 @@ impl ActivityHandler for UndoFollowCommunity { }; // This will fail if they aren't a follower, but ignore the error. - blocking(context.pool(), move |conn| { - CommunityFollower::unfollow(conn, &community_follower_form).ok() - }) - .await?; + CommunityFollower::unfollow(context.pool(), &community_follower_form) + .await + .ok(); Ok(()) } } diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 0c013fbe..3cf9771e 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -13,7 +13,6 @@ use activitypub_federation::{ }; use activitystreams_kinds::public; use anyhow::anyhow; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ newtypes::CommunityId, source::{community::Community, local_site::LocalSite}, @@ -43,7 +42,7 @@ async fn verify_person( request_counter: &mut i32, ) -> Result<(), LemmyError> { let person = person_id - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; if person.banned { let err = anyhow!("Person {} is banned", person_id); @@ -62,16 +61,17 @@ pub(crate) async fn verify_person_in_community( request_counter: &mut i32, ) -> Result<(), LemmyError> { let person = person_id - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; if person.banned { return Err(LemmyError::from_message("Person is banned from site")); } let person_id = person.id; let community_id = community.id; - let is_banned = - move |conn: &mut _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok(); - if blocking(context.pool(), is_banned).await? { + let is_banned = CommunityPersonBanView::get(context.pool(), person_id, community_id) + .await + .is_ok(); + if is_banned { return Err(LemmyError::from_message("Person is banned from community")); } @@ -92,13 +92,11 @@ pub(crate) async fn verify_mod_action( request_counter: &mut i32, ) -> Result<(), LemmyError> { let mod_ = mod_id - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; - let is_mod_or_admin = blocking(context.pool(), move |conn| { - CommunityView::is_mod_or_admin(conn, mod_.id, community_id) - }) - .await?; + let is_mod_or_admin = + CommunityView::is_mod_or_admin(context.pool(), mod_.id, community_id).await?; if is_mod_or_admin { return Ok(()); } @@ -170,8 +168,8 @@ where ActorT: Actor + ActorType, Activity: ActivityHandler, { - let federation_enabled = blocking(context.pool(), &LocalSite::read) - .await? + let federation_enabled = LocalSite::read(context.pool()) + .await .map(|l| l.federation_enabled) .unwrap_or(false); if !federation_enabled { @@ -189,7 +187,7 @@ where actor.get_public_key(), actor.private_key().expect("actor has private key"), inbox, - local_instance(context), + local_instance(context).await, ) .await?; diff --git a/crates/apub/src/activities/voting/mod.rs b/crates/apub/src/activities/voting/mod.rs index 6744e1c5..bff67efe 100644 --- a/crates/apub/src/activities/voting/mod.rs +++ b/crates/apub/src/activities/voting/mod.rs @@ -2,7 +2,6 @@ use crate::{ objects::{comment::ApubComment, person::ApubPerson, post::ApubPost}, protocol::activities::voting::vote::VoteType, }; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ comment::{CommentLike, CommentLikeForm}, @@ -35,11 +34,8 @@ async fn vote_comment( score: vote_type.into(), }; let person_id = actor.id; - blocking(context.pool(), move |conn| { - CommentLike::remove(conn, person_id, comment_id)?; - CommentLike::like(conn, &like_form) - }) - .await??; + CommentLike::remove(context.pool(), person_id, comment_id).await?; + CommentLike::like(context.pool(), &like_form).await?; send_comment_ws_message_simple(comment_id, UserOperation::CreateCommentLike, context).await?; Ok(()) @@ -59,11 +55,8 @@ async fn vote_post( score: vote_type.into(), }; let person_id = actor.id; - blocking(context.pool(), move |conn| { - PostLike::remove(conn, person_id, post_id)?; - PostLike::like(conn, &like_form) - }) - .await??; + PostLike::remove(context.pool(), person_id, post_id).await?; + PostLike::like(context.pool(), &like_form).await?; send_post_ws_message(post.id, UserOperation::CreatePostLike, None, None, context).await?; Ok(()) @@ -77,10 +70,7 @@ async fn undo_vote_comment( ) -> Result<(), LemmyError> { let comment_id = comment.id; let person_id = actor.id; - blocking(context.pool(), move |conn| { - CommentLike::remove(conn, person_id, comment_id) - }) - .await??; + CommentLike::remove(context.pool(), person_id, comment_id).await?; send_comment_ws_message_simple(comment_id, UserOperation::CreateCommentLike, context).await?; Ok(()) @@ -94,10 +84,7 @@ async fn undo_vote_post( ) -> Result<(), LemmyError> { let post_id = post.id; let person_id = actor.id; - blocking(context.pool(), move |conn| { - PostLike::remove(conn, person_id, post_id) - }) - .await??; + PostLike::remove(context.pool(), person_id, post_id).await?; send_post_ws_message(post_id, UserOperation::CreatePostLike, None, None, context).await?; Ok(()) diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index f6fc36a2..9415e547 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -22,7 +22,6 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::activity::UndoType; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud}; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -40,11 +39,7 @@ impl UndoVote { kind: VoteType, context: &LemmyContext, ) -> Result<(), LemmyError> { - let community: ApubCommunity = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await?? - .into(); + let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); let object = Vote::new(object, actor, kind.clone(), context)?; let id = generate_activity_id( @@ -97,12 +92,12 @@ impl ActivityHandler for UndoVote { ) -> Result<(), LemmyError> { let actor = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let object = self .object .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; match object { PostOrComment::Post(p) => undo_vote_post(actor, &p, context).await, diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index e33c9567..8a022f7d 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -14,7 +14,6 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler}; use anyhow::anyhow; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ newtypes::CommunityId, source::{community::Community, local_site::LocalSite, post::Post}, @@ -50,11 +49,7 @@ impl Vote { kind: VoteType, context: &LemmyContext, ) -> Result<(), LemmyError> { - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await?? - .into(); + let community = Community::read(context.pool(), community_id).await?.into(); let vote = Vote::new(object, actor, kind, context)?; let activity = AnnouncableActivities::Vote(vote); @@ -83,8 +78,8 @@ impl ActivityHandler for Vote { ) -> Result<(), LemmyError> { let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; - let enable_downvotes = blocking(context.pool(), LocalSite::read) - .await? + let enable_downvotes = LocalSite::read(context.pool()) + .await .map(|l| l.enable_downvotes) .unwrap_or(true); if self.kind == VoteType::Dislike && !enable_downvotes { @@ -101,11 +96,11 @@ impl ActivityHandler for Vote { ) -> Result<(), LemmyError> { let actor = self .actor - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let object = self .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; match object { PostOrComment::Post(p) => vote_post(&self.kind, actor, &p, context).await, @@ -124,17 +119,13 @@ impl GetCommunity for Vote { ) -> Result { let object = self .object - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let cid = match object { PostOrComment::Post(p) => p.community_id, - PostOrComment::Comment(c) => { - blocking(context.pool(), move |conn| Post::read(conn, c.post_id)) - .await?? - .community_id - } + PostOrComment::Comment(c) => Post::read(context.pool(), c.post_id).await?.community_id, }; - let community = blocking(context.pool(), move |conn| Community::read(conn, cid)).await??; + let community = Community::read(context.pool(), cid).await?; Ok(community.into()) } } diff --git a/crates/apub/src/collections/community_moderators.rs b/crates/apub/src/collections/community_moderators.rs index 3f88010d..3770882f 100644 --- a/crates/apub/src/collections/community_moderators.rs +++ b/crates/apub/src/collections/community_moderators.rs @@ -12,7 +12,6 @@ use activitypub_federation::{ }; use activitystreams_kinds::collection::OrderedCollectionType; use chrono::NaiveDateTime; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::community::{CommunityModerator, CommunityModeratorForm}, traits::Joinable, @@ -42,10 +41,7 @@ impl ApubObject for ApubCommunityModerators { // Only read from database if its a local community, otherwise fetch over http if data.0.local { let cid = data.0.id; - let moderators = blocking(data.1.pool(), move |conn| { - CommunityModeratorView::for_community(conn, cid) - }) - .await??; + let moderators = CommunityModeratorView::for_community(data.1.pool(), cid).await?; Ok(Some(ApubCommunityModerators(moderators))) } else { Ok(None) @@ -89,10 +85,8 @@ impl ApubObject for ApubCommunityModerators { request_counter: &mut i32, ) -> Result { let community_id = data.0.id; - let current_moderators = blocking(data.1.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await??; + let current_moderators = + CommunityModeratorView::for_community(data.1.pool(), community_id).await?; // Remove old mods from database which arent in the moderators collection anymore for mod_user in ¤t_moderators { let mod_id = ObjectId::new(mod_user.moderator.actor_id.clone()); @@ -101,10 +95,7 @@ impl ApubObject for ApubCommunityModerators { community_id: mod_user.community.id, person_id: mod_user.moderator.id, }; - blocking(data.1.pool(), move |conn| { - CommunityModerator::leave(conn, &community_moderator_form) - }) - .await??; + CommunityModerator::leave(data.1.pool(), &community_moderator_form).await?; } } @@ -112,7 +103,7 @@ impl ApubObject for ApubCommunityModerators { for mod_id in apub.ordered_items { let mod_id = ObjectId::new(mod_id); let mod_user: ApubPerson = mod_id - .dereference(&data.1, local_instance(&data.1), request_counter) + .dereference(&data.1, local_instance(&data.1).await, request_counter) .await?; if !current_moderators @@ -124,10 +115,7 @@ impl ApubObject for ApubCommunityModerators { community_id: data.0.id, person_id: mod_user.id, }; - blocking(data.1.pool(), move |conn| { - CommunityModerator::join(conn, &community_moderator_form) - }) - .await??; + CommunityModerator::join(data.1.pool(), &community_moderator_form).await?; } } @@ -163,13 +151,14 @@ mod tests { #[actix_rt::test] #[serial] async fn test_parse_lemmy_community_moderators() { - let context = init_context(); - let conn = &mut context.pool().get().unwrap(); + let context = init_context().await; let (new_mod, site) = parse_lemmy_person(&context).await; let community = parse_lemmy_community(&context).await; let community_id = community.id; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(context.pool(), "my_domain.tld") + .await + .unwrap(); let old_mod = PersonInsertForm::builder() .name("holly".into()) @@ -177,13 +166,15 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let old_mod = Person::create(conn, &old_mod).unwrap(); + let old_mod = Person::create(context.pool(), &old_mod).await.unwrap(); let community_moderator_form = CommunityModeratorForm { community_id: community.id, person_id: old_mod.id, }; - CommunityModerator::join(conn, &community_moderator_form).unwrap(); + CommunityModerator::join(context.pool(), &community_moderator_form) + .await + .unwrap(); assert_eq!(site.actor_id.to_string(), "https://enterprise.lemmy.ml/"); @@ -191,7 +182,7 @@ mod tests { file_to_json_object("assets/lemmy/collections/group_moderators.json").unwrap(); let url = Url::parse("https://enterprise.lemmy.ml/c/tenforward").unwrap(); let mut request_counter = 0; - let community_context = CommunityContext(community, context); + let community_context = CommunityContext(community, context.to_owned()); ApubCommunityModerators::verify(&json, &url, &community_context, &mut request_counter) .await .unwrap(); @@ -200,20 +191,21 @@ mod tests { .unwrap(); assert_eq!(request_counter, 0); - let current_moderators = blocking(community_context.1.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await - .unwrap() - .unwrap(); + let current_moderators = CommunityModeratorView::for_community(context.pool(), community_id) + .await + .unwrap(); assert_eq!(current_moderators.len(), 1); assert_eq!(current_moderators[0].moderator.id, new_mod.id); - Person::delete(conn, old_mod.id).unwrap(); - Person::delete(conn, new_mod.id).unwrap(); - Community::delete(conn, community_context.0.id).unwrap(); - Site::delete(conn, site.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + Person::delete(context.pool(), old_mod.id).await.unwrap(); + Person::delete(context.pool(), new_mod.id).await.unwrap(); + Community::delete(context.pool(), community_context.0.id) + .await + .unwrap(); + Site::delete(context.pool(), site.id).await.unwrap(); + Instance::delete(context.pool(), inserted_instance.id) + .await + .unwrap(); } } diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs index dde98859..d9fbf4f2 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -16,7 +16,6 @@ use activitypub_federation::{ use activitystreams_kinds::collection::OrderedCollectionType; use chrono::NaiveDateTime; use futures::future::join_all; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::source::post::Post; use lemmy_utils::error::LemmyError; use url::Url; @@ -42,13 +41,11 @@ impl ApubObject for ApubCommunityOutbox { // Only read from database if its a local community, otherwise fetch over http if data.0.local { let community_id = data.0.id; - let post_list: Vec = blocking(data.1.pool(), move |conn| { - Post::list_for_community(conn, community_id) - }) - .await?? - .into_iter() - .map(Into::into) - .collect(); + let post_list: Vec = Post::list_for_community(data.1.pool(), community_id) + .await? + .into_iter() + .map(Into::into) + .collect(); Ok(Some(ApubCommunityOutbox(post_list))) } else { Ok(None) diff --git a/crates/apub/src/fetcher/deletable_apub_object.rs b/crates/apub/src/fetcher/deletable_apub_object.rs index 2eb4f884..c84ebabb 100644 --- a/crates/apub/src/fetcher/deletable_apub_object.rs +++ b/crates/apub/src/fetcher/deletable_apub_object.rs @@ -1,5 +1,4 @@ use crate::fetcher::post_or_comment::PostOrComment; -use lemmy_api_common::utils::blocking; use lemmy_db_queries::source::{ comment::Comment_, community::Community_, @@ -27,10 +26,8 @@ pub trait DeletableApubObject { impl DeletableApubObject for Community { async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { let id = self.id; - blocking(context.pool(), move |conn| { - Community::update_deleted(conn, id, true) - }) - .await??; + Community::update_deleted(context.pool(), id, true) + .await?; Ok(()) } } @@ -39,7 +36,7 @@ impl DeletableApubObject for Community { impl DeletableApubObject for Person { async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { let id = self.id; - blocking(context.pool(), move |conn| Person::delete_account(conn, id)).await??; + Person::delete_account(context.pool(), id).await?; Ok(()) } } @@ -48,10 +45,8 @@ impl DeletableApubObject for Person { impl DeletableApubObject for Post { async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { let id = self.id; - blocking(context.pool(), move |conn| { - Post::update_deleted(conn, id, true) - }) - .await??; + Post::update_deleted(context.pool(), id, true) + .await?; Ok(()) } } @@ -60,10 +55,8 @@ impl DeletableApubObject for Post { impl DeletableApubObject for Comment { async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { let id = self.id; - blocking(context.pool(), move |conn| { - Comment::update_deleted(conn, id, true) - }) - .await??; + Comment::update_deleted(context.pool(), id, true) + .await?; Ok(()) } } @@ -73,16 +66,12 @@ impl DeletableApubObject for PostOrComment { async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { match self { PostOrComment::Comment(c) => { - blocking(context.pool(), move |conn| { - Comment::update_deleted(conn, c.id, true) - }) - .await??; + Comment::update_deleted(context.pool(), c.id, true) + .await?; } PostOrComment::Post(p) => { - blocking(context.pool(), move |conn| { - Post::update_deleted(conn, p.id, true) - }) - .await??; + Post::update_deleted(context.pool(), p.id, true) + .await?; } } diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index edb8a759..d98bb8e4 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -1,7 +1,6 @@ use crate::{fetcher::webfinger::webfinger_resolve_actor, ActorType}; use activitypub_federation::traits::ApubObject; use itertools::Itertools; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::traits::ApubActor; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -37,31 +36,21 @@ where .expect("invalid query"); let name = name.to_string(); let domain = format!("{}://{}", context.settings().get_protocol_string(), domain); - let actor = blocking(context.pool(), move |conn| { - DbActor::read_from_name_and_domain(conn, &name, &domain) - }) - .await?; + let actor = DbActor::read_from_name_and_domain(context.pool(), &name, &domain).await; if actor.is_ok() { Ok(actor?) } else { // Fetch the actor from its home instance using webfinger let id = webfinger_resolve_actor::(identifier, true, context, &mut 0).await?; - let actor: DbActor = blocking(context.pool(), move |conn| { - DbActor::read_from_apub_id(conn, &id) - }) - .await?? - .expect("actor exists as we fetched just before"); + let actor: DbActor = DbActor::read_from_apub_id(context.pool(), &id) + .await? + .expect("actor exists as we fetched just before"); Ok(actor) } } // local actor else { let identifier = identifier.to_string(); - Ok( - blocking(context.pool(), move |conn| { - DbActor::read_from_name(conn, &identifier, include_deleted) - }) - .await??, - ) + Ok(DbActor::read_from_name(context.pool(), &identifier, include_deleted).await?) } } diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs index 3f7eeeab..1daccd3a 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -47,7 +47,7 @@ pub async fn search_query_to_object_id( object_id.dereference_local(context).await } else { object_id - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await } } diff --git a/crates/apub/src/fetcher/webfinger.rs b/crates/apub/src/fetcher/webfinger.rs index 0dfdfc22..30ac0e0a 100644 --- a/crates/apub/src/fetcher/webfinger.rs +++ b/crates/apub/src/fetcher/webfinger.rs @@ -2,7 +2,6 @@ use crate::{local_instance, ActorType}; use activitypub_federation::{core::object_id::ObjectId, traits::ApubObject}; use anyhow::anyhow; use itertools::Itertools; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{newtypes::DbUrl, source::local_site::LocalSite}; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -48,7 +47,7 @@ where ); debug!("Fetching webfinger url: {}", &fetch_url); - let local_site = blocking(context.pool(), LocalSite::read).await?; + let local_site = LocalSite::read(context.pool()).await; let http_fetch_retry_limit = local_site .as_ref() .map(|l| l.federation_http_fetch_retry_limit) @@ -81,7 +80,7 @@ where object_id.dereference_local(context).await } else { object_id - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await }; if object.is_ok() { diff --git a/crates/apub/src/http/comment.rs b/crates/apub/src/http/comment.rs index 4a498a16..e2d0fb77 100644 --- a/crates/apub/src/http/comment.rs +++ b/crates/apub/src/http/comment.rs @@ -5,7 +5,6 @@ use crate::{ use activitypub_federation::traits::ApubObject; use actix_web::{web, web::Path, HttpResponse}; use diesel::result::Error::NotFound; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{newtypes::CommentId, source::comment::Comment, traits::Crud}; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -23,9 +22,7 @@ pub(crate) async fn get_apub_comment( context: web::Data, ) -> Result { let id = CommentId(info.comment_id.parse::()?); - let comment: ApubComment = blocking(context.pool(), move |conn| Comment::read(conn, id)) - .await?? - .into(); + let comment: ApubComment = Comment::read(context.pool(), id).await?.into(); if !comment.local { return Err(NotFound.into()); } diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index d4528236..87a0f1b4 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -17,7 +17,6 @@ use activitypub_federation::{ traits::ApubObject, }; use actix_web::{web, HttpRequest, HttpResponse}; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{source::community::Community, traits::ApubActor}; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -34,11 +33,10 @@ pub(crate) async fn get_apub_community_http( info: web::Path, context: web::Data, ) -> Result { - let community: ApubCommunity = blocking(context.pool(), move |conn| { - Community::read_from_name(conn, &info.community_name, true) - }) - .await?? - .into(); + let community: ApubCommunity = + Community::read_from_name(context.pool(), &info.community_name, true) + .await? + .into(); if !community.deleted && !community.removed { let apub = community.into_apub(&**context).await?; @@ -65,10 +63,7 @@ pub(crate) async fn get_apub_community_followers( info: web::Path, context: web::Data, ) -> Result { - let community = blocking(context.pool(), move |conn| { - Community::read_from_name(conn, &info.community_name, false) - }) - .await??; + let community = Community::read_from_name(context.pool(), &info.community_name, false).await?; let followers = GroupFollowers::new(community, &context).await?; Ok(create_apub_response(&followers)) } @@ -79,18 +74,14 @@ pub(crate) async fn get_apub_community_outbox( info: web::Path, context: web::Data, ) -> Result { - let community = blocking(context.pool(), move |conn| { - Community::read_from_name(conn, &info.community_name, false) - }) - .await??; + let community = Community::read_from_name(context.pool(), &info.community_name, false).await?; if community.deleted || community.removed { return Err(LemmyError::from_message("deleted")); } - let id = ObjectId::new(generate_outbox_url(&community.actor_id)?); let outbox_data = CommunityContext(community.into(), context.get_ref().clone()); let outbox: ApubCommunityOutbox = id - .dereference(&outbox_data, local_instance(&context), &mut 0) + .dereference(&outbox_data, local_instance(&context).await, &mut 0) .await?; Ok(create_apub_response(&outbox.into_apub(&outbox_data).await?)) } @@ -100,19 +91,17 @@ pub(crate) async fn get_apub_community_moderators( info: web::Path, context: web::Data, ) -> Result { - let community: ApubCommunity = blocking(context.pool(), move |conn| { - Community::read_from_name(conn, &info.community_name, false) - }) - .await?? - .into(); + let community: ApubCommunity = + Community::read_from_name(context.pool(), &info.community_name, false) + .await? + .into(); if community.deleted || community.removed { return Err(LemmyError::from_message("deleted")); } - let id = ObjectId::new(generate_outbox_url(&community.actor_id)?); let outbox_data = CommunityContext(community, context.get_ref().clone()); let moderators: ApubCommunityModerators = id - .dereference(&outbox_data, local_instance(&context), &mut 0) + .dereference(&outbox_data, local_instance(&context).await, &mut 0) .await?; Ok(create_apub_response( &moderators.into_apub(&outbox_data).await?, diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index e2fb0b42..05837f93 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -15,7 +15,6 @@ use activitypub_federation::{ }; use actix_web::{web, HttpRequest, HttpResponse}; use http::StatusCode; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::source::activity::Activity; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -71,7 +70,7 @@ where receive_activity::( request, activity, - local_instance(&context), + local_instance(&context).await, data, ) .await @@ -122,10 +121,7 @@ pub(crate) async fn get_activity( info.id ))? .into(); - let activity = blocking(context.pool(), move |conn| { - Activity::read_from_apub_id(conn, &activity_id) - }) - .await??; + let activity = Activity::read_from_apub_id(context.pool(), &activity_id).await?; let sensitive = activity.sensitive.unwrap_or(true); if !activity.local || sensitive { diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index 16c937b3..bf82a47c 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -8,7 +8,6 @@ use crate::{ }; use activitypub_federation::{deser::context::WithContext, traits::ApubObject}; use actix_web::{web, HttpRequest, HttpResponse}; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{source::person::Person, traits::ApubActor}; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -27,11 +26,9 @@ pub(crate) async fn get_apub_person_http( ) -> Result { let user_name = info.into_inner().user_name; // TODO: this needs to be able to read deleted persons, so that it can send tombstones - let person: ApubPerson = blocking(context.pool(), move |conn| { - Person::read_from_name(conn, &user_name, true) - }) - .await?? - .into(); + let person: ApubPerson = Person::read_from_name(context.pool(), &user_name, true) + .await? + .into(); if !person.deleted { let apub = person.into_apub(&context).await?; @@ -59,10 +56,7 @@ pub(crate) async fn get_apub_person_outbox( info: web::Path, context: web::Data, ) -> Result { - let person = blocking(context.pool(), move |conn| { - Person::read_from_name(conn, &info.user_name, false) - }) - .await??; + let person = Person::read_from_name(context.pool(), &info.user_name, false).await?; let outbox_id = generate_outbox_url(&person.actor_id)?.into(); let outbox = EmptyOutbox::new(outbox_id).await?; Ok(create_apub_response(&outbox)) diff --git a/crates/apub/src/http/post.rs b/crates/apub/src/http/post.rs index 5960db44..5da69fb4 100644 --- a/crates/apub/src/http/post.rs +++ b/crates/apub/src/http/post.rs @@ -5,7 +5,6 @@ use crate::{ use activitypub_federation::traits::ApubObject; use actix_web::{web, HttpResponse}; use diesel::result::Error::NotFound; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{newtypes::PostId, source::post::Post, traits::Crud}; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -23,9 +22,7 @@ pub(crate) async fn get_apub_post( context: web::Data, ) -> Result { let id = PostId(info.post_id.parse::()?); - let post: ApubPost = blocking(context.pool(), move |conn| Post::read(conn, id)) - .await?? - .into(); + let post: ApubPost = Post::read(context.pool(), id).await?.into(); if !post.local { return Err(NotFound.into()); } diff --git a/crates/apub/src/http/site.rs b/crates/apub/src/http/site.rs index 503bc5a9..28eef88a 100644 --- a/crates/apub/src/http/site.rs +++ b/crates/apub/src/http/site.rs @@ -6,7 +6,6 @@ use crate::{ }; use activitypub_federation::{deser::context::WithContext, traits::ApubObject}; use actix_web::{web, HttpRequest, HttpResponse}; -use lemmy_api_common::utils::blocking; use lemmy_db_views::structs::SiteView; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -15,10 +14,7 @@ use url::Url; pub(crate) async fn get_apub_site_http( context: web::Data, ) -> Result { - let site: ApubSite = blocking(context.pool(), SiteView::read_local) - .await?? - .site - .into(); + let site: ApubSite = SiteView::read_local(context.pool()).await?.site.into(); let apub = site.into_apub(&context).await?; Ok(create_apub_response(&apub)) diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 8c7c042c..d8394a6e 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -8,8 +8,6 @@ use activitypub_federation::{ }; use anyhow::Context; use async_trait::async_trait; -use diesel::PgConnection; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ newtypes::DbUrl, source::{activity::Activity, instance::Instance, local_site::LocalSite}, @@ -17,7 +15,8 @@ use lemmy_db_schema::{ }; use lemmy_utils::{error::LemmyError, location_info, settings::structs::Settings}; use lemmy_websocket::LemmyContext; -use once_cell::sync::{Lazy, OnceCell}; +use once_cell::sync::Lazy; +use tokio::sync::OnceCell; use url::{ParseError, Url}; pub mod activities; @@ -35,42 +34,40 @@ static CONTEXT: Lazy> = Lazy::new(|| { // TODO: store this in context? but its only used in this crate, no need to expose it elsewhere // TODO this singleton needs to be redone to account for live data. -fn local_instance(context: &LemmyContext) -> &'static LocalInstance { - static LOCAL_INSTANCE: OnceCell = OnceCell::new(); - LOCAL_INSTANCE.get_or_init(|| { - let conn = &mut context - .pool() - .get() - .expect("getting connection for LOCAL_INSTANCE init"); - // Local site may be missing - let local_site = &LocalSite::read(conn); - let worker_count = local_site - .as_ref() - .map(|l| l.federation_worker_count) - .unwrap_or(64) as u64; - let http_fetch_retry_limit = local_site - .as_ref() - .map(|l| l.federation_http_fetch_retry_limit) - .unwrap_or(25); - let federation_debug = local_site - .as_ref() - .map(|l| l.federation_debug) - .unwrap_or(true); - - let settings = InstanceSettings::builder() - .http_fetch_retry_limit(http_fetch_retry_limit) - .worker_count(worker_count) - .debug(federation_debug) - .http_signature_compat(true) - .url_verifier(Box::new(VerifyUrlData(context.clone()))) - .build() - .expect("configure federation"); - LocalInstance::new( - context.settings().hostname.to_owned(), - context.client().clone(), - settings, - ) - }) +async fn local_instance(context: &LemmyContext) -> &'static LocalInstance { + static LOCAL_INSTANCE: OnceCell = OnceCell::const_new(); + LOCAL_INSTANCE + .get_or_init(|| async { + // Local site may be missing + let local_site = &LocalSite::read(context.pool()).await; + let worker_count = local_site + .as_ref() + .map(|l| l.federation_worker_count) + .unwrap_or(64) as u64; + let http_fetch_retry_limit = local_site + .as_ref() + .map(|l| l.federation_http_fetch_retry_limit) + .unwrap_or(25); + let federation_debug = local_site + .as_ref() + .map(|l| l.federation_debug) + .unwrap_or(true); + + let settings = InstanceSettings::builder() + .http_fetch_retry_limit(http_fetch_retry_limit) + .worker_count(worker_count) + .debug(federation_debug) + .http_signature_compat(true) + .url_verifier(Box::new(VerifyUrlData(context.clone()))) + .build() + .expect("configure federation"); + LocalInstance::new( + context.settings().hostname.to_owned(), + context.client().clone(), + settings, + ) + }) + .await } #[derive(Clone)] @@ -79,9 +76,8 @@ struct VerifyUrlData(LemmyContext); #[async_trait] impl UrlVerifier for VerifyUrlData { async fn verify(&self, url: &Url) -> Result<(), &'static str> { - let local_site_data = blocking(self.0.pool(), fetch_local_site_data) + let local_site_data = fetch_local_site_data(self.0.pool()) .await - .expect("read local site data") .expect("read local site data"); check_apub_id_valid(url, &local_site_data, self.0.settings()) } @@ -146,13 +142,13 @@ pub(crate) struct LocalSiteData { blocked_instances: Option>, } -pub(crate) fn fetch_local_site_data( - conn: &mut PgConnection, +pub(crate) async fn fetch_local_site_data( + pool: &DbPool, ) -> Result { // LocalSite may be missing - let local_site = LocalSite::read(conn).ok(); - let allowed = Instance::allowlist(conn)?; - let blocked = Instance::blocklist(conn)?; + let local_site = LocalSite::read(pool).await.ok(); + let allowed = Instance::allowlist(pool).await?; + let blocked = Instance::blocklist(pool).await?; // These can return empty vectors, so convert them to options let allowed_instances = (!allowed.is_empty()).then(|| allowed); @@ -277,12 +273,7 @@ async fn insert_activity( pool: &DbPool, ) -> Result { let ap_id = ap_id.to_owned().into(); - Ok( - blocking(pool, move |conn| { - Activity::insert(conn, ap_id, activity, local, Some(sensitive)) - }) - .await??, - ) + Ok(Activity::insert(pool, ap_id, activity, local, Some(sensitive)).await?) } /// Common methods provided by ActivityPub actors (community and person). Not all methods are diff --git a/crates/apub/src/mentions.rs b/crates/apub/src/mentions.rs index aa10658b..8e24270d 100644 --- a/crates/apub/src/mentions.rs +++ b/crates/apub/src/mentions.rs @@ -5,7 +5,6 @@ use crate::{ }; use activitypub_federation::core::object_id::ObjectId; use activitystreams_kinds::link::MentionType; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{comment::Comment, person::Person, post::Post}, traits::Crud, @@ -104,17 +103,12 @@ async fn get_comment_parent_creator( comment: &Comment, ) -> Result { let parent_creator_id = if let Some(parent_comment_id) = comment.parent_comment_id() { - let parent_comment = - blocking(pool, move |conn| Comment::read(conn, parent_comment_id)).await??; + let parent_comment = Comment::read(pool, parent_comment_id).await?; parent_comment.creator_id } else { let parent_post_id = comment.post_id; - let parent_post = blocking(pool, move |conn| Post::read(conn, parent_post_id)).await??; + let parent_post = Post::read(pool, parent_post_id).await?; parent_post.creator_id }; - Ok( - blocking(pool, move |conn| Person::read(conn, parent_creator_id)) - .await?? - .into(), - ) + Ok(Person::read(pool, parent_creator_id).await?.into()) } diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index cca092db..ba3e518b 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -19,7 +19,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::{object::NoteType, public}; use chrono::NaiveDateTime; -use lemmy_api_common::utils::{blocking, local_site_opt_to_slur_regex}; +use lemmy_api_common::utils::local_site_opt_to_slur_regex; use lemmy_db_schema::{ source::{ comment::{Comment, CommentInsertForm, CommentUpdateForm}, @@ -71,22 +71,17 @@ impl ApubObject for ApubComment { context: &LemmyContext, ) -> Result, LemmyError> { Ok( - blocking(context.pool(), move |conn| { - Comment::read_from_apub_id(conn, object_id) - }) - .await?? - .map(Into::into), + Comment::read_from_apub_id(context.pool(), object_id) + .await? + .map(Into::into), ) } #[tracing::instrument(skip_all)] async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { if !self.deleted { - blocking(context.pool(), move |conn| { - let form = CommentUpdateForm::builder().deleted(Some(true)).build(); - Comment::update(conn, self.id, &form) - }) - .await??; + let form = CommentUpdateForm::builder().deleted(Some(true)).build(); + Comment::update(context.pool(), self.id, &form).await?; } Ok(()) } @@ -94,19 +89,15 @@ impl ApubObject for ApubComment { #[tracing::instrument(skip_all)] async fn into_apub(self, context: &LemmyContext) -> Result { let creator_id = self.creator_id; - let creator = blocking(context.pool(), move |conn| Person::read(conn, creator_id)).await??; + let creator = Person::read(context.pool(), creator_id).await?; let post_id = self.post_id; - let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let post = Post::read(context.pool(), post_id).await?; let community_id = post.community_id; - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + let community = Community::read(context.pool(), community_id).await?; let in_reply_to = if let Some(comment_id) = self.parent_comment_id() { - let parent_comment = - blocking(context.pool(), move |conn| Comment::read(conn, comment_id)).await??; + let parent_comment = Comment::read(context.pool(), comment_id).await?; ObjectId::::new(parent_comment.ap_id) } else { ObjectId::::new(post.ap_id) @@ -147,11 +138,8 @@ impl ApubObject for ApubComment { verify_is_public(¬e.to, ¬e.cc)?; let (post, _) = note.get_parents(context, request_counter).await?; let community_id = post.community_id; - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; - let local_site_data = blocking(context.pool(), fetch_local_site_data).await??; + let community = Community::read(context.pool(), community_id).await?; + let local_site_data = fetch_local_site_data(context.pool()).await?; check_apub_id_valid_with_strictness( note.id.inner(), @@ -184,13 +172,13 @@ impl ApubObject for ApubComment { ) -> Result { let creator = note .attributed_to - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let (post, parent_comment) = note.get_parents(context, request_counter).await?; let content = read_from_string_or_source(¬e.content, ¬e.media_type, ¬e.source); - let local_site = blocking(context.pool(), LocalSite::read).await?.ok(); + let local_site = LocalSite::read(context.pool()).await.ok(); let slur_regex = &local_site_opt_to_slur_regex(&local_site); let content_slurs_removed = remove_slurs(&content, slur_regex); let language_id = LanguageTag::to_language_id_single(note.language, context.pool()).await?; @@ -209,10 +197,7 @@ impl ApubObject for ApubComment { language_id, }; let parent_comment_path = parent_comment.map(|t| t.0.path); - let comment = blocking(context.pool(), move |conn| { - Comment::create(conn, &form, parent_comment_path.as_ref()) - }) - .await??; + let comment = Comment::create(context.pool(), &form, parent_comment_path.as_ref()).await?; Ok(comment.into()) } } @@ -251,20 +236,18 @@ pub(crate) mod tests { (person, community, post, site) } - fn cleanup(data: (ApubPerson, ApubCommunity, ApubPost, ApubSite), context: &LemmyContext) { - let conn = &mut context.pool().get().unwrap(); - Post::delete(conn, data.2.id).unwrap(); - Community::delete(conn, data.1.id).unwrap(); - Person::delete(conn, data.0.id).unwrap(); - Site::delete(conn, data.3.id).unwrap(); - LocalSite::delete(conn).unwrap(); + async fn cleanup(data: (ApubPerson, ApubCommunity, ApubPost, ApubSite), context: &LemmyContext) { + Post::delete(context.pool(), data.2.id).await.unwrap(); + Community::delete(context.pool(), data.1.id).await.unwrap(); + Person::delete(context.pool(), data.0.id).await.unwrap(); + Site::delete(context.pool(), data.3.id).await.unwrap(); + LocalSite::delete(context.pool()).await.unwrap(); } #[actix_rt::test] #[serial] pub(crate) async fn test_parse_lemmy_comment() { - let context = init_context(); - let conn = &mut context.pool().get().unwrap(); + let context = init_context().await; let url = Url::parse("https://enterprise.lemmy.ml/comment/38741").unwrap(); let data = prepare_comment_test(&url, &context).await; @@ -286,15 +269,14 @@ pub(crate) mod tests { let to_apub = comment.into_apub(&context).await.unwrap(); assert_json_include!(actual: json, expected: to_apub); - Comment::delete(conn, comment_id).unwrap(); - cleanup(data, &context); + Comment::delete(context.pool(), comment_id).await.unwrap(); + cleanup(data, &context).await; } #[actix_rt::test] #[serial] async fn test_parse_pleroma_comment() { - let context = init_context(); - let conn = &mut context.pool().get().unwrap(); + let context = init_context().await; let url = Url::parse("https://enterprise.lemmy.ml/comment/38741").unwrap(); let data = prepare_comment_test(&url, &context).await; @@ -322,8 +304,8 @@ pub(crate) mod tests { assert!(!comment.local); assert_eq!(request_counter, 0); - Comment::delete(conn, comment.id).unwrap(); - cleanup(data, &context); + Comment::delete(context.pool(), comment.id).await.unwrap(); + cleanup(data, &context).await; } #[actix_rt::test] diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs index 6e04f2c1..77c370f1 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -20,7 +20,6 @@ use activitypub_federation::{ use activitystreams_kinds::actor::GroupType; use chrono::NaiveDateTime; use itertools::Itertools; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ actor_language::CommunityLanguage, @@ -72,31 +71,23 @@ impl ApubObject for ApubCommunity { context: &LemmyContext, ) -> Result, LemmyError> { Ok( - blocking(context.pool(), move |conn| { - Community::read_from_apub_id(conn, &object_id.into()) - }) - .await?? - .map(Into::into), + Community::read_from_apub_id(context.pool(), &object_id.into()) + .await? + .map(Into::into), ) } #[tracing::instrument(skip_all)] async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - blocking(context.pool(), move |conn| { - let form = CommunityUpdateForm::builder().deleted(Some(true)).build(); - Community::update(conn, self.id, &form) - }) - .await??; + let form = CommunityUpdateForm::builder().deleted(Some(true)).build(); + Community::update(context.pool(), self.id, &form).await?; Ok(()) } #[tracing::instrument(skip_all)] async fn into_apub(self, data: &LemmyContext) -> Result { let community_id = self.id; - let langs = blocking(data.pool(), move |conn| { - CommunityLanguage::read(conn, community_id) - }) - .await??; + let langs = CommunityLanguage::read(data.pool(), community_id).await?; let language = LanguageTag::new_multiple(langs, data.pool()).await?; let group = Group { @@ -145,35 +136,29 @@ impl ApubObject for ApubCommunity { request_counter: &mut i32, ) -> Result { let apub_id = group.id.inner().to_owned(); - let instance = blocking(context.pool(), move |conn| { - Instance::create_from_actor_id(conn, &apub_id) - }) - .await??; + let instance = Instance::create_from_actor_id(context.pool(), &apub_id).await?; let form = Group::into_insert_form(group.clone(), instance.id); let languages = LanguageTag::to_language_id_multiple(group.language, context.pool()).await?; - let community: ApubCommunity = blocking(context.pool(), move |conn| { - let community = Community::create(conn, &form)?; - CommunityLanguage::update(conn, languages, community.id)?; - Ok::(community) - }) - .await?? - .into(); + let community = Community::create(context.pool(), &form).await?; + CommunityLanguage::update(context.pool(), languages, community.id).await?; + + let community: ApubCommunity = community.into(); let outbox_data = CommunityContext(community.clone(), context.clone()); // Fetching mods and outbox is not necessary for Lemmy to work, so ignore errors. Besides, // we need to ignore these errors so that tests can work entirely offline. group .outbox - .dereference(&outbox_data, local_instance(context), request_counter) + .dereference(&outbox_data, local_instance(context).await, request_counter) .await .map_err(|e| debug!("{}", e)) .ok(); if let Some(moderators) = &group.moderators { moderators - .dereference(&outbox_data, local_instance(context), request_counter) + .dereference(&outbox_data, local_instance(context).await, request_counter) .await .map_err(|e| debug!("{}", e)) .ok(); @@ -217,11 +202,8 @@ impl ApubCommunity { ) -> Result, LemmyError> { let id = self.id; - let local_site_data = blocking(context.pool(), fetch_local_site_data).await??; - let follows = blocking(context.pool(), move |conn| { - CommunityFollowerView::for_community(conn, id) - }) - .await??; + let local_site_data = fetch_local_site_data(context.pool()).await?; + let follows = CommunityFollowerView::for_community(context.pool(), id).await?; let inboxes: Vec = follows .into_iter() .filter(|f| !f.follower.local) @@ -277,8 +259,7 @@ pub(crate) mod tests { #[actix_rt::test] #[serial] async fn test_parse_lemmy_community() { - let context = init_context(); - let conn = &mut context.pool().get().unwrap(); + let context = init_context().await; let site = parse_lemmy_instance(&context).await; let community = parse_lemmy_community(&context).await; @@ -286,7 +267,9 @@ pub(crate) mod tests { assert!(!community.local); assert_eq!(community.description.as_ref().unwrap().len(), 132); - Community::delete(conn, community.id).unwrap(); - Site::delete(conn, site.id).unwrap(); + Community::delete(context.pool(), community.id) + .await + .unwrap(); + Site::delete(context.pool(), site.id).await.unwrap(); } } diff --git a/crates/apub/src/objects/instance.rs b/crates/apub/src/objects/instance.rs index de4839ad..e9c70da0 100644 --- a/crates/apub/src/objects/instance.rs +++ b/crates/apub/src/objects/instance.rs @@ -20,7 +20,7 @@ use activitypub_federation::{ utils::verify_domains_match, }; use chrono::NaiveDateTime; -use lemmy_api_common::utils::{blocking, local_site_opt_to_slur_regex}; +use lemmy_api_common::utils::local_site_opt_to_slur_regex; use lemmy_db_schema::{ source::{ actor_language::SiteLanguage, @@ -72,11 +72,9 @@ impl ApubObject for ApubSite { data: &Self::DataType, ) -> Result, LemmyError> { Ok( - blocking(data.pool(), move |conn| { - Site::read_from_apub_id(conn, object_id) - }) - .await?? - .map(Into::into), + Site::read_from_apub_id(data.pool(), object_id) + .await? + .map(Into::into), ) } @@ -87,7 +85,7 @@ impl ApubObject for ApubSite { #[tracing::instrument(skip_all)] async fn into_apub(self, data: &Self::DataType) -> Result { let site_id = self.id; - let langs = blocking(data.pool(), move |conn| SiteLanguage::read(conn, site_id)).await??; + let langs = SiteLanguage::read(data.pool(), site_id).await?; let language = LanguageTag::new_multiple(langs, data.pool()).await?; let instance = Instance { @@ -117,7 +115,7 @@ impl ApubObject for ApubSite { data: &Self::DataType, _request_counter: &mut i32, ) -> Result<(), LemmyError> { - let local_site_data = blocking(data.pool(), fetch_local_site_data).await??; + let local_site_data = fetch_local_site_data(data.pool()).await?; check_apub_id_valid_with_strictness(apub.id.inner(), true, &local_site_data, data.settings())?; verify_domains_match(expected_domain, apub.id.inner())?; @@ -136,10 +134,7 @@ impl ApubObject for ApubSite { _request_counter: &mut i32, ) -> Result { let apub_id = apub.id.inner().to_owned(); - let instance = blocking(data.pool(), move |conn| { - DbInstance::create_from_actor_id(conn, &apub_id) - }) - .await??; + let instance = DbInstance::create_from_actor_id(data.pool(), &apub_id).await?; let site_form = SiteInsertForm { name: apub.name.clone(), @@ -157,12 +152,8 @@ impl ApubObject for ApubSite { }; let languages = LanguageTag::to_language_id_multiple(apub.language, data.pool()).await?; - let site = blocking(data.pool(), move |conn| { - let site = Site::create(conn, &site_form)?; - SiteLanguage::update(conn, languages, &site)?; - Ok::(site) - }) - .await??; + let site = Site::create(data.pool(), &site_form).await?; + SiteLanguage::update(data.pool(), languages, &site).await?; Ok(site.into()) } } @@ -204,7 +195,7 @@ pub(in crate::objects) async fn fetch_instance_actor_for_object( // try to fetch the instance actor (to make things like instance rules available) let instance_id = instance_actor_id_from_url(object_id); let site = ObjectId::::new(instance_id.clone()) - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await; if let Err(e) = site { debug!("Failed to dereference site for {}: {}", instance_id, e); @@ -213,8 +204,8 @@ pub(in crate::objects) async fn fetch_instance_actor_for_object( pub(crate) async fn remote_instance_inboxes(pool: &DbPool) -> Result, LemmyError> { Ok( - blocking(pool, Site::read_remote_sites) - .await?? + Site::read_remote_sites(pool) + .await? .into_iter() .map(|s| ApubSite::from(s).shared_inbox_or_inbox()) .collect(), @@ -245,13 +236,12 @@ pub(crate) mod tests { #[actix_rt::test] #[serial] async fn test_parse_lemmy_instance() { - let context = init_context(); - let conn = &mut context.pool().get().unwrap(); + let context = init_context().await; let site = parse_lemmy_instance(&context).await; assert_eq!(site.name, "Enterprise"); assert_eq!(site.description.as_ref().unwrap().len(), 15); - Site::delete(conn, site.id).unwrap(); + Site::delete(context.pool(), site.id).await.unwrap(); } } diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs index f54d0756..1e2ac79b 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -56,15 +56,8 @@ pub(crate) fn verify_is_remote_object(id: &Url, settings: &Settings) -> Result<( pub(crate) mod tests { use actix::Actor; use anyhow::anyhow; - use diesel::{ - r2d2::{ConnectionManager, Pool}, - PgConnection, - }; use lemmy_api_common::request::build_user_agent; - use lemmy_db_schema::{ - source::secret::Secret, - utils::{establish_unpooled_connection, get_database_url_from_env}, - }; + use lemmy_db_schema::{source::secret::Secret, utils::build_db_pool_for_tests}; use lemmy_utils::{ error::LemmyError, rate_limit::{rate_limiter::RateLimiter, RateLimit, RateLimitConfig}, @@ -92,9 +85,10 @@ pub(crate) mod tests { } // TODO: would be nice if we didnt have to use a full context for tests. - pub(crate) fn init_context() -> LemmyContext { + pub(crate) async fn init_context() -> LemmyContext { // call this to run migrations - establish_unpooled_connection(); + let pool = build_db_pool_for_tests().await; + let settings = SETTINGS.to_owned(); let client = Client::builder() .user_agent(build_user_agent(&settings)) @@ -106,15 +100,6 @@ pub(crate) mod tests { id: 0, jwt_secret: "".to_string(), }; - let db_url = match get_database_url_from_env() { - Ok(url) => url, - Err(_) => settings.get_database_url(), - }; - let manager = ConnectionManager::::new(&db_url); - let pool = Pool::builder() - .max_size(settings.database.pool_size) - .build(manager) - .unwrap_or_else(|_| panic!("Error connecting to {}", db_url)); async fn x() -> Result { Ok("".to_string()) } diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index 41d6b777..efe2c3ee 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -19,7 +19,7 @@ use activitypub_federation::{ utils::verify_domains_match, }; use chrono::NaiveDateTime; -use lemmy_api_common::utils::{blocking, local_site_opt_to_slur_regex}; +use lemmy_api_common::utils::local_site_opt_to_slur_regex; use lemmy_db_schema::{ source::{ instance::Instance, @@ -69,21 +69,16 @@ impl ApubObject for ApubPerson { context: &LemmyContext, ) -> Result, LemmyError> { Ok( - blocking(context.pool(), move |conn| { - DbPerson::read_from_apub_id(conn, &object_id.into()) - }) - .await?? - .map(Into::into), + DbPerson::read_from_apub_id(context.pool(), &object_id.into()) + .await? + .map(Into::into), ) } #[tracing::instrument(skip_all)] async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - blocking(context.pool(), move |conn| { - let form = PersonUpdateForm::builder().deleted(Some(true)).build(); - DbPerson::update(conn, self.id, &form) - }) - .await??; + let form = PersonUpdateForm::builder().deleted(Some(true)).build(); + DbPerson::update(context.pool(), self.id, &form).await?; Ok(()) } @@ -124,7 +119,7 @@ impl ApubObject for ApubPerson { context: &LemmyContext, _request_counter: &mut i32, ) -> Result<(), LemmyError> { - let local_site_data = blocking(context.pool(), fetch_local_site_data).await??; + let local_site_data = fetch_local_site_data(context.pool()).await?; let slur_regex = &local_site_opt_to_slur_regex(&local_site_data.local_site); check_slurs(&person.preferred_username, slur_regex)?; @@ -150,10 +145,7 @@ impl ApubObject for ApubPerson { request_counter: &mut i32, ) -> Result { let apub_id = person.id.inner().to_owned(); - let instance = blocking(context.pool(), move |conn| { - Instance::create_from_actor_id(conn, &apub_id) - }) - .await??; + let instance = Instance::create_from_actor_id(context.pool(), &apub_id).await?; let person_form = PersonInsertForm { name: person.preferred_username, @@ -178,10 +170,7 @@ impl ApubObject for ApubPerson { matrix_user_id: person.matrix_user_id, instance_id: instance.id, }; - let person = blocking(context.pool(), move |conn| { - DbPerson::create(conn, &person_form) - }) - .await??; + let person = DbPerson::create(context.pool(), &person_form).await?; let actor_id = person.actor_id.clone().into(); fetch_instance_actor_for_object(actor_id, context, request_counter).await; @@ -245,20 +234,20 @@ pub(crate) mod tests { #[actix_rt::test] #[serial] async fn test_parse_lemmy_person() { - let context = init_context(); + let context = init_context().await; let (person, site) = parse_lemmy_person(&context).await; assert_eq!(person.display_name, Some("Jean-Luc Picard".to_string())); assert!(!person.local); assert_eq!(person.bio.as_ref().unwrap().len(), 39); - cleanup((person, site), &context); + cleanup((person, site), &context).await; } #[actix_rt::test] #[serial] async fn test_parse_pleroma_person() { - let context = init_context(); + let context = init_context().await; // create and parse a fake pleroma instance actor, to avoid network request during test let mut json: Instance = file_to_json_object("assets/lemmy/objects/instance.json").unwrap(); @@ -285,12 +274,11 @@ pub(crate) mod tests { assert_eq!(request_counter, 0); assert_eq!(person.bio.as_ref().unwrap().len(), 873); - cleanup((person, site), &context); + cleanup((person, site), &context).await; } - fn cleanup(data: (ApubPerson, ApubSite), context: &LemmyContext) { - let conn = &mut context.pool().get().unwrap(); - DbPerson::delete(conn, data.0.id).unwrap(); - Site::delete(conn, data.1.id).unwrap(); + async fn cleanup(data: (ApubPerson, ApubSite), context: &LemmyContext) { + DbPerson::delete(context.pool(), data.0.id).await.unwrap(); + Site::delete(context.pool(), data.1.id).await.unwrap(); } } diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index ac9b82eb..d6719926 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -21,10 +21,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::public; use chrono::NaiveDateTime; -use lemmy_api_common::{ - request::fetch_site_data, - utils::{blocking, local_site_opt_to_slur_regex}, -}; +use lemmy_api_common::{request::fetch_site_data, utils::local_site_opt_to_slur_regex}; use lemmy_db_schema::{ self, source::{ @@ -77,22 +74,17 @@ impl ApubObject for ApubPost { context: &LemmyContext, ) -> Result, LemmyError> { Ok( - blocking(context.pool(), move |conn| { - Post::read_from_apub_id(conn, object_id) - }) - .await?? - .map(Into::into), + Post::read_from_apub_id(context.pool(), object_id) + .await? + .map(Into::into), ) } #[tracing::instrument(skip_all)] async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { if !self.deleted { - blocking(context.pool(), move |conn| { - let form = PostUpdateForm::builder().deleted(Some(true)).build(); - Post::update(conn, self.id, &form) - }) - .await??; + let form = PostUpdateForm::builder().deleted(Some(true)).build(); + Post::update(context.pool(), self.id, &form).await?; } Ok(()) } @@ -101,12 +93,9 @@ impl ApubObject for ApubPost { #[tracing::instrument(skip_all)] async fn into_apub(self, context: &LemmyContext) -> Result { let creator_id = self.creator_id; - let creator = blocking(context.pool(), move |conn| Person::read(conn, creator_id)).await??; + let creator = Person::read(context.pool(), creator_id).await?; let community_id = self.community_id; - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + let community = Community::read(context.pool(), community_id).await?; let language = LanguageTag::new_single(self.language_id, context.pool()).await?; let page = Page { @@ -146,7 +135,7 @@ impl ApubObject for ApubPost { verify_is_remote_object(page.id.inner(), context.settings())?; }; - let local_site_data = blocking(context.pool(), fetch_local_site_data).await??; + let local_site_data = fetch_local_site_data(context.pool()).await?; let community = page.extract_community(context, request_counter).await?; check_apub_id_valid_with_strictness( @@ -173,7 +162,7 @@ impl ApubObject for ApubPost { ) -> Result { let creator = page .creator()? - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let community = page.extract_community(context, request_counter).await?; @@ -199,7 +188,7 @@ impl ApubObject for ApubPost { let (embed_title, embed_description, embed_video_url) = metadata_res .map(|u| (u.title, u.description, u.embed_video_url)) .unwrap_or_default(); - let local_site = blocking(context.pool(), LocalSite::read).await?.ok(); + let local_site = LocalSite::read(context.pool()).await.ok(); let slur_regex = &local_site_opt_to_slur_regex(&local_site); let body_slurs_removed = @@ -246,7 +235,7 @@ impl ApubObject for ApubPost { .dereference_local(context) .await; - let post = blocking(context.pool(), move |conn| Post::create(conn, &form)).await??; + let post = Post::create(context.pool(), &form).await?; // write mod log entries for sticky/lock if Page::is_stickied_changed(&old_post, &page.stickied) { @@ -255,10 +244,7 @@ impl ApubObject for ApubPost { post_id: post.id, stickied: Some(post.stickied), }; - blocking(context.pool(), move |conn| { - ModStickyPost::create(conn, &form) - }) - .await??; + ModStickyPost::create(context.pool(), &form).await?; } if Page::is_locked_changed(&old_post, &page.comments_enabled) { let form = ModLockPostForm { @@ -266,7 +252,7 @@ impl ApubObject for ApubPost { post_id: post.id, locked: Some(post.locked), }; - blocking(context.pool(), move |conn| ModLockPost::create(conn, &form)).await??; + ModLockPost::create(context.pool(), &form).await?; } Ok(post.into()) @@ -291,8 +277,7 @@ mod tests { #[actix_rt::test] #[serial] async fn test_parse_lemmy_post() { - let context = init_context(); - let conn = &mut context.pool().get().unwrap(); + let context = init_context().await; let (person, site) = parse_lemmy_person(&context).await; let community = parse_lemmy_community(&context).await; @@ -314,9 +299,11 @@ mod tests { assert!(post.stickied); assert_eq!(request_counter, 0); - Post::delete(conn, post.id).unwrap(); - Person::delete(conn, person.id).unwrap(); - Community::delete(conn, community.id).unwrap(); - Site::delete(conn, site.id).unwrap(); + Post::delete(context.pool(), post.id).await.unwrap(); + Person::delete(context.pool(), person.id).await.unwrap(); + Community::delete(context.pool(), community.id) + .await + .unwrap(); + Site::delete(context.pool(), site.id).await.unwrap(); } } diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs index 87f88de8..47a9c5d1 100644 --- a/crates/apub/src/objects/private_message.rs +++ b/crates/apub/src/objects/private_message.rs @@ -15,7 +15,7 @@ use activitypub_federation::{ utils::verify_domains_match, }; use chrono::NaiveDateTime; -use lemmy_api_common::utils::{blocking, check_person_block}; +use lemmy_api_common::utils::check_person_block; use lemmy_db_schema::{ source::{ person::Person, @@ -64,11 +64,9 @@ impl ApubObject for ApubPrivateMessage { context: &LemmyContext, ) -> Result, LemmyError> { Ok( - blocking(context.pool(), move |conn| { - PrivateMessage::read_from_apub_id(conn, object_id) - }) - .await?? - .map(Into::into), + PrivateMessage::read_from_apub_id(context.pool(), object_id) + .await? + .map(Into::into), ) } @@ -80,11 +78,10 @@ impl ApubObject for ApubPrivateMessage { #[tracing::instrument(skip_all)] async fn into_apub(self, context: &LemmyContext) -> Result { let creator_id = self.creator_id; - let creator = blocking(context.pool(), move |conn| Person::read(conn, creator_id)).await??; + let creator = Person::read(context.pool(), creator_id).await?; let recipient_id = self.recipient_id; - let recipient = - blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??; + let recipient = Person::read(context.pool(), recipient_id).await?; let note = ChatMessage { r#type: ChatMessageType::ChatMessage, @@ -110,7 +107,7 @@ impl ApubObject for ApubPrivateMessage { verify_domains_match(note.id.inner(), expected_domain)?; verify_domains_match(note.attributed_to.inner(), note.id.inner())?; - let local_site_data = blocking(context.pool(), fetch_local_site_data).await??; + let local_site_data = fetch_local_site_data(context.pool()).await?; check_apub_id_valid_with_strictness( note.id.inner(), @@ -120,7 +117,7 @@ impl ApubObject for ApubPrivateMessage { )?; let person = note .attributed_to - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; if person.banned { return Err(LemmyError::from_message("Person is banned from site")); @@ -136,10 +133,10 @@ impl ApubObject for ApubPrivateMessage { ) -> Result { let creator = note .attributed_to - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; let recipient = note.to[0] - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?; check_person_block(creator.id, recipient.id, context.pool()).await?; @@ -154,10 +151,7 @@ impl ApubObject for ApubPrivateMessage { ap_id: Some(note.id.into()), local: Some(false), }; - let pm = blocking(context.pool(), move |conn| { - PrivateMessage::create(conn, &form) - }) - .await??; + let pm = PrivateMessage::create(context.pool(), &form).await?; Ok(pm.into()) } } @@ -200,18 +194,16 @@ mod tests { (person1, person2, site) } - fn cleanup(data: (ApubPerson, ApubPerson, ApubSite), context: &LemmyContext) { - let conn = &mut context.pool().get().unwrap(); - Person::delete(conn, data.0.id).unwrap(); - Person::delete(conn, data.1.id).unwrap(); - Site::delete(conn, data.2.id).unwrap(); + async fn cleanup(data: (ApubPerson, ApubPerson, ApubSite), context: &LemmyContext) { + Person::delete(context.pool(), data.0.id).await.unwrap(); + Person::delete(context.pool(), data.1.id).await.unwrap(); + Site::delete(context.pool(), data.2.id).await.unwrap(); } #[actix_rt::test] #[serial] async fn test_parse_lemmy_pm() { - let context = init_context(); - let conn = &mut context.pool().get().unwrap(); + let context = init_context().await; let url = Url::parse("https://enterprise.lemmy.ml/private_message/1621").unwrap(); let data = prepare_comment_test(&url, &context).await; let json: ChatMessage = file_to_json_object("assets/lemmy/objects/chat_message.json").unwrap(); @@ -231,15 +223,14 @@ mod tests { let to_apub = pm.into_apub(&context).await.unwrap(); assert_json_include!(actual: json, expected: to_apub); - PrivateMessage::delete(conn, pm_id).unwrap(); - cleanup(data, &context); + PrivateMessage::delete(context.pool(), pm_id).await.unwrap(); + cleanup(data, &context).await; } #[actix_rt::test] #[serial] async fn test_parse_pleroma_pm() { - let context = init_context(); - let conn = &mut context.pool().get().unwrap(); + let context = init_context().await; let url = Url::parse("https://enterprise.lemmy.ml/private_message/1621").unwrap(); let data = prepare_comment_test(&url, &context).await; let pleroma_url = Url::parse("https://queer.hacktivis.me/objects/2").unwrap(); @@ -256,7 +247,7 @@ mod tests { assert_eq!(pm.content.len(), 3); assert_eq!(request_counter, 0); - PrivateMessage::delete(conn, pm.id).unwrap(); - cleanup(data, &context); + PrivateMessage::delete(context.pool(), pm.id).await.unwrap(); + cleanup(data, &context).await; } } diff --git a/crates/apub/src/protocol/collections/group_followers.rs b/crates/apub/src/protocol/collections/group_followers.rs index eeea8e07..ac1ef228 100644 --- a/crates/apub/src/protocol/collections/group_followers.rs +++ b/crates/apub/src/protocol/collections/group_followers.rs @@ -1,6 +1,5 @@ use crate::generate_followers_url; use activitystreams_kinds::collection::CollectionType; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::source::community::Community; use lemmy_db_views_actor::structs::CommunityFollowerView; use lemmy_utils::error::LemmyError; @@ -23,10 +22,8 @@ impl GroupFollowers { context: &LemmyContext, ) -> Result { let community_id = community.id; - let community_followers = blocking(context.pool(), move |conn| { - CommunityFollowerView::for_community(conn, community_id) - }) - .await??; + let community_followers = + CommunityFollowerView::for_community(context.pool(), community_id).await?; Ok(GroupFollowers { id: generate_followers_url(&community.actor_id)?.into(), diff --git a/crates/apub/src/protocol/mod.rs b/crates/apub/src/protocol/mod.rs index c81a5c15..c259a6e9 100644 --- a/crates/apub/src/protocol/mod.rs +++ b/crates/apub/src/protocol/mod.rs @@ -74,7 +74,7 @@ impl IdOrNestedObject { ) -> Result { match self { IdOrNestedObject::Id(i) => { - Ok(fetch_object_http(&i, local_instance(context), request_counter).await?) + Ok(fetch_object_http(&i, local_instance(context).await, request_counter).await?) } IdOrNestedObject::NestedObject(o) => Ok(o), } diff --git a/crates/apub/src/protocol/objects/group.rs b/crates/apub/src/protocol/objects/group.rs index 7d207da4..1935589e 100644 --- a/crates/apub/src/protocol/objects/group.rs +++ b/crates/apub/src/protocol/objects/group.rs @@ -19,7 +19,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::actor::GroupType; use chrono::{DateTime, FixedOffset}; -use lemmy_api_common::utils::{blocking, local_site_opt_to_slur_regex}; +use lemmy_api_common::utils::local_site_opt_to_slur_regex; use lemmy_db_schema::{ newtypes::InstanceId, source::community::{CommunityInsertForm, CommunityUpdateForm}, @@ -75,7 +75,7 @@ impl Group { expected_domain: &Url, context: &LemmyContext, ) -> Result<(), LemmyError> { - let local_site_data = blocking(context.pool(), fetch_local_site_data).await??; + let local_site_data = fetch_local_site_data(context.pool()).await?; check_apub_id_valid_with_strictness( self.id.inner(), diff --git a/crates/apub/src/protocol/objects/mod.rs b/crates/apub/src/protocol/objects/mod.rs index 31b8eb32..0fcbc08e 100644 --- a/crates/apub/src/protocol/objects/mod.rs +++ b/crates/apub/src/protocol/objects/mod.rs @@ -1,4 +1,3 @@ -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{newtypes::LanguageId, source::language::Language, utils::DbPool}; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; @@ -31,7 +30,7 @@ impl LanguageTag { lang: LanguageId, pool: &DbPool, ) -> Result, LemmyError> { - let lang = blocking(pool, move |conn| Language::read_from_id(conn, lang)).await??; + let lang = Language::read_from_id(pool, lang).await?; // undetermined if lang.code == "und" { @@ -45,16 +44,14 @@ impl LanguageTag { } pub(crate) async fn new_multiple( - langs: Vec, + lang_ids: Vec, pool: &DbPool, ) -> Result, LemmyError> { - let langs = blocking(pool, move |conn| { - langs - .into_iter() - .map(|l| Language::read_from_id(conn, l)) - .collect::, diesel::result::Error>>() - }) - .await??; + let mut langs = Vec::::new(); + + for l in lang_ids { + langs.push(Language::read_from_id(pool, l).await?); + } let langs = langs .into_iter() @@ -71,10 +68,7 @@ impl LanguageTag { pool: &DbPool, ) -> Result, LemmyError> { let identifier = lang.map(|l| l.identifier); - let language = blocking(pool, move |conn| { - Language::read_id_from_code_opt(conn, identifier.as_deref()) - }) - .await??; + let language = Language::read_id_from_code_opt(pool, identifier.as_deref()).await?; Ok(language) } @@ -83,15 +77,14 @@ impl LanguageTag { langs: Vec, pool: &DbPool, ) -> Result, LemmyError> { - let languages = blocking(pool, move |conn| { - langs - .into_iter() - .map(|l| l.identifier) - .map(|l| Language::read_id_from_code(conn, &l)) - .collect::, diesel::result::Error>>() - }) - .await??; - Ok(languages) + let mut language_ids = Vec::new(); + + for l in langs { + let id = l.identifier; + language_ids.push(Language::read_id_from_code(pool, &id).await?); + } + + Ok(language_ids) } } diff --git a/crates/apub/src/protocol/objects/note.rs b/crates/apub/src/protocol/objects/note.rs index cdcec1a7..c91ed8d1 100644 --- a/crates/apub/src/protocol/objects/note.rs +++ b/crates/apub/src/protocol/objects/note.rs @@ -14,7 +14,6 @@ use activitypub_federation::{ }; use activitystreams_kinds::object::NoteType; use chrono::{DateTime, FixedOffset}; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{source::post::Post, traits::Crud}; use lemmy_utils::error::LemmyError; use lemmy_websocket::LemmyContext; @@ -59,7 +58,7 @@ impl Note { let parent = Box::pin( self .in_reply_to - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await?, ); match parent.deref() { @@ -69,7 +68,7 @@ impl Note { } PostOrComment::Comment(c) => { let post_id = c.post_id; - let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let post = Post::read(context.pool(), post_id).await?; let comment = c.deref().to_owned(); Ok((post.into(), Some(comment))) } diff --git a/crates/apub/src/protocol/objects/page.rs b/crates/apub/src/protocol/objects/page.rs index 1cf55aca..5ffb4869 100644 --- a/crates/apub/src/protocol/objects/page.rs +++ b/crates/apub/src/protocol/objects/page.rs @@ -155,7 +155,7 @@ impl Page { if let Some(cid) = iter.next() { let cid = ObjectId::new(cid.clone()); if let Ok(c) = cid - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await { break Ok(c); @@ -170,7 +170,7 @@ impl Page { .find(|a| a.kind == PersonOrGroupType::Group) .map(|a| ObjectId::::new(a.id.clone().into_inner())) .ok_or_else(|| LemmyError::from_message("page does not specify group"))? - .dereference(context, local_instance(context), request_counter) + .dereference(context, local_instance(context).await, request_counter) .await } } diff --git a/crates/db_schema/Cargo.toml b/crates/db_schema/Cargo.toml index 5808f81c..da508b29 100644 --- a/crates/db_schema/Cargo.toml +++ b/crates/db_schema/Cargo.toml @@ -19,22 +19,26 @@ full = ["diesel", "diesel-derive-newtype", "diesel_migrations", "bcrypt", "lemmy [dependencies] chrono = { version = "0.4.22", features = ["serde"], default-features = false } -serde = { version = "1.0.145", features = ["derive"] } +serde = { version = "1.0.147", features = ["derive"] } url = { version = "2.3.1", features = ["serde"] } strum = "0.24.1" strum_macros = "0.24.3" -serde_json = { version = "1.0.85", features = ["preserve_order"], optional = true } +serde_json = { version = "1.0.87", features = ["preserve_order"], optional = true } activitypub_federation = { version = "0.2.3", optional = true } lemmy_utils = { version = "=0.16.5", path = "../utils", optional = true } bcrypt = { version = "0.13.0", optional = true } -diesel = { version = "2.0.0", features = ["postgres","chrono","r2d2","serde_json"], optional = true } +diesel = { version = "2.0.2", features = ["postgres","chrono", "serde_json"], optional = true } diesel-derive-newtype = { version = "2.0.0-rc.0", optional = true } diesel_migrations = { version = "2.0.0", optional = true } +diesel-async = { version = "0.1.1", features = ["postgres", "bb8"] } +bb8 = "0.8.0" sha2 = { version = "0.10.6", optional = true } regex = { version = "1.6.0", optional = true } once_cell = { version = "1.15.0", optional = true } diesel_ltree = "0.3.0" typed-builder = "0.10.0" +async-trait = "0.1.58" +tokio = "1.21.2" [dev-dependencies] serial_test = "0.9.0" diff --git a/crates/db_schema/src/aggregates/comment_aggregates.rs b/crates/db_schema/src/aggregates/comment_aggregates.rs index 1130d910..56528a5f 100644 --- a/crates/db_schema/src/aggregates/comment_aggregates.rs +++ b/crates/db_schema/src/aggregates/comment_aggregates.rs @@ -2,14 +2,18 @@ use crate::{ aggregates::structs::CommentAggregates, newtypes::CommentId, schema::comment_aggregates, + utils::{get_conn, DbPool}, }; -use diesel::{result::Error, *}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; impl CommentAggregates { - pub fn read(conn: &mut PgConnection, comment_id: CommentId) -> Result { + pub async fn read(pool: &DbPool, comment_id: CommentId) -> Result { + let conn = &mut get_conn(pool).await?; comment_aggregates::table .filter(comment_aggregates::comment_id.eq(comment_id)) .first::(conn) + .await } } @@ -25,16 +29,16 @@ mod tests { post::{Post, PostInsertForm}, }, traits::{Crud, Likeable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("thommy_comment_agg".into()) @@ -42,7 +46,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let another_person = PersonInsertForm::builder() .name("jerry_comment_agg".into()) @@ -50,7 +54,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let another_inserted_person = Person::create(conn, &another_person).unwrap(); + let another_inserted_person = Person::create(pool, &another_person).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("TIL_comment_agg".into()) @@ -59,7 +63,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -67,7 +71,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -75,7 +79,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let child_comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -84,7 +88,9 @@ mod tests { .build(); let _inserted_child_comment = - Comment::create(conn, &child_comment_form, Some(&inserted_comment.path)).unwrap(); + Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)) + .await + .unwrap(); let comment_like = CommentLikeForm { comment_id: inserted_comment.id, @@ -93,9 +99,11 @@ mod tests { score: 1, }; - CommentLike::like(conn, &comment_like).unwrap(); + CommentLike::like(pool, &comment_like).await.unwrap(); - let comment_aggs_before_delete = CommentAggregates::read(conn, inserted_comment.id).unwrap(); + let comment_aggs_before_delete = CommentAggregates::read(pool, inserted_comment.id) + .await + .unwrap(); assert_eq!(1, comment_aggs_before_delete.score); assert_eq!(1, comment_aggs_before_delete.upvotes); @@ -109,37 +117,47 @@ mod tests { score: -1, }; - CommentLike::like(conn, &comment_dislike).unwrap(); + CommentLike::like(pool, &comment_dislike).await.unwrap(); - let comment_aggs_after_dislike = CommentAggregates::read(conn, inserted_comment.id).unwrap(); + let comment_aggs_after_dislike = CommentAggregates::read(pool, inserted_comment.id) + .await + .unwrap(); assert_eq!(0, comment_aggs_after_dislike.score); assert_eq!(1, comment_aggs_after_dislike.upvotes); assert_eq!(1, comment_aggs_after_dislike.downvotes); // Remove the first comment like - CommentLike::remove(conn, inserted_person.id, inserted_comment.id).unwrap(); - let after_like_remove = CommentAggregates::read(conn, inserted_comment.id).unwrap(); + CommentLike::remove(pool, inserted_person.id, inserted_comment.id) + .await + .unwrap(); + let after_like_remove = CommentAggregates::read(pool, inserted_comment.id) + .await + .unwrap(); assert_eq!(-1, after_like_remove.score); assert_eq!(0, after_like_remove.upvotes); assert_eq!(1, after_like_remove.downvotes); // Remove the parent post - Post::delete(conn, inserted_post.id).unwrap(); + Post::delete(pool, inserted_post.id).await.unwrap(); // Should be none found, since the post was deleted - let after_delete = CommentAggregates::read(conn, inserted_comment.id); + let after_delete = CommentAggregates::read(pool, inserted_comment.id).await; assert!(after_delete.is_err()); // This should delete all the associated rows, and fire triggers - Person::delete(conn, another_inserted_person.id).unwrap(); - let person_num_deleted = Person::delete(conn, inserted_person.id).unwrap(); + Person::delete(pool, another_inserted_person.id) + .await + .unwrap(); + let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap(); assert_eq!(1, person_num_deleted); // Delete the community - let community_num_deleted = Community::delete(conn, inserted_community.id).unwrap(); + let community_num_deleted = Community::delete(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(1, community_num_deleted); - Instance::delete(conn, inserted_instance.id).unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); } } diff --git a/crates/db_schema/src/aggregates/community_aggregates.rs b/crates/db_schema/src/aggregates/community_aggregates.rs index 1a2c4d24..96dbb8fb 100644 --- a/crates/db_schema/src/aggregates/community_aggregates.rs +++ b/crates/db_schema/src/aggregates/community_aggregates.rs @@ -2,14 +2,18 @@ use crate::{ aggregates::structs::CommunityAggregates, newtypes::CommunityId, schema::community_aggregates, + utils::{get_conn, DbPool}, }; -use diesel::{result::Error, *}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; impl CommunityAggregates { - pub fn read(conn: &mut PgConnection, community_id: CommunityId) -> Result { + pub async fn read(pool: &DbPool, community_id: CommunityId) -> Result { + let conn = &mut get_conn(pool).await?; community_aggregates::table .filter(community_aggregates::community_id.eq(community_id)) .first::(conn) + .await } } @@ -25,16 +29,16 @@ mod tests { post::{Post, PostInsertForm}, }, traits::{Crud, Followable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("thommy_community_agg".into()) @@ -42,7 +46,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let another_person = PersonInsertForm::builder() .name("jerry_community_agg".into()) @@ -50,7 +54,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let another_inserted_person = Person::create(conn, &another_person).unwrap(); + let another_inserted_person = Person::create(pool, &another_person).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("TIL_community_agg".into()) @@ -59,7 +63,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let another_community = CommunityInsertForm::builder() .name("TIL_community_agg_2".into()) @@ -68,7 +72,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let another_inserted_community = Community::create(conn, &another_community).unwrap(); + let another_inserted_community = Community::create(pool, &another_community).await.unwrap(); let first_person_follow = CommunityFollowerForm { community_id: inserted_community.id, @@ -76,7 +80,9 @@ mod tests { pending: false, }; - CommunityFollower::follow(conn, &first_person_follow).unwrap(); + CommunityFollower::follow(pool, &first_person_follow) + .await + .unwrap(); let second_person_follow = CommunityFollowerForm { community_id: inserted_community.id, @@ -84,7 +90,9 @@ mod tests { pending: false, }; - CommunityFollower::follow(conn, &second_person_follow).unwrap(); + CommunityFollower::follow(pool, &second_person_follow) + .await + .unwrap(); let another_community_follow = CommunityFollowerForm { community_id: another_inserted_community.id, @@ -92,7 +100,9 @@ mod tests { pending: false, }; - CommunityFollower::follow(conn, &another_community_follow).unwrap(); + CommunityFollower::follow(pool, &another_community_follow) + .await + .unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -100,7 +110,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -108,7 +118,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let child_comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -117,57 +127,78 @@ mod tests { .build(); let _inserted_child_comment = - Comment::create(conn, &child_comment_form, Some(&inserted_comment.path)).unwrap(); + Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)) + .await + .unwrap(); - let community_aggregates_before_delete = - CommunityAggregates::read(conn, inserted_community.id).unwrap(); + let community_aggregates_before_delete = CommunityAggregates::read(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(2, community_aggregates_before_delete.subscribers); assert_eq!(1, community_aggregates_before_delete.posts); assert_eq!(2, community_aggregates_before_delete.comments); // Test the other community - let another_community_aggs = - CommunityAggregates::read(conn, another_inserted_community.id).unwrap(); + let another_community_aggs = CommunityAggregates::read(pool, another_inserted_community.id) + .await + .unwrap(); assert_eq!(1, another_community_aggs.subscribers); assert_eq!(0, another_community_aggs.posts); assert_eq!(0, another_community_aggs.comments); // Unfollow test - CommunityFollower::unfollow(conn, &second_person_follow).unwrap(); - let after_unfollow = CommunityAggregates::read(conn, inserted_community.id).unwrap(); + CommunityFollower::unfollow(pool, &second_person_follow) + .await + .unwrap(); + let after_unfollow = CommunityAggregates::read(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(1, after_unfollow.subscribers); // Follow again just for the later tests - CommunityFollower::follow(conn, &second_person_follow).unwrap(); - let after_follow_again = CommunityAggregates::read(conn, inserted_community.id).unwrap(); + CommunityFollower::follow(pool, &second_person_follow) + .await + .unwrap(); + let after_follow_again = CommunityAggregates::read(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(2, after_follow_again.subscribers); // Remove a parent comment (the comment count should also be 0) - Post::delete(conn, inserted_post.id).unwrap(); - let after_parent_post_delete = CommunityAggregates::read(conn, inserted_community.id).unwrap(); + Post::delete(pool, inserted_post.id).await.unwrap(); + let after_parent_post_delete = CommunityAggregates::read(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(0, after_parent_post_delete.comments); assert_eq!(0, after_parent_post_delete.posts); // Remove the 2nd person - Person::delete(conn, another_inserted_person.id).unwrap(); - let after_person_delete = CommunityAggregates::read(conn, inserted_community.id).unwrap(); + Person::delete(pool, another_inserted_person.id) + .await + .unwrap(); + let after_person_delete = CommunityAggregates::read(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(1, after_person_delete.subscribers); // This should delete all the associated rows, and fire triggers - let person_num_deleted = Person::delete(conn, inserted_person.id).unwrap(); + let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap(); assert_eq!(1, person_num_deleted); // Delete the community - let community_num_deleted = Community::delete(conn, inserted_community.id).unwrap(); + let community_num_deleted = Community::delete(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(1, community_num_deleted); - let another_community_num_deleted = - Community::delete(conn, another_inserted_community.id).unwrap(); + let another_community_num_deleted = Community::delete(pool, another_inserted_community.id) + .await + .unwrap(); assert_eq!(1, another_community_num_deleted); // Should be none found, since the creator was deleted - let after_delete = CommunityAggregates::read(conn, inserted_community.id); + let after_delete = CommunityAggregates::read(pool, inserted_community.id).await; assert!(after_delete.is_err()); } } diff --git a/crates/db_schema/src/aggregates/person_aggregates.rs b/crates/db_schema/src/aggregates/person_aggregates.rs index e9417efb..b8e1887a 100644 --- a/crates/db_schema/src/aggregates/person_aggregates.rs +++ b/crates/db_schema/src/aggregates/person_aggregates.rs @@ -1,11 +1,19 @@ -use crate::{aggregates::structs::PersonAggregates, newtypes::PersonId, schema::person_aggregates}; -use diesel::{result::Error, *}; +use crate::{ + aggregates::structs::PersonAggregates, + newtypes::PersonId, + schema::person_aggregates, + utils::{get_conn, DbPool}, +}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; impl PersonAggregates { - pub fn read(conn: &mut PgConnection, person_id: PersonId) -> Result { + pub async fn read(pool: &DbPool, person_id: PersonId) -> Result { + let conn = &mut get_conn(pool).await?; person_aggregates::table .filter(person_aggregates::person_id.eq(person_id)) .first::(conn) + .await } } @@ -21,16 +29,16 @@ mod tests { post::{Post, PostInsertForm, PostLike, PostLikeForm}, }, traits::{Crud, Likeable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("thommy_user_agg".into()) @@ -38,7 +46,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let another_person = PersonInsertForm::builder() .name("jerry_user_agg".into()) @@ -46,7 +54,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let another_inserted_person = Person::create(conn, &another_person).unwrap(); + let another_inserted_person = Person::create(pool, &another_person).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("TIL_site_agg".into()) @@ -55,7 +63,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -63,7 +71,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let post_like = PostLikeForm { post_id: inserted_post.id, @@ -71,7 +79,7 @@ mod tests { score: 1, }; - let _inserted_post_like = PostLike::like(conn, &post_like).unwrap(); + let _inserted_post_like = PostLike::like(pool, &post_like).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -79,7 +87,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let mut comment_like = CommentLikeForm { comment_id: inserted_comment.id, @@ -88,7 +96,7 @@ mod tests { score: 1, }; - let _inserted_comment_like = CommentLike::like(conn, &comment_like).unwrap(); + let _inserted_comment_like = CommentLike::like(pool, &comment_like).await.unwrap(); let child_comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -97,7 +105,9 @@ mod tests { .build(); let inserted_child_comment = - Comment::create(conn, &child_comment_form, Some(&inserted_comment.path)).unwrap(); + Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)) + .await + .unwrap(); let child_comment_like = CommentLikeForm { comment_id: inserted_child_comment.id, @@ -106,9 +116,11 @@ mod tests { score: 1, }; - let _inserted_child_comment_like = CommentLike::like(conn, &child_comment_like).unwrap(); + let _inserted_child_comment_like = CommentLike::like(pool, &child_comment_like).await.unwrap(); - let person_aggregates_before_delete = PersonAggregates::read(conn, inserted_person.id).unwrap(); + let person_aggregates_before_delete = PersonAggregates::read(pool, inserted_person.id) + .await + .unwrap(); assert_eq!(1, person_aggregates_before_delete.post_count); assert_eq!(1, person_aggregates_before_delete.post_score); @@ -116,47 +128,65 @@ mod tests { assert_eq!(2, person_aggregates_before_delete.comment_score); // Remove a post like - PostLike::remove(conn, inserted_person.id, inserted_post.id).unwrap(); - let after_post_like_remove = PersonAggregates::read(conn, inserted_person.id).unwrap(); + PostLike::remove(pool, inserted_person.id, inserted_post.id) + .await + .unwrap(); + let after_post_like_remove = PersonAggregates::read(pool, inserted_person.id) + .await + .unwrap(); assert_eq!(0, after_post_like_remove.post_score); // Remove a parent comment (the scores should also be removed) - Comment::delete(conn, inserted_comment.id).unwrap(); - Comment::delete(conn, inserted_child_comment.id).unwrap(); - let after_parent_comment_delete = PersonAggregates::read(conn, inserted_person.id).unwrap(); + Comment::delete(pool, inserted_comment.id).await.unwrap(); + Comment::delete(pool, inserted_child_comment.id) + .await + .unwrap(); + let after_parent_comment_delete = PersonAggregates::read(pool, inserted_person.id) + .await + .unwrap(); assert_eq!(0, after_parent_comment_delete.comment_count); assert_eq!(0, after_parent_comment_delete.comment_score); // Add in the two comments again, then delete the post. - let new_parent_comment = Comment::create(conn, &comment_form, None).unwrap(); + let new_parent_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let _new_child_comment = - Comment::create(conn, &child_comment_form, Some(&new_parent_comment.path)).unwrap(); + Comment::create(pool, &child_comment_form, Some(&new_parent_comment.path)) + .await + .unwrap(); comment_like.comment_id = new_parent_comment.id; - CommentLike::like(conn, &comment_like).unwrap(); - let after_comment_add = PersonAggregates::read(conn, inserted_person.id).unwrap(); + CommentLike::like(pool, &comment_like).await.unwrap(); + let after_comment_add = PersonAggregates::read(pool, inserted_person.id) + .await + .unwrap(); assert_eq!(2, after_comment_add.comment_count); assert_eq!(1, after_comment_add.comment_score); - Post::delete(conn, inserted_post.id).unwrap(); - let after_post_delete = PersonAggregates::read(conn, inserted_person.id).unwrap(); + Post::delete(pool, inserted_post.id).await.unwrap(); + let after_post_delete = PersonAggregates::read(pool, inserted_person.id) + .await + .unwrap(); assert_eq!(0, after_post_delete.comment_score); assert_eq!(0, after_post_delete.comment_count); assert_eq!(0, after_post_delete.post_score); assert_eq!(0, after_post_delete.post_count); // This should delete all the associated rows, and fire triggers - let person_num_deleted = Person::delete(conn, inserted_person.id).unwrap(); + let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap(); assert_eq!(1, person_num_deleted); - Person::delete(conn, another_inserted_person.id).unwrap(); + Person::delete(pool, another_inserted_person.id) + .await + .unwrap(); // Delete the community - let community_num_deleted = Community::delete(conn, inserted_community.id).unwrap(); + let community_num_deleted = Community::delete(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(1, community_num_deleted); // Should be none found - let after_delete = PersonAggregates::read(conn, inserted_person.id); + let after_delete = PersonAggregates::read(pool, inserted_person.id).await; assert!(after_delete.is_err()); - Instance::delete(conn, inserted_instance.id).unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); } } diff --git a/crates/db_schema/src/aggregates/person_post_aggregates.rs b/crates/db_schema/src/aggregates/person_post_aggregates.rs index 2d268d4f..5a2fb17d 100644 --- a/crates/db_schema/src/aggregates/person_post_aggregates.rs +++ b/crates/db_schema/src/aggregates/person_post_aggregates.rs @@ -1,27 +1,29 @@ use crate::{ aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm}, + diesel::BoolExpressionMethods, newtypes::{PersonId, PostId}, + schema::person_post_aggregates::dsl::*, + utils::{get_conn, DbPool}, }; -use diesel::{result::Error, *}; +use diesel::{insert_into, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; impl PersonPostAggregates { - pub fn upsert(conn: &mut PgConnection, form: &PersonPostAggregatesForm) -> Result { - use crate::schema::person_post_aggregates::dsl::*; + pub async fn upsert(pool: &DbPool, form: &PersonPostAggregatesForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(person_post_aggregates) .values(form) .on_conflict((person_id, post_id)) .do_update() .set(form) .get_result::(conn) + .await } - pub fn read( - conn: &mut PgConnection, - person_id_: PersonId, - post_id_: PostId, - ) -> Result { - use crate::schema::person_post_aggregates::dsl::*; + pub async fn read(pool: &DbPool, person_id_: PersonId, post_id_: PostId) -> Result { + let conn = &mut get_conn(pool).await?; person_post_aggregates .filter(post_id.eq(post_id_).and(person_id.eq(person_id_))) .first::(conn) + .await } } diff --git a/crates/db_schema/src/aggregates/post_aggregates.rs b/crates/db_schema/src/aggregates/post_aggregates.rs index ac7c0eac..dca5fb82 100644 --- a/crates/db_schema/src/aggregates/post_aggregates.rs +++ b/crates/db_schema/src/aggregates/post_aggregates.rs @@ -1,11 +1,19 @@ -use crate::{aggregates::structs::PostAggregates, newtypes::PostId, schema::post_aggregates}; -use diesel::{result::Error, *}; +use crate::{ + aggregates::structs::PostAggregates, + newtypes::PostId, + schema::post_aggregates, + utils::{get_conn, DbPool}, +}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; impl PostAggregates { - pub fn read(conn: &mut PgConnection, post_id: PostId) -> Result { + pub async fn read(pool: &DbPool, post_id: PostId) -> Result { + let conn = &mut get_conn(pool).await?; post_aggregates::table .filter(post_aggregates::post_id.eq(post_id)) .first::(conn) + .await } } @@ -21,16 +29,16 @@ mod tests { post::{Post, PostInsertForm, PostLike, PostLikeForm}, }, traits::{Crud, Likeable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("thommy_community_agg".into()) @@ -38,7 +46,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let another_person = PersonInsertForm::builder() .name("jerry_community_agg".into()) @@ -46,7 +54,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let another_inserted_person = Person::create(conn, &another_person).unwrap(); + let another_inserted_person = Person::create(pool, &another_person).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("TIL_community_agg".into()) @@ -55,7 +63,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -63,7 +71,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -71,7 +79,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let child_comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -80,7 +88,9 @@ mod tests { .build(); let inserted_child_comment = - Comment::create(conn, &child_comment_form, Some(&inserted_comment.path)).unwrap(); + Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)) + .await + .unwrap(); let post_like = PostLikeForm { post_id: inserted_post.id, @@ -88,9 +98,9 @@ mod tests { score: 1, }; - PostLike::like(conn, &post_like).unwrap(); + PostLike::like(pool, &post_like).await.unwrap(); - let post_aggs_before_delete = PostAggregates::read(conn, inserted_post.id).unwrap(); + let post_aggs_before_delete = PostAggregates::read(pool, inserted_post.id).await.unwrap(); assert_eq!(2, post_aggs_before_delete.comments); assert_eq!(1, post_aggs_before_delete.score); @@ -104,9 +114,9 @@ mod tests { score: -1, }; - PostLike::like(conn, &post_dislike).unwrap(); + PostLike::like(pool, &post_dislike).await.unwrap(); - let post_aggs_after_dislike = PostAggregates::read(conn, inserted_post.id).unwrap(); + let post_aggs_after_dislike = PostAggregates::read(pool, inserted_post.id).await.unwrap(); assert_eq!(2, post_aggs_after_dislike.comments); assert_eq!(0, post_aggs_after_dislike.score); @@ -114,35 +124,43 @@ mod tests { assert_eq!(1, post_aggs_after_dislike.downvotes); // Remove the comments - Comment::delete(conn, inserted_comment.id).unwrap(); - Comment::delete(conn, inserted_child_comment.id).unwrap(); - let after_comment_delete = PostAggregates::read(conn, inserted_post.id).unwrap(); + Comment::delete(pool, inserted_comment.id).await.unwrap(); + Comment::delete(pool, inserted_child_comment.id) + .await + .unwrap(); + let after_comment_delete = PostAggregates::read(pool, inserted_post.id).await.unwrap(); assert_eq!(0, after_comment_delete.comments); assert_eq!(0, after_comment_delete.score); assert_eq!(1, after_comment_delete.upvotes); assert_eq!(1, after_comment_delete.downvotes); // Remove the first post like - PostLike::remove(conn, inserted_person.id, inserted_post.id).unwrap(); - let after_like_remove = PostAggregates::read(conn, inserted_post.id).unwrap(); + PostLike::remove(pool, inserted_person.id, inserted_post.id) + .await + .unwrap(); + let after_like_remove = PostAggregates::read(pool, inserted_post.id).await.unwrap(); assert_eq!(0, after_like_remove.comments); assert_eq!(-1, after_like_remove.score); assert_eq!(0, after_like_remove.upvotes); assert_eq!(1, after_like_remove.downvotes); // This should delete all the associated rows, and fire triggers - Person::delete(conn, another_inserted_person.id).unwrap(); - let person_num_deleted = Person::delete(conn, inserted_person.id).unwrap(); + Person::delete(pool, another_inserted_person.id) + .await + .unwrap(); + let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap(); assert_eq!(1, person_num_deleted); // Delete the community - let community_num_deleted = Community::delete(conn, inserted_community.id).unwrap(); + let community_num_deleted = Community::delete(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(1, community_num_deleted); // Should be none found, since the creator was deleted - let after_delete = PostAggregates::read(conn, inserted_post.id); + let after_delete = PostAggregates::read(pool, inserted_post.id).await; assert!(after_delete.is_err()); - Instance::delete(conn, inserted_instance.id).unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); } } diff --git a/crates/db_schema/src/aggregates/site_aggregates.rs b/crates/db_schema/src/aggregates/site_aggregates.rs index 41e82c95..8b4ccb37 100644 --- a/crates/db_schema/src/aggregates/site_aggregates.rs +++ b/crates/db_schema/src/aggregates/site_aggregates.rs @@ -1,9 +1,15 @@ -use crate::{aggregates::structs::SiteAggregates, schema::site_aggregates}; -use diesel::{result::Error, *}; +use crate::{ + aggregates::structs::SiteAggregates, + schema::site_aggregates, + utils::{get_conn, DbPool}, +}; +use diesel::result::Error; +use diesel_async::RunQueryDsl; impl SiteAggregates { - pub fn read(conn: &mut PgConnection) -> Result { - site_aggregates::table.first::(conn) + pub async fn read(pool: &DbPool) -> Result { + let conn = &mut get_conn(pool).await?; + site_aggregates::table.first::(conn).await } } @@ -20,16 +26,16 @@ mod tests { site::{Site, SiteInsertForm}, }, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("thommy_site_agg".into()) @@ -37,14 +43,14 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let site_form = SiteInsertForm::builder() .name("test_site".into()) .instance_id(inserted_instance.id) .build(); - let inserted_site = Site::create(conn, &site_form).unwrap(); + let inserted_site = Site::create(pool, &site_form).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("TIL_site_agg".into()) @@ -53,7 +59,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -62,8 +68,8 @@ mod tests { .build(); // Insert two of those posts - let inserted_post = Post::create(conn, &new_post).unwrap(); - let _inserted_post_again = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); + let _inserted_post_again = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -72,7 +78,7 @@ mod tests { .build(); // Insert two of those comments - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let child_comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -81,9 +87,11 @@ mod tests { .build(); let _inserted_child_comment = - Comment::create(conn, &child_comment_form, Some(&inserted_comment.path)).unwrap(); + Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)) + .await + .unwrap(); - let site_aggregates_before_delete = SiteAggregates::read(conn).unwrap(); + let site_aggregates_before_delete = SiteAggregates::read(pool).await.unwrap(); // TODO: this is unstable, sometimes it returns 0 users, sometimes 1 //assert_eq!(0, site_aggregates_before_delete.users); @@ -92,27 +100,29 @@ mod tests { assert_eq!(2, site_aggregates_before_delete.comments); // Try a post delete - Post::delete(conn, inserted_post.id).unwrap(); - let site_aggregates_after_post_delete = SiteAggregates::read(conn).unwrap(); + Post::delete(pool, inserted_post.id).await.unwrap(); + let site_aggregates_after_post_delete = SiteAggregates::read(pool).await.unwrap(); assert_eq!(1, site_aggregates_after_post_delete.posts); assert_eq!(0, site_aggregates_after_post_delete.comments); // This shouuld delete all the associated rows, and fire triggers - let person_num_deleted = Person::delete(conn, inserted_person.id).unwrap(); + let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap(); assert_eq!(1, person_num_deleted); // Delete the community - let community_num_deleted = Community::delete(conn, inserted_community.id).unwrap(); + let community_num_deleted = Community::delete(pool, inserted_community.id) + .await + .unwrap(); assert_eq!(1, community_num_deleted); // Site should still exist, it can without a site creator. - let after_delete_creator = SiteAggregates::read(conn); + let after_delete_creator = SiteAggregates::read(pool).await; assert!(after_delete_creator.is_ok()); - Site::delete(conn, inserted_site.id).unwrap(); - let after_delete_site = SiteAggregates::read(conn); + Site::delete(pool, inserted_site.id).await.unwrap(); + let after_delete_site = SiteAggregates::read(pool).await; assert!(after_delete_site.is_err()); - Instance::delete(conn, inserted_instance.id).unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); } } diff --git a/crates/db_schema/src/aggregates/structs.rs b/crates/db_schema/src/aggregates/structs.rs index 0cc4dd05..08d5e914 100644 --- a/crates/db_schema/src/aggregates/structs.rs +++ b/crates/db_schema/src/aggregates/structs.rs @@ -1,4 +1,4 @@ -use crate::newtypes::{CommentId, CommunityId, PersonId, PostId}; +use crate::newtypes::{CommentId, CommunityId, PersonId, PostId, SiteId}; #[cfg(feature = "full")] use crate::schema::{ comment_aggregates, @@ -102,7 +102,7 @@ pub struct PersonPostAggregatesForm { #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::site::Site)))] pub struct SiteAggregates { pub id: i32, - pub site_id: i32, + pub site_id: SiteId, pub users: i64, pub posts: i64, pub comments: i64, diff --git a/crates/db_schema/src/impls/activity.rs b/crates/db_schema/src/impls/activity.rs index c24a66bd..0809ee9c 100644 --- a/crates/db_schema/src/impls/activity.rs +++ b/crates/db_schema/src/impls/activity.rs @@ -1,61 +1,74 @@ -use crate::{newtypes::DbUrl, source::activity::*, traits::Crud}; +use crate::{ + newtypes::DbUrl, + schema::activity::dsl::*, + source::activity::*, + traits::Crud, + utils::{get_conn, DbPool}, +}; use diesel::{ dsl::*, result::{DatabaseErrorKind, Error}, - *, + ExpressionMethods, + QueryDsl, }; +use diesel_async::RunQueryDsl; use serde_json::Value; +#[async_trait] impl Crud for Activity { type InsertForm = ActivityInsertForm; type UpdateForm = ActivityUpdateForm; type IdType = i32; - fn read(conn: &mut PgConnection, activity_id: i32) -> Result { - use crate::schema::activity::dsl::*; - activity.find(activity_id).first::(conn) + async fn read(pool: &DbPool, activity_id: i32) -> Result { + let conn = &mut get_conn(pool).await?; + activity.find(activity_id).first::(conn).await } - fn create(conn: &mut PgConnection, new_activity: &Self::InsertForm) -> Result { - use crate::schema::activity::dsl::*; + async fn create(pool: &DbPool, new_activity: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(activity) .values(new_activity) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, activity_id: i32, new_activity: &Self::UpdateForm, ) -> Result { - use crate::schema::activity::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(activity.find(activity_id)) .set(new_activity) .get_result::(conn) + .await } - fn delete(conn: &mut PgConnection, activity_id: i32) -> Result { - use crate::schema::activity::dsl::*; - diesel::delete(activity.find(activity_id)).execute(conn) + async fn delete(pool: &DbPool, activity_id: i32) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(activity.find(activity_id)) + .execute(conn) + .await } } impl Activity { /// Returns true if the insert was successful // TODO this should probably just be changed to an upsert on_conflict, rather than an error - pub fn insert( - conn: &mut PgConnection, - ap_id: DbUrl, - data: Value, - local: bool, - sensitive: Option, + pub async fn insert( + pool: &DbPool, + ap_id_: DbUrl, + data_: Value, + local_: bool, + sensitive_: Option, ) -> Result { let activity_form = ActivityInsertForm { - ap_id, - data, - local: Some(local), - sensitive, + ap_id: ap_id_, + data: data_, + local: Some(local_), + sensitive: sensitive_, updated: None, }; - match Activity::create(conn, &activity_form) { + match Activity::create(pool, &activity_form).await { Ok(_) => Ok(true), Err(e) => { if let Error::DatabaseError(DatabaseErrorKind::UniqueViolation, _) = e { @@ -66,14 +79,12 @@ impl Activity { } } - pub fn read_from_apub_id(conn: &mut PgConnection, object_id: &DbUrl) -> Result { - use crate::schema::activity::dsl::*; - activity.filter(ap_id.eq(object_id)).first::(conn) - } - - pub fn delete_olds(conn: &mut PgConnection) -> Result { - use crate::schema::activity::dsl::*; - diesel::delete(activity.filter(published.lt(now - 6.months()))).execute(conn) + pub async fn read_from_apub_id(pool: &DbPool, object_id: &DbUrl) -> Result { + let conn = &mut get_conn(pool).await?; + activity + .filter(ap_id.eq(object_id)) + .first::(conn) + .await } } @@ -87,18 +98,18 @@ mod tests { instance::Instance, person::{Person, PersonInsertForm}, }, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serde_json::Value; use serial_test::serial; use url::Url; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let creator_form = PersonInsertForm::builder() .name("activity_creator_ pm".into()) @@ -106,9 +117,9 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_creator = Person::create(conn, &creator_form).unwrap(); + let inserted_creator = Person::create(pool, &creator_form).await.unwrap(); - let ap_id: DbUrl = Url::parse( + let ap_id_: DbUrl = Url::parse( "https://enterprise.lemmy.ml/activities/delete/f1b5d57c-80f8-4e03-a615-688d552e946c", ) .unwrap() @@ -128,17 +139,17 @@ mod tests { ) .unwrap(); let activity_form = ActivityInsertForm { - ap_id: ap_id.clone(), + ap_id: ap_id_.clone(), data: test_json.to_owned(), local: Some(true), sensitive: Some(false), updated: None, }; - let inserted_activity = Activity::create(conn, &activity_form).unwrap(); + let inserted_activity = Activity::create(pool, &activity_form).await.unwrap(); let expected_activity = Activity { - ap_id: ap_id.clone(), + ap_id: ap_id_.clone(), id: inserted_activity.id, data: test_json, local: true, @@ -147,10 +158,10 @@ mod tests { updated: None, }; - let read_activity = Activity::read(conn, inserted_activity.id).unwrap(); - let read_activity_by_apub_id = Activity::read_from_apub_id(conn, &ap_id).unwrap(); - Person::delete(conn, inserted_creator.id).unwrap(); - Activity::delete(conn, inserted_activity.id).unwrap(); + let read_activity = Activity::read(pool, inserted_activity.id).await.unwrap(); + let read_activity_by_apub_id = Activity::read_from_apub_id(pool, &ap_id_).await.unwrap(); + Person::delete(pool, inserted_creator.id).await.unwrap(); + Activity::delete(pool, inserted_activity.id).await.unwrap(); assert_eq!(expected_activity, read_activity); assert_eq!(expected_activity, read_activity_by_apub_id); diff --git a/crates/db_schema/src/impls/actor_language.rs b/crates/db_schema/src/impls/actor_language.rs index 6525a82d..4b8f3e37 100644 --- a/crates/db_schema/src/impls/actor_language.rs +++ b/crates/db_schema/src/impls/actor_language.rs @@ -1,126 +1,157 @@ use crate::{ diesel::JoinOnDsl, newtypes::{CommunityId, InstanceId, LanguageId, LocalUserId, SiteId}, + schema::{local_site, site, site_language}, source::{actor_language::*, language::Language, site::Site}, + utils::{get_conn, DbPool}, }; -use diesel::{ - delete, - dsl::*, - insert_into, - result::Error, - select, - ExpressionMethods, - PgConnection, - QueryDsl, - RunQueryDsl, -}; +use diesel::{delete, dsl::*, insert_into, result::Error, select, ExpressionMethods, QueryDsl}; +use diesel_async::{AsyncPgConnection, RunQueryDsl}; use lemmy_utils::error::LemmyError; -use once_cell::sync::OnceCell; +use tokio::sync::OnceCell; impl LocalUserLanguage { - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, for_local_user_id: LocalUserId, ) -> Result, Error> { use crate::schema::local_user_language::dsl::*; - - let langs = local_user_language - .filter(local_user_id.eq(for_local_user_id)) - .select(language_id) - .get_results(conn)?; - convert_read_languages(conn, langs) + let conn = &mut get_conn(pool).await?; + + conn + .build_transaction() + .run(|conn| { + Box::pin(async move { + let langs = local_user_language + .filter(local_user_id.eq(for_local_user_id)) + .select(language_id) + .get_results(conn) + .await?; + convert_read_languages(conn, langs).await + }) as _ + }) + .await } /// Update the user's languages. /// /// If no language_id vector is given, it will show all languages - pub fn update( - conn: &mut PgConnection, + pub async fn update( + pool: &DbPool, language_ids: Vec, for_local_user_id: LocalUserId, ) -> Result<(), Error> { - conn.build_transaction().read_write().run(|conn| { - use crate::schema::local_user_language::dsl::*; - // Clear the current user languages - delete(local_user_language.filter(local_user_id.eq(for_local_user_id))).execute(conn)?; - - let lang_ids = convert_update_languages(conn, language_ids)?; - for l in lang_ids { - let form = LocalUserLanguageForm { - local_user_id: for_local_user_id, - language_id: l, - }; - insert_into(local_user_language) - .values(form) - .get_result::(conn)?; - } - Ok(()) - }) + let conn = &mut get_conn(pool).await?; + + conn + .build_transaction() + .run(|conn| { + Box::pin(async move { + use crate::schema::local_user_language::dsl::*; + // Clear the current user languages + delete(local_user_language.filter(local_user_id.eq(for_local_user_id))) + .execute(conn) + .await?; + + let lang_ids = convert_update_languages(conn, language_ids).await?; + for l in lang_ids { + let form = LocalUserLanguageForm { + local_user_id: for_local_user_id, + language_id: l, + }; + insert_into(local_user_language) + .values(form) + .get_result::(conn) + .await?; + } + Ok(()) + }) as _ + }) + .await } } impl SiteLanguage { - pub fn read_local(conn: &mut PgConnection) -> Result, Error> { - use crate::schema::{local_site, site, site_language}; + pub async fn read_local(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; site::table .inner_join(local_site::table) .inner_join(site_language::table) .select(site_language::language_id) .load(conn) + .await } - pub fn read(conn: &mut PgConnection, for_site_id: SiteId) -> Result, Error> { - use crate::schema::site_language::dsl::*; - let langs = site_language - .filter(site_id.eq(for_site_id)) - .select(language_id) - .load(conn)?; - convert_read_languages(conn, langs) + pub async fn read(pool: &DbPool, for_site_id: SiteId) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + + let langs = site_language::table + .filter(site_language::site_id.eq(for_site_id)) + .select(site_language::language_id) + .load(conn) + .await?; + convert_read_languages(conn, langs).await } - pub fn update( - conn: &mut PgConnection, + pub async fn update( + pool: &DbPool, language_ids: Vec, site: &Site, ) -> Result<(), Error> { - conn.build_transaction().read_write().run(|conn| { - use crate::schema::site_language::dsl::*; - // Clear the current languages - delete(site_language.filter(site_id.eq(site.id))).execute(conn)?; - - let lang_ids = convert_update_languages(conn, language_ids)?; - for l in lang_ids { - let form = SiteLanguageForm { - site_id: site.id, - language_id: l, - }; - insert_into(site_language) - .values(form) - .get_result::(conn)?; - } - - CommunityLanguage::limit_languages(conn, site.instance_id)?; - - Ok(()) - }) + let conn = &mut get_conn(pool).await?; + let for_site_id = site.id; + let instance_id = site.instance_id; + + conn + .build_transaction() + .run(|conn| { + Box::pin(async move { + use crate::schema::site_language::dsl::*; + + // Clear the current languages + delete(site_language.filter(site_id.eq(for_site_id))) + .execute(conn) + .await?; + + let lang_ids = convert_update_languages(conn, language_ids).await?; + for l in lang_ids { + let form = SiteLanguageForm { + site_id: for_site_id, + language_id: l, + }; + insert_into(site_language) + .values(form) + .get_result::(conn) + .await?; + } + + CommunityLanguage::limit_languages(conn, instance_id).await?; + + Ok(()) + }) as _ + }) + .await } } impl CommunityLanguage { /// Returns true if the given language is one of configured languages for given community - pub fn is_allowed_community_language( - conn: &mut PgConnection, + pub async fn is_allowed_community_language( + pool: &DbPool, for_language_id: Option, for_community_id: CommunityId, ) -> Result<(), LemmyError> { use crate::schema::community_language::dsl::*; + let conn = &mut get_conn(pool).await?; + if let Some(for_language_id) = for_language_id { let is_allowed = select(exists( community_language .filter(language_id.eq(for_language_id)) .filter(community_id.eq(for_community_id)), )) - .get_result(conn)?; + .get_result(conn) + .await?; if is_allowed { Ok(()) @@ -136,7 +167,10 @@ impl CommunityLanguage { /// also part of site languages. This is because post/comment language is only checked against /// community language, and it shouldnt be possible to post content in languages which are not /// allowed by local site. - fn limit_languages(conn: &mut PgConnection, for_instance_id: InstanceId) -> Result<(), Error> { + async fn limit_languages( + conn: &mut AsyncPgConnection, + for_instance_id: InstanceId, + ) -> Result<(), Error> { use crate::schema::{ community::dsl as c, community_language::dsl as cl, @@ -148,65 +182,84 @@ impl CommunityLanguage { .filter(c::instance_id.eq(for_instance_id)) .filter(sl::language_id.is_null()) .select(cl::language_id) - .get_results(conn)?; + .get_results(conn) + .await?; for c in community_languages { - delete(cl::community_language.filter(cl::language_id.eq(c))).execute(conn)?; + delete(cl::community_language.filter(cl::language_id.eq(c))) + .execute(conn) + .await?; } Ok(()) } - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, for_community_id: CommunityId, ) -> Result, Error> { use crate::schema::community_language::dsl::*; + let conn = &mut get_conn(pool).await?; + let langs = community_language .filter(community_id.eq(for_community_id)) .select(language_id) - .get_results(conn)?; - convert_read_languages(conn, langs) + .get_results(conn) + .await?; + convert_read_languages(conn, langs).await } - pub fn update( - conn: &mut PgConnection, + pub async fn update( + pool: &DbPool, mut language_ids: Vec, for_community_id: CommunityId, ) -> Result<(), Error> { - conn.build_transaction().read_write().run(|conn| { - use crate::schema::community_language::dsl::*; - // Clear the current languages - delete(community_language.filter(community_id.eq(for_community_id))).execute(conn)?; + let conn = &mut get_conn(pool).await?; - if language_ids.is_empty() { - language_ids = SiteLanguage::read_local(conn)?; - } - for l in language_ids { - let form = CommunityLanguageForm { - community_id: for_community_id, - language_id: l, - }; - insert_into(community_language) - .values(form) - .get_result::(conn)?; - } - Ok(()) - }) + if language_ids.is_empty() { + language_ids = SiteLanguage::read_local(pool).await?; + } + + conn + .build_transaction() + .run(|conn| { + Box::pin(async move { + use crate::schema::community_language::dsl::*; + // Clear the current languages + delete(community_language.filter(community_id.eq(for_community_id))) + .execute(conn) + .await?; + + for l in language_ids { + let form = CommunityLanguageForm { + community_id: for_community_id, + language_id: l, + }; + insert_into(community_language) + .values(form) + .get_result::(conn) + .await?; + } + Ok(()) + }) as _ + }) + .await } } -pub fn default_post_language( - conn: &mut PgConnection, +pub async fn default_post_language( + pool: &DbPool, community_id: CommunityId, local_user_id: LocalUserId, ) -> Result, Error> { + let conn = &mut get_conn(pool).await?; use crate::schema::{community_language::dsl as cl, local_user_language::dsl as ul}; let intersection = ul::local_user_language .inner_join(cl::community_language.on(ul::language_id.eq(cl::language_id))) .filter(ul::local_user_id.eq(local_user_id)) .filter(cl::community_id.eq(community_id)) .select(cl::language_id) - .get_results::(conn)?; + .get_results::(conn) + .await?; if intersection.len() == 1 { Ok(Some(intersection[0])) @@ -216,13 +269,14 @@ pub fn default_post_language( } /// If no language is given, set all languages -fn convert_update_languages( - conn: &mut PgConnection, +async fn convert_update_languages( + conn: &mut AsyncPgConnection, language_ids: Vec, ) -> Result, Error> { if language_ids.is_empty() { Ok( - Language::read_all(conn)? + Language::read_all_conn(conn) + .await? .into_iter() .map(|l| l.id) .collect(), @@ -233,19 +287,22 @@ fn convert_update_languages( } /// If all languages are returned, return empty vec instead -fn convert_read_languages( - conn: &mut PgConnection, +async fn convert_read_languages( + conn: &mut AsyncPgConnection, language_ids: Vec, ) -> Result, Error> { - static ALL_LANGUAGES_COUNT: OnceCell = OnceCell::new(); - let count = ALL_LANGUAGES_COUNT.get_or_init(|| { - use crate::schema::language::dsl::*; - let count: i64 = language - .select(count(id)) - .first(conn) - .expect("read number of languages"); - count as usize - }); + static ALL_LANGUAGES_COUNT: OnceCell = OnceCell::const_new(); + let count = ALL_LANGUAGES_COUNT + .get_or_init(|| async { + use crate::schema::language::dsl::*; + let count: i64 = language + .select(count(id)) + .first(conn) + .await + .expect("read number of languages"); + count as usize + }) + .await; if &language_ids.len() == count { Ok(vec![]) @@ -267,145 +324,159 @@ mod tests { site::{Site, SiteInsertForm}, }, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - fn test_langs1(conn: &mut PgConnection) -> Vec { + async fn test_langs1(pool: &DbPool) -> Vec { vec![ - Language::read_id_from_code(conn, "en").unwrap(), - Language::read_id_from_code(conn, "fr").unwrap(), - Language::read_id_from_code(conn, "ru").unwrap(), + Language::read_id_from_code(pool, "en").await.unwrap(), + Language::read_id_from_code(pool, "fr").await.unwrap(), + Language::read_id_from_code(pool, "ru").await.unwrap(), ] } - fn test_langs2(conn: &mut PgConnection) -> Vec { + async fn test_langs2(pool: &DbPool) -> Vec { vec![ - Language::read_id_from_code(conn, "fi").unwrap(), - Language::read_id_from_code(conn, "se").unwrap(), + Language::read_id_from_code(pool, "fi").await.unwrap(), + Language::read_id_from_code(pool, "se").await.unwrap(), ] } - fn create_test_site(conn: &mut PgConnection) -> (Site, Instance) { - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + async fn create_test_site(pool: &DbPool) -> (Site, Instance) { + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let site_form = SiteInsertForm::builder() .name("test site".to_string()) .instance_id(inserted_instance.id) .build(); - let site = Site::create(conn, &site_form).unwrap(); + let site = Site::create(pool, &site_form).await.unwrap(); // Create a local site, since this is necessary for local languages let local_site_form = LocalSiteInsertForm::builder().site_id(site.id).build(); - LocalSite::create(conn, &local_site_form).unwrap(); + LocalSite::create(pool, &local_site_form).await.unwrap(); (site, inserted_instance) } - #[test] + #[tokio::test] #[serial] - fn test_convert_update_languages() { - let conn = &mut establish_unpooled_connection(); + async fn test_convert_update_languages() { + let pool = &build_db_pool_for_tests().await; // call with empty vec, returns all languages - let converted1 = convert_update_languages(conn, vec![]).unwrap(); + let conn = &mut get_conn(pool).await.unwrap(); + let converted1 = convert_update_languages(conn, vec![]).await.unwrap(); assert_eq!(184, converted1.len()); // call with nonempty vec, returns same vec - let test_langs = test_langs1(conn); - let converted2 = convert_update_languages(conn, test_langs.clone()).unwrap(); + let test_langs = test_langs1(pool).await; + let converted2 = convert_update_languages(conn, test_langs.clone()) + .await + .unwrap(); assert_eq!(test_langs, converted2); } - #[test] + #[tokio::test] #[serial] - fn test_convert_read_languages() { - let conn = &mut establish_unpooled_connection(); + async fn test_convert_read_languages() { + let pool = &build_db_pool_for_tests().await; // call with all languages, returns empty vec use crate::schema::language::dsl::*; - let all_langs = language.select(id).get_results(conn).unwrap(); - let converted1: Vec = convert_read_languages(conn, all_langs).unwrap(); + let conn = &mut get_conn(pool).await.unwrap(); + let all_langs = language.select(id).get_results(conn).await.unwrap(); + let converted1: Vec = convert_read_languages(conn, all_langs).await.unwrap(); assert_eq!(0, converted1.len()); // call with nonempty vec, returns same vec - let test_langs = test_langs1(conn); - let converted2 = convert_read_languages(conn, test_langs.clone()).unwrap(); + let test_langs = test_langs1(pool).await; + let converted2 = convert_read_languages(conn, test_langs.clone()) + .await + .unwrap(); assert_eq!(test_langs, converted2); } - #[test] + #[tokio::test] #[serial] - fn test_site_languages() { - let conn = &mut establish_unpooled_connection(); + async fn test_site_languages() { + let pool = &build_db_pool_for_tests().await; - let (site, instance) = create_test_site(conn); - let site_languages1 = SiteLanguage::read_local(conn).unwrap(); + let (site, instance) = create_test_site(pool).await; + let site_languages1 = SiteLanguage::read_local(pool).await.unwrap(); // site is created with all languages assert_eq!(184, site_languages1.len()); - let test_langs = test_langs1(conn); - SiteLanguage::update(conn, test_langs.clone(), &site).unwrap(); + let test_langs = test_langs1(pool).await; + SiteLanguage::update(pool, test_langs.clone(), &site) + .await + .unwrap(); - let site_languages2 = SiteLanguage::read_local(conn).unwrap(); + let site_languages2 = SiteLanguage::read_local(pool).await.unwrap(); // after update, site only has new languages assert_eq!(test_langs, site_languages2); - Site::delete(conn, site.id).unwrap(); - Instance::delete(conn, instance.id).unwrap(); - LocalSite::delete(conn).unwrap(); + Site::delete(pool, site.id).await.unwrap(); + Instance::delete(pool, instance.id).await.unwrap(); + LocalSite::delete(pool).await.unwrap(); } - #[test] + #[tokio::test] #[serial] - fn test_user_languages() { - let conn = &mut establish_unpooled_connection(); + async fn test_user_languages() { + let pool = &build_db_pool_for_tests().await; - let (site, instance) = create_test_site(conn); - let test_langs = test_langs1(conn); - SiteLanguage::update(conn, test_langs.clone(), &site).unwrap(); + let (site, instance) = create_test_site(pool).await; + let test_langs = test_langs1(pool).await; + SiteLanguage::update(pool, test_langs.clone(), &site) + .await + .unwrap(); let person_form = PersonInsertForm::builder() .name("my test person".to_string()) .public_key("pubkey".to_string()) .instance_id(instance.id) .build(); - let person = Person::create(conn, &person_form).unwrap(); + let person = Person::create(pool, &person_form).await.unwrap(); let local_user_form = LocalUserInsertForm::builder() .person_id(person.id) .password_encrypted("my_pw".to_string()) .build(); - let local_user = LocalUser::create(conn, &local_user_form).unwrap(); - let local_user_langs1 = LocalUserLanguage::read(conn, local_user.id).unwrap(); + let local_user = LocalUser::create(pool, &local_user_form).await.unwrap(); + let local_user_langs1 = LocalUserLanguage::read(pool, local_user.id).await.unwrap(); // new user should be initialized with site languages assert_eq!(test_langs, local_user_langs1); // update user languages - let test_langs2 = test_langs2(conn); - LocalUserLanguage::update(conn, test_langs2, local_user.id).unwrap(); - let local_user_langs2 = LocalUserLanguage::read(conn, local_user.id).unwrap(); + let test_langs2 = test_langs2(pool).await; + LocalUserLanguage::update(pool, test_langs2, local_user.id) + .await + .unwrap(); + let local_user_langs2 = LocalUserLanguage::read(pool, local_user.id).await.unwrap(); assert_eq!(2, local_user_langs2.len()); - Person::delete(conn, person.id).unwrap(); - LocalUser::delete(conn, local_user.id).unwrap(); - Site::delete(conn, site.id).unwrap(); - LocalSite::delete(conn).unwrap(); - Instance::delete(conn, instance.id).unwrap(); + Person::delete(pool, person.id).await.unwrap(); + LocalUser::delete(pool, local_user.id).await.unwrap(); + Site::delete(pool, site.id).await.unwrap(); + LocalSite::delete(pool).await.unwrap(); + Instance::delete(pool, instance.id).await.unwrap(); } - #[test] + #[tokio::test] #[serial] - fn test_community_languages() { - let conn = &mut establish_unpooled_connection(); - let (site, instance) = create_test_site(conn); - let test_langs = test_langs1(conn); - SiteLanguage::update(conn, test_langs.clone(), &site).unwrap(); - - let read_site_langs = SiteLanguage::read(conn, site.id).unwrap(); + async fn test_community_languages() { + let pool = &build_db_pool_for_tests().await; + let (site, instance) = create_test_site(pool).await; + let test_langs = test_langs1(pool).await; + SiteLanguage::update(pool, test_langs.clone(), &site) + .await + .unwrap(); + + let read_site_langs = SiteLanguage::read(pool, site.id).await.unwrap(); assert_eq!(test_langs, read_site_langs); // Test the local ones are the same - let read_local_site_langs = SiteLanguage::read_local(conn).unwrap(); + let read_local_site_langs = SiteLanguage::read_local(pool).await.unwrap(); assert_eq!(test_langs, read_local_site_langs); let community_form = CommunityInsertForm::builder() @@ -414,45 +485,51 @@ mod tests { .public_key("pubkey".to_string()) .instance_id(instance.id) .build(); - let community = Community::create(conn, &community_form).unwrap(); - let community_langs1 = CommunityLanguage::read(conn, community.id).unwrap(); + let community = Community::create(pool, &community_form).await.unwrap(); + let community_langs1 = CommunityLanguage::read(pool, community.id).await.unwrap(); // community is initialized with site languages assert_eq!(test_langs, community_langs1); let allowed_lang1 = - CommunityLanguage::is_allowed_community_language(conn, Some(test_langs[0]), community.id); + CommunityLanguage::is_allowed_community_language(pool, Some(test_langs[0]), community.id) + .await; assert!(allowed_lang1.is_ok()); - let test_langs2 = test_langs2(conn); + let test_langs2 = test_langs2(pool).await; let allowed_lang2 = - CommunityLanguage::is_allowed_community_language(conn, Some(test_langs2[0]), community.id); + CommunityLanguage::is_allowed_community_language(pool, Some(test_langs2[0]), community.id) + .await; assert!(allowed_lang2.is_err()); // limit site languages to en, fi. after this, community languages should be updated to // intersection of old languages (en, fr, ru) and (en, fi), which is only fi. - SiteLanguage::update(conn, vec![test_langs[0], test_langs2[0]], &site).unwrap(); - let community_langs2 = CommunityLanguage::read(conn, community.id).unwrap(); + SiteLanguage::update(pool, vec![test_langs[0], test_langs2[0]], &site) + .await + .unwrap(); + let community_langs2 = CommunityLanguage::read(pool, community.id).await.unwrap(); assert_eq!(vec![test_langs[0]], community_langs2); // update community languages to different ones - CommunityLanguage::update(conn, test_langs2.clone(), community.id).unwrap(); - let community_langs3 = CommunityLanguage::read(conn, community.id).unwrap(); + CommunityLanguage::update(pool, test_langs2.clone(), community.id) + .await + .unwrap(); + let community_langs3 = CommunityLanguage::read(pool, community.id).await.unwrap(); assert_eq!(test_langs2, community_langs3); - Community::delete(conn, community.id).unwrap(); - Site::delete(conn, site.id).unwrap(); - LocalSite::delete(conn).unwrap(); - Instance::delete(conn, instance.id).unwrap(); + Community::delete(pool, community.id).await.unwrap(); + Site::delete(pool, site.id).await.unwrap(); + LocalSite::delete(pool).await.unwrap(); + Instance::delete(pool, instance.id).await.unwrap(); } - #[test] + #[tokio::test] #[serial] - fn test_default_post_language() { - let conn = &mut establish_unpooled_connection(); - let (site, instance) = create_test_site(conn); - let test_langs = test_langs1(conn); - let test_langs2 = test_langs2(conn); + async fn test_default_post_language() { + let pool = &build_db_pool_for_tests().await; + let (site, instance) = create_test_site(pool).await; + let test_langs = test_langs1(pool).await; + let test_langs2 = test_langs2(pool).await; let community_form = CommunityInsertForm::builder() .name("test community".to_string()) @@ -460,43 +537,53 @@ mod tests { .public_key("pubkey".to_string()) .instance_id(instance.id) .build(); - let community = Community::create(conn, &community_form).unwrap(); - CommunityLanguage::update(conn, test_langs, community.id).unwrap(); + let community = Community::create(pool, &community_form).await.unwrap(); + CommunityLanguage::update(pool, test_langs, community.id) + .await + .unwrap(); let person_form = PersonInsertForm::builder() .name("my test person".to_string()) .public_key("pubkey".to_string()) .instance_id(instance.id) .build(); - let person = Person::create(conn, &person_form).unwrap(); + let person = Person::create(pool, &person_form).await.unwrap(); let local_user_form = LocalUserInsertForm::builder() .person_id(person.id) .password_encrypted("my_pw".to_string()) .build(); - let local_user = LocalUser::create(conn, &local_user_form).unwrap(); - LocalUserLanguage::update(conn, test_langs2, local_user.id).unwrap(); + let local_user = LocalUser::create(pool, &local_user_form).await.unwrap(); + LocalUserLanguage::update(pool, test_langs2, local_user.id) + .await + .unwrap(); // no overlap in user/community languages, so no default language for post - let def1 = default_post_language(conn, community.id, local_user.id).unwrap(); + let def1 = default_post_language(pool, community.id, local_user.id) + .await + .unwrap(); assert_eq!(None, def1); - let ru = Language::read_id_from_code(conn, "ru").unwrap(); + let ru = Language::read_id_from_code(pool, "ru").await.unwrap(); let test_langs3 = vec![ ru, - Language::read_id_from_code(conn, "fi").unwrap(), - Language::read_id_from_code(conn, "se").unwrap(), + Language::read_id_from_code(pool, "fi").await.unwrap(), + Language::read_id_from_code(pool, "se").await.unwrap(), ]; - LocalUserLanguage::update(conn, test_langs3, local_user.id).unwrap(); + LocalUserLanguage::update(pool, test_langs3, local_user.id) + .await + .unwrap(); // this time, both have ru as common lang - let def2 = default_post_language(conn, community.id, local_user.id).unwrap(); + let def2 = default_post_language(pool, community.id, local_user.id) + .await + .unwrap(); assert_eq!(Some(ru), def2); - Person::delete(conn, person.id).unwrap(); - Community::delete(conn, community.id).unwrap(); - LocalUser::delete(conn, local_user.id).unwrap(); - Site::delete(conn, site.id).unwrap(); - LocalSite::delete(conn).unwrap(); - Instance::delete(conn, instance.id).unwrap(); + Person::delete(pool, person.id).await.unwrap(); + Community::delete(pool, community.id).await.unwrap(); + LocalUser::delete(pool, local_user.id).await.unwrap(); + Site::delete(pool, site.id).await.unwrap(); + LocalSite::delete(pool).await.unwrap(); + Instance::delete(pool, instance.id).await.unwrap(); } } diff --git a/crates/db_schema/src/impls/comment.rs b/crates/db_schema/src/impls/comment.rs index d056f1a2..10583203 100644 --- a/crates/db_schema/src/impls/comment.rs +++ b/crates/db_schema/src/impls/comment.rs @@ -1,5 +1,6 @@ use crate::{ newtypes::{CommentId, DbUrl, PersonId}, + schema::comment::dsl::*, source::comment::{ Comment, CommentInsertForm, @@ -10,18 +11,19 @@ use crate::{ CommentUpdateForm, }, traits::{Crud, DeleteableOrRemoveable, Likeable, Saveable}, - utils::naive_now, + utils::{get_conn, naive_now, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use diesel_ltree::Ltree; use url::Url; impl Comment { - pub fn permadelete_for_creator( - conn: &mut PgConnection, + pub async fn permadelete_for_creator( + pool: &DbPool, for_creator_id: PersonId, ) -> Result, Error> { - use crate::schema::comment::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(comment.filter(creator_id.eq(for_creator_id))) .set(( content.eq("*Permananently Deleted*"), @@ -29,25 +31,27 @@ impl Comment { updated.eq(naive_now()), )) .get_results::(conn) + .await } - pub fn update_removed_for_creator( - conn: &mut PgConnection, + pub async fn update_removed_for_creator( + pool: &DbPool, for_creator_id: PersonId, new_removed: bool, ) -> Result, Error> { - use crate::schema::comment::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(comment.filter(creator_id.eq(for_creator_id))) .set((removed.eq(new_removed), updated.eq(naive_now()))) .get_results::(conn) + .await } - pub fn create( - conn: &mut PgConnection, + pub async fn create( + pool: &DbPool, comment_form: &CommentInsertForm, parent_path: Option<&Ltree>, ) -> Result { - use crate::schema::comment::dsl::*; + let conn = &mut get_conn(pool).await?; // Insert, to get the id let inserted_comment = insert_into(comment) @@ -55,7 +59,8 @@ impl Comment { .on_conflict(ap_id) .do_update() .set(comment_form) - .get_result::(conn); + .get_result::(conn) + .await; if let Ok(comment_insert) = inserted_comment { let comment_id = comment_insert.id; @@ -72,7 +77,8 @@ impl Comment { let updated_comment = diesel::update(comment.find(comment_id)) .set(path.eq(ltree)) - .get_result::(conn); + .get_result::(conn) + .await; // Update the child count for the parent comment_aggregates // You could do this with a trigger, but since you have to do this manually anyway, @@ -101,20 +107,21 @@ where ca.comment_id = c.id", top_parent ); - sql_query(update_child_count_stmt).execute(conn)?; + sql_query(update_child_count_stmt).execute(conn).await?; } updated_comment } else { inserted_comment } } - pub fn read_from_apub_id(conn: &mut PgConnection, object_id: Url) -> Result, Error> { - use crate::schema::comment::dsl::*; + pub async fn read_from_apub_id(pool: &DbPool, object_id: Url) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let object_id: DbUrl = object_id.into(); Ok( comment .filter(ap_id.eq(object_id)) .first::(conn) + .await .ok() .map(Into::into), ) @@ -134,86 +141,95 @@ where ca.comment_id = c.id", } } +#[async_trait] impl Crud for Comment { type InsertForm = CommentInsertForm; type UpdateForm = CommentUpdateForm; type IdType = CommentId; - fn read(conn: &mut PgConnection, comment_id: CommentId) -> Result { - use crate::schema::comment::dsl::*; - comment.find(comment_id).first::(conn) + async fn read(pool: &DbPool, comment_id: CommentId) -> Result { + let conn = &mut get_conn(pool).await?; + comment.find(comment_id).first::(conn).await } - fn delete(conn: &mut PgConnection, comment_id: CommentId) -> Result { - use crate::schema::comment::dsl::*; - diesel::delete(comment.find(comment_id)).execute(conn) + async fn delete(pool: &DbPool, comment_id: CommentId) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(comment.find(comment_id)).execute(conn).await } /// This is unimplemented, use [[Comment::create]] - fn create(_conn: &mut PgConnection, _comment_form: &Self::InsertForm) -> Result { + async fn create(_pool: &DbPool, _comment_form: &Self::InsertForm) -> Result { unimplemented!(); } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, comment_id: CommentId, comment_form: &Self::UpdateForm, ) -> Result { - use crate::schema::comment::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(comment.find(comment_id)) .set(comment_form) .get_result::(conn) + .await } } +#[async_trait] impl Likeable for CommentLike { type Form = CommentLikeForm; type IdType = CommentId; - fn like(conn: &mut PgConnection, comment_like_form: &CommentLikeForm) -> Result { + async fn like(pool: &DbPool, comment_like_form: &CommentLikeForm) -> Result { use crate::schema::comment_like::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(comment_like) .values(comment_like_form) .on_conflict((comment_id, person_id)) .do_update() .set(comment_like_form) .get_result::(conn) + .await } - fn remove( - conn: &mut PgConnection, - person_id: PersonId, - comment_id: CommentId, + async fn remove( + pool: &DbPool, + person_id_: PersonId, + comment_id_: CommentId, ) -> Result { - use crate::schema::comment_like::dsl; + use crate::schema::comment_like::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::delete( - dsl::comment_like - .filter(dsl::comment_id.eq(comment_id)) - .filter(dsl::person_id.eq(person_id)), + comment_like + .filter(comment_id.eq(comment_id_)) + .filter(person_id.eq(person_id_)), ) .execute(conn) + .await } } +#[async_trait] impl Saveable for CommentSaved { type Form = CommentSavedForm; - fn save(conn: &mut PgConnection, comment_saved_form: &CommentSavedForm) -> Result { + async fn save(pool: &DbPool, comment_saved_form: &CommentSavedForm) -> Result { use crate::schema::comment_saved::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(comment_saved) .values(comment_saved_form) .on_conflict((comment_id, person_id)) .do_update() .set(comment_saved_form) .get_result::(conn) + .await } - fn unsave( - conn: &mut PgConnection, - comment_saved_form: &CommentSavedForm, - ) -> Result { + async fn unsave(pool: &DbPool, comment_saved_form: &CommentSavedForm) -> Result { use crate::schema::comment_saved::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::delete( comment_saved .filter(comment_id.eq(comment_saved_form.comment_id)) .filter(person_id.eq(comment_saved_form.person_id)), ) .execute(conn) + .await } } @@ -236,17 +252,17 @@ mod tests { post::*, }, traits::{Crud, Likeable, Saveable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use diesel_ltree::Ltree; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("terry".into()) @@ -254,7 +270,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("test community".to_string()) @@ -263,7 +279,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -271,7 +287,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -279,7 +295,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let expected_comment = Comment { id: inserted_comment.id, @@ -304,7 +320,9 @@ mod tests { .build(); let inserted_child_comment = - Comment::create(conn, &child_comment_form, Some(&inserted_comment.path)).unwrap(); + Comment::create(pool, &child_comment_form, Some(&inserted_comment.path)) + .await + .unwrap(); // Comment Like let comment_like_form = CommentLikeForm { @@ -314,7 +332,7 @@ mod tests { score: 1, }; - let inserted_comment_like = CommentLike::like(conn, &comment_like_form).unwrap(); + let inserted_comment_like = CommentLike::like(pool, &comment_like_form).await.unwrap(); let expected_comment_like = CommentLike { id: inserted_comment_like.id, @@ -331,7 +349,7 @@ mod tests { person_id: inserted_person.id, }; - let inserted_comment_saved = CommentSaved::save(conn, &comment_saved_form).unwrap(); + let inserted_comment_saved = CommentSaved::save(pool, &comment_saved_form).await.unwrap(); let expected_comment_saved = CommentSaved { id: inserted_comment_saved.id, @@ -344,17 +362,27 @@ mod tests { .content(Some("A test comment".into())) .build(); - let updated_comment = Comment::update(conn, inserted_comment.id, &comment_update_form).unwrap(); - - let read_comment = Comment::read(conn, inserted_comment.id).unwrap(); - let like_removed = CommentLike::remove(conn, inserted_person.id, inserted_comment.id).unwrap(); - let saved_removed = CommentSaved::unsave(conn, &comment_saved_form).unwrap(); - let num_deleted = Comment::delete(conn, inserted_comment.id).unwrap(); - Comment::delete(conn, inserted_child_comment.id).unwrap(); - Post::delete(conn, inserted_post.id).unwrap(); - Community::delete(conn, inserted_community.id).unwrap(); - Person::delete(conn, inserted_person.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + let updated_comment = Comment::update(pool, inserted_comment.id, &comment_update_form) + .await + .unwrap(); + + let read_comment = Comment::read(pool, inserted_comment.id).await.unwrap(); + let like_removed = CommentLike::remove(pool, inserted_person.id, inserted_comment.id) + .await + .unwrap(); + let saved_removed = CommentSaved::unsave(pool, &comment_saved_form) + .await + .unwrap(); + let num_deleted = Comment::delete(pool, inserted_comment.id).await.unwrap(); + Comment::delete(pool, inserted_child_comment.id) + .await + .unwrap(); + Post::delete(pool, inserted_post.id).await.unwrap(); + Community::delete(pool, inserted_community.id) + .await + .unwrap(); + Person::delete(pool, inserted_person.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_comment, read_comment); assert_eq!(expected_comment, inserted_comment); diff --git a/crates/db_schema/src/impls/comment_reply.rs b/crates/db_schema/src/impls/comment_reply.rs index 84d6fda5..4c7a38d7 100644 --- a/crates/db_schema/src/impls/comment_reply.rs +++ b/crates/db_schema/src/impls/comment_reply.rs @@ -1,21 +1,29 @@ use crate::{ newtypes::{CommentId, CommentReplyId, PersonId}, + schema::comment_reply::dsl::*, source::comment_reply::*, traits::Crud, + utils::{get_conn, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; +#[async_trait] impl Crud for CommentReply { type InsertForm = CommentReplyInsertForm; type UpdateForm = CommentReplyUpdateForm; type IdType = CommentReplyId; - fn read(conn: &mut PgConnection, comment_reply_id: CommentReplyId) -> Result { - use crate::schema::comment_reply::dsl::*; - comment_reply.find(comment_reply_id).first::(conn) + async fn read(pool: &DbPool, comment_reply_id: CommentReplyId) -> Result { + let conn = &mut get_conn(pool).await?; + comment_reply + .find(comment_reply_id) + .first::(conn) + .await } - fn create(conn: &mut PgConnection, comment_reply_form: &Self::InsertForm) -> Result { - use crate::schema::comment_reply::dsl::*; + async fn create(pool: &DbPool, comment_reply_form: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; + // since the return here isnt utilized, we dont need to do an update // but get_result doesnt return the existing row here insert_into(comment_reply) @@ -24,26 +32,28 @@ impl Crud for CommentReply { .do_update() .set(comment_reply_form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, comment_reply_id: CommentReplyId, comment_reply_form: &Self::UpdateForm, ) -> Result { - use crate::schema::comment_reply::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(comment_reply.find(comment_reply_id)) .set(comment_reply_form) .get_result::(conn) + .await } } impl CommentReply { - pub fn mark_all_as_read( - conn: &mut PgConnection, + pub async fn mark_all_as_read( + pool: &DbPool, for_recipient_id: PersonId, ) -> Result, Error> { - use crate::schema::comment_reply::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update( comment_reply .filter(recipient_id.eq(for_recipient_id)) @@ -51,16 +61,15 @@ impl CommentReply { ) .set(read.eq(true)) .get_results::(conn) + .await } - pub fn read_by_comment( - conn: &mut PgConnection, - for_comment_id: CommentId, - ) -> Result { - use crate::schema::comment_reply::dsl::*; + pub async fn read_by_comment(pool: &DbPool, for_comment_id: CommentId) -> Result { + let conn = &mut get_conn(pool).await?; comment_reply .filter(comment_id.eq(for_comment_id)) .first::(conn) + .await } } @@ -76,16 +85,16 @@ mod tests { post::*, }, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("terrylake".into()) @@ -93,7 +102,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let recipient_form = PersonInsertForm::builder() .name("terrylakes recipient".into()) @@ -101,7 +110,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_recipient = Person::create(conn, &recipient_form).unwrap(); + let inserted_recipient = Person::create(pool, &recipient_form).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("test community lake".to_string()) @@ -110,7 +119,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -118,7 +127,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -126,7 +135,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let comment_reply_form = CommentReplyInsertForm { recipient_id: inserted_recipient.id, @@ -134,7 +143,9 @@ mod tests { read: None, }; - let inserted_reply = CommentReply::create(conn, &comment_reply_form).unwrap(); + let inserted_reply = CommentReply::create(pool, &comment_reply_form) + .await + .unwrap(); let expected_reply = CommentReply { id: inserted_reply.id, @@ -144,18 +155,21 @@ mod tests { published: inserted_reply.published, }; - let read_reply = CommentReply::read(conn, inserted_reply.id).unwrap(); + let read_reply = CommentReply::read(pool, inserted_reply.id).await.unwrap(); let comment_reply_update_form = CommentReplyUpdateForm { read: Some(false) }; - let updated_reply = - CommentReply::update(conn, inserted_reply.id, &comment_reply_update_form).unwrap(); - - Comment::delete(conn, inserted_comment.id).unwrap(); - Post::delete(conn, inserted_post.id).unwrap(); - Community::delete(conn, inserted_community.id).unwrap(); - Person::delete(conn, inserted_person.id).unwrap(); - Person::delete(conn, inserted_recipient.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + let updated_reply = CommentReply::update(pool, inserted_reply.id, &comment_reply_update_form) + .await + .unwrap(); + + Comment::delete(pool, inserted_comment.id).await.unwrap(); + Post::delete(pool, inserted_post.id).await.unwrap(); + Community::delete(pool, inserted_community.id) + .await + .unwrap(); + Person::delete(pool, inserted_person.id).await.unwrap(); + Person::delete(pool, inserted_recipient.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_reply, read_reply); assert_eq!(expected_reply, inserted_reply); diff --git a/crates/db_schema/src/impls/comment_report.rs b/crates/db_schema/src/impls/comment_report.rs index ebafddab..b299e951 100644 --- a/crates/db_schema/src/impls/comment_report.rs +++ b/crates/db_schema/src/impls/comment_report.rs @@ -1,11 +1,14 @@ use crate::{ newtypes::{CommentReportId, PersonId}, + schema::comment_report::dsl::*, source::comment_report::{CommentReport, CommentReportForm}, traits::Reportable, - utils::naive_now, + utils::{get_conn, naive_now, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; +#[async_trait] impl Reportable for CommentReport { type Form = CommentReportForm; type IdType = CommentReportId; @@ -13,14 +16,12 @@ impl Reportable for CommentReport { /// /// * `conn` - the postgres connection /// * `comment_report_form` - the filled CommentReportForm to insert - fn report( - conn: &mut PgConnection, - comment_report_form: &CommentReportForm, - ) -> Result { - use crate::schema::comment_report::dsl::*; + async fn report(pool: &DbPool, comment_report_form: &CommentReportForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(comment_report) .values(comment_report_form) .get_result::(conn) + .await } /// resolve a comment report @@ -28,19 +29,20 @@ impl Reportable for CommentReport { /// * `conn` - the postgres connection /// * `report_id` - the id of the report to resolve /// * `by_resolver_id` - the id of the user resolving the report - fn resolve( - conn: &mut PgConnection, - report_id: Self::IdType, + async fn resolve( + pool: &DbPool, + report_id_: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use crate::schema::comment_report::dsl::*; - update(comment_report.find(report_id)) + let conn = &mut get_conn(pool).await?; + update(comment_report.find(report_id_)) .set(( resolved.eq(true), resolver_id.eq(by_resolver_id), updated.eq(naive_now()), )) .execute(conn) + .await } /// unresolve a comment report @@ -48,18 +50,19 @@ impl Reportable for CommentReport { /// * `conn` - the postgres connection /// * `report_id` - the id of the report to unresolve /// * `by_resolver_id` - the id of the user unresolving the report - fn unresolve( - conn: &mut PgConnection, - report_id: Self::IdType, + async fn unresolve( + pool: &DbPool, + report_id_: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use crate::schema::comment_report::dsl::*; - update(comment_report.find(report_id)) + let conn = &mut get_conn(pool).await?; + update(comment_report.find(report_id_)) .set(( resolved.eq(false), resolver_id.eq(by_resolver_id), updated.eq(naive_now()), )) .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/community.rs b/crates/db_schema/src/impls/community.rs index 47c7b0e0..d23baed9 100644 --- a/crates/db_schema/src/impls/community.rs +++ b/crates/db_schema/src/impls/community.rs @@ -1,5 +1,6 @@ use crate::{ newtypes::{CommunityId, DbUrl, PersonId}, + schema::community::dsl::*, source::{ actor_language::{CommunityLanguage, SiteLanguage}, community::{ @@ -16,18 +17,11 @@ use crate::{ }, }, traits::{ApubActor, Bannable, Crud, DeleteableOrRemoveable, Followable, Joinable}, - utils::functions::lower, + utils::{functions::lower, get_conn, DbPool}, SubscribedType, }; -use diesel::{ - dsl::*, - result::Error, - ExpressionMethods, - PgConnection, - QueryDsl, - RunQueryDsl, - TextExpressionMethods, -}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl, TextExpressionMethods}; +use diesel_async::RunQueryDsl; mod safe_type { use crate::{schema::community::*, source::community::Community, traits::ToSafe}; @@ -76,76 +70,86 @@ mod safe_type { } } +#[async_trait] impl Crud for Community { type InsertForm = CommunityInsertForm; type UpdateForm = CommunityUpdateForm; type IdType = CommunityId; - fn read(conn: &mut PgConnection, community_id: CommunityId) -> Result { - use crate::schema::community::dsl::*; - community.find(community_id).first::(conn) + async fn read(pool: &DbPool, community_id: CommunityId) -> Result { + let conn = &mut get_conn(pool).await?; + community.find(community_id).first::(conn).await } - fn delete(conn: &mut PgConnection, community_id: CommunityId) -> Result { - use crate::schema::community::dsl::*; - diesel::delete(community.find(community_id)).execute(conn) + async fn delete(pool: &DbPool, community_id: CommunityId) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(community.find(community_id)) + .execute(conn) + .await } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { - use crate::schema::community::dsl::*; + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; let community_ = insert_into(community) .values(form) .on_conflict(actor_id) .do_update() .set(form) - .get_result::(conn)?; + .get_result::(conn) + .await?; - let site_languages = SiteLanguage::read_local(conn); + let site_languages = SiteLanguage::read_local(pool).await; if let Ok(langs) = site_languages { // if site exists, init user with site languages - CommunityLanguage::update(conn, langs, community_.id)?; + CommunityLanguage::update(pool, langs, community_.id).await?; } else { // otherwise, init with all languages (this only happens during tests) - CommunityLanguage::update(conn, vec![], community_.id)?; + CommunityLanguage::update(pool, vec![], community_.id).await?; } Ok(community_) } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, community_id: CommunityId, form: &Self::UpdateForm, ) -> Result { - use crate::schema::community::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(community.find(community_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Joinable for CommunityModerator { type Form = CommunityModeratorForm; - fn join( - conn: &mut PgConnection, + async fn join( + pool: &DbPool, community_moderator_form: &CommunityModeratorForm, ) -> Result { use crate::schema::community_moderator::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(community_moderator) .values(community_moderator_form) .get_result::(conn) + .await } - fn leave( - conn: &mut PgConnection, + async fn leave( + pool: &DbPool, community_moderator_form: &CommunityModeratorForm, ) -> Result { use crate::schema::community_moderator::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::delete( community_moderator .filter(community_id.eq(community_moderator_form.community_id)) .filter(person_id.eq(community_moderator_form.person_id)), ) .execute(conn) + .await } } @@ -170,52 +174,63 @@ impl DeleteableOrRemoveable for Community { } impl CommunityModerator { - pub fn delete_for_community( - conn: &mut PgConnection, + pub async fn delete_for_community( + pool: &DbPool, for_community_id: CommunityId, ) -> Result { use crate::schema::community_moderator::dsl::*; - diesel::delete(community_moderator.filter(community_id.eq(for_community_id))).execute(conn) + let conn = &mut get_conn(pool).await?; + + diesel::delete(community_moderator.filter(community_id.eq(for_community_id))) + .execute(conn) + .await } - pub fn get_person_moderated_communities( - conn: &mut PgConnection, + pub async fn get_person_moderated_communities( + pool: &DbPool, for_person_id: PersonId, ) -> Result, Error> { use crate::schema::community_moderator::dsl::*; + let conn = &mut get_conn(pool).await?; community_moderator .filter(person_id.eq(for_person_id)) .select(community_id) .load::(conn) + .await } } +#[async_trait] impl Bannable for CommunityPersonBan { type Form = CommunityPersonBanForm; - fn ban( - conn: &mut PgConnection, + async fn ban( + pool: &DbPool, community_person_ban_form: &CommunityPersonBanForm, ) -> Result { use crate::schema::community_person_ban::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(community_person_ban) .values(community_person_ban_form) .on_conflict((community_id, person_id)) .do_update() .set(community_person_ban_form) .get_result::(conn) + .await } - fn unban( - conn: &mut PgConnection, + async fn unban( + pool: &DbPool, community_person_ban_form: &CommunityPersonBanForm, ) -> Result { use crate::schema::community_person_ban::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::delete( community_person_ban .filter(community_id.eq(community_person_ban_form.community_id)) .filter(person_id.eq(community_person_ban_form.person_id)), ) .execute(conn) + .await } } @@ -235,29 +250,30 @@ impl CommunityFollower { } } +#[async_trait] impl Followable for CommunityFollower { type Form = CommunityFollowerForm; - fn follow( - conn: &mut PgConnection, + async fn follow( + pool: &DbPool, community_follower_form: &CommunityFollowerForm, ) -> Result { use crate::schema::community_follower::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(community_follower) .values(community_follower_form) .on_conflict((community_id, person_id)) .do_update() .set(community_follower_form) .get_result::(conn) + .await } - fn follow_accepted( - conn: &mut PgConnection, + async fn follow_accepted( + pool: &DbPool, community_id_: CommunityId, person_id_: PersonId, - ) -> Result - where - Self: Sized, - { + ) -> Result { use crate::schema::community_follower::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update( community_follower .filter(community_id.eq(community_id_)) @@ -265,51 +281,55 @@ impl Followable for CommunityFollower { ) .set(pending.eq(false)) .get_result::(conn) + .await } - fn unfollow( - conn: &mut PgConnection, + async fn unfollow( + pool: &DbPool, community_follower_form: &CommunityFollowerForm, ) -> Result { use crate::schema::community_follower::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::delete( community_follower .filter(community_id.eq(&community_follower_form.community_id)) .filter(person_id.eq(&community_follower_form.person_id)), ) .execute(conn) + .await } // TODO: this function name only makes sense if you call it with a remote community. for a local // community, it will also return true if only remote followers exist - fn has_local_followers( - conn: &mut PgConnection, - community_id_: CommunityId, - ) -> Result { + async fn has_local_followers(pool: &DbPool, community_id_: CommunityId) -> Result { use crate::schema::community_follower::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::select(exists( community_follower.filter(community_id.eq(community_id_)), )) .get_result(conn) + .await } } +#[async_trait] impl ApubActor for Community { - fn read_from_apub_id(conn: &mut PgConnection, object_id: &DbUrl) -> Result, Error> { - use crate::schema::community::dsl::*; + async fn read_from_apub_id(pool: &DbPool, object_id: &DbUrl) -> Result, Error> { + let conn = &mut get_conn(pool).await?; Ok( community .filter(actor_id.eq(object_id)) .first::(conn) + .await .ok() .map(Into::into), ) } - fn read_from_name( - conn: &mut PgConnection, + async fn read_from_name( + pool: &DbPool, community_name: &str, include_deleted: bool, ) -> Result { - use crate::schema::community::dsl::*; + let conn = &mut get_conn(pool).await?; let mut q = community .into_boxed() .filter(local.eq(true)) @@ -317,19 +337,20 @@ impl ApubActor for Community { if !include_deleted { q = q.filter(deleted.eq(false)).filter(removed.eq(false)); } - q.first::(conn) + q.first::(conn).await } - fn read_from_name_and_domain( - conn: &mut PgConnection, + async fn read_from_name_and_domain( + pool: &DbPool, community_name: &str, protocol_domain: &str, ) -> Result { - use crate::schema::community::dsl::*; + let conn = &mut get_conn(pool).await?; community .filter(lower(name).eq(lower(community_name))) .filter(actor_id.like(format!("{}%", protocol_domain))) .first::(conn) + .await } } @@ -338,16 +359,16 @@ mod tests { use crate::{ source::{community::*, instance::Instance, person::*}, traits::{Bannable, Crud, Followable, Joinable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("bobbee".into()) @@ -355,7 +376,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("TIL".into()) @@ -364,7 +385,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let expected_community = Community { id: inserted_community.id, @@ -397,8 +418,9 @@ mod tests { pending: false, }; - let inserted_community_follower = - CommunityFollower::follow(conn, &community_follower_form).unwrap(); + let inserted_community_follower = CommunityFollower::follow(pool, &community_follower_form) + .await + .unwrap(); let expected_community_follower = CommunityFollower { id: inserted_community_follower.id, @@ -413,8 +435,9 @@ mod tests { person_id: inserted_person.id, }; - let inserted_community_moderator = - CommunityModerator::join(conn, &community_moderator_form).unwrap(); + let inserted_community_moderator = CommunityModerator::join(pool, &community_moderator_form) + .await + .unwrap(); let expected_community_moderator = CommunityModerator { id: inserted_community_moderator.id, @@ -429,8 +452,9 @@ mod tests { expires: None, }; - let inserted_community_person_ban = - CommunityPersonBan::ban(conn, &community_person_ban_form).unwrap(); + let inserted_community_person_ban = CommunityPersonBan::ban(pool, &community_person_ban_form) + .await + .unwrap(); let expected_community_person_ban = CommunityPersonBan { id: inserted_community_person_ban.id, @@ -440,20 +464,29 @@ mod tests { expires: None, }; - let read_community = Community::read(conn, inserted_community.id).unwrap(); + let read_community = Community::read(pool, inserted_community.id).await.unwrap(); let update_community_form = CommunityUpdateForm::builder() .title(Some("nada".to_owned())) .build(); - let updated_community = - Community::update(conn, inserted_community.id, &update_community_form).unwrap(); - - let ignored_community = CommunityFollower::unfollow(conn, &community_follower_form).unwrap(); - let left_community = CommunityModerator::leave(conn, &community_moderator_form).unwrap(); - let unban = CommunityPersonBan::unban(conn, &community_person_ban_form).unwrap(); - let num_deleted = Community::delete(conn, inserted_community.id).unwrap(); - Person::delete(conn, inserted_person.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + let updated_community = Community::update(pool, inserted_community.id, &update_community_form) + .await + .unwrap(); + + let ignored_community = CommunityFollower::unfollow(pool, &community_follower_form) + .await + .unwrap(); + let left_community = CommunityModerator::leave(pool, &community_moderator_form) + .await + .unwrap(); + let unban = CommunityPersonBan::unban(pool, &community_person_ban_form) + .await + .unwrap(); + let num_deleted = Community::delete(pool, inserted_community.id) + .await + .unwrap(); + Person::delete(pool, inserted_person.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_community, read_community); assert_eq!(expected_community, inserted_community); diff --git a/crates/db_schema/src/impls/community_block.rs b/crates/db_schema/src/impls/community_block.rs index 49a86173..9e7d5ffa 100644 --- a/crates/db_schema/src/impls/community_block.rs +++ b/crates/db_schema/src/impls/community_block.rs @@ -1,27 +1,33 @@ use crate::{ + schema::community_block::dsl::*, source::community_block::{CommunityBlock, CommunityBlockForm}, traits::Blockable, + utils::{get_conn, DbPool}, }; use diesel::{dsl::*, result::Error, *}; +use diesel_async::RunQueryDsl; +#[async_trait] impl Blockable for CommunityBlock { type Form = CommunityBlockForm; - fn block(conn: &mut PgConnection, community_block_form: &Self::Form) -> Result { - use crate::schema::community_block::dsl::*; + async fn block(pool: &DbPool, community_block_form: &Self::Form) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(community_block) .values(community_block_form) .on_conflict((person_id, community_id)) .do_update() .set(community_block_form) .get_result::(conn) + .await } - fn unblock(conn: &mut PgConnection, community_block_form: &Self::Form) -> Result { - use crate::schema::community_block::dsl::*; + async fn unblock(pool: &DbPool, community_block_form: &Self::Form) -> Result { + let conn = &mut get_conn(pool).await?; diesel::delete( community_block .filter(person_id.eq(community_block_form.person_id)) .filter(community_id.eq(community_block_form.community_id)), ) .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/email_verification.rs b/crates/db_schema/src/impls/email_verification.rs index c6140f4b..5bd57417 100644 --- a/crates/db_schema/src/impls/email_verification.rs +++ b/crates/db_schema/src/impls/email_verification.rs @@ -1,34 +1,36 @@ -use crate::{newtypes::LocalUserId, source::email_verification::*}; -use diesel::{ - dsl::*, - insert_into, - result::Error, - ExpressionMethods, - PgConnection, - QueryDsl, - RunQueryDsl, +use crate::{ + newtypes::LocalUserId, + schema::email_verification::dsl::*, + source::email_verification::*, + utils::{get_conn, DbPool}, }; +use diesel::{dsl::*, insert_into, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; impl EmailVerification { - pub fn create(conn: &mut PgConnection, form: &EmailVerificationForm) -> Result { - use crate::schema::email_verification::dsl::*; + pub async fn create(pool: &DbPool, form: &EmailVerificationForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(email_verification) .values(form) .get_result::(conn) + .await } - pub fn read_for_token(conn: &mut PgConnection, token: &str) -> Result { - use crate::schema::email_verification::dsl::*; + pub async fn read_for_token(pool: &DbPool, token: &str) -> Result { + let conn = &mut get_conn(pool).await?; email_verification .filter(verification_token.eq(token)) .filter(published.gt(now - 7.days())) .first::(conn) + .await } - pub fn delete_old_tokens_for_local_user( - conn: &mut PgConnection, + pub async fn delete_old_tokens_for_local_user( + pool: &DbPool, local_user_id_: LocalUserId, ) -> Result { - use crate::schema::email_verification::dsl::*; - diesel::delete(email_verification.filter(local_user_id.eq(local_user_id_))).execute(conn) + let conn = &mut get_conn(pool).await?; + diesel::delete(email_verification.filter(local_user_id.eq(local_user_id_))) + .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/federation_allowlist.rs b/crates/db_schema/src/impls/federation_allowlist.rs index 406b0e2c..29b4d01f 100644 --- a/crates/db_schema/src/impls/federation_allowlist.rs +++ b/crates/db_schema/src/impls/federation_allowlist.rs @@ -4,59 +4,70 @@ use crate::{ federation_allowlist::{FederationAllowList, FederationAllowListForm}, instance::Instance, }, + utils::{get_conn, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error}; +use diesel_async::{AsyncPgConnection, RunQueryDsl}; impl FederationAllowList { - pub fn replace(conn: &mut PgConnection, list_opt: Option>) -> Result<(), Error> { - conn.build_transaction().read_write().run(|conn| { - if let Some(list) = list_opt { - Self::clear(conn)?; + pub async fn replace(pool: &DbPool, list_opt: Option>) -> Result<(), Error> { + let conn = &mut get_conn(pool).await?; + conn + .build_transaction() + .run(|conn| { + Box::pin(async move { + if let Some(list) = list_opt { + Self::clear(conn).await?; - for domain in list { - // Upsert all of these as instances - let instance = Instance::create(conn, &domain)?; + for domain in list { + // Upsert all of these as instances + let instance = Instance::create_conn(conn, &domain).await?; - let form = FederationAllowListForm { - instance_id: instance.id, - updated: None, - }; - insert_into(federation_allowlist::table) - .values(form) - .get_result::(conn)?; - } - Ok(()) - } else { - Ok(()) - } - }) + let form = FederationAllowListForm { + instance_id: instance.id, + updated: None, + }; + insert_into(federation_allowlist::table) + .values(form) + .get_result::(conn) + .await?; + } + Ok(()) + } else { + Ok(()) + } + }) as _ + }) + .await } - pub fn clear(conn: &mut PgConnection) -> Result { - diesel::delete(federation_allowlist::table).execute(conn) + async fn clear(conn: &mut AsyncPgConnection) -> Result { + diesel::delete(federation_allowlist::table) + .execute(conn) + .await } } #[cfg(test)] mod tests { use crate::{ source::{federation_allowlist::FederationAllowList, instance::Instance}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_allowlist_insert_and_clear() { - let conn = &mut establish_unpooled_connection(); + async fn test_allowlist_insert_and_clear() { + let pool = &build_db_pool_for_tests().await; let allowed = Some(vec![ "tld1.xyz".to_string(), "tld2.xyz".to_string(), "tld3.xyz".to_string(), ]); - FederationAllowList::replace(conn, allowed).unwrap(); + FederationAllowList::replace(pool, allowed).await.unwrap(); - let allows = Instance::allowlist(conn).unwrap(); + let allows = Instance::allowlist(pool).await.unwrap(); assert_eq!(3, allows.len()); assert_eq!( @@ -71,11 +82,13 @@ mod tests { // Now test clearing them via Some(empty vec) let clear_allows = Some(Vec::new()); - FederationAllowList::replace(conn, clear_allows).unwrap(); - let allows = Instance::allowlist(conn).unwrap(); + FederationAllowList::replace(pool, clear_allows) + .await + .unwrap(); + let allows = Instance::allowlist(pool).await.unwrap(); assert_eq!(0, allows.len()); - Instance::delete_all(conn).unwrap(); + Instance::delete_all(pool).await.unwrap(); } } diff --git a/crates/db_schema/src/impls/federation_blocklist.rs b/crates/db_schema/src/impls/federation_blocklist.rs index 58ea4e91..0dd02405 100644 --- a/crates/db_schema/src/impls/federation_blocklist.rs +++ b/crates/db_schema/src/impls/federation_blocklist.rs @@ -4,35 +4,46 @@ use crate::{ federation_blocklist::{FederationBlockList, FederationBlockListForm}, instance::Instance, }, + utils::{get_conn, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error}; +use diesel_async::{AsyncPgConnection, RunQueryDsl}; impl FederationBlockList { - pub fn replace(conn: &mut PgConnection, list_opt: Option>) -> Result<(), Error> { - conn.build_transaction().read_write().run(|conn| { - if let Some(list) = list_opt { - Self::clear(conn)?; + pub async fn replace(pool: &DbPool, list_opt: Option>) -> Result<(), Error> { + let conn = &mut get_conn(pool).await?; + conn + .build_transaction() + .run(|conn| { + Box::pin(async move { + if let Some(list) = list_opt { + Self::clear(conn).await?; - for domain in list { - // Upsert all of these as instances - let instance = Instance::create(conn, &domain)?; + for domain in list { + // Upsert all of these as instances + let instance = Instance::create_conn(conn, &domain).await?; - let form = FederationBlockListForm { - instance_id: instance.id, - updated: None, - }; - insert_into(federation_blocklist::table) - .values(form) - .get_result::(conn)?; - } - Ok(()) - } else { - Ok(()) - } - }) + let form = FederationBlockListForm { + instance_id: instance.id, + updated: None, + }; + insert_into(federation_blocklist::table) + .values(form) + .get_result::(conn) + .await?; + } + Ok(()) + } else { + Ok(()) + } + }) as _ + }) + .await } - pub fn clear(conn: &mut PgConnection) -> Result { - diesel::delete(federation_blocklist::table).execute(conn) + async fn clear(conn: &mut AsyncPgConnection) -> Result { + diesel::delete(federation_blocklist::table) + .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/instance.rs b/crates/db_schema/src/impls/instance.rs index c2afa6ae..716d638e 100644 --- a/crates/db_schema/src/impls/instance.rs +++ b/crates/db_schema/src/impls/instance.rs @@ -2,14 +2,18 @@ use crate::{ newtypes::InstanceId, schema::{federation_allowlist, federation_blocklist, instance}, source::instance::{Instance, InstanceForm}, - utils::naive_now, + utils::{get_conn, naive_now, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::{AsyncPgConnection, RunQueryDsl}; use lemmy_utils::utils::generate_domain_url; use url::Url; impl Instance { - fn create_from_form(conn: &mut PgConnection, form: &InstanceForm) -> Result { + async fn create_from_form_conn( + conn: &mut AsyncPgConnection, + form: &InstanceForm, + ) -> Result { // Do upsert on domain name conflict insert_into(instance::table) .values(form) @@ -17,43 +21,58 @@ impl Instance { .do_update() .set(form) .get_result::(conn) + .await } - pub fn create(conn: &mut PgConnection, domain: &str) -> Result { + pub async fn create(pool: &DbPool, domain: &str) -> Result { + let conn = &mut get_conn(pool).await?; + Self::create_conn(conn, domain).await + } + pub async fn create_from_actor_id(pool: &DbPool, actor_id: &Url) -> Result { + let domain = &generate_domain_url(actor_id).expect("actor id missing a domain"); + Self::create(pool, domain).await + } + pub async fn create_conn(conn: &mut AsyncPgConnection, domain: &str) -> Result { let form = InstanceForm { domain: domain.to_string(), updated: Some(naive_now()), }; - Self::create_from_form(conn, &form) - } - pub fn create_from_actor_id(conn: &mut PgConnection, actor_id: &Url) -> Result { - let domain = &generate_domain_url(actor_id).expect("actor id missing a domain"); - Self::create(conn, domain) + Self::create_from_form_conn(conn, &form).await } - pub fn delete(conn: &mut PgConnection, instance_id: InstanceId) -> Result { - diesel::delete(instance::table.find(instance_id)).execute(conn) + pub async fn delete(pool: &DbPool, instance_id: InstanceId) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(instance::table.find(instance_id)) + .execute(conn) + .await } - pub fn delete_all(conn: &mut PgConnection) -> Result { - diesel::delete(instance::table).execute(conn) + pub async fn delete_all(pool: &DbPool) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(instance::table).execute(conn).await } - pub fn allowlist(conn: &mut PgConnection) -> Result, Error> { + pub async fn allowlist(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; instance::table .inner_join(federation_allowlist::table) .select(instance::domain) .load::(conn) + .await } - pub fn blocklist(conn: &mut PgConnection) -> Result, Error> { + pub async fn blocklist(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; instance::table .inner_join(federation_blocklist::table) .select(instance::domain) .load::(conn) + .await } - pub fn linked(conn: &mut PgConnection) -> Result, Error> { + pub async fn linked(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; instance::table .left_join(federation_blocklist::table) .filter(federation_blocklist::id.is_null()) .select(instance::domain) .load::(conn) + .await } } diff --git a/crates/db_schema/src/impls/language.rs b/crates/db_schema/src/impls/language.rs index a56c26d7..9da5663e 100644 --- a/crates/db_schema/src/impls/language.rs +++ b/crates/db_schema/src/impls/language.rs @@ -1,28 +1,45 @@ -use crate::{diesel::ExpressionMethods, newtypes::LanguageId, source::language::Language}; -use diesel::{result::Error, PgConnection, QueryDsl, RunQueryDsl}; +use crate::{ + diesel::ExpressionMethods, + newtypes::LanguageId, + schema::language::dsl::*, + source::language::Language, + utils::{get_conn, DbPool}, +}; +use diesel::{result::Error, QueryDsl}; +use diesel_async::{AsyncPgConnection, RunQueryDsl}; impl Language { - pub fn read_all(conn: &mut PgConnection) -> Result, Error> { - use crate::schema::language::dsl::*; - language.load::(conn) + pub async fn read_all(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + Self::read_all_conn(conn).await } - pub fn read_from_id(conn: &mut PgConnection, id_: LanguageId) -> Result { - use crate::schema::language::dsl::*; - language.filter(id.eq(id_)).first::(conn) + pub async fn read_all_conn(conn: &mut AsyncPgConnection) -> Result, Error> { + language.load::(conn).await } - pub fn read_id_from_code(conn: &mut PgConnection, code_: &str) -> Result { - use crate::schema::language::dsl::*; - Ok(language.filter(code.eq(code_)).first::(conn)?.id) + pub async fn read_from_id(pool: &DbPool, id_: LanguageId) -> Result { + let conn = &mut get_conn(pool).await?; + language.filter(id.eq(id_)).first::(conn).await } - pub fn read_id_from_code_opt( - conn: &mut PgConnection, + pub async fn read_id_from_code(pool: &DbPool, code_: &str) -> Result { + let conn = &mut get_conn(pool).await?; + Ok( + language + .filter(code.eq(code_)) + .first::(conn) + .await? + .id, + ) + } + + pub async fn read_id_from_code_opt( + pool: &DbPool, code_: Option<&str>, ) -> Result, Error> { if let Some(code_) = code_ { - Ok(Some(Language::read_id_from_code(conn, code_)?)) + Ok(Some(Language::read_id_from_code(pool, code_).await?)) } else { Ok(None) } @@ -31,15 +48,15 @@ impl Language { #[cfg(test)] mod tests { - use crate::{source::language::Language, utils::establish_unpooled_connection}; + use crate::{source::language::Language, utils::build_db_pool_for_tests}; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_languages() { - let conn = &mut establish_unpooled_connection(); + async fn test_languages() { + let pool = &build_db_pool_for_tests().await; - let all = Language::read_all(conn).unwrap(); + let all = Language::read_all(pool).await.unwrap(); assert_eq!(184, all.len()); assert_eq!("ak", all[5].code); diff --git a/crates/db_schema/src/impls/local_site.rs b/crates/db_schema/src/impls/local_site.rs index 4686ac80..4c6712cb 100644 --- a/crates/db_schema/src/impls/local_site.rs +++ b/crates/db_schema/src/impls/local_site.rs @@ -1,21 +1,32 @@ -use crate::{schema::local_site::dsl::*, source::local_site::*}; -use diesel::{dsl::*, result::Error, *}; +use crate::{ + schema::local_site::dsl::*, + source::local_site::*, + utils::{get_conn, DbPool}, +}; +use diesel::{dsl::*, result::Error}; +use diesel_async::RunQueryDsl; impl LocalSite { - pub fn create(conn: &mut PgConnection, form: &LocalSiteInsertForm) -> Result { + pub async fn create(pool: &DbPool, form: &LocalSiteInsertForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(local_site) .values(form) .get_result::(conn) + .await } - pub fn read(conn: &mut PgConnection) -> Result { - local_site.first::(conn) + pub async fn read(pool: &DbPool) -> Result { + let conn = &mut get_conn(pool).await?; + local_site.first::(conn).await } - pub fn update(conn: &mut PgConnection, form: &LocalSiteUpdateForm) -> Result { + pub async fn update(pool: &DbPool, form: &LocalSiteUpdateForm) -> Result { + let conn = &mut get_conn(pool).await?; diesel::update(local_site) .set(form) .get_result::(conn) + .await } - pub fn delete(conn: &mut PgConnection) -> Result { - diesel::delete(local_site).execute(conn) + pub async fn delete(pool: &DbPool) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(local_site).execute(conn).await } } diff --git a/crates/db_schema/src/impls/local_site_rate_limit.rs b/crates/db_schema/src/impls/local_site_rate_limit.rs index 55ab3984..6c467781 100644 --- a/crates/db_schema/src/impls/local_site_rate_limit.rs +++ b/crates/db_schema/src/impls/local_site_rate_limit.rs @@ -1,25 +1,29 @@ -use crate::{schema::local_site_rate_limit, source::local_site_rate_limit::*}; -use diesel::{dsl::*, result::Error, *}; +use crate::{ + schema::local_site_rate_limit, + source::local_site_rate_limit::*, + utils::{get_conn, DbPool}, +}; +use diesel::{dsl::*, result::Error}; +use diesel_async::RunQueryDsl; impl LocalSiteRateLimit { - pub fn read(conn: &mut PgConnection) -> Result { - local_site_rate_limit::table.first::(conn) + pub async fn read(pool: &DbPool) -> Result { + let conn = &mut get_conn(pool).await?; + local_site_rate_limit::table.first::(conn).await } - pub fn create( - conn: &mut PgConnection, - form: &LocalSiteRateLimitInsertForm, - ) -> Result { + pub async fn create(pool: &DbPool, form: &LocalSiteRateLimitInsertForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(local_site_rate_limit::table) .values(form) .get_result::(conn) + .await } - pub fn update( - conn: &mut PgConnection, - form: &LocalSiteRateLimitUpdateForm, - ) -> Result { + pub async fn update(pool: &DbPool, form: &LocalSiteRateLimitUpdateForm) -> Result { + let conn = &mut get_conn(pool).await?; diesel::update(local_site_rate_limit::table) .set(form) .get_result::(conn) + .await } } diff --git a/crates/db_schema/src/impls/local_user.rs b/crates/db_schema/src/impls/local_user.rs index 9f2c1c3c..eb36fce6 100644 --- a/crates/db_schema/src/impls/local_user.rs +++ b/crates/db_schema/src/impls/local_user.rs @@ -6,10 +6,11 @@ use crate::{ local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm}, }, traits::Crud, - utils::naive_now, + utils::{get_conn, naive_now, DbPool}, }; use bcrypt::{hash, DEFAULT_COST}; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; mod safe_settings_type { use crate::{ @@ -67,11 +68,12 @@ mod safe_settings_type { } impl LocalUser { - pub fn update_password( - conn: &mut PgConnection, + pub async fn update_password( + pool: &DbPool, local_user_id: LocalUserId, new_password: &str, ) -> Result { + let conn = &mut get_conn(pool).await?; let password_hash = hash(new_password, DEFAULT_COST).expect("Couldn't hash password"); diesel::update(local_user.find(local_user_id)) @@ -80,34 +82,45 @@ impl LocalUser { validator_time.eq(naive_now()), )) .get_result::(conn) + .await } - pub fn set_all_users_email_verified(conn: &mut PgConnection) -> Result, Error> { + pub async fn set_all_users_email_verified(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; diesel::update(local_user) .set(email_verified.eq(true)) .get_results::(conn) + .await } - pub fn set_all_users_registration_applications_accepted( - conn: &mut PgConnection, + pub async fn set_all_users_registration_applications_accepted( + pool: &DbPool, ) -> Result, Error> { + let conn = &mut get_conn(pool).await?; diesel::update(local_user) .set(accepted_application.eq(true)) .get_results::(conn) + .await } } +#[async_trait] impl Crud for LocalUser { type InsertForm = LocalUserInsertForm; type UpdateForm = LocalUserUpdateForm; type IdType = LocalUserId; - fn read(conn: &mut PgConnection, local_user_id: LocalUserId) -> Result { - local_user.find(local_user_id).first::(conn) + async fn read(pool: &DbPool, local_user_id: LocalUserId) -> Result { + let conn = &mut get_conn(pool).await?; + local_user.find(local_user_id).first::(conn).await } - fn delete(conn: &mut PgConnection, local_user_id: LocalUserId) -> Result { - diesel::delete(local_user.find(local_user_id)).execute(conn) + async fn delete(pool: &DbPool, local_user_id: LocalUserId) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(local_user.find(local_user_id)) + .execute(conn) + .await } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; let mut form_with_encrypted_password = form.clone(); let password_hash = hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password"); @@ -115,27 +128,31 @@ impl Crud for LocalUser { let local_user_ = insert_into(local_user) .values(form_with_encrypted_password) - .get_result::(conn)?; + .get_result::(conn) + .await + .expect("couldnt create local user"); - let site_languages = SiteLanguage::read_local(conn); + let site_languages = SiteLanguage::read_local(pool).await; if let Ok(langs) = site_languages { // if site exists, init user with site languages - LocalUserLanguage::update(conn, langs, local_user_.id)?; + LocalUserLanguage::update(pool, langs, local_user_.id).await?; } else { // otherwise, init with all languages (this only happens during tests and // for first admin user, which is created before site) - LocalUserLanguage::update(conn, vec![], local_user_.id)?; + LocalUserLanguage::update(pool, vec![], local_user_.id).await?; } Ok(local_user_) } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, local_user_id: LocalUserId, form: &Self::UpdateForm, ) -> Result { + let conn = &mut get_conn(pool).await?; diesel::update(local_user.find(local_user_id)) .set(form) .get_result::(conn) + .await } } diff --git a/crates/db_schema/src/impls/moderator.rs b/crates/db_schema/src/impls/moderator.rs index 824001de..c9d5a94f 100644 --- a/crates/db_schema/src/impls/moderator.rs +++ b/crates/db_schema/src/impls/moderator.rs @@ -1,394 +1,480 @@ -use crate::{source::moderator::*, traits::Crud}; -use diesel::{dsl::*, result::Error, *}; - -// TODO grep for ..xxxDefault() - +use crate::{ + source::moderator::*, + traits::Crud, + utils::{get_conn, DbPool}, +}; +use diesel::{dsl::*, result::Error, QueryDsl}; +use diesel_async::RunQueryDsl; + +#[async_trait] impl Crud for ModRemovePost { type InsertForm = ModRemovePostForm; type UpdateForm = ModRemovePostForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_remove_post::dsl::*; - mod_remove_post.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_remove_post.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModRemovePostForm) -> Result { + async fn create(pool: &DbPool, form: &ModRemovePostForm) -> Result { use crate::schema::mod_remove_post::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_remove_post) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, - from_id: i32, - form: &ModRemovePostForm, - ) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &ModRemovePostForm) -> Result { use crate::schema::mod_remove_post::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_remove_post.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModLockPost { type InsertForm = ModLockPostForm; type UpdateForm = ModLockPostForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_lock_post::dsl::*; - mod_lock_post.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_lock_post.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModLockPostForm) -> Result { + async fn create(pool: &DbPool, form: &ModLockPostForm) -> Result { use crate::schema::mod_lock_post::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_lock_post) .values(form) .get_result::(conn) + .await } - fn update(conn: &mut PgConnection, from_id: i32, form: &ModLockPostForm) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &ModLockPostForm) -> Result { use crate::schema::mod_lock_post::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_lock_post.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModStickyPost { type InsertForm = ModStickyPostForm; type UpdateForm = ModStickyPostForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_sticky_post::dsl::*; - mod_sticky_post.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_sticky_post.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModStickyPostForm) -> Result { + async fn create(pool: &DbPool, form: &ModStickyPostForm) -> Result { use crate::schema::mod_sticky_post::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_sticky_post) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, - from_id: i32, - form: &ModStickyPostForm, - ) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &ModStickyPostForm) -> Result { use crate::schema::mod_sticky_post::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_sticky_post.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModRemoveComment { type InsertForm = ModRemoveCommentForm; type UpdateForm = ModRemoveCommentForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_remove_comment::dsl::*; - mod_remove_comment.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_remove_comment.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModRemoveCommentForm) -> Result { + async fn create(pool: &DbPool, form: &ModRemoveCommentForm) -> Result { use crate::schema::mod_remove_comment::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_remove_comment) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, - from_id: i32, - form: &ModRemoveCommentForm, - ) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &ModRemoveCommentForm) -> Result { use crate::schema::mod_remove_comment::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_remove_comment.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModRemoveCommunity { type InsertForm = ModRemoveCommunityForm; type UpdateForm = ModRemoveCommunityForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_remove_community::dsl::*; - mod_remove_community.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_remove_community.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModRemoveCommunityForm) -> Result { + async fn create(pool: &DbPool, form: &ModRemoveCommunityForm) -> Result { use crate::schema::mod_remove_community::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_remove_community) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, from_id: i32, form: &ModRemoveCommunityForm, ) -> Result { use crate::schema::mod_remove_community::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_remove_community.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModBanFromCommunity { type InsertForm = ModBanFromCommunityForm; type UpdateForm = ModBanFromCommunityForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_ban_from_community::dsl::*; - mod_ban_from_community.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_ban_from_community + .find(from_id) + .first::(conn) + .await } - fn create(conn: &mut PgConnection, form: &ModBanFromCommunityForm) -> Result { + async fn create(pool: &DbPool, form: &ModBanFromCommunityForm) -> Result { use crate::schema::mod_ban_from_community::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_ban_from_community) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, from_id: i32, form: &ModBanFromCommunityForm, ) -> Result { use crate::schema::mod_ban_from_community::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_ban_from_community.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModBan { type InsertForm = ModBanForm; type UpdateForm = ModBanForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_ban::dsl::*; - mod_ban.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_ban.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModBanForm) -> Result { + async fn create(pool: &DbPool, form: &ModBanForm) -> Result { use crate::schema::mod_ban::dsl::*; - insert_into(mod_ban).values(form).get_result::(conn) + let conn = &mut get_conn(pool).await?; + insert_into(mod_ban) + .values(form) + .get_result::(conn) + .await } - fn update(conn: &mut PgConnection, from_id: i32, form: &ModBanForm) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &ModBanForm) -> Result { use crate::schema::mod_ban::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_ban.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModHideCommunity { type InsertForm = ModHideCommunityForm; type UpdateForm = ModHideCommunityForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_hide_community::dsl::*; - mod_hide_community.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_hide_community.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModHideCommunityForm) -> Result { + async fn create(pool: &DbPool, form: &ModHideCommunityForm) -> Result { use crate::schema::mod_hide_community::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_hide_community) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, - from_id: i32, - form: &ModHideCommunityForm, - ) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &ModHideCommunityForm) -> Result { use crate::schema::mod_hide_community::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_hide_community.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModAddCommunity { type InsertForm = ModAddCommunityForm; type UpdateForm = ModAddCommunityForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_add_community::dsl::*; - mod_add_community.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_add_community.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModAddCommunityForm) -> Result { + async fn create(pool: &DbPool, form: &ModAddCommunityForm) -> Result { use crate::schema::mod_add_community::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_add_community) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, - from_id: i32, - form: &ModAddCommunityForm, - ) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &ModAddCommunityForm) -> Result { use crate::schema::mod_add_community::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_add_community.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModTransferCommunity { type InsertForm = ModTransferCommunityForm; type UpdateForm = ModTransferCommunityForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_transfer_community::dsl::*; - mod_transfer_community.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_transfer_community + .find(from_id) + .first::(conn) + .await } - fn create(conn: &mut PgConnection, form: &ModTransferCommunityForm) -> Result { + async fn create(pool: &DbPool, form: &ModTransferCommunityForm) -> Result { use crate::schema::mod_transfer_community::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(mod_transfer_community) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, from_id: i32, form: &ModTransferCommunityForm, ) -> Result { use crate::schema::mod_transfer_community::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_transfer_community.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for ModAdd { type InsertForm = ModAddForm; type UpdateForm = ModAddForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::mod_add::dsl::*; - mod_add.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + mod_add.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &ModAddForm) -> Result { + async fn create(pool: &DbPool, form: &ModAddForm) -> Result { use crate::schema::mod_add::dsl::*; - insert_into(mod_add).values(form).get_result::(conn) + let conn = &mut get_conn(pool).await?; + insert_into(mod_add) + .values(form) + .get_result::(conn) + .await } - fn update(conn: &mut PgConnection, from_id: i32, form: &ModAddForm) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &ModAddForm) -> Result { use crate::schema::mod_add::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(mod_add.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for AdminPurgePerson { type InsertForm = AdminPurgePersonForm; type UpdateForm = AdminPurgePersonForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::admin_purge_person::dsl::*; - admin_purge_person.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + admin_purge_person.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { use crate::schema::admin_purge_person::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(admin_purge_person) .values(form) .get_result::(conn) + .await } - fn update(conn: &mut PgConnection, from_id: i32, form: &Self::InsertForm) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &Self::InsertForm) -> Result { use crate::schema::admin_purge_person::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(admin_purge_person.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for AdminPurgeCommunity { type InsertForm = AdminPurgeCommunityForm; type UpdateForm = AdminPurgeCommunityForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::admin_purge_community::dsl::*; - admin_purge_community.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + admin_purge_community + .find(from_id) + .first::(conn) + .await } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { use crate::schema::admin_purge_community::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(admin_purge_community) .values(form) .get_result::(conn) + .await } - fn update(conn: &mut PgConnection, from_id: i32, form: &Self::InsertForm) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &Self::InsertForm) -> Result { use crate::schema::admin_purge_community::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(admin_purge_community.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for AdminPurgePost { type InsertForm = AdminPurgePostForm; type UpdateForm = AdminPurgePostForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::admin_purge_post::dsl::*; - admin_purge_post.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + admin_purge_post.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { use crate::schema::admin_purge_post::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(admin_purge_post) .values(form) .get_result::(conn) + .await } - fn update(conn: &mut PgConnection, from_id: i32, form: &Self::InsertForm) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &Self::InsertForm) -> Result { use crate::schema::admin_purge_post::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(admin_purge_post.find(from_id)) .set(form) .get_result::(conn) + .await } } +#[async_trait] impl Crud for AdminPurgeComment { type InsertForm = AdminPurgeCommentForm; type UpdateForm = AdminPurgeCommentForm; type IdType = i32; - fn read(conn: &mut PgConnection, from_id: i32) -> Result { + async fn read(pool: &DbPool, from_id: i32) -> Result { use crate::schema::admin_purge_comment::dsl::*; - admin_purge_comment.find(from_id).first::(conn) + let conn = &mut get_conn(pool).await?; + admin_purge_comment.find(from_id).first::(conn).await } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { use crate::schema::admin_purge_comment::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(admin_purge_comment) .values(form) .get_result::(conn) + .await } - fn update(conn: &mut PgConnection, from_id: i32, form: &Self::InsertForm) -> Result { + async fn update(pool: &DbPool, from_id: i32, form: &Self::InsertForm) -> Result { use crate::schema::admin_purge_comment::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(admin_purge_comment.find(from_id)) .set(form) .get_result::(conn) + .await } } @@ -397,17 +483,15 @@ mod tests { use crate::{ source::{comment::*, community::*, instance::Instance, moderator::*, person::*, post::*}, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - - // use Crud; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_mod = PersonInsertForm::builder() .name("the mod".into()) @@ -415,7 +499,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_mod = Person::create(conn, &new_mod).unwrap(); + let inserted_mod = Person::create(pool, &new_mod).await.unwrap(); let new_person = PersonInsertForm::builder() .name("jim2".into()) @@ -423,7 +507,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("mod_community".to_string()) @@ -432,7 +516,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post thweep".into()) @@ -440,7 +524,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -448,7 +532,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); // Now the actual tests @@ -459,8 +543,12 @@ mod tests { reason: None, removed: None, }; - let inserted_mod_remove_post = ModRemovePost::create(conn, &mod_remove_post_form).unwrap(); - let read_mod_remove_post = ModRemovePost::read(conn, inserted_mod_remove_post.id).unwrap(); + let inserted_mod_remove_post = ModRemovePost::create(pool, &mod_remove_post_form) + .await + .unwrap(); + let read_mod_remove_post = ModRemovePost::read(pool, inserted_mod_remove_post.id) + .await + .unwrap(); let expected_mod_remove_post = ModRemovePost { id: inserted_mod_remove_post.id, post_id: inserted_post.id, @@ -477,8 +565,12 @@ mod tests { post_id: inserted_post.id, locked: None, }; - let inserted_mod_lock_post = ModLockPost::create(conn, &mod_lock_post_form).unwrap(); - let read_mod_lock_post = ModLockPost::read(conn, inserted_mod_lock_post.id).unwrap(); + let inserted_mod_lock_post = ModLockPost::create(pool, &mod_lock_post_form) + .await + .unwrap(); + let read_mod_lock_post = ModLockPost::read(pool, inserted_mod_lock_post.id) + .await + .unwrap(); let expected_mod_lock_post = ModLockPost { id: inserted_mod_lock_post.id, post_id: inserted_post.id, @@ -494,8 +586,12 @@ mod tests { post_id: inserted_post.id, stickied: None, }; - let inserted_mod_sticky_post = ModStickyPost::create(conn, &mod_sticky_post_form).unwrap(); - let read_mod_sticky_post = ModStickyPost::read(conn, inserted_mod_sticky_post.id).unwrap(); + let inserted_mod_sticky_post = ModStickyPost::create(pool, &mod_sticky_post_form) + .await + .unwrap(); + let read_mod_sticky_post = ModStickyPost::read(pool, inserted_mod_sticky_post.id) + .await + .unwrap(); let expected_mod_sticky_post = ModStickyPost { id: inserted_mod_sticky_post.id, post_id: inserted_post.id, @@ -512,10 +608,12 @@ mod tests { reason: None, removed: None, }; - let inserted_mod_remove_comment = - ModRemoveComment::create(conn, &mod_remove_comment_form).unwrap(); - let read_mod_remove_comment = - ModRemoveComment::read(conn, inserted_mod_remove_comment.id).unwrap(); + let inserted_mod_remove_comment = ModRemoveComment::create(pool, &mod_remove_comment_form) + .await + .unwrap(); + let read_mod_remove_comment = ModRemoveComment::read(pool, inserted_mod_remove_comment.id) + .await + .unwrap(); let expected_mod_remove_comment = ModRemoveComment { id: inserted_mod_remove_comment.id, comment_id: inserted_comment.id, @@ -535,9 +633,13 @@ mod tests { expires: None, }; let inserted_mod_remove_community = - ModRemoveCommunity::create(conn, &mod_remove_community_form).unwrap(); + ModRemoveCommunity::create(pool, &mod_remove_community_form) + .await + .unwrap(); let read_mod_remove_community = - ModRemoveCommunity::read(conn, inserted_mod_remove_community.id).unwrap(); + ModRemoveCommunity::read(pool, inserted_mod_remove_community.id) + .await + .unwrap(); let expected_mod_remove_community = ModRemoveCommunity { id: inserted_mod_remove_community.id, community_id: inserted_community.id, @@ -559,9 +661,13 @@ mod tests { expires: None, }; let inserted_mod_ban_from_community = - ModBanFromCommunity::create(conn, &mod_ban_from_community_form).unwrap(); + ModBanFromCommunity::create(pool, &mod_ban_from_community_form) + .await + .unwrap(); let read_mod_ban_from_community = - ModBanFromCommunity::read(conn, inserted_mod_ban_from_community.id).unwrap(); + ModBanFromCommunity::read(pool, inserted_mod_ban_from_community.id) + .await + .unwrap(); let expected_mod_ban_from_community = ModBanFromCommunity { id: inserted_mod_ban_from_community.id, community_id: inserted_community.id, @@ -582,8 +688,8 @@ mod tests { banned: None, expires: None, }; - let inserted_mod_ban = ModBan::create(conn, &mod_ban_form).unwrap(); - let read_mod_ban = ModBan::read(conn, inserted_mod_ban.id).unwrap(); + let inserted_mod_ban = ModBan::create(pool, &mod_ban_form).await.unwrap(); + let read_mod_ban = ModBan::read(pool, inserted_mod_ban.id).await.unwrap(); let expected_mod_ban = ModBan { id: inserted_mod_ban.id, mod_person_id: inserted_mod.id, @@ -602,10 +708,12 @@ mod tests { community_id: inserted_community.id, removed: None, }; - let inserted_mod_add_community = - ModAddCommunity::create(conn, &mod_add_community_form).unwrap(); - let read_mod_add_community = - ModAddCommunity::read(conn, inserted_mod_add_community.id).unwrap(); + let inserted_mod_add_community = ModAddCommunity::create(pool, &mod_add_community_form) + .await + .unwrap(); + let read_mod_add_community = ModAddCommunity::read(pool, inserted_mod_add_community.id) + .await + .unwrap(); let expected_mod_add_community = ModAddCommunity { id: inserted_mod_add_community.id, community_id: inserted_community.id, @@ -622,8 +730,8 @@ mod tests { other_person_id: inserted_person.id, removed: None, }; - let inserted_mod_add = ModAdd::create(conn, &mod_add_form).unwrap(); - let read_mod_add = ModAdd::read(conn, inserted_mod_add.id).unwrap(); + let inserted_mod_add = ModAdd::create(pool, &mod_add_form).await.unwrap(); + let read_mod_add = ModAdd::read(pool, inserted_mod_add.id).await.unwrap(); let expected_mod_add = ModAdd { id: inserted_mod_add.id, mod_person_id: inserted_mod.id, @@ -632,12 +740,14 @@ mod tests { when_: inserted_mod_add.when_, }; - Comment::delete(conn, inserted_comment.id).unwrap(); - Post::delete(conn, inserted_post.id).unwrap(); - Community::delete(conn, inserted_community.id).unwrap(); - Person::delete(conn, inserted_person.id).unwrap(); - Person::delete(conn, inserted_mod.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + Comment::delete(pool, inserted_comment.id).await.unwrap(); + Post::delete(pool, inserted_post.id).await.unwrap(); + Community::delete(pool, inserted_community.id) + .await + .unwrap(); + Person::delete(pool, inserted_person.id).await.unwrap(); + Person::delete(pool, inserted_mod.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_mod_remove_post, read_mod_remove_post); assert_eq!(expected_mod_lock_post, read_mod_lock_post); diff --git a/crates/db_schema/src/impls/password_reset_request.rs b/crates/db_schema/src/impls/password_reset_request.rs index 7a4d4c83..fb6873d9 100644 --- a/crates/db_schema/src/impls/password_reset_request.rs +++ b/crates/db_schema/src/impls/password_reset_request.rs @@ -3,38 +3,47 @@ use crate::{ schema::password_reset_request::dsl::*, source::password_reset_request::*, traits::Crud, + utils::{get_conn, DbPool}, }; -use diesel::{dsl::*, result::Error, PgConnection, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use sha2::{Digest, Sha256}; +#[async_trait] impl Crud for PasswordResetRequest { type InsertForm = PasswordResetRequestForm; type UpdateForm = PasswordResetRequestForm; type IdType = i32; - fn read(conn: &mut PgConnection, password_reset_request_id: i32) -> Result { + async fn read(pool: &DbPool, password_reset_request_id: i32) -> Result { + let conn = &mut get_conn(pool).await?; password_reset_request .find(password_reset_request_id) .first::(conn) + .await } - fn create(conn: &mut PgConnection, form: &PasswordResetRequestForm) -> Result { + async fn create(pool: &DbPool, form: &PasswordResetRequestForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(password_reset_request) .values(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, password_reset_request_id: i32, form: &PasswordResetRequestForm, ) -> Result { + let conn = &mut get_conn(pool).await?; diesel::update(password_reset_request.find(password_reset_request_id)) .set(form) .get_result::(conn) + .await } } impl PasswordResetRequest { - pub fn create_token( - conn: &mut PgConnection, + pub async fn create_token( + pool: &DbPool, from_local_user_id: LocalUserId, token: &str, ) -> Result { @@ -47,12 +56,10 @@ impl PasswordResetRequest { token_encrypted: token_hash, }; - Self::create(conn, &form) + Self::create(pool, &form).await } - pub fn read_from_token( - conn: &mut PgConnection, - token: &str, - ) -> Result { + pub async fn read_from_token(pool: &DbPool, token: &str) -> Result { + let conn = &mut get_conn(pool).await?; let mut hasher = Sha256::new(); hasher.update(token); let token_hash: String = bytes_to_hex(hasher.finalize().to_vec()); @@ -60,6 +67,7 @@ impl PasswordResetRequest { .filter(token_encrypted.eq(token_hash)) .filter(published.gt(now - 1.days())) .first::(conn) + .await } } @@ -81,16 +89,16 @@ mod tests { person::*, }, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("thommy prw".into()) @@ -98,20 +106,22 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let new_local_user = LocalUserInsertForm::builder() .person_id(inserted_person.id) .password_encrypted("pass".to_string()) .build(); - let inserted_local_user = LocalUser::create(conn, &new_local_user).unwrap(); + let inserted_local_user = LocalUser::create(pool, &new_local_user).await.unwrap(); let token = "nope"; let token_encrypted_ = "ca3704aa0b06f5954c79ee837faa152d84d6b2d42838f0637a15eda8337dbdce"; let inserted_password_reset_request = - PasswordResetRequest::create_token(conn, inserted_local_user.id, token).unwrap(); + PasswordResetRequest::create_token(pool, inserted_local_user.id, token) + .await + .unwrap(); let expected_password_reset_request = PasswordResetRequest { id: inserted_password_reset_request.id, @@ -120,9 +130,11 @@ mod tests { published: inserted_password_reset_request.published, }; - let read_password_reset_request = PasswordResetRequest::read_from_token(conn, token).unwrap(); - let num_deleted = Person::delete(conn, inserted_person.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + let read_password_reset_request = PasswordResetRequest::read_from_token(pool, token) + .await + .unwrap(); + let num_deleted = Person::delete(pool, inserted_person.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_password_reset_request, read_password_reset_request); assert_eq!( diff --git a/crates/db_schema/src/impls/person.rs b/crates/db_schema/src/impls/person.rs index 22a26440..17467775 100644 --- a/crates/db_schema/src/impls/person.rs +++ b/crates/db_schema/src/impls/person.rs @@ -3,17 +3,10 @@ use crate::{ schema::person::dsl::*, source::person::{Person, PersonInsertForm, PersonUpdateForm}, traits::{ApubActor, Crud}, - utils::{functions::lower, naive_now}, -}; -use diesel::{ - dsl::*, - result::Error, - ExpressionMethods, - PgConnection, - QueryDsl, - RunQueryDsl, - TextExpressionMethods, + utils::{functions::lower, get_conn, naive_now, DbPool}, }; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl, TextExpressionMethods}; +use diesel_async::RunQueryDsl; mod safe_type { use crate::{schema::person::columns::*, source::person::Person, traits::ToSafe}; @@ -68,41 +61,50 @@ mod safe_type { } } +#[async_trait] impl Crud for Person { type InsertForm = PersonInsertForm; type UpdateForm = PersonUpdateForm; type IdType = PersonId; - fn read(conn: &mut PgConnection, person_id: PersonId) -> Result { + async fn read(pool: &DbPool, person_id: PersonId) -> Result { + let conn = &mut get_conn(pool).await?; person .filter(deleted.eq(false)) .find(person_id) .first::(conn) + .await } - fn delete(conn: &mut PgConnection, person_id: PersonId) -> Result { - diesel::delete(person.find(person_id)).execute(conn) + async fn delete(pool: &DbPool, person_id: PersonId) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(person.find(person_id)).execute(conn).await } - fn create(conn: &mut PgConnection, form: &PersonInsertForm) -> Result { + async fn create(pool: &DbPool, form: &PersonInsertForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(person) .values(form) .on_conflict(actor_id) .do_update() .set(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, person_id: PersonId, form: &PersonUpdateForm, ) -> Result { + let conn = &mut get_conn(pool).await?; diesel::update(person.find(person_id)) .set(form) .get_result::(conn) + .await } } impl Person { - pub fn delete_account(conn: &mut PgConnection, person_id: PersonId) -> Result { + pub async fn delete_account(pool: &DbPool, person_id: PersonId) -> Result { use crate::schema::local_user; + let conn = &mut get_conn(pool).await?; // Set the local user info to none diesel::update(local_user::table.filter(local_user::person_id.eq(person_id))) @@ -110,7 +112,8 @@ impl Person { local_user::email.eq::>(None), local_user::validator_time.eq(naive_now()), )) - .execute(conn)?; + .execute(conn) + .await?; diesel::update(person.find(person_id)) .set(( @@ -123,6 +126,7 @@ impl Person { updated.eq(naive_now()), )) .get_result::(conn) + .await } } @@ -134,24 +138,27 @@ pub fn is_banned(banned_: bool, expires: Option) -> bool } } +#[async_trait] impl ApubActor for Person { - fn read_from_apub_id(conn: &mut PgConnection, object_id: &DbUrl) -> Result, Error> { - use crate::schema::person::dsl::*; + async fn read_from_apub_id(pool: &DbPool, object_id: &DbUrl) -> Result, Error> { + let conn = &mut get_conn(pool).await?; Ok( person .filter(deleted.eq(false)) .filter(actor_id.eq(object_id)) .first::(conn) + .await .ok() .map(Into::into), ) } - fn read_from_name( - conn: &mut PgConnection, + async fn read_from_name( + pool: &DbPool, from_name: &str, include_deleted: bool, ) -> Result { + let conn = &mut get_conn(pool).await?; let mut q = person .into_boxed() .filter(local.eq(true)) @@ -159,19 +166,20 @@ impl ApubActor for Person { if !include_deleted { q = q.filter(deleted.eq(false)) } - q.first::(conn) + q.first::(conn).await } - fn read_from_name_and_domain( - conn: &mut PgConnection, + async fn read_from_name_and_domain( + pool: &DbPool, person_name: &str, protocol_domain: &str, ) -> Result { - use crate::schema::person::dsl::*; + let conn = &mut get_conn(pool).await?; person .filter(lower(name).eq(lower(person_name))) .filter(actor_id.like(format!("{}%", protocol_domain))) .first::(conn) + .await } } @@ -180,16 +188,16 @@ mod tests { use crate::{ source::{instance::Instance, person::*}, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("holly".into()) @@ -197,7 +205,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let expected_person = Person { id: inserted_person.id, @@ -224,15 +232,17 @@ mod tests { instance_id: inserted_instance.id, }; - let read_person = Person::read(conn, inserted_person.id).unwrap(); + let read_person = Person::read(pool, inserted_person.id).await.unwrap(); let update_person_form = PersonUpdateForm::builder() .actor_id(Some(inserted_person.actor_id.to_owned())) .build(); - let updated_person = Person::update(conn, inserted_person.id, &update_person_form).unwrap(); + let updated_person = Person::update(pool, inserted_person.id, &update_person_form) + .await + .unwrap(); - let num_deleted = Person::delete(conn, inserted_person.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + let num_deleted = Person::delete(pool, inserted_person.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_person, read_person); assert_eq!(expected_person, inserted_person); diff --git a/crates/db_schema/src/impls/person_block.rs b/crates/db_schema/src/impls/person_block.rs index 6ee617d6..0158a327 100644 --- a/crates/db_schema/src/impls/person_block.rs +++ b/crates/db_schema/src/impls/person_block.rs @@ -1,42 +1,49 @@ use crate::{ newtypes::PersonId, + schema::person_block::dsl::*, source::person_block::{PersonBlock, PersonBlockForm}, traits::Blockable, + utils::{get_conn, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; impl PersonBlock { - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, for_person_id: PersonId, for_recipient_id: PersonId, ) -> Result { - use crate::schema::person_block::dsl::*; + let conn = &mut get_conn(pool).await?; person_block .filter(person_id.eq(for_person_id)) .filter(target_id.eq(for_recipient_id)) .first::(conn) + .await } } +#[async_trait] impl Blockable for PersonBlock { type Form = PersonBlockForm; - fn block(conn: &mut PgConnection, person_block_form: &PersonBlockForm) -> Result { - use crate::schema::person_block::dsl::*; + async fn block(pool: &DbPool, person_block_form: &PersonBlockForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(person_block) .values(person_block_form) .on_conflict((person_id, target_id)) .do_update() .set(person_block_form) .get_result::(conn) + .await } - fn unblock(conn: &mut PgConnection, person_block_form: &Self::Form) -> Result { - use crate::schema::person_block::dsl::*; + async fn unblock(pool: &DbPool, person_block_form: &Self::Form) -> Result { + let conn = &mut get_conn(pool).await?; diesel::delete( person_block .filter(person_id.eq(person_block_form.person_id)) .filter(target_id.eq(person_block_form.target_id)), ) .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/person_mention.rs b/crates/db_schema/src/impls/person_mention.rs index e83de1fe..d902e951 100644 --- a/crates/db_schema/src/impls/person_mention.rs +++ b/crates/db_schema/src/impls/person_mention.rs @@ -1,24 +1,28 @@ use crate::{ newtypes::{CommentId, PersonId, PersonMentionId}, + schema::person_mention::dsl::*, source::person_mention::*, traits::Crud, + utils::{get_conn, DbPool}, }; use diesel::{dsl::*, result::Error, *}; +use diesel_async::RunQueryDsl; +#[async_trait] impl Crud for PersonMention { type InsertForm = PersonMentionInsertForm; type UpdateForm = PersonMentionUpdateForm; type IdType = PersonMentionId; - fn read(conn: &mut PgConnection, person_mention_id: PersonMentionId) -> Result { - use crate::schema::person_mention::dsl::*; - person_mention.find(person_mention_id).first::(conn) + async fn read(pool: &DbPool, person_mention_id: PersonMentionId) -> Result { + let conn = &mut get_conn(pool).await?; + person_mention + .find(person_mention_id) + .first::(conn) + .await } - fn create( - conn: &mut PgConnection, - person_mention_form: &Self::InsertForm, - ) -> Result { - use crate::schema::person_mention::dsl::*; + async fn create(pool: &DbPool, person_mention_form: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; // since the return here isnt utilized, we dont need to do an update // but get_result doesnt return the existing row here insert_into(person_mention) @@ -27,26 +31,28 @@ impl Crud for PersonMention { .do_update() .set(person_mention_form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, person_mention_id: PersonMentionId, person_mention_form: &Self::UpdateForm, ) -> Result { - use crate::schema::person_mention::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(person_mention.find(person_mention_id)) .set(person_mention_form) .get_result::(conn) + .await } } impl PersonMention { - pub fn mark_all_as_read( - conn: &mut PgConnection, + pub async fn mark_all_as_read( + pool: &DbPool, for_recipient_id: PersonId, ) -> Result, Error> { - use crate::schema::person_mention::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update( person_mention .filter(recipient_id.eq(for_recipient_id)) @@ -54,18 +60,20 @@ impl PersonMention { ) .set(read.eq(true)) .get_results::(conn) + .await } - pub fn read_by_comment_and_person( - conn: &mut PgConnection, + pub async fn read_by_comment_and_person( + pool: &DbPool, for_comment_id: CommentId, for_recipient_id: PersonId, ) -> Result { - use crate::schema::person_mention::dsl::*; + let conn = &mut get_conn(pool).await?; person_mention .filter(comment_id.eq(for_comment_id)) .filter(recipient_id.eq(for_recipient_id)) .first::(conn) + .await } } @@ -81,16 +89,16 @@ mod tests { post::*, }, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("terrylake".into()) @@ -98,7 +106,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let recipient_form = PersonInsertForm::builder() .name("terrylakes recipient".into()) @@ -106,7 +114,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_recipient = Person::create(conn, &recipient_form).unwrap(); + let inserted_recipient = Person::create(pool, &recipient_form).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("test community lake".to_string()) @@ -115,7 +123,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -123,7 +131,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment".into()) @@ -131,7 +139,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); let person_mention_form = PersonMentionInsertForm { recipient_id: inserted_recipient.id, @@ -139,7 +147,9 @@ mod tests { read: None, }; - let inserted_mention = PersonMention::create(conn, &person_mention_form).unwrap(); + let inserted_mention = PersonMention::create(pool, &person_mention_form) + .await + .unwrap(); let expected_mention = PersonMention { id: inserted_mention.id, @@ -149,17 +159,23 @@ mod tests { published: inserted_mention.published, }; - let read_mention = PersonMention::read(conn, inserted_mention.id).unwrap(); + let read_mention = PersonMention::read(pool, inserted_mention.id) + .await + .unwrap(); let person_mention_update_form = PersonMentionUpdateForm { read: Some(false) }; let updated_mention = - PersonMention::update(conn, inserted_mention.id, &person_mention_update_form).unwrap(); - Comment::delete(conn, inserted_comment.id).unwrap(); - Post::delete(conn, inserted_post.id).unwrap(); - Community::delete(conn, inserted_community.id).unwrap(); - Person::delete(conn, inserted_person.id).unwrap(); - Person::delete(conn, inserted_recipient.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + PersonMention::update(pool, inserted_mention.id, &person_mention_update_form) + .await + .unwrap(); + Comment::delete(pool, inserted_comment.id).await.unwrap(); + Post::delete(pool, inserted_post.id).await.unwrap(); + Community::delete(pool, inserted_community.id) + .await + .unwrap(); + Person::delete(pool, inserted_person.id).await.unwrap(); + Person::delete(pool, inserted_recipient.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_mention, read_mention); assert_eq!(expected_mention, inserted_mention); diff --git a/crates/db_schema/src/impls/post.rs b/crates/db_schema/src/impls/post.rs index 95535b19..738e8a3b 100644 --- a/crates/db_schema/src/impls/post.rs +++ b/crates/db_schema/src/impls/post.rs @@ -1,5 +1,6 @@ use crate::{ newtypes::{CommunityId, DbUrl, PersonId, PostId}, + schema::post::dsl::*, source::post::{ Post, PostInsertForm, @@ -12,53 +13,57 @@ use crate::{ PostUpdateForm, }, traits::{Crud, DeleteableOrRemoveable, Likeable, Readable, Saveable}, - utils::{naive_now, FETCH_LIMIT_MAX}, + utils::{get_conn, naive_now, DbPool, FETCH_LIMIT_MAX}, }; -use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl, *}; -use url::Url; +use ::url::Url; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl, TextExpressionMethods}; +use diesel_async::RunQueryDsl; +#[async_trait] impl Crud for Post { type InsertForm = PostInsertForm; type UpdateForm = PostUpdateForm; type IdType = PostId; - fn read(conn: &mut PgConnection, post_id: PostId) -> Result { - use crate::schema::post::dsl::*; - post.find(post_id).first::(conn) + async fn read(pool: &DbPool, post_id: PostId) -> Result { + let conn = &mut get_conn(pool).await?; + post.find(post_id).first::(conn).await } - fn delete(conn: &mut PgConnection, post_id: PostId) -> Result { - use crate::schema::post::dsl::*; - diesel::delete(post.find(post_id)).execute(conn) + async fn delete(pool: &DbPool, post_id: PostId) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(post.find(post_id)).execute(conn).await } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { - use crate::schema::post::dsl::*; + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(post) .values(form) .on_conflict(ap_id) .do_update() .set(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, post_id: PostId, new_post: &Self::UpdateForm, ) -> Result { - use crate::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(post.find(post_id)) .set(new_post) .get_result::(conn) + .await } } impl Post { - pub fn list_for_community( - conn: &mut PgConnection, + pub async fn list_for_community( + pool: &DbPool, the_community_id: CommunityId, ) -> Result, Error> { - use crate::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; post .filter(community_id.eq(the_community_id)) .filter(deleted.eq(false)) @@ -67,13 +72,14 @@ impl Post { .then_order_by(stickied.desc()) .limit(FETCH_LIMIT_MAX) .load::(conn) + .await } - pub fn permadelete_for_creator( - conn: &mut PgConnection, + pub async fn permadelete_for_creator( + pool: &DbPool, for_creator_id: PersonId, ) -> Result, Error> { - use crate::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; let perma_deleted = "*Permananently Deleted*"; let perma_deleted_url = "https://deleted.com"; @@ -87,15 +93,16 @@ impl Post { updated.eq(naive_now()), )) .get_results::(conn) + .await } - pub fn update_removed_for_creator( - conn: &mut PgConnection, + pub async fn update_removed_for_creator( + pool: &DbPool, for_creator_id: PersonId, for_community_id: Option, new_removed: bool, ) -> Result, Error> { - use crate::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; let mut update = diesel::update(post).into_boxed(); update = update.filter(creator_id.eq(for_creator_id)); @@ -107,43 +114,47 @@ impl Post { update .set((removed.eq(new_removed), updated.eq(naive_now()))) .get_results::(conn) + .await } pub fn is_post_creator(person_id: PersonId, post_creator_id: PersonId) -> bool { person_id == post_creator_id } - pub fn read_from_apub_id(conn: &mut PgConnection, object_id: Url) -> Result, Error> { - use crate::schema::post::dsl::*; + pub async fn read_from_apub_id(pool: &DbPool, object_id: Url) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let object_id: DbUrl = object_id.into(); Ok( post .filter(ap_id.eq(object_id)) .first::(conn) + .await .ok() .map(Into::into), ) } - pub fn fetch_pictrs_posts_for_creator( - conn: &mut PgConnection, + pub async fn fetch_pictrs_posts_for_creator( + pool: &DbPool, for_creator_id: PersonId, ) -> Result, Error> { use crate::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; let pictrs_search = "%pictrs/image%"; post .filter(creator_id.eq(for_creator_id)) .filter(url.like(pictrs_search)) .load::(conn) + .await } /// Sets the url and thumbnails fields to None - pub fn remove_pictrs_post_images_and_thumbnails_for_creator( - conn: &mut PgConnection, + pub async fn remove_pictrs_post_images_and_thumbnails_for_creator( + pool: &DbPool, for_creator_id: PersonId, ) -> Result, Error> { - use crate::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; let pictrs_search = "%pictrs/image%"; diesel::update( @@ -156,26 +167,28 @@ impl Post { thumbnail_url.eq::>(None), )) .get_results::(conn) + .await } - pub fn fetch_pictrs_posts_for_community( - conn: &mut PgConnection, + pub async fn fetch_pictrs_posts_for_community( + pool: &DbPool, for_community_id: CommunityId, ) -> Result, Error> { - use crate::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; let pictrs_search = "%pictrs/image%"; post .filter(community_id.eq(for_community_id)) .filter(url.like(pictrs_search)) .load::(conn) + .await } /// Sets the url and thumbnails fields to None - pub fn remove_pictrs_post_images_and_thumbnails_for_community( - conn: &mut PgConnection, + pub async fn remove_pictrs_post_images_and_thumbnails_for_community( + pool: &DbPool, for_community_id: CommunityId, ) -> Result, Error> { - use crate::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; let pictrs_search = "%pictrs/image%"; diesel::update( @@ -188,77 +201,90 @@ impl Post { thumbnail_url.eq::>(None), )) .get_results::(conn) + .await } } +#[async_trait] impl Likeable for PostLike { type Form = PostLikeForm; type IdType = PostId; - fn like(conn: &mut PgConnection, post_like_form: &PostLikeForm) -> Result { + async fn like(pool: &DbPool, post_like_form: &PostLikeForm) -> Result { use crate::schema::post_like::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(post_like) .values(post_like_form) .on_conflict((post_id, person_id)) .do_update() .set(post_like_form) .get_result::(conn) + .await } - fn remove(conn: &mut PgConnection, person_id: PersonId, post_id: PostId) -> Result { + async fn remove(pool: &DbPool, person_id: PersonId, post_id: PostId) -> Result { use crate::schema::post_like::dsl; + let conn = &mut get_conn(pool).await?; diesel::delete( dsl::post_like .filter(dsl::post_id.eq(post_id)) .filter(dsl::person_id.eq(person_id)), ) .execute(conn) + .await } } +#[async_trait] impl Saveable for PostSaved { type Form = PostSavedForm; - fn save(conn: &mut PgConnection, post_saved_form: &PostSavedForm) -> Result { + async fn save(pool: &DbPool, post_saved_form: &PostSavedForm) -> Result { use crate::schema::post_saved::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(post_saved) .values(post_saved_form) .on_conflict((post_id, person_id)) .do_update() .set(post_saved_form) .get_result::(conn) + .await } - fn unsave(conn: &mut PgConnection, post_saved_form: &PostSavedForm) -> Result { + async fn unsave(pool: &DbPool, post_saved_form: &PostSavedForm) -> Result { use crate::schema::post_saved::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::delete( post_saved .filter(post_id.eq(post_saved_form.post_id)) .filter(person_id.eq(post_saved_form.person_id)), ) .execute(conn) + .await } } +#[async_trait] impl Readable for PostRead { type Form = PostReadForm; - fn mark_as_read(conn: &mut PgConnection, post_read_form: &PostReadForm) -> Result { + async fn mark_as_read(pool: &DbPool, post_read_form: &PostReadForm) -> Result { use crate::schema::post_read::dsl::*; + let conn = &mut get_conn(pool).await?; insert_into(post_read) .values(post_read_form) .on_conflict((post_id, person_id)) .do_update() .set(post_read_form) .get_result::(conn) + .await } - fn mark_as_unread( - conn: &mut PgConnection, - post_read_form: &PostReadForm, - ) -> Result { + async fn mark_as_unread(pool: &DbPool, post_read_form: &PostReadForm) -> Result { use crate::schema::post_read::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::delete( post_read .filter(post_id.eq(post_read_form.post_id)) .filter(person_id.eq(post_read_form.person_id)), ) .execute(conn) + .await } } @@ -286,16 +312,16 @@ mod tests { post::*, }, traits::{Crud, Likeable, Readable, Saveable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("jim".into()) @@ -303,7 +329,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("test community_3".to_string()) @@ -312,7 +338,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post".into()) @@ -320,7 +346,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let expected_post = Post { id: inserted_post.id, @@ -352,7 +378,7 @@ mod tests { score: 1, }; - let inserted_post_like = PostLike::like(conn, &post_like_form).unwrap(); + let inserted_post_like = PostLike::like(pool, &post_like_form).await.unwrap(); let expected_post_like = PostLike { id: inserted_post_like.id, @@ -368,7 +394,7 @@ mod tests { person_id: inserted_person.id, }; - let inserted_post_saved = PostSaved::save(conn, &post_saved_form).unwrap(); + let inserted_post_saved = PostSaved::save(pool, &post_saved_form).await.unwrap(); let expected_post_saved = PostSaved { id: inserted_post_saved.id, @@ -383,7 +409,7 @@ mod tests { person_id: inserted_person.id, }; - let inserted_post_read = PostRead::mark_as_read(conn, &post_read_form).unwrap(); + let inserted_post_read = PostRead::mark_as_read(pool, &post_read_form).await.unwrap(); let expected_post_read = PostRead { id: inserted_post_read.id, @@ -392,20 +418,28 @@ mod tests { published: inserted_post_read.published, }; - let read_post = Post::read(conn, inserted_post.id).unwrap(); + let read_post = Post::read(pool, inserted_post.id).await.unwrap(); let new_post_update = PostUpdateForm::builder() .name(Some("A test post".into())) .build(); - let updated_post = Post::update(conn, inserted_post.id, &new_post_update).unwrap(); - - let like_removed = PostLike::remove(conn, inserted_person.id, inserted_post.id).unwrap(); - let saved_removed = PostSaved::unsave(conn, &post_saved_form).unwrap(); - let read_removed = PostRead::mark_as_unread(conn, &post_read_form).unwrap(); - let num_deleted = Post::delete(conn, inserted_post.id).unwrap(); - Community::delete(conn, inserted_community.id).unwrap(); - Person::delete(conn, inserted_person.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + let updated_post = Post::update(pool, inserted_post.id, &new_post_update) + .await + .unwrap(); + + let like_removed = PostLike::remove(pool, inserted_person.id, inserted_post.id) + .await + .unwrap(); + let saved_removed = PostSaved::unsave(pool, &post_saved_form).await.unwrap(); + let read_removed = PostRead::mark_as_unread(pool, &post_read_form) + .await + .unwrap(); + let num_deleted = Post::delete(pool, inserted_post.id).await.unwrap(); + Community::delete(pool, inserted_community.id) + .await + .unwrap(); + Person::delete(pool, inserted_person.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_post, read_post); assert_eq!(expected_post, inserted_post); diff --git a/crates/db_schema/src/impls/post_report.rs b/crates/db_schema/src/impls/post_report.rs index f9a1eab2..07e58a88 100644 --- a/crates/db_schema/src/impls/post_report.rs +++ b/crates/db_schema/src/impls/post_report.rs @@ -1,37 +1,32 @@ use crate::{ newtypes::{PersonId, PostReportId}, + schema::post_report::dsl::*, source::post_report::*, traits::Reportable, - utils::naive_now, + utils::{get_conn, naive_now, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; +#[async_trait] impl Reportable for PostReport { type Form = PostReportForm; type IdType = PostReportId; - /// creates a post report and returns it - /// - /// * `conn` - the postgres connection - /// * `post_report_form` - the filled CommentReportForm to insert - fn report(conn: &mut PgConnection, post_report_form: &PostReportForm) -> Result { - use crate::schema::post_report::dsl::*; + async fn report(pool: &DbPool, post_report_form: &PostReportForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(post_report) .values(post_report_form) .get_result::(conn) + .await } - /// resolve a post report - /// - /// * `conn` - the postgres connection - /// * `report_id` - the id of the report to resolve - /// * `by_resolver_id` - the id of the user resolving the report - fn resolve( - conn: &mut PgConnection, + async fn resolve( + pool: &DbPool, report_id: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use crate::schema::post_report::dsl::*; + let conn = &mut get_conn(pool).await?; update(post_report.find(report_id)) .set(( resolved.eq(true), @@ -39,19 +34,15 @@ impl Reportable for PostReport { updated.eq(naive_now()), )) .execute(conn) + .await } - /// resolve a post report - /// - /// * `conn` - the postgres connection - /// * `report_id` - the id of the report to unresolve - /// * `by_resolver_id` - the id of the user unresolving the report - fn unresolve( - conn: &mut PgConnection, + async fn unresolve( + pool: &DbPool, report_id: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use crate::schema::post_report::dsl::*; + let conn = &mut get_conn(pool).await?; update(post_report.find(report_id)) .set(( resolved.eq(false), @@ -59,5 +50,6 @@ impl Reportable for PostReport { updated.eq(naive_now()), )) .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/private_message.rs b/crates/db_schema/src/impls/private_message.rs index 80818ee3..0e5a5031 100644 --- a/crates/db_schema/src/impls/private_message.rs +++ b/crates/db_schema/src/impls/private_message.rs @@ -1,53 +1,64 @@ use crate::{ newtypes::{DbUrl, PersonId, PrivateMessageId}, + schema::private_message::dsl::*, source::private_message::*, traits::{Crud, DeleteableOrRemoveable}, + utils::{get_conn, DbPool}, }; use diesel::{dsl::*, result::Error, *}; +use diesel_async::RunQueryDsl; use lemmy_utils::error::LemmyError; use url::Url; +#[async_trait] impl Crud for PrivateMessage { type InsertForm = PrivateMessageInsertForm; type UpdateForm = PrivateMessageUpdateForm; type IdType = PrivateMessageId; - fn read(conn: &mut PgConnection, private_message_id: PrivateMessageId) -> Result { - use crate::schema::private_message::dsl::*; - private_message.find(private_message_id).first::(conn) + async fn read(pool: &DbPool, private_message_id: PrivateMessageId) -> Result { + let conn = &mut get_conn(pool).await?; + private_message + .find(private_message_id) + .first::(conn) + .await } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { - use crate::schema::private_message::dsl::*; + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(private_message) .values(form) .on_conflict(ap_id) .do_update() .set(form) .get_result::(conn) + .await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, private_message_id: PrivateMessageId, form: &Self::UpdateForm, ) -> Result { - use crate::schema::private_message::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(private_message.find(private_message_id)) .set(form) .get_result::(conn) + .await } - fn delete(conn: &mut PgConnection, pm_id: Self::IdType) -> Result { - use crate::schema::private_message::dsl::*; - diesel::delete(private_message.find(pm_id)).execute(conn) + async fn delete(pool: &DbPool, pm_id: Self::IdType) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(private_message.find(pm_id)) + .execute(conn) + .await } } impl PrivateMessage { - pub fn mark_all_as_read( - conn: &mut PgConnection, + pub async fn mark_all_as_read( + pool: &DbPool, for_recipient_id: PersonId, ) -> Result, Error> { - use crate::schema::private_message::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update( private_message .filter(recipient_id.eq(for_recipient_id)) @@ -55,18 +66,20 @@ impl PrivateMessage { ) .set(read.eq(true)) .get_results::(conn) + .await } - pub fn read_from_apub_id( - conn: &mut PgConnection, + pub async fn read_from_apub_id( + pool: &DbPool, object_id: Url, ) -> Result, LemmyError> { - use crate::schema::private_message::dsl::*; + let conn = &mut get_conn(pool).await?; let object_id: DbUrl = object_id.into(); Ok( private_message .filter(ap_id.eq(object_id)) .first::(conn) + .await .ok() .map(Into::into), ) @@ -85,16 +98,16 @@ mod tests { use crate::{ source::{instance::Instance, person::*, private_message::*}, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let creator_form = PersonInsertForm::builder() .name("creator_pm".into()) @@ -102,7 +115,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_creator = Person::create(conn, &creator_form).unwrap(); + let inserted_creator = Person::create(pool, &creator_form).await.unwrap(); let recipient_form = PersonInsertForm::builder() .name("recipient_pm".into()) @@ -110,7 +123,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_recipient = Person::create(conn, &recipient_form).unwrap(); + let inserted_recipient = Person::create(pool, &recipient_form).await.unwrap(); let private_message_form = PrivateMessageInsertForm::builder() .content("A test private message".into()) @@ -118,7 +131,9 @@ mod tests { .recipient_id(inserted_recipient.id) .build(); - let inserted_private_message = PrivateMessage::create(conn, &private_message_form).unwrap(); + let inserted_private_message = PrivateMessage::create(pool, &private_message_form) + .await + .unwrap(); let expected_private_message = PrivateMessage { id: inserted_private_message.id, @@ -133,35 +148,40 @@ mod tests { local: true, }; - let read_private_message = PrivateMessage::read(conn, inserted_private_message.id).unwrap(); + let read_private_message = PrivateMessage::read(pool, inserted_private_message.id) + .await + .unwrap(); let private_message_update_form = PrivateMessageUpdateForm::builder() .content(Some("A test private message".into())) .build(); let updated_private_message = PrivateMessage::update( - conn, + pool, inserted_private_message.id, &private_message_update_form, ) + .await .unwrap(); let deleted_private_message = PrivateMessage::update( - conn, + pool, inserted_private_message.id, &PrivateMessageUpdateForm::builder() .deleted(Some(true)) .build(), ) + .await .unwrap(); let marked_read_private_message = PrivateMessage::update( - conn, + pool, inserted_private_message.id, &PrivateMessageUpdateForm::builder().read(Some(true)).build(), ) + .await .unwrap(); - Person::delete(conn, inserted_creator.id).unwrap(); - Person::delete(conn, inserted_recipient.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + Person::delete(pool, inserted_creator.id).await.unwrap(); + Person::delete(pool, inserted_recipient.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); assert_eq!(expected_private_message, read_private_message); assert_eq!(expected_private_message, updated_private_message); diff --git a/crates/db_schema/src/impls/private_message_report.rs b/crates/db_schema/src/impls/private_message_report.rs index 08fe4d28..70af3615 100644 --- a/crates/db_schema/src/impls/private_message_report.rs +++ b/crates/db_schema/src/impls/private_message_report.rs @@ -1,39 +1,32 @@ use crate::{ newtypes::{PersonId, PrivateMessageReportId}, + schema::private_message_report::dsl::*, source::private_message_report::{PrivateMessageReport, PrivateMessageReportForm}, traits::Reportable, - utils::naive_now, + utils::{get_conn, naive_now, DbPool}, }; use diesel::{dsl::*, result::Error, *}; +use diesel_async::RunQueryDsl; +#[async_trait] impl Reportable for PrivateMessageReport { type Form = PrivateMessageReportForm; type IdType = PrivateMessageReportId; - /// creates a comment report and returns it - /// - /// * `conn` - the postgres connection - /// * `comment_report_form` - the filled CommentReportForm to insert - fn report( - conn: &mut PgConnection, - pm_report_form: &PrivateMessageReportForm, - ) -> Result { - use crate::schema::private_message_report::dsl::*; + + async fn report(pool: &DbPool, pm_report_form: &PrivateMessageReportForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(private_message_report) .values(pm_report_form) .get_result::(conn) + .await } - /// resolve a pm report - /// - /// * `conn` - the postgres connection - /// * `report_id` - the id of the report to resolve - /// * `by_resolver_id` - the id of the user resolving the report - fn resolve( - conn: &mut PgConnection, + async fn resolve( + pool: &DbPool, report_id: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use crate::schema::private_message_report::dsl::*; + let conn = &mut get_conn(pool).await?; update(private_message_report.find(report_id)) .set(( resolved.eq(true), @@ -41,19 +34,15 @@ impl Reportable for PrivateMessageReport { updated.eq(naive_now()), )) .execute(conn) + .await } - /// unresolve a comment report - /// - /// * `conn` - the postgres connection - /// * `report_id` - the id of the report to unresolve - /// * `by_resolver_id` - the id of the user unresolving the report - fn unresolve( - conn: &mut PgConnection, + async fn unresolve( + pool: &DbPool, report_id: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use crate::schema::private_message_report::dsl::*; + let conn = &mut get_conn(pool).await?; update(private_message_report.find(report_id)) .set(( resolved.eq(false), @@ -61,5 +50,6 @@ impl Reportable for PrivateMessageReport { updated.eq(naive_now()), )) .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/registration_application.rs b/crates/db_schema/src/impls/registration_application.rs index 8004abc6..72daf4eb 100644 --- a/crates/db_schema/src/impls/registration_application.rs +++ b/crates/db_schema/src/impls/registration_application.rs @@ -1,47 +1,61 @@ -use crate::{newtypes::LocalUserId, source::registration_application::*, traits::Crud}; -use diesel::{insert_into, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; +use crate::{ + newtypes::LocalUserId, + schema::registration_application::dsl::*, + source::registration_application::*, + traits::Crud, + utils::{get_conn, DbPool}, +}; +use diesel::{insert_into, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; +#[async_trait] impl Crud for RegistrationApplication { type InsertForm = RegistrationApplicationInsertForm; type UpdateForm = RegistrationApplicationUpdateForm; type IdType = i32; - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { - use crate::schema::registration_application::dsl::*; + + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; insert_into(registration_application) .values(form) .get_result::(conn) + .await } - fn read(conn: &mut PgConnection, id_: Self::IdType) -> Result { - use crate::schema::registration_application::dsl::*; - registration_application.find(id_).first::(conn) + async fn read(pool: &DbPool, id_: Self::IdType) -> Result { + let conn = &mut get_conn(pool).await?; + registration_application.find(id_).first::(conn).await } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, id_: Self::IdType, form: &Self::UpdateForm, ) -> Result { - use crate::schema::registration_application::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(registration_application.find(id_)) .set(form) .get_result::(conn) + .await } - fn delete(conn: &mut PgConnection, id_: Self::IdType) -> Result { - use crate::schema::registration_application::dsl::*; - diesel::delete(registration_application.find(id_)).execute(conn) + async fn delete(pool: &DbPool, id_: Self::IdType) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(registration_application.find(id_)) + .execute(conn) + .await } } impl RegistrationApplication { - pub fn find_by_local_user_id( - conn: &mut PgConnection, + pub async fn find_by_local_user_id( + pool: &DbPool, local_user_id_: LocalUserId, ) -> Result { - use crate::schema::registration_application::dsl::*; + let conn = &mut get_conn(pool).await?; registration_application .filter(local_user_id.eq(local_user_id_)) .first::(conn) + .await } } diff --git a/crates/db_schema/src/impls/secret.rs b/crates/db_schema/src/impls/secret.rs index 1f92ee24..0c005c09 100644 --- a/crates/db_schema/src/impls/secret.rs +++ b/crates/db_schema/src/impls/secret.rs @@ -1,15 +1,20 @@ -use crate::source::secret::Secret; -use diesel::{result::Error, *}; +use crate::{ + schema::secret::dsl::*, + source::secret::Secret, + utils::{get_conn, DbPool}, +}; +use diesel::result::Error; +use diesel_async::RunQueryDsl; impl Secret { /// Initialize the Secrets from the DB. /// Warning: You should only call this once. - pub fn init(conn: &mut PgConnection) -> Result { - read_secrets(conn) + pub async fn init(pool: &DbPool) -> Result { + Self::read_secrets(pool).await } -} -fn read_secrets(conn: &mut PgConnection) -> Result { - use crate::schema::secret::dsl::*; - secret.first::(conn) + async fn read_secrets(pool: &DbPool) -> Result { + let conn = &mut get_conn(pool).await?; + secret.first::(conn).await + } } diff --git a/crates/db_schema/src/impls/site.rs b/crates/db_schema/src/impls/site.rs index de53c19d..0588f008 100644 --- a/crates/db_schema/src/impls/site.rs +++ b/crates/db_schema/src/impls/site.rs @@ -1,68 +1,75 @@ use crate::{ newtypes::{DbUrl, SiteId}, + schema::site::dsl::*, source::{actor_language::SiteLanguage, site::*}, traits::Crud, + utils::{get_conn, DbPool}, }; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use url::Url; +#[async_trait] impl Crud for Site { type InsertForm = SiteInsertForm; type UpdateForm = SiteUpdateForm; type IdType = SiteId; - fn read(conn: &mut PgConnection, _site_id: SiteId) -> Result { - use crate::schema::site::dsl::*; - site.first::(conn) - } - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result { - use crate::schema::site::dsl::*; + async fn read(pool: &DbPool, _site_id: SiteId) -> Result { + let conn = &mut get_conn(pool).await?; + site.first::(conn).await + } + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result { + let conn = &mut get_conn(pool).await?; let site_ = insert_into(site) .values(form) .on_conflict(actor_id) .do_update() .set(form) - .get_result::(conn)?; + .get_result::(conn) + .await?; // initialize with all languages - SiteLanguage::update(conn, vec![], &site_)?; + SiteLanguage::update(pool, vec![], &site_).await?; Ok(site_) } - fn update( - conn: &mut PgConnection, + async fn update( + pool: &DbPool, site_id: SiteId, new_site: &Self::UpdateForm, ) -> Result { - use crate::schema::site::dsl::*; + let conn = &mut get_conn(pool).await?; diesel::update(site.find(site_id)) .set(new_site) .get_result::(conn) + .await } - fn delete(conn: &mut PgConnection, site_id: SiteId) -> Result { - use crate::schema::site::dsl::*; - diesel::delete(site.find(site_id)).execute(conn) + async fn delete(pool: &DbPool, site_id: SiteId) -> Result { + let conn = &mut get_conn(pool).await?; + diesel::delete(site.find(site_id)).execute(conn).await } } impl Site { - pub fn read_from_apub_id(conn: &mut PgConnection, object_id: Url) -> Result, Error> { - use crate::schema::site::dsl::*; + pub async fn read_from_apub_id(pool: &DbPool, object_id: Url) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let object_id: DbUrl = object_id.into(); Ok( site .filter(actor_id.eq(object_id)) .first::(conn) + .await .ok() .map(Into::into), ) } // TODO this needs fixed - pub fn read_remote_sites(conn: &mut PgConnection) -> Result, Error> { - use crate::schema::site::dsl::*; - site.order_by(id).offset(1).get_results::(conn) + pub async fn read_remote_sites(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + site.order_by(id).offset(1).get_results::(conn).await } } diff --git a/crates/db_schema/src/lib.rs b/crates/db_schema/src/lib.rs index a859b2aa..43b31c91 100644 --- a/crates/db_schema/src/lib.rs +++ b/crates/db_schema/src/lib.rs @@ -12,6 +12,9 @@ extern crate diesel_derive_newtype; #[macro_use] extern crate diesel_migrations; +#[macro_use] +extern crate async_trait; + pub mod aggregates; #[cfg(feature = "full")] pub mod impls; diff --git a/crates/db_schema/src/traits.rs b/crates/db_schema/src/traits.rs index 6e6d2c70..75cfcd50 100644 --- a/crates/db_schema/src/traits.rs +++ b/crates/db_schema/src/traits.rs @@ -1,69 +1,72 @@ -use crate::newtypes::{CommunityId, DbUrl, PersonId}; -use diesel::{result::Error, PgConnection}; +use crate::{ + newtypes::{CommunityId, DbUrl, PersonId}, + utils::DbPool, +}; +use diesel::result::Error; +#[async_trait] pub trait Crud { type InsertForm; type UpdateForm; type IdType; - fn create(conn: &mut PgConnection, form: &Self::InsertForm) -> Result + async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result where Self: Sized; - fn read(conn: &mut PgConnection, id: Self::IdType) -> Result + async fn read(pool: &DbPool, id: Self::IdType) -> Result where Self: Sized; /// when you want to null out a column, you have to send Some(None)), since sending None means you just don't want to update that column. - fn update( - conn: &mut PgConnection, - id: Self::IdType, - form: &Self::UpdateForm, - ) -> Result + async fn update(pool: &DbPool, id: Self::IdType, form: &Self::UpdateForm) -> Result where Self: Sized; - fn delete(_conn: &mut PgConnection, _id: Self::IdType) -> Result + async fn delete(_pool: &DbPool, _id: Self::IdType) -> Result where Self: Sized, + Self::IdType: Send, { - unimplemented!() + async { Err(Error::NotFound) }.await } } +#[async_trait] pub trait Followable { type Form; - fn follow(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn follow(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn follow_accepted( - conn: &mut PgConnection, + async fn follow_accepted( + pool: &DbPool, community_id: CommunityId, person_id: PersonId, ) -> Result where Self: Sized; - fn unfollow(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn unfollow(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn has_local_followers(conn: &mut PgConnection, community_id: CommunityId) - -> Result; + async fn has_local_followers(pool: &DbPool, community_id: CommunityId) -> Result; } +#[async_trait] pub trait Joinable { type Form; - fn join(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn join(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn leave(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn leave(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Likeable { type Form; type IdType; - fn like(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn like(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn remove( - conn: &mut PgConnection, + async fn remove( + pool: &DbPool, person_id: PersonId, item_id: Self::IdType, ) -> Result @@ -71,61 +74,66 @@ pub trait Likeable { Self: Sized; } +#[async_trait] pub trait Bannable { type Form; - fn ban(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn ban(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn unban(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn unban(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Saveable { type Form; - fn save(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn save(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn unsave(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn unsave(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Blockable { type Form; - fn block(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn block(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn unblock(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn unblock(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Readable { type Form; - fn mark_as_read(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn mark_as_read(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn mark_as_unread(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn mark_as_unread(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; } +#[async_trait] pub trait Reportable { type Form; type IdType; - fn report(conn: &mut PgConnection, form: &Self::Form) -> Result + async fn report(pool: &DbPool, form: &Self::Form) -> Result where Self: Sized; - fn resolve( - conn: &mut PgConnection, + async fn resolve( + pool: &DbPool, report_id: Self::IdType, resolver_id: PersonId, ) -> Result where Self: Sized; - fn unresolve( - conn: &mut PgConnection, + async fn unresolve( + pool: &DbPool, report_id: Self::IdType, resolver_id: PersonId, ) -> Result @@ -133,6 +141,7 @@ pub trait Reportable { Self: Sized; } +// TODO these should be removed, there should be another way to do this pub trait DeleteableOrRemoveable { fn blank_out_deleted_or_removed_info(self) -> Self; } @@ -154,22 +163,23 @@ pub trait ViewToVec { Self: Sized; } +#[async_trait] pub trait ApubActor { // TODO: this should be in a trait ApubObject (and implemented for Post, Comment, PrivateMessage as well) - fn read_from_apub_id(conn: &mut PgConnection, object_id: &DbUrl) -> Result, Error> + async fn read_from_apub_id(pool: &DbPool, object_id: &DbUrl) -> Result, Error> where Self: Sized; /// - actor_name is the name of the community or user to read. /// - include_deleted, if true, will return communities or users that were deleted/removed - fn read_from_name( - conn: &mut PgConnection, + async fn read_from_name( + pool: &DbPool, actor_name: &str, include_deleted: bool, ) -> Result where Self: Sized; - fn read_from_name_and_domain( - conn: &mut PgConnection, + async fn read_from_name_and_domain( + pool: &DbPool, actor_name: &str, protocol_domain: &str, ) -> Result diff --git a/crates/db_schema/src/utils.rs b/crates/db_schema/src/utils.rs index d20b32d8..f8a6f7db 100644 --- a/crates/db_schema/src/utils.rs +++ b/crates/db_schema/src/utils.rs @@ -1,18 +1,28 @@ -use crate::{diesel_migrations::MigrationHarness, newtypes::DbUrl, CommentSortType, SortType}; +use crate::{ + diesel::Connection, + diesel_migrations::MigrationHarness, + newtypes::DbUrl, + CommentSortType, + SortType, +}; use activitypub_federation::{core::object_id::ObjectId, traits::ApubObject}; +use bb8::PooledConnection; use chrono::NaiveDateTime; use diesel::{ backend::Backend, deserialize::FromSql, pg::Pg, - result::Error::QueryBuilderError, + result::{Error as DieselError, Error::QueryBuilderError}, serialize::{Output, ToSql}, sql_types::Text, - Connection, PgConnection, }; +use diesel_async::{ + pg::AsyncPgConnection, + pooled_connection::{bb8::Pool, AsyncDieselConnectionManager}, +}; use diesel_migrations::EmbeddedMigrations; -use lemmy_utils::error::LemmyError; +use lemmy_utils::{error::LemmyError, settings::structs::Settings}; use once_cell::sync::Lazy; use regex::Regex; use std::{env, env::VarError}; @@ -21,7 +31,14 @@ use url::Url; const FETCH_LIMIT_DEFAULT: i64 = 10; pub const FETCH_LIMIT_MAX: i64 = 50; -pub type DbPool = diesel::r2d2::Pool>; +pub type DbPool = Pool; + +pub async fn get_conn( + pool: &DbPool, +) -> Result>, DieselError> { + // TODO Maybe find a better diesel error for this + pool.get().await.map_err(|_| DieselError::NotInTransaction) +} pub fn get_database_url_from_env() -> Result { env::var("LEMMY_DATABASE_URL") @@ -114,22 +131,57 @@ pub fn diesel_option_overwrite_to_url_create( } } +async fn build_db_pool_settings_opt(settings: Option<&Settings>) -> Result { + let db_url = get_database_url(settings); + let pool_size = settings.map(|s| s.database.pool_size).unwrap_or(5); + let manager = AsyncDieselConnectionManager::::new(&db_url); + let pool = Pool::builder() + .max_size(pool_size) + .min_idle(Some(1)) + .build(manager) + .await?; + + // If there's no settings, that means its a unit test, and migrations need to be run + if settings.is_none() { + run_migrations(&db_url); + } + + Ok(pool) +} + pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); -pub fn establish_unpooled_connection() -> PgConnection { - let db_url = match get_database_url_from_env() { - Ok(url) => url, - Err(e) => panic!( - "Failed to read database URL from env var LEMMY_DATABASE_URL: {}", - e - ), - }; +pub fn run_migrations(db_url: &str) { + // Needs to be a sync connection let mut conn = - PgConnection::establish(&db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url)); + PgConnection::establish(db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url)); let _ = &mut conn .run_pending_migrations(MIGRATIONS) .unwrap_or_else(|_| panic!("Couldn't run DB Migrations")); - conn +} + +pub async fn build_db_pool(settings: &Settings) -> Result { + build_db_pool_settings_opt(Some(settings)).await +} + +pub async fn build_db_pool_for_tests() -> DbPool { + build_db_pool_settings_opt(None) + .await + .expect("db pool missing") +} + +pub fn get_database_url(settings: Option<&Settings>) -> String { + // The env var should override anything in the settings config + match get_database_url_from_env() { + Ok(url) => url, + Err(e) => match settings { + Some(settings) => settings.get_database_url(), + None => panic!( + "Failed to read database URL from env var LEMMY_DATABASE_URL: {}", + e + ), + }, + } } pub fn naive_now() -> NaiveDateTime { diff --git a/crates/db_views/Cargo.toml b/crates/db_views/Cargo.toml index 1a9e31eb..c454c282 100644 --- a/crates/db_views/Cargo.toml +++ b/crates/db_views/Cargo.toml @@ -12,16 +12,18 @@ rust-version = "1.57" doctest = false [features] -full = ["lemmy_db_schema/full", "diesel", "tracing"] +full = ["lemmy_db_schema/full", "diesel", "diesel-async", "diesel_ltree", "tracing"] [dependencies] lemmy_db_schema = { version = "=0.16.5", path = "../db_schema" } -diesel = { version = "2.0.0", features = ["postgres","chrono","r2d2","serde_json"], optional = true } -serde = { version = "1.0.145", features = ["derive"] } +diesel = { version = "2.0.2", features = ["postgres","chrono","serde_json"], optional = true } +diesel-async = { version = "0.1.1", features = ["postgres", "bb8"], optional = true} +diesel_ltree = { version = "0.3.0", optional = true} +serde = { version = "1.0.147", features = ["derive"] } tracing = { version = "0.1.36", optional = true } -diesel_ltree = "0.3.0" typed-builder = "0.10.0" url = { version = "2.3.1", features = ["serde"] } [dev-dependencies] serial_test = "0.9.0" +tokio = "1.21.2" diff --git a/crates/db_views/src/comment_report_view.rs b/crates/db_views/src/comment_report_view.rs index e4a6a493..75aed926 100644 --- a/crates/db_views/src/comment_report_view.rs +++ b/crates/db_views/src/comment_report_view.rs @@ -1,5 +1,14 @@ use crate::structs::CommentReportView; -use diesel::{dsl::*, result::Error, *}; +use diesel::{ + dsl::*, + result::Error, + BoolExpressionMethods, + ExpressionMethods, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::CommentAggregates, newtypes::{CommentReportId, CommunityId, PersonId}, @@ -22,7 +31,7 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; use typed_builder::TypedBuilder; @@ -43,11 +52,13 @@ impl CommentReportView { /// returns the CommentReportView for the provided report_id /// /// * `report_id` - the report id to obtain - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, report_id: CommentReportId, my_person_id: PersonId, ) -> Result { + let conn = &mut get_conn(pool).await?; + let (person_alias_1, person_alias_2) = diesel::alias!(person as person1, person as person2); let ( @@ -108,7 +119,8 @@ impl CommentReportView { .fields(Person::safe_columns_tuple()) .nullable(), )) - .first::(conn)?; + .first::(conn) + .await?; let my_vote = comment_like; @@ -127,14 +139,16 @@ impl CommentReportView { } /// Returns the current unresolved post report count for the communities you mod - pub fn get_report_count( - conn: &mut PgConnection, + pub async fn get_report_count( + pool: &DbPool, my_person_id: PersonId, admin: bool, community_id: Option, ) -> Result { use diesel::dsl::*; + let conn = &mut get_conn(pool).await?; + let mut query = comment_report::table .inner_join(comment::table) .inner_join(post::table.on(comment::post_id.eq(post::id))) @@ -157,8 +171,12 @@ impl CommentReportView { ) .select(count(comment_report::id)) .first::(conn) + .await } else { - query.select(count(comment_report::id)).first::(conn) + query + .select(count(comment_report::id)) + .first::(conn) + .await } } } @@ -167,7 +185,7 @@ impl CommentReportView { #[builder(field_defaults(default))] pub struct CommentReportQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, #[builder(!default)] my_person_id: PersonId, #[builder(!default)] @@ -179,7 +197,9 @@ pub struct CommentReportQuery<'a> { } impl<'a> CommentReportQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { + let conn = &mut get_conn(self.pool).await?; + let (person_alias_1, person_alias_2) = diesel::alias!(person as person1, person as person2); let mut query = comment_report::table @@ -255,9 +275,10 @@ impl<'a> CommentReportQuery<'a> { .and(community_moderator::person_id.eq(self.my_person_id)), ), ) - .load::(self.conn)? + .load::(conn) + .await? } else { - query.load::(self.conn)? + query.load::(conn).await? }; Ok(CommentReportView::from_tuple_to_vec(res)) @@ -292,16 +313,16 @@ mod tests { aggregates::structs::CommentAggregates, source::{comment::*, comment_report::*, community::*, instance::Instance, person::*, post::*}, traits::{Crud, Joinable, Reportable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("timmy_crv".into()) @@ -309,7 +330,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_timmy = Person::create(conn, &new_person).unwrap(); + let inserted_timmy = Person::create(pool, &new_person).await.unwrap(); let new_person_2 = PersonInsertForm::builder() .name("sara_crv".into()) @@ -317,7 +338,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_sara = Person::create(conn, &new_person_2).unwrap(); + let inserted_sara = Person::create(pool, &new_person_2).await.unwrap(); // Add a third person, since new ppl can only report something once. let new_person_3 = PersonInsertForm::builder() @@ -326,7 +347,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_jessica = Person::create(conn, &new_person_3).unwrap(); + let inserted_jessica = Person::create(pool, &new_person_3).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("test community crv".to_string()) @@ -335,7 +356,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); // Make timmy a mod let timmy_moderator_form = CommunityModeratorForm { @@ -343,7 +364,9 @@ mod tests { person_id: inserted_timmy.id, }; - let _inserted_moderator = CommunityModerator::join(conn, &timmy_moderator_form).unwrap(); + let _inserted_moderator = CommunityModerator::join(pool, &timmy_moderator_form) + .await + .unwrap(); let new_post = PostInsertForm::builder() .name("A test post crv".into()) @@ -351,7 +374,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let comment_form = CommentInsertForm::builder() .content("A test comment 32".into()) @@ -359,7 +382,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment = Comment::create(conn, &comment_form, None).unwrap(); + let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap(); // sara reports let sara_report_form = CommentReportForm { @@ -369,7 +392,9 @@ mod tests { reason: "from sara".into(), }; - let inserted_sara_report = CommentReport::report(conn, &sara_report_form).unwrap(); + let inserted_sara_report = CommentReport::report(pool, &sara_report_form) + .await + .unwrap(); // jessica reports let jessica_report_form = CommentReportForm { @@ -379,12 +404,18 @@ mod tests { reason: "from jessica".into(), }; - let inserted_jessica_report = CommentReport::report(conn, &jessica_report_form).unwrap(); + let inserted_jessica_report = CommentReport::report(pool, &jessica_report_form) + .await + .unwrap(); - let agg = CommentAggregates::read(conn, inserted_comment.id).unwrap(); + let agg = CommentAggregates::read(pool, inserted_comment.id) + .await + .unwrap(); let read_jessica_report_view = - CommentReportView::read(conn, inserted_jessica_report.id, inserted_timmy.id).unwrap(); + CommentReportView::read(pool, inserted_jessica_report.id, inserted_timmy.id) + .await + .unwrap(); let expected_jessica_report_view = CommentReportView { comment_report: inserted_jessica_report.to_owned(), comment: inserted_comment.to_owned(), @@ -491,11 +522,12 @@ mod tests { // Do a batch read of timmys reports let reports = CommentReportQuery::builder() - .conn(conn) + .pool(pool) .my_person_id(inserted_timmy.id) .admin(false) .build() .list() + .await .unwrap(); assert_eq!( @@ -507,14 +539,19 @@ mod tests { ); // Make sure the counts are correct - let report_count = - CommentReportView::get_report_count(conn, inserted_timmy.id, false, None).unwrap(); + let report_count = CommentReportView::get_report_count(pool, inserted_timmy.id, false, None) + .await + .unwrap(); assert_eq!(2, report_count); // Try to resolve the report - CommentReport::resolve(conn, inserted_jessica_report.id, inserted_timmy.id).unwrap(); + CommentReport::resolve(pool, inserted_jessica_report.id, inserted_timmy.id) + .await + .unwrap(); let read_jessica_report_view_after_resolve = - CommentReportView::read(conn, inserted_jessica_report.id, inserted_timmy.id).unwrap(); + CommentReportView::read(pool, inserted_jessica_report.id, inserted_timmy.id) + .await + .unwrap(); let mut expected_jessica_report_view_after_resolve = expected_jessica_report_view; expected_jessica_report_view_after_resolve @@ -558,24 +595,29 @@ mod tests { // Do a batch read of timmys reports // It should only show saras, which is unresolved let reports_after_resolve = CommentReportQuery::builder() - .conn(conn) + .pool(pool) .my_person_id(inserted_timmy.id) .admin(false) .build() .list() + .await .unwrap(); assert_eq!(reports_after_resolve[0], expected_sara_report_view); assert_eq!(reports_after_resolve.len(), 1); // Make sure the counts are correct let report_count_after_resolved = - CommentReportView::get_report_count(conn, inserted_timmy.id, false, None).unwrap(); + CommentReportView::get_report_count(pool, inserted_timmy.id, false, None) + .await + .unwrap(); assert_eq!(1, report_count_after_resolved); - Person::delete(conn, inserted_timmy.id).unwrap(); - Person::delete(conn, inserted_sara.id).unwrap(); - Person::delete(conn, inserted_jessica.id).unwrap(); - Community::delete(conn, inserted_community.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + Person::delete(pool, inserted_timmy.id).await.unwrap(); + Person::delete(pool, inserted_sara.id).await.unwrap(); + Person::delete(pool, inserted_jessica.id).await.unwrap(); + Community::delete(pool, inserted_community.id) + .await + .unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); } } diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index 5a94d37a..15ec034f 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -1,5 +1,15 @@ use crate::structs::CommentView; -use diesel::{dsl::*, result::Error, *}; +use diesel::{ + dsl::*, + result::Error, + BoolExpressionMethods, + ExpressionMethods, + JoinOnDsl, + NullableExpressionMethods, + PgTextExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use diesel_ltree::{nlevel, subpath, Ltree, LtreeExtensions}; use lemmy_db_schema::{ aggregates::structs::CommentAggregates, @@ -27,7 +37,7 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::{functions::hot_rank, fuzzy_search, limit_and_offset_unlimited}, + utils::{functions::hot_rank, fuzzy_search, get_conn, limit_and_offset_unlimited, DbPool}, CommentSortType, ListingType, }; @@ -47,11 +57,13 @@ type CommentViewTuple = ( ); impl CommentView { - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, comment_id: CommentId, my_person_id: Option, ) -> Result { + let conn = &mut get_conn(pool).await?; + // The left join below will return None in this case let person_id_join = my_person_id.unwrap_or(PersonId(-1)); @@ -124,7 +136,8 @@ impl CommentView { person_block::all_columns.nullable(), comment_like::score.nullable(), )) - .first::(conn)?; + .first::(conn) + .await?; // If a person is given, then my_vote, if None, should be 0, not null // Necessary to differentiate between other person's votes @@ -153,7 +166,7 @@ impl CommentView { #[builder(field_defaults(default))] pub struct CommentQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, listing_type: Option, sort: Option, community_id: Option, @@ -171,8 +184,9 @@ pub struct CommentQuery<'a> { } impl<'a> CommentQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { use diesel::dsl::*; + let conn = &mut get_conn(self.pool).await?; // The left join below will return None in this case let person_id_join = self.local_user.map(|l| l.person_id).unwrap_or(PersonId(-1)); @@ -359,7 +373,8 @@ impl<'a> CommentQuery<'a> { let res = query .limit(limit) .offset(offset) - .load::(self.conn)?; + .load::(conn) + .await?; Ok(CommentView::from_tuple_to_vec(res)) } @@ -404,7 +419,7 @@ mod tests { post::*, }, traits::{Blockable, Crud, Likeable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, SubscribedType, }; use serial_test::serial; @@ -421,27 +436,27 @@ mod tests { inserted_community: Community, } - fn init_data(conn: &mut PgConnection) -> Data { - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + async fn init_data(pool: &DbPool) -> Data { + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("timmy".into()) .public_key("pubkey".to_string()) .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let local_user_form = LocalUserInsertForm::builder() .person_id(inserted_person.id) .password_encrypted("".to_string()) .build(); - let inserted_local_user = LocalUser::create(conn, &local_user_form).unwrap(); + let inserted_local_user = LocalUser::create(pool, &local_user_form).await.unwrap(); let new_person_2 = PersonInsertForm::builder() .name("sara".into()) .public_key("pubkey".to_string()) .instance_id(inserted_instance.id) .build(); - let inserted_person_2 = Person::create(conn, &new_person_2).unwrap(); + let inserted_person_2 = Person::create(pool, &new_person_2).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("test community 5".to_string()) @@ -450,7 +465,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); let new_post = PostInsertForm::builder() .name("A test post 2".into()) @@ -458,7 +473,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); // Create a comment tree with this hierarchy // 0 @@ -474,7 +489,7 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment_0 = Comment::create(conn, &comment_form_0, None).unwrap(); + let inserted_comment_0 = Comment::create(pool, &comment_form_0, None).await.unwrap(); let comment_form_1 = CommentInsertForm::builder() .content("Comment 1, A test blocked comment".into()) @@ -482,10 +497,11 @@ mod tests { .post_id(inserted_post.id) .build(); - let inserted_comment_1 = - Comment::create(conn, &comment_form_1, Some(&inserted_comment_0.path)).unwrap(); + let inserted_comment_1 = Comment::create(pool, &comment_form_1, Some(&inserted_comment_0.path)) + .await + .unwrap(); - let finnish_id = Language::read_id_from_code(conn, "fi").unwrap(); + let finnish_id = Language::read_id_from_code(pool, "fi").await.unwrap(); let comment_form_2 = CommentInsertForm::builder() .content("Comment 2".into()) .creator_id(inserted_person.id) @@ -493,8 +509,9 @@ mod tests { .language_id(Some(finnish_id)) .build(); - let inserted_comment_2 = - Comment::create(conn, &comment_form_2, Some(&inserted_comment_0.path)).unwrap(); + let inserted_comment_2 = Comment::create(pool, &comment_form_2, Some(&inserted_comment_0.path)) + .await + .unwrap(); let comment_form_3 = CommentInsertForm::builder() .content("Comment 3".into()) @@ -503,9 +520,11 @@ mod tests { .build(); let _inserted_comment_3 = - Comment::create(conn, &comment_form_3, Some(&inserted_comment_1.path)).unwrap(); + Comment::create(pool, &comment_form_3, Some(&inserted_comment_1.path)) + .await + .unwrap(); - let polish_id = Language::read_id_from_code(conn, "pl").unwrap(); + let polish_id = Language::read_id_from_code(pool, "pl").await.unwrap(); let comment_form_4 = CommentInsertForm::builder() .content("Comment 4".into()) .creator_id(inserted_person.id) @@ -513,8 +532,9 @@ mod tests { .language_id(Some(polish_id)) .build(); - let inserted_comment_4 = - Comment::create(conn, &comment_form_4, Some(&inserted_comment_1.path)).unwrap(); + let inserted_comment_4 = Comment::create(pool, &comment_form_4, Some(&inserted_comment_1.path)) + .await + .unwrap(); let comment_form_5 = CommentInsertForm::builder() .content("Comment 5".into()) @@ -523,14 +543,18 @@ mod tests { .build(); let _inserted_comment_5 = - Comment::create(conn, &comment_form_5, Some(&inserted_comment_4.path)).unwrap(); + Comment::create(pool, &comment_form_5, Some(&inserted_comment_4.path)) + .await + .unwrap(); let timmy_blocks_sara_form = PersonBlockForm { person_id: inserted_person.id, target_id: inserted_person_2.id, }; - let inserted_block = PersonBlock::block(conn, &timmy_blocks_sara_form).unwrap(); + let inserted_block = PersonBlock::block(pool, &timmy_blocks_sara_form) + .await + .unwrap(); let expected_block = PersonBlock { id: inserted_block.id, @@ -547,7 +571,7 @@ mod tests { score: 1, }; - let _inserted_comment_like = CommentLike::like(conn, &comment_like_form).unwrap(); + let _inserted_comment_like = CommentLike::like(pool, &comment_like_form).await.unwrap(); Data { inserted_instance, @@ -562,22 +586,23 @@ mod tests { } } - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); - let data = init_data(conn); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; + let data = init_data(pool).await; - let expected_comment_view_no_person = expected_comment_view(&data, conn); + let expected_comment_view_no_person = expected_comment_view(&data, pool).await; let mut expected_comment_view_with_person = expected_comment_view_no_person.to_owned(); expected_comment_view_with_person.my_vote = Some(1); let read_comment_views_no_person = CommentQuery::builder() - .conn(conn) + .pool(pool) .post_id(Some(data.inserted_post.id)) .build() .list() + .await .unwrap(); assert_eq!( @@ -586,11 +611,12 @@ mod tests { ); let read_comment_views_with_person = CommentQuery::builder() - .conn(conn) + .pool(pool) .post_id(Some(data.inserted_post.id)) .local_user(Some(&data.inserted_local_user)) .build() .list() + .await .unwrap(); assert_eq!( @@ -602,40 +628,43 @@ mod tests { assert_eq!(5, read_comment_views_with_person.len()); let read_comment_from_blocked_person = CommentView::read( - conn, + pool, data.inserted_comment_1.id, Some(data.inserted_person.id), ) + .await .unwrap(); // Make sure block set the creator blocked assert!(read_comment_from_blocked_person.creator_blocked); - cleanup(data, conn); + cleanup(data, pool).await; } - #[test] + #[tokio::test] #[serial] - fn test_comment_tree() { - let conn = &mut establish_unpooled_connection(); - let data = init_data(conn); + async fn test_comment_tree() { + let pool = &build_db_pool_for_tests().await; + let data = init_data(pool).await; let top_path = data.inserted_comment_0.path.clone(); let read_comment_views_top_path = CommentQuery::builder() - .conn(conn) + .pool(pool) .post_id(Some(data.inserted_post.id)) .parent_path(Some(top_path)) .build() .list() + .await .unwrap(); let child_path = data.inserted_comment_1.path.clone(); let read_comment_views_child_path = CommentQuery::builder() - .conn(conn) + .pool(pool) .post_id(Some(data.inserted_post.id)) .parent_path(Some(child_path)) .build() .list() + .await .unwrap(); // Make sure the comment parent-limited fetch is correct @@ -651,29 +680,31 @@ mod tests { assert!(!child_comments.contains(&data.inserted_comment_2)); let read_comment_views_top_max_depth = CommentQuery::builder() - .conn(conn) + .pool(pool) .post_id(Some(data.inserted_post.id)) .max_depth(Some(1)) .build() .list() + .await .unwrap(); // Make sure a depth limited one only has the top comment assert_eq!( - expected_comment_view(&data, conn), + expected_comment_view(&data, pool).await, read_comment_views_top_max_depth[0] ); assert_eq!(1, read_comment_views_top_max_depth.len()); let child_path = data.inserted_comment_1.path.clone(); let read_comment_views_parent_max_depth = CommentQuery::builder() - .conn(conn) + .pool(pool) .post_id(Some(data.inserted_post.id)) .parent_path(Some(child_path)) .max_depth(Some(1)) .sort(Some(CommentSortType::New)) .build() .list() + .await .unwrap(); // Make sure a depth limited one, and given child comment 1, has 3 @@ -683,33 +714,37 @@ mod tests { .eq("Comment 3")); assert_eq!(3, read_comment_views_parent_max_depth.len()); - cleanup(data, conn); + cleanup(data, pool).await; } - #[test] + #[tokio::test] #[serial] - fn test_languages() { - let conn = &mut establish_unpooled_connection(); - let data = init_data(conn); + async fn test_languages() { + let pool = &build_db_pool_for_tests().await; + let data = init_data(pool).await; // by default, user has all languages enabled and should see all comments // (except from blocked user) let all_languages = CommentQuery::builder() - .conn(conn) + .pool(pool) .local_user(Some(&data.inserted_local_user)) .build() .list() + .await .unwrap(); assert_eq!(5, all_languages.len()); // change user lang to finnish, should only show single finnish comment - let finnish_id = Language::read_id_from_code(conn, "fi").unwrap(); - LocalUserLanguage::update(conn, vec![finnish_id], data.inserted_local_user.id).unwrap(); + let finnish_id = Language::read_id_from_code(pool, "fi").await.unwrap(); + LocalUserLanguage::update(pool, vec![finnish_id], data.inserted_local_user.id) + .await + .unwrap(); let finnish_comment = CommentQuery::builder() - .conn(conn) + .pool(pool) .local_user(Some(&data.inserted_local_user)) .build() .list() + .await .unwrap(); assert_eq!(1, finnish_comment.len()); assert_eq!( @@ -719,32 +754,49 @@ mod tests { assert_eq!(finnish_id, finnish_comment[0].comment.language_id); // now show all comments with undetermined language (which is the default value) - let undetermined_id = Language::read_id_from_code(conn, "und").unwrap(); - LocalUserLanguage::update(conn, vec![undetermined_id], data.inserted_local_user.id).unwrap(); + let undetermined_id = Language::read_id_from_code(pool, "und").await.unwrap(); + LocalUserLanguage::update(pool, vec![undetermined_id], data.inserted_local_user.id) + .await + .unwrap(); let undetermined_comment = CommentQuery::builder() - .conn(conn) + .pool(pool) .local_user(Some(&data.inserted_local_user)) .build() .list() + .await .unwrap(); assert_eq!(3, undetermined_comment.len()); - cleanup(data, conn); + cleanup(data, pool).await; } - fn cleanup(data: Data, conn: &mut PgConnection) { - CommentLike::remove(conn, data.inserted_person.id, data.inserted_comment_0.id).unwrap(); - Comment::delete(conn, data.inserted_comment_0.id).unwrap(); - Comment::delete(conn, data.inserted_comment_1.id).unwrap(); - Post::delete(conn, data.inserted_post.id).unwrap(); - Community::delete(conn, data.inserted_community.id).unwrap(); - Person::delete(conn, data.inserted_person.id).unwrap(); - Person::delete(conn, data.inserted_person_2.id).unwrap(); - Instance::delete(conn, data.inserted_instance.id).unwrap(); + async fn cleanup(data: Data, pool: &DbPool) { + CommentLike::remove(pool, data.inserted_person.id, data.inserted_comment_0.id) + .await + .unwrap(); + Comment::delete(pool, data.inserted_comment_0.id) + .await + .unwrap(); + Comment::delete(pool, data.inserted_comment_1.id) + .await + .unwrap(); + Post::delete(pool, data.inserted_post.id).await.unwrap(); + Community::delete(pool, data.inserted_community.id) + .await + .unwrap(); + Person::delete(pool, data.inserted_person.id).await.unwrap(); + Person::delete(pool, data.inserted_person_2.id) + .await + .unwrap(); + Instance::delete(pool, data.inserted_instance.id) + .await + .unwrap(); } - fn expected_comment_view(data: &Data, conn: &mut PgConnection) -> CommentView { - let agg = CommentAggregates::read(conn, data.inserted_comment_0.id).unwrap(); + async fn expected_comment_view(data: &Data, pool: &DbPool) -> CommentView { + let agg = CommentAggregates::read(pool, data.inserted_comment_0.id) + .await + .unwrap(); CommentView { creator_banned_from_community: false, my_vote: None, diff --git a/crates/db_views/src/local_user_discussion_language_view.rs b/crates/db_views/src/local_user_discussion_language_view.rs index 0268de1c..9ffa47ec 100644 --- a/crates/db_views/src/local_user_discussion_language_view.rs +++ b/crates/db_views/src/local_user_discussion_language_view.rs @@ -1,5 +1,6 @@ use crate::structs::LocalUserDiscussionLanguageView; -use diesel::{result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::LocalUserId, schema::{language, local_user, local_user_language}, @@ -8,15 +9,18 @@ use lemmy_db_schema::{ local_user::{LocalUser, LocalUserSettings}, }, traits::ToSafeSettings, + utils::{get_conn, DbPool}, }; type LocalUserDiscussionLanguageViewTuple = (LocalUserSettings, Language); impl LocalUserDiscussionLanguageView { - pub fn read_languages( - conn: &mut PgConnection, + pub async fn read_languages( + pool: &DbPool, local_user_id: LocalUserId, ) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + let res = local_user_language::table .inner_join(local_user::table) .inner_join(language::table) @@ -25,7 +29,8 @@ impl LocalUserDiscussionLanguageView { language::all_columns, )) .filter(local_user::id.eq(local_user_id)) - .load::(conn)?; + .load::(conn) + .await?; Ok(res.into_iter().map(|a| a.1).collect::>()) } diff --git a/crates/db_views/src/local_user_view.rs b/crates/db_views/src/local_user_view.rs index b5a758b8..da735aae 100644 --- a/crates/db_views/src/local_user_view.rs +++ b/crates/db_views/src/local_user_view.rs @@ -1,5 +1,6 @@ use crate::structs::{LocalUserSettingsView, LocalUserView}; -use diesel::{result::Error, *}; +use diesel::{result::Error, BoolExpressionMethods, ExpressionMethods, JoinOnDsl, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::PersonAggregates, newtypes::{LocalUserId, PersonId}, @@ -9,13 +10,15 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ToSafeSettings, ViewToVec}, - utils::functions::lower, + utils::{functions::lower, get_conn, DbPool}, }; type LocalUserViewTuple = (LocalUser, Person, PersonAggregates); impl LocalUserView { - pub fn read(conn: &mut PgConnection, local_user_id: LocalUserId) -> Result { + pub async fn read(pool: &DbPool, local_user_id: LocalUserId) -> Result { + let conn = &mut get_conn(pool).await?; + let (local_user, person, counts) = local_user::table .find(local_user_id) .inner_join(person::table) @@ -25,7 +28,8 @@ impl LocalUserView { person::all_columns, person_aggregates::all_columns, )) - .first::(conn)?; + .first::(conn) + .await?; Ok(Self { local_user, person, @@ -33,7 +37,8 @@ impl LocalUserView { }) } - pub fn read_person(conn: &mut PgConnection, person_id: PersonId) -> Result { + pub async fn read_person(pool: &DbPool, person_id: PersonId) -> Result { + let conn = &mut get_conn(pool).await?; let (local_user, person, counts) = local_user::table .filter(person::id.eq(person_id)) .inner_join(person::table) @@ -43,7 +48,8 @@ impl LocalUserView { person::all_columns, person_aggregates::all_columns, )) - .first::(conn)?; + .first::(conn) + .await?; Ok(Self { local_user, person, @@ -52,7 +58,8 @@ impl LocalUserView { } // TODO check where this is used - pub fn read_from_name(conn: &mut PgConnection, name: &str) -> Result { + pub async fn read_from_name(pool: &DbPool, name: &str) -> Result { + let conn = &mut get_conn(pool).await?; let (local_user, person, counts) = local_user::table .filter(person::name.eq(name)) .inner_join(person::table) @@ -62,7 +69,8 @@ impl LocalUserView { person::all_columns, person_aggregates::all_columns, )) - .first::(conn)?; + .first::(conn) + .await?; Ok(Self { local_user, person, @@ -70,10 +78,8 @@ impl LocalUserView { }) } - pub fn find_by_email_or_name( - conn: &mut PgConnection, - name_or_email: &str, - ) -> Result { + pub async fn find_by_email_or_name(pool: &DbPool, name_or_email: &str) -> Result { + let conn = &mut get_conn(pool).await?; let (local_user, person, counts) = local_user::table .inner_join(person::table) .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) @@ -87,7 +93,8 @@ impl LocalUserView { person::all_columns, person_aggregates::all_columns, )) - .first::(conn)?; + .first::(conn) + .await?; Ok(Self { local_user, person, @@ -95,7 +102,8 @@ impl LocalUserView { }) } - pub fn find_by_email(conn: &mut PgConnection, from_email: &str) -> Result { + pub async fn find_by_email(pool: &DbPool, from_email: &str) -> Result { + let conn = &mut get_conn(pool).await?; let (local_user, person, counts) = local_user::table .inner_join(person::table) .inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id))) @@ -105,7 +113,8 @@ impl LocalUserView { person::all_columns, person_aggregates::all_columns, )) - .first::(conn)?; + .first::(conn) + .await?; Ok(Self { local_user, person, @@ -117,7 +126,8 @@ impl LocalUserView { type LocalUserSettingsViewTuple = (LocalUserSettings, PersonSafe, PersonAggregates); impl LocalUserSettingsView { - pub fn read(conn: &mut PgConnection, local_user_id: LocalUserId) -> Result { + pub async fn read(pool: &DbPool, local_user_id: LocalUserId) -> Result { + let conn = &mut get_conn(pool).await?; let (local_user, person, counts) = local_user::table .find(local_user_id) .inner_join(person::table) @@ -127,7 +137,8 @@ impl LocalUserSettingsView { Person::safe_columns_tuple(), person_aggregates::all_columns, )) - .first::(conn)?; + .first::(conn) + .await?; Ok(Self { local_user, person, @@ -135,7 +146,8 @@ impl LocalUserSettingsView { }) } - pub fn list_admins_with_emails(conn: &mut PgConnection) -> Result, Error> { + pub async fn list_admins_with_emails(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let res = local_user::table .filter(person::admin.eq(true)) .filter(local_user::email.is_not_null()) @@ -146,7 +158,8 @@ impl LocalUserSettingsView { Person::safe_columns_tuple(), person_aggregates::all_columns, )) - .load::(conn)?; + .load::(conn) + .await?; Ok(LocalUserSettingsView::from_tuple_to_vec(res)) } diff --git a/crates/db_views/src/post_report_view.rs b/crates/db_views/src/post_report_view.rs index 83c43ff4..555a65ae 100644 --- a/crates/db_views/src/post_report_view.rs +++ b/crates/db_views/src/post_report_view.rs @@ -1,5 +1,14 @@ use crate::structs::PostReportView; -use diesel::{dsl::*, result::Error, *}; +use diesel::{ + dsl::*, + result::Error, + BoolExpressionMethods, + ExpressionMethods, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::PostAggregates, newtypes::{CommunityId, PersonId, PostReportId}, @@ -20,7 +29,7 @@ use lemmy_db_schema::{ post_report::PostReport, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; use typed_builder::TypedBuilder; @@ -40,11 +49,12 @@ impl PostReportView { /// returns the PostReportView for the provided report_id /// /// * `report_id` - the report id to obtain - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, report_id: PostReportId, my_person_id: PersonId, ) -> Result { + let conn = &mut get_conn(pool).await?; let (person_alias_1, person_alias_2) = diesel::alias!(person as person1, person as person2); let ( @@ -97,7 +107,8 @@ impl PostReportView { post_aggregates::all_columns, person_alias_2.fields(Person::safe_columns_tuple().nullable()), )) - .first::(conn)?; + .first::(conn) + .await?; let my_vote = post_like; @@ -115,13 +126,14 @@ impl PostReportView { } /// returns the current unresolved post report count for the communities you mod - pub fn get_report_count( - conn: &mut PgConnection, + pub async fn get_report_count( + pool: &DbPool, my_person_id: PersonId, admin: bool, community_id: Option, ) -> Result { use diesel::dsl::*; + let conn = &mut get_conn(pool).await?; let mut query = post_report::table .inner_join(post::table) .filter(post_report::resolved.eq(false)) @@ -143,8 +155,12 @@ impl PostReportView { ) .select(count(post_report::id)) .first::(conn) + .await } else { - query.select(count(post_report::id)).first::(conn) + query + .select(count(post_report::id)) + .first::(conn) + .await } } } @@ -153,7 +169,7 @@ impl PostReportView { #[builder(field_defaults(default))] pub struct PostReportQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, #[builder(!default)] my_person_id: PersonId, #[builder(!default)] @@ -165,7 +181,8 @@ pub struct PostReportQuery<'a> { } impl<'a> PostReportQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { + let conn = &mut get_conn(self.pool).await?; let (person_alias_1, person_alias_2) = diesel::alias!(person as person1, person as person2); let mut query = post_report::table @@ -236,9 +253,10 @@ impl<'a> PostReportQuery<'a> { .and(community_moderator::person_id.eq(self.my_person_id)), ), ) - .load::(self.conn)? + .load::(conn) + .await? } else { - query.load::(self.conn)? + query.load::(conn).await? }; Ok(PostReportView::from_tuple_to_vec(res)) @@ -278,16 +296,16 @@ mod tests { post_report::{PostReport, PostReportForm}, }, traits::{Crud, Joinable, Reportable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person = PersonInsertForm::builder() .name("timmy_prv".into()) @@ -295,7 +313,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_timmy = Person::create(conn, &new_person).unwrap(); + let inserted_timmy = Person::create(pool, &new_person).await.unwrap(); let new_person_2 = PersonInsertForm::builder() .name("sara_prv".into()) @@ -303,7 +321,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_sara = Person::create(conn, &new_person_2).unwrap(); + let inserted_sara = Person::create(pool, &new_person_2).await.unwrap(); // Add a third person, since new ppl can only report something once. let new_person_3 = PersonInsertForm::builder() @@ -312,7 +330,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_jessica = Person::create(conn, &new_person_3).unwrap(); + let inserted_jessica = Person::create(pool, &new_person_3).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("test community prv".to_string()) @@ -321,7 +339,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); // Make timmy a mod let timmy_moderator_form = CommunityModeratorForm { @@ -329,7 +347,9 @@ mod tests { person_id: inserted_timmy.id, }; - let _inserted_moderator = CommunityModerator::join(conn, &timmy_moderator_form).unwrap(); + let _inserted_moderator = CommunityModerator::join(pool, &timmy_moderator_form) + .await + .unwrap(); let new_post = PostInsertForm::builder() .name("A test post crv".into()) @@ -337,7 +357,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); // sara reports let sara_report_form = PostReportForm { @@ -349,7 +369,7 @@ mod tests { reason: "from sara".into(), }; - let inserted_sara_report = PostReport::report(conn, &sara_report_form).unwrap(); + let inserted_sara_report = PostReport::report(pool, &sara_report_form).await.unwrap(); // jessica reports let jessica_report_form = PostReportForm { @@ -361,12 +381,16 @@ mod tests { reason: "from jessica".into(), }; - let inserted_jessica_report = PostReport::report(conn, &jessica_report_form).unwrap(); + let inserted_jessica_report = PostReport::report(pool, &jessica_report_form) + .await + .unwrap(); - let agg = PostAggregates::read(conn, inserted_post.id).unwrap(); + let agg = PostAggregates::read(pool, inserted_post.id).await.unwrap(); let read_jessica_report_view = - PostReportView::read(conn, inserted_jessica_report.id, inserted_timmy.id).unwrap(); + PostReportView::read(pool, inserted_jessica_report.id, inserted_timmy.id) + .await + .unwrap(); let expected_jessica_report_view = PostReportView { post_report: inserted_jessica_report.to_owned(), post: inserted_post.to_owned(), @@ -476,11 +500,12 @@ mod tests { // Do a batch read of timmys reports let reports = PostReportQuery::builder() - .conn(conn) + .pool(pool) .my_person_id(inserted_timmy.id) .admin(false) .build() .list() + .await .unwrap(); assert_eq!( @@ -492,14 +517,19 @@ mod tests { ); // Make sure the counts are correct - let report_count = - PostReportView::get_report_count(conn, inserted_timmy.id, false, None).unwrap(); + let report_count = PostReportView::get_report_count(pool, inserted_timmy.id, false, None) + .await + .unwrap(); assert_eq!(2, report_count); // Try to resolve the report - PostReport::resolve(conn, inserted_jessica_report.id, inserted_timmy.id).unwrap(); + PostReport::resolve(pool, inserted_jessica_report.id, inserted_timmy.id) + .await + .unwrap(); let read_jessica_report_view_after_resolve = - PostReportView::read(conn, inserted_jessica_report.id, inserted_timmy.id).unwrap(); + PostReportView::read(pool, inserted_jessica_report.id, inserted_timmy.id) + .await + .unwrap(); let mut expected_jessica_report_view_after_resolve = expected_jessica_report_view; expected_jessica_report_view_after_resolve @@ -541,23 +571,28 @@ mod tests { // Do a batch read of timmys reports // It should only show saras, which is unresolved let reports_after_resolve = PostReportQuery::builder() - .conn(conn) + .pool(pool) .my_person_id(inserted_timmy.id) .admin(false) .build() .list() + .await .unwrap(); assert_eq!(reports_after_resolve[0], expected_sara_report_view); // Make sure the counts are correct let report_count_after_resolved = - PostReportView::get_report_count(conn, inserted_timmy.id, false, None).unwrap(); + PostReportView::get_report_count(pool, inserted_timmy.id, false, None) + .await + .unwrap(); assert_eq!(1, report_count_after_resolved); - Person::delete(conn, inserted_timmy.id).unwrap(); - Person::delete(conn, inserted_sara.id).unwrap(); - Person::delete(conn, inserted_jessica.id).unwrap(); - Community::delete(conn, inserted_community.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + Person::delete(pool, inserted_timmy.id).await.unwrap(); + Person::delete(pool, inserted_sara.id).await.unwrap(); + Person::delete(pool, inserted_jessica.id).await.unwrap(); + Community::delete(pool, inserted_community.id) + .await + .unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); } } diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index aebddc1c..d47db578 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -1,5 +1,19 @@ use crate::structs::PostView; -use diesel::{dsl::*, pg::Pg, result::Error, *}; +use diesel::{ + debug_query, + dsl::*, + pg::Pg, + result::Error, + sql_function, + sql_types, + BoolExpressionMethods, + ExpressionMethods, + JoinOnDsl, + NullableExpressionMethods, + PgTextExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::PostAggregates, newtypes::{CommunityId, DbUrl, LocalUserId, PersonId, PostId}, @@ -26,7 +40,7 @@ use lemmy_db_schema::{ post::{Post, PostRead, PostSaved}, }, traits::{ToSafe, ViewToVec}, - utils::{functions::hot_rank, fuzzy_search, limit_and_offset}, + utils::{functions::hot_rank, fuzzy_search, get_conn, limit_and_offset, DbPool}, ListingType, SortType, }; @@ -50,11 +64,13 @@ type PostViewTuple = ( sql_function!(fn coalesce(x: sql_types::Nullable, y: sql_types::BigInt) -> sql_types::BigInt); impl PostView { - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, post_id: PostId, my_person_id: Option, ) -> Result { + let conn = &mut get_conn(pool).await?; + // The left join below will return None in this case let person_id_join = my_person_id.unwrap_or(PersonId(-1)); let ( @@ -144,7 +160,8 @@ impl PostView { post_aggregates::comments, ), )) - .first::(conn)?; + .first::(conn) + .await?; // If a person is given, then my_vote, if None, should be 0, not null // Necessary to differentiate between other person's votes @@ -174,7 +191,7 @@ impl PostView { #[builder(field_defaults(default))] pub struct PostQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, listing_type: Option, sort: Option, creator_id: Option, @@ -189,8 +206,9 @@ pub struct PostQuery<'a> { } impl<'a> PostQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { use diesel::dsl::*; + let conn = &mut get_conn(self.pool).await?; // The left join below will return None in this case let person_id_join = self.local_user.map(|l| l.person_id).unwrap_or(PersonId(-1)); @@ -418,7 +436,7 @@ impl<'a> PostQuery<'a> { debug!("Post View Query: {:?}", debug_query::(&query)); - let res = query.load::(self.conn)?; + let res = query.load::(conn).await?; Ok(PostView::from_tuple_to_vec(res)) } @@ -449,7 +467,6 @@ impl ViewToVec for PostView { #[cfg(test)] mod tests { use crate::post_view::{PostQuery, PostView}; - use diesel::PgConnection; use lemmy_db_schema::{ aggregates::structs::PostAggregates, newtypes::LanguageId, @@ -465,7 +482,7 @@ mod tests { post::*, }, traits::{Blockable, Crud, Likeable}, - utils::establish_unpooled_connection, + utils::{build_db_pool_for_tests, DbPool}, SortType, SubscribedType, }; @@ -481,8 +498,8 @@ mod tests { inserted_post: Post, } - fn init_data(conn: &mut PgConnection) -> Data { - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + async fn init_data(pool: &DbPool) -> Data { + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let person_name = "tegan".to_string(); @@ -492,13 +509,13 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_person = Person::create(conn, &new_person).unwrap(); + let inserted_person = Person::create(pool, &new_person).await.unwrap(); let local_user_form = LocalUserInsertForm::builder() .person_id(inserted_person.id) .password_encrypted("".to_string()) .build(); - let inserted_local_user = LocalUser::create(conn, &local_user_form).unwrap(); + let inserted_local_user = LocalUser::create(pool, &local_user_form).await.unwrap(); let new_bot = PersonInsertForm::builder() .name("mybot".to_string()) @@ -507,7 +524,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_bot = Person::create(conn, &new_bot).unwrap(); + let inserted_bot = Person::create(pool, &new_bot).await.unwrap(); let new_community = CommunityInsertForm::builder() .name("test_community_3".to_string()) @@ -516,7 +533,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_community = Community::create(conn, &new_community).unwrap(); + let inserted_community = Community::create(pool, &new_community).await.unwrap(); // Test a person block, make sure the post query doesn't include their post let blocked_person = PersonInsertForm::builder() @@ -525,7 +542,7 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_blocked_person = Person::create(conn, &blocked_person).unwrap(); + let inserted_blocked_person = Person::create(pool, &blocked_person).await.unwrap(); let post_from_blocked_person = PostInsertForm::builder() .name("blocked_person_post".to_string()) @@ -534,7 +551,7 @@ mod tests { .language_id(Some(LanguageId(1))) .build(); - Post::create(conn, &post_from_blocked_person).unwrap(); + Post::create(pool, &post_from_blocked_person).await.unwrap(); // block that person let person_block = PersonBlockForm { @@ -542,7 +559,7 @@ mod tests { target_id: inserted_blocked_person.id, }; - PersonBlock::block(conn, &person_block).unwrap(); + PersonBlock::block(pool, &person_block).await.unwrap(); // A sample post let new_post = PostInsertForm::builder() @@ -552,7 +569,7 @@ mod tests { .language_id(Some(LanguageId(47))) .build(); - let inserted_post = Post::create(conn, &new_post).unwrap(); + let inserted_post = Post::create(pool, &new_post).await.unwrap(); let new_bot_post = PostInsertForm::builder() .name("test bot post".to_string()) @@ -560,7 +577,7 @@ mod tests { .community_id(inserted_community.id) .build(); - let _inserted_bot_post = Post::create(conn, &new_bot_post).unwrap(); + let _inserted_bot_post = Post::create(pool, &new_bot_post).await.unwrap(); Data { inserted_instance, @@ -573,31 +590,36 @@ mod tests { } } - #[test] + #[tokio::test] #[serial] - fn post_listing_with_person() { - let conn = &mut establish_unpooled_connection(); - let data = init_data(conn); + async fn post_listing_with_person() { + let pool = &build_db_pool_for_tests().await; + let data = init_data(pool).await; let local_user_form = LocalUserUpdateForm::builder() .show_bot_accounts(Some(false)) .build(); let inserted_local_user = - LocalUser::update(conn, data.inserted_local_user.id, &local_user_form).unwrap(); + LocalUser::update(pool, data.inserted_local_user.id, &local_user_form) + .await + .unwrap(); let read_post_listing = PostQuery::builder() - .conn(conn) + .pool(pool) .sort(Some(SortType::New)) .community_id(Some(data.inserted_community.id)) .local_user(Some(&inserted_local_user)) .build() .list() + .await .unwrap(); let post_listing_single_with_person = - PostView::read(conn, data.inserted_post.id, Some(data.inserted_person.id)).unwrap(); + PostView::read(pool, data.inserted_post.id, Some(data.inserted_person.id)) + .await + .unwrap(); - let mut expected_post_listing_with_user = expected_post_view(&data, conn); + let mut expected_post_listing_with_user = expected_post_view(&data, pool).await; // Should be only one person, IE the bot post, and blocked should be missing assert_eq!(1, read_post_listing.len()); @@ -613,40 +635,45 @@ mod tests { .show_bot_accounts(Some(true)) .build(); let inserted_local_user = - LocalUser::update(conn, data.inserted_local_user.id, &local_user_form).unwrap(); + LocalUser::update(pool, data.inserted_local_user.id, &local_user_form) + .await + .unwrap(); let post_listings_with_bots = PostQuery::builder() - .conn(conn) + .pool(pool) .sort(Some(SortType::New)) .community_id(Some(data.inserted_community.id)) .local_user(Some(&inserted_local_user)) .build() .list() + .await .unwrap(); // should include bot post which has "undetermined" language assert_eq!(2, post_listings_with_bots.len()); - cleanup(data, conn); + cleanup(data, pool).await; } - #[test] + #[tokio::test] #[serial] - fn post_listing_no_person() { - let conn = &mut establish_unpooled_connection(); - let data = init_data(conn); + async fn post_listing_no_person() { + let pool = &build_db_pool_for_tests().await; + let data = init_data(pool).await; let read_post_listing_multiple_no_person = PostQuery::builder() - .conn(conn) + .pool(pool) .sort(Some(SortType::New)) .community_id(Some(data.inserted_community.id)) .build() .list() + .await .unwrap(); - let read_post_listing_single_no_person = - PostView::read(conn, data.inserted_post.id, None).unwrap(); + let read_post_listing_single_no_person = PostView::read(pool, data.inserted_post.id, None) + .await + .unwrap(); - let expected_post_listing_no_person = expected_post_view(&data, conn); + let expected_post_listing_no_person = expected_post_view(&data, pool).await; // Should be 2 posts, with the bot post, and the blocked assert_eq!(3, read_post_listing_multiple_no_person.len()); @@ -660,41 +687,44 @@ mod tests { read_post_listing_single_no_person ); - cleanup(data, conn); + cleanup(data, pool).await; } - #[test] + #[tokio::test] #[serial] - fn post_listing_block_community() { - let conn = &mut establish_unpooled_connection(); - let data = init_data(conn); + async fn post_listing_block_community() { + let pool = &build_db_pool_for_tests().await; + let data = init_data(pool).await; let community_block = CommunityBlockForm { person_id: data.inserted_person.id, community_id: data.inserted_community.id, }; - CommunityBlock::block(conn, &community_block).unwrap(); + CommunityBlock::block(pool, &community_block).await.unwrap(); let read_post_listings_with_person_after_block = PostQuery::builder() - .conn(conn) + .pool(pool) .sort(Some(SortType::New)) .community_id(Some(data.inserted_community.id)) .local_user(Some(&data.inserted_local_user)) .build() .list() + .await .unwrap(); // Should be 0 posts after the community block assert_eq!(0, read_post_listings_with_person_after_block.len()); - CommunityBlock::unblock(conn, &community_block).unwrap(); - cleanup(data, conn); + CommunityBlock::unblock(pool, &community_block) + .await + .unwrap(); + cleanup(data, pool).await; } - #[test] + #[tokio::test] #[serial] - fn post_listing_like() { - let conn = &mut establish_unpooled_connection(); - let data = init_data(conn); + async fn post_listing_like() { + let pool = &build_db_pool_for_tests().await; + let data = init_data(pool).await; let post_like_form = PostLikeForm { post_id: data.inserted_post.id, @@ -702,7 +732,7 @@ mod tests { score: 1, }; - let inserted_post_like = PostLike::like(conn, &post_like_form).unwrap(); + let inserted_post_like = PostLike::like(pool, &post_like_form).await.unwrap(); let expected_post_like = PostLike { id: inserted_post_like.id, @@ -713,19 +743,20 @@ mod tests { }; assert_eq!(expected_post_like, inserted_post_like); - let like_removed = - PostLike::remove(conn, data.inserted_person.id, data.inserted_post.id).unwrap(); + let like_removed = PostLike::remove(pool, data.inserted_person.id, data.inserted_post.id) + .await + .unwrap(); assert_eq!(1, like_removed); - cleanup(data, conn); + cleanup(data, pool).await; } - #[test] + #[tokio::test] #[serial] - fn post_listing_person_language() { - let conn = &mut establish_unpooled_connection(); - let data = init_data(conn); + async fn post_listing_person_language() { + let pool = &build_db_pool_for_tests().await; + let data = init_data(pool).await; - let spanish_id = Language::read_id_from_code(conn, "es").unwrap(); + let spanish_id = Language::read_id_from_code(pool, "es").await.unwrap(); let post_spanish = PostInsertForm::builder() .name("asffgdsc".to_string()) .creator_id(data.inserted_person.id) @@ -733,47 +764,53 @@ mod tests { .language_id(Some(spanish_id)) .build(); - Post::create(conn, &post_spanish).unwrap(); + Post::create(pool, &post_spanish).await.unwrap(); let post_listings_all = PostQuery::builder() - .conn(conn) + .pool(pool) .sort(Some(SortType::New)) .local_user(Some(&data.inserted_local_user)) .build() .list() + .await .unwrap(); // no language filters specified, all posts should be returned assert_eq!(3, post_listings_all.len()); - let french_id = Language::read_id_from_code(conn, "fr").unwrap(); - LocalUserLanguage::update(conn, vec![french_id], data.inserted_local_user.id).unwrap(); + let french_id = Language::read_id_from_code(pool, "fr").await.unwrap(); + LocalUserLanguage::update(pool, vec![french_id], data.inserted_local_user.id) + .await + .unwrap(); let post_listing_french = PostQuery::builder() - .conn(conn) + .pool(pool) .sort(Some(SortType::New)) .local_user(Some(&data.inserted_local_user)) .build() .list() + .await .unwrap(); // only one french language post should be returned assert_eq!(1, post_listing_french.len()); assert_eq!(french_id, post_listing_french[0].post.language_id); - let undetermined_id = Language::read_id_from_code(conn, "und").unwrap(); + let undetermined_id = Language::read_id_from_code(pool, "und").await.unwrap(); LocalUserLanguage::update( - conn, + pool, vec![french_id, undetermined_id], data.inserted_local_user.id, ) + .await .unwrap(); let post_listings_french_und = PostQuery::builder() - .conn(conn) + .pool(pool) .sort(Some(SortType::New)) .local_user(Some(&data.inserted_local_user)) .build() .list() + .await .unwrap(); // french post and undetermined language post should be returned @@ -784,26 +821,32 @@ mod tests { ); assert_eq!(french_id, post_listings_french_und[1].post.language_id); - cleanup(data, conn); + cleanup(data, pool).await; } - fn cleanup(data: Data, conn: &mut PgConnection) { - let num_deleted = Post::delete(conn, data.inserted_post.id).unwrap(); - Community::delete(conn, data.inserted_community.id).unwrap(); - Person::delete(conn, data.inserted_person.id).unwrap(); - Person::delete(conn, data.inserted_bot.id).unwrap(); - Person::delete(conn, data.inserted_blocked_person.id).unwrap(); - Instance::delete(conn, data.inserted_instance.id).unwrap(); + async fn cleanup(data: Data, pool: &DbPool) { + let num_deleted = Post::delete(pool, data.inserted_post.id).await.unwrap(); + Community::delete(pool, data.inserted_community.id) + .await + .unwrap(); + Person::delete(pool, data.inserted_person.id).await.unwrap(); + Person::delete(pool, data.inserted_bot.id).await.unwrap(); + Person::delete(pool, data.inserted_blocked_person.id) + .await + .unwrap(); + Instance::delete(pool, data.inserted_instance.id) + .await + .unwrap(); assert_eq!(1, num_deleted); } - fn expected_post_view(data: &Data, conn: &mut PgConnection) -> PostView { + async fn expected_post_view(data: &Data, pool: &DbPool) -> PostView { let (inserted_person, inserted_community, inserted_post) = ( &data.inserted_person, &data.inserted_community, &data.inserted_post, ); - let agg = PostAggregates::read(conn, inserted_post.id).unwrap(); + let agg = PostAggregates::read(pool, inserted_post.id).await.unwrap(); PostView { post: Post { diff --git a/crates/db_views/src/private_message_report_view.rs b/crates/db_views/src/private_message_report_view.rs index 2b198196..75a89ca4 100644 --- a/crates/db_views/src/private_message_report_view.rs +++ b/crates/db_views/src/private_message_report_view.rs @@ -1,5 +1,6 @@ use crate::structs::PrivateMessageReportView; -use diesel::{result::Error, *}; +use diesel::{result::Error, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PrivateMessageReportId, schema::{person, private_message, private_message_report}, @@ -9,7 +10,7 @@ use lemmy_db_schema::{ private_message_report::PrivateMessageReport, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; use typed_builder::TypedBuilder; @@ -25,7 +26,8 @@ impl PrivateMessageReportView { /// returns the PrivateMessageReportView for the provided report_id /// /// * `report_id` - the report id to obtain - pub fn read(conn: &mut PgConnection, report_id: PrivateMessageReportId) -> Result { + pub async fn read(pool: &DbPool, report_id: PrivateMessageReportId) -> Result { + let conn = &mut get_conn(pool).await?; let (person_alias_1, person_alias_2) = diesel::alias!(person as person1, person as person2); let (private_message_report, private_message, private_message_creator, creator, resolver) = @@ -51,7 +53,8 @@ impl PrivateMessageReportView { .fields(Person::safe_columns_tuple()) .nullable(), )) - .first::(conn)?; + .first::(conn) + .await?; Ok(Self { private_message_report, @@ -63,8 +66,9 @@ impl PrivateMessageReportView { } /// Returns the current unresolved post report count for the communities you mod - pub fn get_report_count(conn: &mut PgConnection) -> Result { + pub async fn get_report_count(pool: &DbPool) -> Result { use diesel::dsl::*; + let conn = &mut get_conn(pool).await?; private_message_report::table .inner_join(private_message::table) @@ -72,6 +76,7 @@ impl PrivateMessageReportView { .into_boxed() .select(count(private_message_report::id)) .first::(conn) + .await } } @@ -79,14 +84,15 @@ impl PrivateMessageReportView { #[builder(field_defaults(default))] pub struct PrivateMessageReportQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, page: Option, limit: Option, unresolved_only: Option, } impl<'a> PrivateMessageReportQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { + let conn = &mut get_conn(self.pool).await?; let (person_alias_1, person_alias_2) = diesel::alias!(person as person1, person as person2); let mut query = private_message_report::table @@ -121,7 +127,7 @@ impl<'a> PrivateMessageReportQuery<'a> { .limit(limit) .offset(offset); - let res = query.load::(self.conn)?; + let res = query.load::(conn).await?; Ok(PrivateMessageReportView::from_tuple_to_vec(res)) } @@ -154,30 +160,30 @@ mod tests { private_message_report::{PrivateMessageReport, PrivateMessageReportForm}, }, traits::{Crud, Reportable}, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let new_person_1 = PersonInsertForm::builder() .name("timmy_mrv".into()) .public_key("pubkey".to_string()) .instance_id(inserted_instance.id) .build(); - let inserted_timmy = Person::create(conn, &new_person_1).unwrap(); + let inserted_timmy = Person::create(pool, &new_person_1).await.unwrap(); let new_person_2 = PersonInsertForm::builder() .name("jessica_mrv".into()) .public_key("pubkey".to_string()) .instance_id(inserted_instance.id) .build(); - let inserted_jessica = Person::create(conn, &new_person_2).unwrap(); + let inserted_jessica = Person::create(pool, &new_person_2).await.unwrap(); // timmy sends private message to jessica let pm_form = PrivateMessageInsertForm::builder() @@ -185,7 +191,7 @@ mod tests { .recipient_id(inserted_jessica.id) .content("something offensive".to_string()) .build(); - let pm = PrivateMessage::create(conn, &pm_form).unwrap(); + let pm = PrivateMessage::create(pool, &pm_form).await.unwrap(); // jessica reports private message let pm_report_form = PrivateMessageReportForm { @@ -194,12 +200,15 @@ mod tests { private_message_id: pm.id, reason: "its offensive".to_string(), }; - let pm_report = PrivateMessageReport::report(conn, &pm_report_form).unwrap(); + let pm_report = PrivateMessageReport::report(pool, &pm_report_form) + .await + .unwrap(); let reports = PrivateMessageReportQuery::builder() - .conn(conn) + .pool(pool) .build() .list() + .await .unwrap(); assert_eq!(1, reports.len()); assert!(!reports[0].private_message_report.resolved); @@ -213,16 +222,19 @@ mod tests { .public_key("pubkey".to_string()) .instance_id(inserted_instance.id) .build(); - let inserted_admin = Person::create(conn, &new_person_3).unwrap(); + let inserted_admin = Person::create(pool, &new_person_3).await.unwrap(); // admin resolves the report (after taking appropriate action) - PrivateMessageReport::resolve(conn, pm_report.id, inserted_admin.id).unwrap(); + PrivateMessageReport::resolve(pool, pm_report.id, inserted_admin.id) + .await + .unwrap(); let reports = PrivateMessageReportQuery::builder() - .conn(conn) + .pool(pool) .unresolved_only(Some(false)) .build() .list() + .await .unwrap(); assert_eq!(1, reports.len()); assert!(reports[0].private_message_report.resolved); @@ -232,6 +244,6 @@ mod tests { reports[0].resolver.as_ref().unwrap().name ); - Instance::delete(conn, inserted_instance.id).unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); } } diff --git a/crates/db_views/src/private_message_view.rs b/crates/db_views/src/private_message_view.rs index 281df8ba..cfbc2dc9 100644 --- a/crates/db_views/src/private_message_view.rs +++ b/crates/db_views/src/private_message_view.rs @@ -1,5 +1,14 @@ use crate::structs::PrivateMessageView; -use diesel::{pg::Pg, result::Error, *}; +use diesel::{ + debug_query, + pg::Pg, + result::Error, + BoolExpressionMethods, + ExpressionMethods, + JoinOnDsl, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::{PersonId, PrivateMessageId}, schema::{person, private_message}, @@ -8,7 +17,7 @@ use lemmy_db_schema::{ private_message::PrivateMessage, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; use tracing::debug; use typed_builder::TypedBuilder; @@ -16,10 +25,8 @@ use typed_builder::TypedBuilder; type PrivateMessageViewTuple = (PrivateMessage, PersonSafe, PersonSafe); impl PrivateMessageView { - pub fn read( - conn: &mut PgConnection, - private_message_id: PrivateMessageId, - ) -> Result { + pub async fn read(pool: &DbPool, private_message_id: PrivateMessageId) -> Result { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); let (private_message, creator, recipient) = private_message::table @@ -34,7 +41,8 @@ impl PrivateMessageView { Person::safe_columns_tuple(), person_alias_1.fields(Person::safe_columns_tuple()), )) - .first::(conn)?; + .first::(conn) + .await?; Ok(PrivateMessageView { private_message, @@ -44,17 +52,16 @@ impl PrivateMessageView { } /// Gets the number of unread messages - pub fn get_unread_messages( - conn: &mut PgConnection, - my_person_id: PersonId, - ) -> Result { + pub async fn get_unread_messages(pool: &DbPool, my_person_id: PersonId) -> Result { use diesel::dsl::*; + let conn = &mut get_conn(pool).await?; private_message::table .filter(private_message::read.eq(false)) .filter(private_message::recipient_id.eq(my_person_id)) .filter(private_message::deleted.eq(false)) .select(count(private_message::id)) .first::(conn) + .await } } @@ -62,7 +69,7 @@ impl PrivateMessageView { #[builder(field_defaults(default))] pub struct PrivateMessageQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, #[builder(!default)] recipient_id: PersonId, unread_only: Option, @@ -71,7 +78,8 @@ pub struct PrivateMessageQuery<'a> { } impl<'a> PrivateMessageQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { + let conn = &mut get_conn(self.pool).await?; let person_alias_1 = diesel::alias!(person as person1); let mut query = private_message::table @@ -114,7 +122,7 @@ impl<'a> PrivateMessageQuery<'a> { debug_query::(&query) ); - let res = query.load::(self.conn)?; + let res = query.load::(conn).await?; Ok(PrivateMessageView::from_tuple_to_vec(res)) } diff --git a/crates/db_views/src/registration_application_view.rs b/crates/db_views/src/registration_application_view.rs index 265292ef..31f4ad13 100644 --- a/crates/db_views/src/registration_application_view.rs +++ b/crates/db_views/src/registration_application_view.rs @@ -1,5 +1,13 @@ use crate::structs::RegistrationApplicationView; -use diesel::{dsl::count, result::Error, *}; +use diesel::{ + dsl::count, + result::Error, + ExpressionMethods, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ schema::{local_user, person, registration_application}, source::{ @@ -8,7 +16,7 @@ use lemmy_db_schema::{ registration_application::RegistrationApplication, }, traits::{ToSafe, ToSafeSettings, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; use typed_builder::TypedBuilder; @@ -20,7 +28,8 @@ type RegistrationApplicationViewTuple = ( ); impl RegistrationApplicationView { - pub fn read(conn: &mut PgConnection, registration_application_id: i32) -> Result { + pub async fn read(pool: &DbPool, registration_application_id: i32) -> Result { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); let (registration_application, creator_local_user, creator, admin) = @@ -43,7 +52,8 @@ impl RegistrationApplicationView { .fields(Person::safe_columns_tuple()) .nullable(), )) - .first::(conn)?; + .first::(conn) + .await?; Ok(RegistrationApplicationView { registration_application, @@ -54,10 +64,8 @@ impl RegistrationApplicationView { } /// Returns the current unread registration_application count - pub fn get_unread_count( - conn: &mut PgConnection, - verified_email_only: bool, - ) -> Result { + pub async fn get_unread_count(pool: &DbPool, verified_email_only: bool) -> Result { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); let mut query = registration_application::table @@ -77,6 +85,7 @@ impl RegistrationApplicationView { query .select(count(registration_application::id)) .first::(conn) + .await } } @@ -84,7 +93,7 @@ impl RegistrationApplicationView { #[builder(field_defaults(default))] pub struct RegistrationApplicationQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, unread_only: Option, verified_email_only: Option, page: Option, @@ -92,7 +101,8 @@ pub struct RegistrationApplicationQuery<'a> { } impl<'a> RegistrationApplicationQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { + let conn = &mut get_conn(self.pool).await?; let person_alias_1 = diesel::alias!(person as person1); let mut query = registration_application::table @@ -128,7 +138,7 @@ impl<'a> RegistrationApplicationQuery<'a> { .offset(offset) .order_by(registration_application::published.desc()); - let res = query.load::(self.conn)?; + let res = query.load::(conn).await?; Ok(RegistrationApplicationView::from_tuple_to_vec(res)) } @@ -167,16 +177,16 @@ mod tests { }, }, traits::Crud, - utils::establish_unpooled_connection, + utils::build_db_pool_for_tests, }; use serial_test::serial; - #[test] + #[tokio::test] #[serial] - fn test_crud() { - let conn = &mut establish_unpooled_connection(); + async fn test_crud() { + let pool = &build_db_pool_for_tests().await; - let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap(); + let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap(); let timmy_person_form = PersonInsertForm::builder() .name("timmy_rav".into()) @@ -185,14 +195,16 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_timmy_person = Person::create(conn, &timmy_person_form).unwrap(); + let inserted_timmy_person = Person::create(pool, &timmy_person_form).await.unwrap(); let timmy_local_user_form = LocalUserInsertForm::builder() .person_id(inserted_timmy_person.id) .password_encrypted("nada".to_string()) .build(); - let _inserted_timmy_local_user = LocalUser::create(conn, &timmy_local_user_form).unwrap(); + let _inserted_timmy_local_user = LocalUser::create(pool, &timmy_local_user_form) + .await + .unwrap(); let sara_person_form = PersonInsertForm::builder() .name("sara_rav".into()) @@ -200,14 +212,16 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_sara_person = Person::create(conn, &sara_person_form).unwrap(); + let inserted_sara_person = Person::create(pool, &sara_person_form).await.unwrap(); let sara_local_user_form = LocalUserInsertForm::builder() .person_id(inserted_sara_person.id) .password_encrypted("nada".to_string()) .build(); - let inserted_sara_local_user = LocalUser::create(conn, &sara_local_user_form).unwrap(); + let inserted_sara_local_user = LocalUser::create(pool, &sara_local_user_form) + .await + .unwrap(); // Sara creates an application let sara_app_form = RegistrationApplicationInsertForm { @@ -215,9 +229,13 @@ mod tests { answer: "LET ME IIIIINN".to_string(), }; - let sara_app = RegistrationApplication::create(conn, &sara_app_form).unwrap(); + let sara_app = RegistrationApplication::create(pool, &sara_app_form) + .await + .unwrap(); - let read_sara_app_view = RegistrationApplicationView::read(conn, sara_app.id).unwrap(); + let read_sara_app_view = RegistrationApplicationView::read(pool, sara_app.id) + .await + .unwrap(); let jess_person_form = PersonInsertForm::builder() .name("jess_rav".into()) @@ -225,14 +243,16 @@ mod tests { .instance_id(inserted_instance.id) .build(); - let inserted_jess_person = Person::create(conn, &jess_person_form).unwrap(); + let inserted_jess_person = Person::create(pool, &jess_person_form).await.unwrap(); let jess_local_user_form = LocalUserInsertForm::builder() .person_id(inserted_jess_person.id) .password_encrypted("nada".to_string()) .build(); - let inserted_jess_local_user = LocalUser::create(conn, &jess_local_user_form).unwrap(); + let inserted_jess_local_user = LocalUser::create(pool, &jess_local_user_form) + .await + .unwrap(); // Sara creates an application let jess_app_form = RegistrationApplicationInsertForm { @@ -240,9 +260,13 @@ mod tests { answer: "LET ME IIIIINN".to_string(), }; - let jess_app = RegistrationApplication::create(conn, &jess_app_form).unwrap(); + let jess_app = RegistrationApplication::create(pool, &jess_app_form) + .await + .unwrap(); - let read_jess_app_view = RegistrationApplicationView::read(conn, jess_app.id).unwrap(); + let read_jess_app_view = RegistrationApplicationView::read(pool, jess_app.id) + .await + .unwrap(); let mut expected_sara_app_view = RegistrationApplicationView { registration_application: sara_app.to_owned(), @@ -293,10 +317,11 @@ mod tests { // Do a batch read of the applications let apps = RegistrationApplicationQuery::builder() - .conn(conn) + .pool(pool) .unread_only(Some(true)) .build() .list() + .await .unwrap(); assert_eq!( @@ -308,7 +333,9 @@ mod tests { ); // Make sure the counts are correct - let unread_count = RegistrationApplicationView::get_unread_count(conn, false).unwrap(); + let unread_count = RegistrationApplicationView::get_unread_count(pool, false) + .await + .unwrap(); assert_eq!(unread_count, 2); // Approve the application @@ -317,17 +344,22 @@ mod tests { deny_reason: None, }; - RegistrationApplication::update(conn, sara_app.id, &approve_form).unwrap(); + RegistrationApplication::update(pool, sara_app.id, &approve_form) + .await + .unwrap(); // Update the local_user row let approve_local_user_form = LocalUserUpdateForm::builder() .accepted_application(Some(true)) .build(); - LocalUser::update(conn, inserted_sara_local_user.id, &approve_local_user_form).unwrap(); + LocalUser::update(pool, inserted_sara_local_user.id, &approve_local_user_form) + .await + .unwrap(); - let read_sara_app_view_after_approve = - RegistrationApplicationView::read(conn, sara_app.id).unwrap(); + let read_sara_app_view_after_approve = RegistrationApplicationView::read(pool, sara_app.id) + .await + .unwrap(); // Make sure the columns changed expected_sara_app_view @@ -361,29 +393,34 @@ mod tests { // Do a batch read of apps again // It should show only jessicas which is unresolved let apps_after_resolve = RegistrationApplicationQuery::builder() - .conn(conn) + .pool(pool) .unread_only(Some(true)) .build() .list() + .await .unwrap(); assert_eq!(apps_after_resolve, vec![read_jess_app_view]); // Make sure the counts are correct - let unread_count_after_approve = - RegistrationApplicationView::get_unread_count(conn, false).unwrap(); + let unread_count_after_approve = RegistrationApplicationView::get_unread_count(pool, false) + .await + .unwrap(); assert_eq!(unread_count_after_approve, 1); // Make sure the not undenied_only has all the apps let all_apps = RegistrationApplicationQuery::builder() - .conn(conn) + .pool(pool) .build() .list() + .await .unwrap(); assert_eq!(all_apps.len(), 2); - Person::delete(conn, inserted_timmy_person.id).unwrap(); - Person::delete(conn, inserted_sara_person.id).unwrap(); - Person::delete(conn, inserted_jess_person.id).unwrap(); - Instance::delete(conn, inserted_instance.id).unwrap(); + Person::delete(pool, inserted_timmy_person.id) + .await + .unwrap(); + Person::delete(pool, inserted_sara_person.id).await.unwrap(); + Person::delete(pool, inserted_jess_person.id).await.unwrap(); + Instance::delete(pool, inserted_instance.id).await.unwrap(); } } diff --git a/crates/db_views/src/site_view.rs b/crates/db_views/src/site_view.rs index 10b36ac8..a1d0231a 100644 --- a/crates/db_views/src/site_view.rs +++ b/crates/db_views/src/site_view.rs @@ -1,13 +1,16 @@ use crate::structs::SiteView; -use diesel::{result::Error, *}; +use diesel::{result::Error, ExpressionMethods, JoinOnDsl, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::SiteAggregates, schema::{local_site, local_site_rate_limit, site, site_aggregates}, source::{local_site::LocalSite, local_site_rate_limit::LocalSiteRateLimit, site::Site}, + utils::{get_conn, DbPool}, }; impl SiteView { - pub fn read_local(conn: &mut PgConnection) -> Result { + pub async fn read_local(pool: &DbPool) -> Result { + let conn = &mut get_conn(pool).await?; let (mut site, local_site, local_site_rate_limit, counts) = site::table .inner_join(local_site::table) .inner_join( @@ -20,7 +23,8 @@ impl SiteView { local_site_rate_limit::all_columns, site_aggregates::all_columns, )) - .first::<(Site, LocalSite, LocalSiteRateLimit, SiteAggregates)>(conn)?; + .first::<(Site, LocalSite, LocalSiteRateLimit, SiteAggregates)>(conn) + .await?; site.private_key = None; Ok(SiteView { diff --git a/crates/db_views_actor/Cargo.toml b/crates/db_views_actor/Cargo.toml index e49990ae..ef97f8c1 100644 --- a/crates/db_views_actor/Cargo.toml +++ b/crates/db_views_actor/Cargo.toml @@ -12,10 +12,11 @@ rust-version = "1.57" doctest = false [features] -full = ["lemmy_db_schema/full", "diesel"] +full = ["lemmy_db_schema/full", "diesel", "diesel-async"] [dependencies] lemmy_db_schema = { version = "=0.16.5", path = "../db_schema" } -diesel = { version = "2.0.0", features = ["postgres","chrono","r2d2","serde_json"], optional = true } -serde = { version = "1.0.145", features = ["derive"] } +diesel = { version = "2.0.2", features = ["postgres","chrono","serde_json"], optional = true } +diesel-async = { version = "0.1.1", features = ["postgres", "bb8"], optional = true } +serde = { version = "1.0.147", features = ["derive"] } typed-builder = "0.10.0" diff --git a/crates/db_views_actor/src/comment_reply_view.rs b/crates/db_views_actor/src/comment_reply_view.rs index c6794162..73972dee 100644 --- a/crates/db_views_actor/src/comment_reply_view.rs +++ b/crates/db_views_actor/src/comment_reply_view.rs @@ -1,5 +1,14 @@ use crate::structs::CommentReplyView; -use diesel::{dsl::*, result::Error, *}; +use diesel::{ + dsl::*, + result::Error, + BoolExpressionMethods, + ExpressionMethods, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::CommentAggregates, newtypes::{CommentReplyId, PersonId}, @@ -25,7 +34,7 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::{functions::hot_rank, limit_and_offset}, + utils::{functions::hot_rank, get_conn, limit_and_offset, DbPool}, CommentSortType, }; use typed_builder::TypedBuilder; @@ -46,11 +55,12 @@ type CommentReplyViewTuple = ( ); impl CommentReplyView { - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, comment_reply_id: CommentReplyId, my_person_id: Option, ) -> Result { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); // The left join below will return None in this case @@ -131,7 +141,8 @@ impl CommentReplyView { person_block::all_columns.nullable(), comment_like::score.nullable(), )) - .first::(conn)?; + .first::(conn) + .await?; Ok(CommentReplyView { comment_reply, @@ -150,9 +161,11 @@ impl CommentReplyView { } /// Gets the number of unread replies - pub fn get_unread_replies(conn: &mut PgConnection, my_person_id: PersonId) -> Result { + pub async fn get_unread_replies(pool: &DbPool, my_person_id: PersonId) -> Result { use diesel::dsl::*; + let conn = &mut get_conn(pool).await?; + comment_reply::table .inner_join(comment::table) .filter(comment_reply::recipient_id.eq(my_person_id)) @@ -161,6 +174,7 @@ impl CommentReplyView { .filter(comment::removed.eq(false)) .select(count(comment_reply::id)) .first::(conn) + .await } } @@ -168,7 +182,7 @@ impl CommentReplyView { #[builder(field_defaults(default))] pub struct CommentReplyQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, my_person_id: Option, recipient_id: Option, sort: Option, @@ -179,8 +193,9 @@ pub struct CommentReplyQuery<'a> { } impl<'a> CommentReplyQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { use diesel::dsl::*; + let conn = &mut get_conn(self.pool).await?; let person_alias_1 = diesel::alias!(person as person1); @@ -276,7 +291,8 @@ impl<'a> CommentReplyQuery<'a> { let res = query .limit(limit) .offset(offset) - .load::(self.conn)?; + .load::(conn) + .await?; Ok(CommentReplyView::from_tuple_to_vec(res)) } diff --git a/crates/db_views_actor/src/community_block_view.rs b/crates/db_views_actor/src/community_block_view.rs index 6c46904a..2a774b03 100644 --- a/crates/db_views_actor/src/community_block_view.rs +++ b/crates/db_views_actor/src/community_block_view.rs @@ -1,5 +1,6 @@ use crate::structs::CommunityBlockView; -use diesel::{result::Error, *}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, community_block, person}, @@ -8,12 +9,14 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, + utils::{get_conn, DbPool}, }; type CommunityBlockViewTuple = (PersonSafe, CommunitySafe); impl CommunityBlockView { - pub fn for_person(conn: &mut PgConnection, person_id: PersonId) -> Result, Error> { + pub async fn for_person(pool: &DbPool, person_id: PersonId) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let res = community_block::table .inner_join(person::table) .inner_join(community::table) @@ -25,7 +28,8 @@ impl CommunityBlockView { .filter(community::deleted.eq(false)) .filter(community::removed.eq(false)) .order_by(community_block::published) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(res)) } diff --git a/crates/db_views_actor/src/community_follower_view.rs b/crates/db_views_actor/src/community_follower_view.rs index 51e58fda..3b03b027 100644 --- a/crates/db_views_actor/src/community_follower_view.rs +++ b/crates/db_views_actor/src/community_follower_view.rs @@ -1,5 +1,6 @@ use crate::structs::CommunityFollowerView; -use diesel::{result::Error, *}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::{CommunityId, PersonId}, schema::{community, community_follower, person}, @@ -8,15 +9,14 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, + utils::{get_conn, DbPool}, }; type CommunityFollowerViewTuple = (CommunitySafe, PersonSafe); impl CommunityFollowerView { - pub fn for_community( - conn: &mut PgConnection, - community_id: CommunityId, - ) -> Result, Error> { + pub async fn for_community(pool: &DbPool, community_id: CommunityId) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let res = community_follower::table .inner_join(community::table) .inner_join(person::table) @@ -26,12 +26,14 @@ impl CommunityFollowerView { )) .filter(community_follower::community_id.eq(community_id)) .order_by(community::title) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(res)) } - pub fn for_person(conn: &mut PgConnection, person_id: PersonId) -> Result, Error> { + pub async fn for_person(pool: &DbPool, person_id: PersonId) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let res = community_follower::table .inner_join(community::table) .inner_join(person::table) @@ -43,7 +45,8 @@ impl CommunityFollowerView { .filter(community::deleted.eq(false)) .filter(community::removed.eq(false)) .order_by(community::title) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(res)) } diff --git a/crates/db_views_actor/src/community_moderator_view.rs b/crates/db_views_actor/src/community_moderator_view.rs index 28ad6d84..e9e6625c 100644 --- a/crates/db_views_actor/src/community_moderator_view.rs +++ b/crates/db_views_actor/src/community_moderator_view.rs @@ -1,5 +1,6 @@ use crate::structs::CommunityModeratorView; -use diesel::{result::Error, *}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::{CommunityId, PersonId}, schema::{community, community_moderator, person}, @@ -8,15 +9,14 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, + utils::{get_conn, DbPool}, }; type CommunityModeratorViewTuple = (CommunitySafe, PersonSafe); impl CommunityModeratorView { - pub fn for_community( - conn: &mut PgConnection, - community_id: CommunityId, - ) -> Result, Error> { + pub async fn for_community(pool: &DbPool, community_id: CommunityId) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let res = community_moderator::table .inner_join(community::table) .inner_join(person::table) @@ -26,12 +26,14 @@ impl CommunityModeratorView { )) .filter(community_moderator::community_id.eq(community_id)) .order_by(community_moderator::published) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(res)) } - pub fn for_person(conn: &mut PgConnection, person_id: PersonId) -> Result, Error> { + pub async fn for_person(pool: &DbPool, person_id: PersonId) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let res = community_moderator::table .inner_join(community::table) .inner_join(person::table) @@ -43,14 +45,16 @@ impl CommunityModeratorView { .filter(community::deleted.eq(false)) .filter(community::removed.eq(false)) .order_by(community_moderator::published) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(res)) } /// Finds all communities first mods / creators /// Ideally this should be a group by, but diesel doesn't support it yet - pub fn get_community_first_mods(conn: &mut PgConnection) -> Result, Error> { + pub async fn get_community_first_mods(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let res = community_moderator::table .inner_join(community::table) .inner_join(person::table) @@ -65,7 +69,8 @@ impl CommunityModeratorView { community_moderator::community_id, community_moderator::person_id, )) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(res)) } diff --git a/crates/db_views_actor/src/community_person_ban_view.rs b/crates/db_views_actor/src/community_person_ban_view.rs index 8672ad21..ff7f26c9 100644 --- a/crates/db_views_actor/src/community_person_ban_view.rs +++ b/crates/db_views_actor/src/community_person_ban_view.rs @@ -1,5 +1,6 @@ use crate::structs::CommunityPersonBanView; -use diesel::{dsl::*, result::Error, *}; +use diesel::{dsl::*, result::Error, BoolExpressionMethods, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::{CommunityId, PersonId}, schema::{community, community_person_ban, person}, @@ -8,14 +9,16 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::ToSafe, + utils::{get_conn, DbPool}, }; impl CommunityPersonBanView { - pub fn get( - conn: &mut PgConnection, + pub async fn get( + pool: &DbPool, from_person_id: PersonId, from_community_id: CommunityId, ) -> Result { + let conn = &mut get_conn(pool).await?; let (community, person) = community_person_ban::table .inner_join(community::table) .inner_join(person::table) @@ -31,7 +34,8 @@ impl CommunityPersonBanView { .or(community_person_ban::expires.gt(now)), ) .order_by(community_person_ban::published) - .first::<(CommunitySafe, PersonSafe)>(conn)?; + .first::<(CommunitySafe, PersonSafe)>(conn) + .await?; Ok(CommunityPersonBanView { community, person }) } diff --git a/crates/db_views_actor/src/community_view.rs b/crates/db_views_actor/src/community_view.rs index 5a65b887..f27c58c8 100644 --- a/crates/db_views_actor/src/community_view.rs +++ b/crates/db_views_actor/src/community_view.rs @@ -1,5 +1,14 @@ use crate::structs::{CommunityModeratorView, CommunityView, PersonViewSafe}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + JoinOnDsl, + NullableExpressionMethods, + PgTextExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::CommunityAggregates, newtypes::{CommunityId, PersonId}, @@ -10,7 +19,7 @@ use lemmy_db_schema::{ local_user::LocalUser, }, traits::{ToSafe, ViewToVec}, - utils::{functions::hot_rank, fuzzy_search, limit_and_offset}, + utils::{functions::hot_rank, fuzzy_search, get_conn, limit_and_offset, DbPool}, ListingType, SortType, }; @@ -24,11 +33,12 @@ type CommunityViewTuple = ( ); impl CommunityView { - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, community_id: CommunityId, my_person_id: Option, ) -> Result { + let conn = &mut get_conn(pool).await?; // The left join below will return None in this case let person_id_join = my_person_id.unwrap_or(PersonId(-1)); @@ -55,7 +65,8 @@ impl CommunityView { community_follower::all_columns.nullable(), community_block::all_columns.nullable(), )) - .first::(conn)?; + .first::(conn) + .await?; Ok(CommunityView { community, @@ -65,12 +76,13 @@ impl CommunityView { }) } - pub fn is_mod_or_admin( - conn: &mut PgConnection, + pub async fn is_mod_or_admin( + pool: &DbPool, person_id: PersonId, community_id: CommunityId, - ) -> bool { - let is_mod = CommunityModeratorView::for_community(conn, community_id) + ) -> Result { + let is_mod = CommunityModeratorView::for_community(pool, community_id) + .await .map(|v| { v.into_iter() .map(|m| m.moderator.id) @@ -79,17 +91,19 @@ impl CommunityView { .unwrap_or_default() .contains(&person_id); if is_mod { - return true; + return Ok(true); } - PersonViewSafe::admins(conn) + let is_admin = PersonViewSafe::admins(pool) + .await .map(|v| { v.into_iter() .map(|a| a.person.id) .collect::>() }) .unwrap_or_default() - .contains(&person_id) + .contains(&person_id); + Ok(is_admin) } } @@ -97,7 +111,7 @@ impl CommunityView { #[builder(field_defaults(default))] pub struct CommunityQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, listing_type: Option, sort: Option, local_user: Option<&'a LocalUser>, @@ -107,7 +121,9 @@ pub struct CommunityQuery<'a> { } impl<'a> CommunityQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { + let conn = &mut get_conn(self.pool).await?; + // The left join below will return None in this case let person_id_join = self.local_user.map(|l| l.person_id).unwrap_or(PersonId(-1)); @@ -203,7 +219,8 @@ impl<'a> CommunityQuery<'a> { .offset(offset) .filter(community::removed.eq(false)) .filter(community::deleted.eq(false)) - .load::(self.conn)?; + .load::(conn) + .await?; Ok(CommunityView::from_tuple_to_vec(res)) } diff --git a/crates/db_views_actor/src/person_block_view.rs b/crates/db_views_actor/src/person_block_view.rs index b8bb09fe..5ece0439 100644 --- a/crates/db_views_actor/src/person_block_view.rs +++ b/crates/db_views_actor/src/person_block_view.rs @@ -1,16 +1,19 @@ use crate::structs::PersonBlockView; -use diesel::{result::Error, *}; +use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{person, person_block}, source::person::{Person, PersonSafe}, traits::{ToSafe, ViewToVec}, + utils::{get_conn, DbPool}, }; type PersonBlockViewTuple = (PersonSafe, PersonSafe); impl PersonBlockView { - pub fn for_person(conn: &mut PgConnection, person_id: PersonId) -> Result, Error> { + pub async fn for_person(pool: &DbPool, person_id: PersonId) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); let res = person_block::table @@ -23,7 +26,8 @@ impl PersonBlockView { .filter(person_block::person_id.eq(person_id)) .filter(person_alias_1.field(person::deleted).eq(false)) .order_by(person_block::published) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(res)) } diff --git a/crates/db_views_actor/src/person_mention_view.rs b/crates/db_views_actor/src/person_mention_view.rs index 2b6daf5d..3930382a 100644 --- a/crates/db_views_actor/src/person_mention_view.rs +++ b/crates/db_views_actor/src/person_mention_view.rs @@ -1,5 +1,14 @@ use crate::structs::PersonMentionView; -use diesel::{dsl::*, result::Error, *}; +use diesel::{ + dsl::*, + result::Error, + BoolExpressionMethods, + ExpressionMethods, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::CommentAggregates, newtypes::{PersonId, PersonMentionId}, @@ -25,7 +34,7 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::{functions::hot_rank, limit_and_offset}, + utils::{functions::hot_rank, get_conn, limit_and_offset, DbPool}, CommentSortType, }; use typed_builder::TypedBuilder; @@ -46,11 +55,12 @@ type PersonMentionViewTuple = ( ); impl PersonMentionView { - pub fn read( - conn: &mut PgConnection, + pub async fn read( + pool: &DbPool, person_mention_id: PersonMentionId, my_person_id: Option, ) -> Result { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); // The left join below will return None in this case @@ -131,7 +141,8 @@ impl PersonMentionView { person_block::all_columns.nullable(), comment_like::score.nullable(), )) - .first::(conn)?; + .first::(conn) + .await?; Ok(PersonMentionView { person_mention, @@ -150,11 +161,9 @@ impl PersonMentionView { } /// Gets the number of unread mentions - pub fn get_unread_mentions( - conn: &mut PgConnection, - my_person_id: PersonId, - ) -> Result { + pub async fn get_unread_mentions(pool: &DbPool, my_person_id: PersonId) -> Result { use diesel::dsl::*; + let conn = &mut get_conn(pool).await?; person_mention::table .inner_join(comment::table) @@ -164,6 +173,7 @@ impl PersonMentionView { .filter(comment::removed.eq(false)) .select(count(person_mention::id)) .first::(conn) + .await } } @@ -171,7 +181,7 @@ impl PersonMentionView { #[builder(field_defaults(default))] pub struct PersonMentionQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, my_person_id: Option, recipient_id: Option, sort: Option, @@ -182,8 +192,9 @@ pub struct PersonMentionQuery<'a> { } impl<'a> PersonMentionQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { use diesel::dsl::*; + let conn = &mut get_conn(self.pool).await?; let person_alias_1 = diesel::alias!(person as person1); @@ -279,7 +290,8 @@ impl<'a> PersonMentionQuery<'a> { let res = query .limit(limit) .offset(offset) - .load::(self.conn)?; + .load::(conn) + .await?; Ok(PersonMentionView::from_tuple_to_vec(res)) } diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs index 55a64819..cbacb8e5 100644 --- a/crates/db_views_actor/src/person_view.rs +++ b/crates/db_views_actor/src/person_view.rs @@ -1,41 +1,55 @@ use crate::structs::PersonViewSafe; -use diesel::{dsl::*, result::Error, *}; +use diesel::{ + dsl::*, + result::Error, + BoolExpressionMethods, + ExpressionMethods, + PgTextExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aggregates::structs::PersonAggregates, newtypes::PersonId, schema::{person, person_aggregates}, source::person::{Person, PersonSafe}, traits::{ToSafe, ViewToVec}, - utils::{fuzzy_search, limit_and_offset}, + utils::{fuzzy_search, get_conn, limit_and_offset, DbPool}, SortType, }; +use std::iter::Iterator; use typed_builder::TypedBuilder; type PersonViewSafeTuple = (PersonSafe, PersonAggregates); impl PersonViewSafe { - pub fn read(conn: &mut PgConnection, person_id: PersonId) -> Result { + pub async fn read(pool: &DbPool, person_id: PersonId) -> Result { + let conn = &mut get_conn(pool).await?; let (person, counts) = person::table .find(person_id) .inner_join(person_aggregates::table) .select((Person::safe_columns_tuple(), person_aggregates::all_columns)) - .first::(conn)?; + .first::(conn) + .await?; Ok(Self { person, counts }) } - pub fn admins(conn: &mut PgConnection) -> Result, Error> { + pub async fn admins(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let admins = person::table .inner_join(person_aggregates::table) .select((Person::safe_columns_tuple(), person_aggregates::all_columns)) .filter(person::admin.eq(true)) .filter(person::deleted.eq(false)) .order_by(person::published) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(admins)) } - pub fn banned(conn: &mut PgConnection) -> Result, Error> { + pub async fn banned(pool: &DbPool) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let banned = person::table .inner_join(person_aggregates::table) .select((Person::safe_columns_tuple(), person_aggregates::all_columns)) @@ -47,7 +61,8 @@ impl PersonViewSafe { ), ) .filter(person::deleted.eq(false)) - .load::(conn)?; + .load::(conn) + .await?; Ok(Self::from_tuple_to_vec(banned)) } @@ -57,7 +72,7 @@ impl PersonViewSafe { #[builder(field_defaults(default))] pub struct PersonQuery<'a> { #[builder(!default)] - conn: &'a mut PgConnection, + pool: &'a DbPool, sort: Option, search_term: Option, page: Option, @@ -65,7 +80,8 @@ pub struct PersonQuery<'a> { } impl<'a> PersonQuery<'a> { - pub fn list(self) -> Result, Error> { + pub async fn list(self) -> Result, Error> { + let conn = &mut get_conn(self.pool).await?; let mut query = person::table .inner_join(person_aggregates::table) .select((Person::safe_columns_tuple(), person_aggregates::all_columns)) @@ -107,7 +123,7 @@ impl<'a> PersonQuery<'a> { let (limit, offset) = limit_and_offset(self.page, self.limit)?; query = query.limit(limit).offset(offset); - let res = query.load::(self.conn)?; + let res = query.load::(conn).await?; Ok(PersonViewSafe::from_tuple_to_vec(res)) } diff --git a/crates/db_views_moderator/Cargo.toml b/crates/db_views_moderator/Cargo.toml index e2823993..c568dae0 100644 --- a/crates/db_views_moderator/Cargo.toml +++ b/crates/db_views_moderator/Cargo.toml @@ -12,9 +12,10 @@ rust-version = "1.57" doctest = false [features] -full = ["lemmy_db_schema/full", "diesel"] +full = ["lemmy_db_schema/full", "diesel", "diesel-async"] [dependencies] lemmy_db_schema = { version = "=0.16.5", path = "../db_schema" } -diesel = { version = "2.0.0", features = ["postgres","chrono","r2d2","serde_json"], optional = true } -serde = { version = "1.0.145", features = ["derive"] } +diesel = { version = "2.0.2", features = ["postgres","chrono","serde_json"], optional = true } +diesel-async = { version = "0.1.1", features = ["postgres", "bb8"], optional = true } +serde = { version = "1.0.147", features = ["derive"] } diff --git a/crates/db_views_moderator/src/admin_purge_comment_view.rs b/crates/db_views_moderator/src/admin_purge_comment_view.rs index 035f86d1..d9edaa10 100644 --- a/crates/db_views_moderator/src/admin_purge_comment_view.rs +++ b/crates/db_views_moderator/src/admin_purge_comment_view.rs @@ -1,5 +1,14 @@ use crate::structs::{AdminPurgeCommentView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{admin_purge_comment, person, post}, @@ -9,13 +18,14 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type AdminPurgeCommentViewTuple = (AdminPurgeComment, Option, Post); impl AdminPurgeCommentView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; let show_mod_names_expr = show_mod_names.as_sql::(); @@ -44,7 +54,8 @@ impl AdminPurgeCommentView { .limit(limit) .offset(offset) .order_by(admin_purge_comment::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/admin_purge_community_view.rs b/crates/db_views_moderator/src/admin_purge_community_view.rs index fb582d6d..501013d0 100644 --- a/crates/db_views_moderator/src/admin_purge_community_view.rs +++ b/crates/db_views_moderator/src/admin_purge_community_view.rs @@ -1,5 +1,14 @@ use crate::structs::{AdminPurgeCommunityView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{admin_purge_community, person}, @@ -8,13 +17,14 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type AdminPurgeCommunityViewTuple = (AdminPurgeCommunity, Option); impl AdminPurgeCommunityView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; let show_mod_names_expr = show_mod_names.as_sql::(); @@ -41,7 +51,8 @@ impl AdminPurgeCommunityView { .limit(limit) .offset(offset) .order_by(admin_purge_community::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/admin_purge_person_view.rs b/crates/db_views_moderator/src/admin_purge_person_view.rs index 023bcb37..a0abe0ca 100644 --- a/crates/db_views_moderator/src/admin_purge_person_view.rs +++ b/crates/db_views_moderator/src/admin_purge_person_view.rs @@ -1,5 +1,14 @@ use crate::structs::{AdminPurgePersonView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{admin_purge_person, person}, @@ -8,13 +17,15 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type AdminPurgePersonViewTuple = (AdminPurgePerson, Option); impl AdminPurgePersonView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; let show_mod_names_expr = show_mod_names.as_sql::(); @@ -40,7 +51,8 @@ impl AdminPurgePersonView { .limit(limit) .offset(offset) .order_by(admin_purge_person::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/admin_purge_post_view.rs b/crates/db_views_moderator/src/admin_purge_post_view.rs index 6a65c7a4..38cb6b5e 100644 --- a/crates/db_views_moderator/src/admin_purge_post_view.rs +++ b/crates/db_views_moderator/src/admin_purge_post_view.rs @@ -1,5 +1,14 @@ use crate::structs::{AdminPurgePostView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{admin_purge_post, community, person}, @@ -9,13 +18,15 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type AdminPurgePostViewTuple = (AdminPurgePost, Option, CommunitySafe); impl AdminPurgePostView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; let show_mod_names_expr = show_mod_names.as_sql::(); @@ -43,7 +54,8 @@ impl AdminPurgePostView { .limit(limit) .offset(offset) .order_by(admin_purge_post::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_add_community_view.rs b/crates/db_views_moderator/src/mod_add_community_view.rs index b7b9e93a..bad3a1de 100644 --- a/crates/db_views_moderator/src/mod_add_community_view.rs +++ b/crates/db_views_moderator/src/mod_add_community_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModAddCommunityView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, mod_add_community, person}, @@ -9,7 +18,7 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModAddCommunityViewTuple = ( @@ -20,7 +29,8 @@ type ModAddCommunityViewTuple = ( ); impl ModAddCommunityView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -61,7 +71,8 @@ impl ModAddCommunityView { .limit(limit) .offset(offset) .order_by(mod_add_community::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_add_view.rs b/crates/db_views_moderator/src/mod_add_view.rs index e7155250..3fc4b35b 100644 --- a/crates/db_views_moderator/src/mod_add_view.rs +++ b/crates/db_views_moderator/src/mod_add_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModAddView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{mod_add, person}, @@ -8,13 +17,14 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModAddViewTuple = (ModAdd, Option, PersonSafe); impl ModAddView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -47,7 +57,8 @@ impl ModAddView { .limit(limit) .offset(offset) .order_by(mod_add::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_ban_from_community_view.rs b/crates/db_views_moderator/src/mod_ban_from_community_view.rs index bf885dbc..cf10c53a 100644 --- a/crates/db_views_moderator/src/mod_ban_from_community_view.rs +++ b/crates/db_views_moderator/src/mod_ban_from_community_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModBanFromCommunityView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, mod_ban_from_community, person}, @@ -9,7 +18,7 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModBanFromCommunityViewTuple = ( @@ -20,7 +29,9 @@ type ModBanFromCommunityViewTuple = ( ); impl ModBanFromCommunityView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + let person_alias_1 = diesel::alias!(person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -62,7 +73,8 @@ impl ModBanFromCommunityView { .limit(limit) .offset(offset) .order_by(mod_ban_from_community::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_ban_view.rs b/crates/db_views_moderator/src/mod_ban_view.rs index 94bfbc8d..adb0623c 100644 --- a/crates/db_views_moderator/src/mod_ban_view.rs +++ b/crates/db_views_moderator/src/mod_ban_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModBanView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{mod_ban, person}, @@ -8,13 +17,14 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModBanViewTuple = (ModBan, Option, PersonSafe); impl ModBanView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -47,7 +57,8 @@ impl ModBanView { .limit(limit) .offset(offset) .order_by(mod_ban::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_hide_community_view.rs b/crates/db_views_moderator/src/mod_hide_community_view.rs index 0250d2e7..4b382d51 100644 --- a/crates/db_views_moderator/src/mod_hide_community_view.rs +++ b/crates/db_views_moderator/src/mod_hide_community_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModHideCommunityView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, mod_hide_community, person}, @@ -9,14 +18,16 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModHideCommunityViewTuple = (ModHideCommunity, Option, CommunitySafe); impl ModHideCommunityView { // Pass in mod_id as admin_id because only admins can do this action - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; let show_mod_names_expr = show_mod_names.as_sql::(); @@ -48,7 +59,8 @@ impl ModHideCommunityView { .limit(limit) .offset(offset) .order_by(mod_hide_community::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_lock_post_view.rs b/crates/db_views_moderator/src/mod_lock_post_view.rs index 6d88c5ae..27758446 100644 --- a/crates/db_views_moderator/src/mod_lock_post_view.rs +++ b/crates/db_views_moderator/src/mod_lock_post_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModLockPostView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, mod_lock_post, person, post}, @@ -10,13 +19,15 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModLockPostViewTuple = (ModLockPost, Option, Post, CommunitySafe); impl ModLockPostView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + let person_alias_1 = diesel::alias!(person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -56,7 +67,8 @@ impl ModLockPostView { .limit(limit) .offset(offset) .order_by(mod_lock_post::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_remove_comment_view.rs b/crates/db_views_moderator/src/mod_remove_comment_view.rs index c0b58845..52eb8e75 100644 --- a/crates/db_views_moderator/src/mod_remove_comment_view.rs +++ b/crates/db_views_moderator/src/mod_remove_comment_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModRemoveCommentView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{comment, community, mod_remove_comment, person, post}, @@ -11,7 +20,7 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModRemoveCommentViewTuple = ( @@ -24,7 +33,8 @@ type ModRemoveCommentViewTuple = ( ); impl ModRemoveCommentView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(lemmy_db_schema::schema::person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -67,7 +77,8 @@ impl ModRemoveCommentView { .limit(limit) .offset(offset) .order_by(mod_remove_comment::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_remove_community_view.rs b/crates/db_views_moderator/src/mod_remove_community_view.rs index ffd62d45..293b8455 100644 --- a/crates/db_views_moderator/src/mod_remove_community_view.rs +++ b/crates/db_views_moderator/src/mod_remove_community_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModRemoveCommunityView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, mod_remove_community, person}, @@ -9,13 +18,14 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModRemoveCommunityTuple = (ModRemoveCommunity, Option, CommunitySafe); impl ModRemoveCommunityView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; let show_mod_names_expr = show_mod_names.as_sql::(); @@ -43,7 +53,8 @@ impl ModRemoveCommunityView { .limit(limit) .offset(offset) .order_by(mod_remove_community::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_remove_post_view.rs b/crates/db_views_moderator/src/mod_remove_post_view.rs index c1bc2e8f..20d5b09b 100644 --- a/crates/db_views_moderator/src/mod_remove_post_view.rs +++ b/crates/db_views_moderator/src/mod_remove_post_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModRemovePostView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, mod_remove_post, person, post}, @@ -10,13 +19,15 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModRemovePostViewTuple = (ModRemovePost, Option, Post, CommunitySafe); impl ModRemovePostView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + let person_alias_1 = diesel::alias!(person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -56,7 +67,8 @@ impl ModRemovePostView { .limit(limit) .offset(offset) .order_by(mod_remove_post::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_sticky_post_view.rs b/crates/db_views_moderator/src/mod_sticky_post_view.rs index d802de69..28736292 100644 --- a/crates/db_views_moderator/src/mod_sticky_post_view.rs +++ b/crates/db_views_moderator/src/mod_sticky_post_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModStickyPostView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, mod_sticky_post, person, post}, @@ -10,13 +19,14 @@ use lemmy_db_schema::{ post::Post, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModStickyPostViewTuple = (ModStickyPost, Option, Post, CommunitySafe); impl ModStickyPostView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; let person_alias_1 = diesel::alias!(person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -56,7 +66,8 @@ impl ModStickyPostView { .limit(limit) .offset(offset) .order_by(mod_sticky_post::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/db_views_moderator/src/mod_transfer_community_view.rs b/crates/db_views_moderator/src/mod_transfer_community_view.rs index bea839eb..182558a4 100644 --- a/crates/db_views_moderator/src/mod_transfer_community_view.rs +++ b/crates/db_views_moderator/src/mod_transfer_community_view.rs @@ -1,5 +1,14 @@ use crate::structs::{ModTransferCommunityView, ModlogListParams}; -use diesel::{result::Error, *}; +use diesel::{ + result::Error, + BoolExpressionMethods, + ExpressionMethods, + IntoSql, + JoinOnDsl, + NullableExpressionMethods, + QueryDsl, +}; +use diesel_async::RunQueryDsl; use lemmy_db_schema::{ newtypes::PersonId, schema::{community, mod_transfer_community, person}, @@ -9,7 +18,7 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, }, traits::{ToSafe, ViewToVec}, - utils::limit_and_offset, + utils::{get_conn, limit_and_offset, DbPool}, }; type ModTransferCommunityViewTuple = ( @@ -20,7 +29,9 @@ type ModTransferCommunityViewTuple = ( ); impl ModTransferCommunityView { - pub fn list(conn: &mut PgConnection, params: ModlogListParams) -> Result, Error> { + pub async fn list(pool: &DbPool, params: ModlogListParams) -> Result, Error> { + let conn = &mut get_conn(pool).await?; + let person_alias_1 = diesel::alias!(person as person1); let admin_person_id_join = params.mod_person_id.unwrap_or(PersonId(-1)); let show_mod_names = !params.hide_modlog_names; @@ -62,7 +73,8 @@ impl ModTransferCommunityView { .limit(limit) .offset(offset) .order_by(mod_transfer_community::when_.desc()) - .load::(conn)?; + .load::(conn) + .await?; let results = Self::from_tuple_to_vec(res); Ok(results) diff --git a/crates/routes/Cargo.toml b/crates/routes/Cargo.toml index bda019d3..1186a6b9 100644 --- a/crates/routes/Cargo.toml +++ b/crates/routes/Cargo.toml @@ -19,17 +19,17 @@ lemmy_db_views_actor = { version = "=0.16.5", path = "../db_views_actor" } lemmy_db_schema = { version = "=0.16.5", path = "../db_schema" } lemmy_api_common = { version = "=0.16.5", path = "../api_common" } lemmy_apub = { version = "=0.16.5", path = "../apub" } -diesel = "2.0.0" +diesel = "2.0.2" actix-web = { version = "4.2.1", default-features = false, features = ["rustls"] } -anyhow = "1.0.65" +anyhow = "1.0.66" chrono = { version = "0.4.22", features = ["serde"], default-features = false } -futures = "0.3.24" +futures = "0.3.25" reqwest = { version = "0.11.12", features = ["stream"] } reqwest-middleware = "0.1.6" rss = "2.0.1" -serde = { version = "1.0.145", features = ["derive"] } +serde = { version = "1.0.147", features = ["derive"] } url = { version = "2.3.1", features = ["serde"] } strum = "0.24.1" once_cell = "1.15.0" tracing = "0.1.36" -tokio = { version = "1.21.1", features = ["sync"] } +tokio = { version = "1.21.2", features = ["sync"] } diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 1943c280..cb4fb918 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -1,12 +1,11 @@ use actix_web::{error::ErrorBadRequest, *}; use anyhow::anyhow; use chrono::{DateTime, NaiveDateTime, Utc}; -use diesel::PgConnection; -use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ newtypes::LocalUserId, source::{community::Community, local_user::LocalUser, person::Person}, traits::{ApubActor, Crud}, + utils::DbPool, CommentSortType, ListingType, SortType, @@ -88,18 +87,16 @@ async fn get_feed_data( listing_type: ListingType, sort_type: SortType, ) -> Result { - let site_view = blocking(context.pool(), SiteView::read_local).await??; - - let posts = blocking(context.pool(), move |conn| { - PostQuery::builder() - .conn(conn) - .listing_type(Some(listing_type)) - .sort(Some(sort_type)) - .limit(Some(RSS_FETCH_LIMIT)) - .build() - .list() - }) - .await??; + let site_view = SiteView::read_local(context.pool()).await?; + + let posts = PostQuery::builder() + .pool(context.pool()) + .listing_type(Some(listing_type)) + .sort(Some(sort_type)) + .limit(Some(RSS_FETCH_LIMIT)) + .build() + .list() + .await?; let items = create_post_items(posts, &context.settings().get_protocol_and_hostname())?; @@ -144,19 +141,27 @@ async fn get_feed( let jwt_secret = context.secret().jwt_secret.to_owned(); let protocol_and_hostname = context.settings().get_protocol_and_hostname(); - let builder = blocking(context.pool(), move |conn| match request_type { - RequestType::User => get_feed_user(conn, &sort_type, ¶m, &protocol_and_hostname), - RequestType::Community => get_feed_community(conn, &sort_type, ¶m, &protocol_and_hostname), - RequestType::Front => get_feed_front( - conn, - &jwt_secret, - &sort_type, - ¶m, - &protocol_and_hostname, - ), - RequestType::Inbox => get_feed_inbox(conn, &jwt_secret, ¶m, &protocol_and_hostname), - }) - .await? + let builder = match request_type { + RequestType::User => { + get_feed_user(context.pool(), &sort_type, ¶m, &protocol_and_hostname).await + } + RequestType::Community => { + get_feed_community(context.pool(), &sort_type, ¶m, &protocol_and_hostname).await + } + RequestType::Front => { + get_feed_front( + context.pool(), + &jwt_secret, + &sort_type, + ¶m, + &protocol_and_hostname, + ) + .await + } + RequestType::Inbox => { + get_feed_inbox(context.pool(), &jwt_secret, ¶m, &protocol_and_hostname).await + } + } .map_err(ErrorBadRequest)?; let rss = builder.build().to_string(); @@ -177,23 +182,24 @@ fn get_sort_type(info: web::Query) -> Result { } #[tracing::instrument(skip_all)] -fn get_feed_user( - conn: &mut PgConnection, +async fn get_feed_user( + pool: &DbPool, sort_type: &SortType, user_name: &str, protocol_and_hostname: &str, ) -> Result { - let site_view = SiteView::read_local(conn)?; - let person = Person::read_from_name(conn, user_name, false)?; + let site_view = SiteView::read_local(pool).await?; + let person = Person::read_from_name(pool, user_name, false).await?; let posts = PostQuery::builder() - .conn(conn) + .pool(pool) .listing_type(Some(ListingType::All)) .sort(Some(*sort_type)) .creator_id(Some(person.id)) .limit(Some(RSS_FETCH_LIMIT)) .build() - .list()?; + .list() + .await?; let items = create_post_items(posts, protocol_and_hostname)?; @@ -208,22 +214,23 @@ fn get_feed_user( } #[tracing::instrument(skip_all)] -fn get_feed_community( - conn: &mut PgConnection, +async fn get_feed_community( + pool: &DbPool, sort_type: &SortType, community_name: &str, protocol_and_hostname: &str, ) -> Result { - let site_view = SiteView::read_local(conn)?; - let community = Community::read_from_name(conn, community_name, false)?; + let site_view = SiteView::read_local(pool).await?; + let community = Community::read_from_name(pool, community_name, false).await?; let posts = PostQuery::builder() - .conn(conn) + .pool(pool) .sort(Some(*sort_type)) .community_id(Some(community.id)) .limit(Some(RSS_FETCH_LIMIT)) .build() - .list()?; + .list() + .await?; let items = create_post_items(posts, protocol_and_hostname)?; @@ -242,25 +249,26 @@ fn get_feed_community( } #[tracing::instrument(skip_all)] -fn get_feed_front( - conn: &mut PgConnection, +async fn get_feed_front( + pool: &DbPool, jwt_secret: &str, sort_type: &SortType, jwt: &str, protocol_and_hostname: &str, ) -> Result { - let site_view = SiteView::read_local(conn)?; + let site_view = SiteView::read_local(pool).await?; let local_user_id = LocalUserId(Claims::decode(jwt, jwt_secret)?.claims.sub); - let local_user = LocalUser::read(conn, local_user_id)?; + let local_user = LocalUser::read(pool, local_user_id).await?; let posts = PostQuery::builder() - .conn(conn) + .pool(pool) .listing_type(Some(ListingType::Subscribed)) .local_user(Some(&local_user)) .sort(Some(*sort_type)) .limit(Some(RSS_FETCH_LIMIT)) .build() - .list()?; + .list() + .await?; let items = create_post_items(posts, protocol_and_hostname)?; @@ -279,39 +287,41 @@ fn get_feed_front( } #[tracing::instrument(skip_all)] -fn get_feed_inbox( - conn: &mut PgConnection, +async fn get_feed_inbox( + pool: &DbPool, jwt_secret: &str, jwt: &str, protocol_and_hostname: &str, ) -> Result { - let site_view = SiteView::read_local(conn)?; + let site_view = SiteView::read_local(pool).await?; let local_user_id = LocalUserId(Claims::decode(jwt, jwt_secret)?.claims.sub); - let local_user = LocalUser::read(conn, local_user_id)?; + let local_user = LocalUser::read(pool, local_user_id).await?; let person_id = local_user.person_id; let show_bot_accounts = local_user.show_bot_accounts; let sort = CommentSortType::New; let replies = CommentReplyQuery::builder() - .conn(conn) + .pool(pool) .recipient_id(Some(person_id)) .my_person_id(Some(person_id)) .show_bot_accounts(Some(show_bot_accounts)) .sort(Some(sort)) .limit(Some(RSS_FETCH_LIMIT)) .build() - .list()?; + .list() + .await?; let mentions = PersonMentionQuery::builder() - .conn(conn) + .pool(pool) .recipient_id(Some(person_id)) .my_person_id(Some(person_id)) .show_bot_accounts(Some(show_bot_accounts)) .sort(Some(sort)) .limit(Some(RSS_FETCH_LIMIT)) .build() - .list()?; + .list() + .await?; let items = create_reply_and_mention_items(replies, mentions, protocol_and_hostname)?; diff --git a/crates/routes/src/images.rs b/crates/routes/src/images.rs index 59a55fde..97134078 100644 --- a/crates/routes/src/images.rs +++ b/crates/routes/src/images.rs @@ -11,7 +11,7 @@ use actix_web::{ HttpResponse, }; use futures::stream::{Stream, StreamExt}; -use lemmy_api_common::utils::{blocking, get_local_user_view_from_jwt}; +use lemmy_api_common::utils::get_local_user_view_from_jwt; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_utils::{claims::Claims, rate_limit::RateLimit, REQWEST_TIMEOUT}; use lemmy_websocket::LemmyContext; @@ -126,10 +126,9 @@ async fn full_res( context: web::Data, ) -> Result { // block access to images if instance is private and unauthorized, public - let local_site = blocking(context.pool(), LocalSite::read) - .await? + let local_site = LocalSite::read(context.pool()) + .await .map_err(error::ErrorBadRequest)?; - // The site might not be set up yet if local_site.private_instance { let jwt = req .cookie("jwt") diff --git a/crates/routes/src/nodeinfo.rs b/crates/routes/src/nodeinfo.rs index c0d7cf7e..d5baf3aa 100644 --- a/crates/routes/src/nodeinfo.rs +++ b/crates/routes/src/nodeinfo.rs @@ -1,6 +1,5 @@ use actix_web::{error::ErrorBadRequest, *}; use anyhow::anyhow; -use lemmy_api_common::utils::blocking; use lemmy_db_views::structs::SiteView; use lemmy_utils::{error::LemmyError, version}; use lemmy_websocket::LemmyContext; @@ -29,8 +28,8 @@ async fn node_info_well_known( } async fn node_info(context: web::Data) -> Result { - let site_view = blocking(context.pool(), SiteView::read_local) - .await? + let site_view = SiteView::read_local(context.pool()) + .await .map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?; let protocols = if site_view.local_site.federation_enabled { diff --git a/crates/routes/src/webfinger.rs b/crates/routes/src/webfinger.rs index a13aad3e..33322347 100644 --- a/crates/routes/src/webfinger.rs +++ b/crates/routes/src/webfinger.rs @@ -1,6 +1,5 @@ use actix_web::{web, web::Query, HttpResponse}; use anyhow::Context; -use lemmy_api_common::utils::blocking; use lemmy_apub::fetcher::webfinger::{WebfingerLink, WebfingerResponse}; use lemmy_db_schema::{ source::{community::Community, person::Person}, @@ -43,18 +42,14 @@ async fn get_webfinger_response( .to_string(); let name_ = name.clone(); - let user_id: Option = blocking(context.pool(), move |conn| { - Person::read_from_name(conn, &name_, false) - }) - .await? - .ok() - .map(|c| c.actor_id.into()); - let community_id: Option = blocking(context.pool(), move |conn| { - Community::read_from_name(conn, &name, false) - }) - .await? - .ok() - .map(|c| c.actor_id.into()); + let user_id: Option = Person::read_from_name(context.pool(), &name_, false) + .await + .ok() + .map(|c| c.actor_id.into()); + let community_id: Option = Community::read_from_name(context.pool(), &name, false) + .await + .ok() + .map(|c| c.actor_id.into()); // Mastodon seems to prioritize the last webfinger item in case of duplicates. Put // community last so that it gets prioritized. For Lemmy the order doesnt matter. diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 6e0fbcbd..f4537590 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -17,30 +17,30 @@ doctest = false regex = "1.6.0" chrono = { version = "0.4.22", features = ["serde", "clock"], default-features = false } lettre = "0.10.1" -tracing = "0.1.36" +tracing = "0.1.37" tracing-error = "0.2.0" itertools = "0.10.5" rand = "0.8.5" -serde = { version = "1.0.145", features = ["derive"] } -serde_json = { version = "1.0.85", features = ["preserve_order"] } +serde = { version = "1.0.147", features = ["derive"] } +serde_json = { version = "1.0.87", features = ["preserve_order"] } comrak = { version = "0.14.0", default-features = false } once_cell = "1.15.0" -openssl = "0.10.41" +openssl = "0.10.42" url = { version = "2.3.1", features = ["serde"] } actix-web = { version = "4.2.1", default-features = false, features = ["rustls"] } -anyhow = "1.0.65" +anyhow = "1.0.66" reqwest-middleware = "0.1.6" strum = "0.24.1" strum_macros = "0.24.3" -futures = "0.3.24" -diesel = { version = "2.0.0", features = ["chrono"] } +futures = "0.3.25" +diesel = { version = "2.0.2", features = ["chrono"] } http = "0.2.8" deser-hjson = "1.0.2" smart-default = "0.6.0" jsonwebtoken = "8.1.1" doku = { version = "0.12.0", features = ["url-2"] } -uuid = { version = "1.1.2", features = ["serde", "v4"] } -html2text = "0.4.2" +uuid = { version = "1.2.1", features = ["serde", "v4"] } +html2text = "0.4.3" rosetta-i18n = "0.1.2" parking_lot = "0.12.1" typed-builder = "0.10.0" diff --git a/crates/websocket/Cargo.toml b/crates/websocket/Cargo.toml index dba9b106..c2d1618f 100644 --- a/crates/websocket/Cargo.toml +++ b/crates/websocket/Cargo.toml @@ -22,17 +22,17 @@ lemmy_db_views_actor = { version = "=0.16.5", path = "../db_views_actor", featur reqwest-middleware = "0.1.6" tracing = "0.1.36" rand = "0.8.5" -serde = { version = "1.0.145", features = ["derive"] } -serde_json = { version = "1.0.85", features = ["preserve_order"] } +serde = { version = "1.0.147", features = ["derive"] } +serde_json = { version = "1.0.87", features = ["preserve_order"] } actix = "0.13.0" -anyhow = "1.0.65" -diesel = "2.0.0" -background-jobs = "0.12.0" -tokio = "1.21.1" +anyhow = "1.0.66" +diesel = "2.0.2" +background-jobs = "0.13.0" +tokio = "1.21.2" strum = "0.24.1" strum_macros = "0.24.3" chrono = { version = "0.4.22", features = ["serde"], default-features = false } actix-web = { version = "4.2.1", default-features = false, features = ["rustls"] } actix-web-actors = { version = "4.1.0", default-features = false } -opentelemetry = "0.17.0" -tracing-opentelemetry = "0.17.2" +opentelemetry = "0.18.0" +tracing-opentelemetry = "0.18.0" diff --git a/crates/websocket/src/chat_server.rs b/crates/websocket/src/chat_server.rs index b0dcabc9..65ab4cbd 100644 --- a/crates/websocket/src/chat_server.rs +++ b/crates/websocket/src/chat_server.rs @@ -8,14 +8,11 @@ use crate::{ }; use actix::prelude::*; use anyhow::Context as acontext; -use diesel::{ - r2d2::{ConnectionManager, Pool}, - PgConnection, -}; use lemmy_api_common::{comment::*, post::*}; use lemmy_db_schema::{ newtypes::{CommunityId, LocalUserId, PostId}, source::secret::Secret, + utils::DbPool, }; use lemmy_utils::{ error::LemmyError, @@ -71,7 +68,7 @@ pub struct ChatServer { pub(super) rng: ThreadRng, /// The DB Pool - pub(super) pool: Pool>, + pub(super) pool: DbPool, /// The Settings pub(super) settings: Settings, @@ -103,7 +100,7 @@ pub struct SessionInfo { impl ChatServer { #![allow(clippy::too_many_arguments)] pub fn startup( - pool: Pool>, + pool: DbPool, rate_limiter: RateLimit, message_handler: MessageHandlerType, message_handler_crud: MessageHandlerCrudType, diff --git a/crates/websocket/src/send.rs b/crates/websocket/src/send.rs index 59187d2c..2793534f 100644 --- a/crates/websocket/src/send.rs +++ b/crates/websocket/src/send.rs @@ -8,7 +8,7 @@ use lemmy_api_common::{ community::CommunityResponse, post::PostResponse, private_message::PrivateMessageResponse, - utils::{blocking, check_person_block, get_interface_language, send_email_to_user}, + utils::{check_person_block, get_interface_language, send_email_to_user}, }; use lemmy_db_schema::{ newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId}, @@ -34,10 +34,7 @@ pub async fn send_post_ws_message person_id: Option, context: &LemmyContext, ) -> Result { - let post_view = blocking(context.pool(), move |conn| { - PostView::read(conn, post_id, person_id) - }) - .await??; + let post_view = PostView::read(context.pool(), post_id, person_id).await?; let res = PostResponse { post_view }; @@ -71,10 +68,7 @@ pub async fn send_comment_ws_message, context: &LemmyContext, ) -> Result { - let mut view = blocking(context.pool(), move |conn| { - CommentView::read(conn, comment_id, person_id) - }) - .await??; + let mut view = CommentView::read(context.pool(), comment_id, person_id).await?; if view.comment.deleted || view.comment.removed { view.comment = view.comment.blank_out_deleted_or_removed_info(); @@ -108,10 +102,7 @@ pub async fn send_community_ws_message, context: &LemmyContext, ) -> Result { - let community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, community_id, person_id) - }) - .await??; + let community_view = CommunityView::read(context.pool(), community_id, person_id).await?; let res = CommunityResponse { community_view }; @@ -136,10 +127,7 @@ pub async fn send_pm_ws_message( websocket_id: Option, context: &LemmyContext, ) -> Result { - let mut view = blocking(context.pool(), move |conn| { - PrivateMessageView::read(conn, private_message_id) - }) - .await??; + let mut view = PrivateMessageView::read(context.pool(), private_message_id).await?; // Blank out deleted or removed info if view.private_message.deleted { @@ -153,10 +141,7 @@ pub async fn send_pm_ws_message( // Send notifications to the local recipient, if one exists if res.private_message_view.recipient.local { let recipient_id = res.private_message_view.recipient.id; - let local_recipient = blocking(context.pool(), move |conn| { - LocalUserView::read_person(conn, recipient_id) - }) - .await??; + let local_recipient = LocalUserView::read_person(context.pool(), recipient_id).await?; context.chat_server().do_send(SendUserRoomMessage { op, response: res.clone(), @@ -187,10 +172,7 @@ pub async fn send_local_notifs( .collect::>() { let mention_name = mention.name.clone(); - let user_view = blocking(context.pool(), move |conn| { - LocalUserView::read_from_name(conn, &mention_name) - }) - .await?; + let user_view = LocalUserView::read_from_name(context.pool(), &mention_name).await; if let Ok(mention_user_view) = user_view { // TODO // At some point, make it so you can't tag the parent creator either @@ -205,11 +187,9 @@ pub async fn send_local_notifs( // Allow this to fail softly, since comment edits might re-update or replace it // Let the uniqueness handle this fail - blocking(context.pool(), move |conn| { - PersonMention::create(conn, &user_mention_form) - }) - .await? - .ok(); + PersonMention::create(context.pool(), &user_mention_form) + .await + .ok(); // Send an email to those local users that have notifications on if do_send_email { @@ -226,10 +206,7 @@ pub async fn send_local_notifs( // Send comment_reply to the parent commenter / poster if let Some(parent_comment_id) = comment.parent_comment_id() { - let parent_comment = blocking(context.pool(), move |conn| { - Comment::read(conn, parent_comment_id) - }) - .await??; + let parent_comment = Comment::read(context.pool(), parent_comment_id).await?; // Get the parent commenter local_user let parent_creator_id = parent_comment.creator_id; @@ -241,10 +218,7 @@ pub async fn send_local_notifs( // Don't send a notif to yourself if parent_comment.creator_id != person.id && !creator_blocked { - let user_view = blocking(context.pool(), move |conn| { - LocalUserView::read_person(conn, parent_creator_id) - }) - .await?; + let user_view = LocalUserView::read_person(context.pool(), parent_creator_id).await; if let Ok(parent_user_view) = user_view { recipient_ids.push(parent_user_view.local_user.id); @@ -256,11 +230,9 @@ pub async fn send_local_notifs( // Allow this to fail softly, since comment edits might re-update or replace it // Let the uniqueness handle this fail - blocking(context.pool(), move |conn| { - CommentReply::create(conn, &comment_reply_form) - }) - .await? - .ok(); + CommentReply::create(context.pool(), &comment_reply_form) + .await + .ok(); if do_send_email { let lang = get_interface_language(&parent_user_view); @@ -282,10 +254,7 @@ pub async fn send_local_notifs( if post.creator_id != person.id && !creator_blocked { let creator_id = post.creator_id; - let parent_user = blocking(context.pool(), move |conn| { - LocalUserView::read_person(conn, creator_id) - }) - .await?; + let parent_user = LocalUserView::read_person(context.pool(), creator_id).await; if let Ok(parent_user_view) = parent_user { recipient_ids.push(parent_user_view.local_user.id); @@ -297,11 +266,9 @@ pub async fn send_local_notifs( // Allow this to fail softly, since comment edits might re-update or replace it // Let the uniqueness handle this fail - blocking(context.pool(), move |conn| { - CommentReply::create(conn, &comment_reply_form) - }) - .await? - .ok(); + CommentReply::create(context.pool(), &comment_reply_form) + .await + .ok(); if do_send_email { let lang = get_interface_language(&parent_user_view); diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 14096dc0..b004720e 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -1,4 +1,4 @@ -ARG RUST_BUILDER_IMAGE=clux/muslrust:1.59.0 +ARG RUST_BUILDER_IMAGE=clux/muslrust:1.64.0 FROM $RUST_BUILDER_IMAGE as chef USER root diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index 52f987b2..c7f3e1ab 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -46,13 +46,13 @@ services: - pictrs lemmy-ui: - image: dessalines/lemmy-ui:dev + # image: dessalines/lemmy-ui:dev # use this to build your local lemmy ui image for development # run docker compose up --build # assuming lemmy-ui is cloned besides lemmy directory - # build: - # context: ../../../lemmy-ui - # dockerfile: Dockerfile + build: + context: ../../../lemmy-ui + dockerfile: dev.dockerfile networks: - lemmyinternal environment: diff --git a/docker/dev/lemmy.hjson b/docker/dev/lemmy.hjson index 2bd0675a..cac95ffd 100644 --- a/docker/dev/lemmy.hjson +++ b/docker/dev/lemmy.hjson @@ -14,10 +14,6 @@ host: postgres } - database: { - host: "postgres" - } - hostname: "localhost" bind: "0.0.0.0" port: 8536 diff --git a/docker/federation/lemmy_alpha.hjson b/docker/federation/lemmy_alpha.hjson index 9622ead4..5620c447 100644 --- a/docker/federation/lemmy_alpha.hjson +++ b/docker/federation/lemmy_alpha.hjson @@ -7,11 +7,12 @@ admin_password: lemmylemmy site_name: lemmy-alpha } + # These are ignored, use LEMMY_DATABASE_URL database: { - database: lemmy + database: lemmy_alpha user: lemmy password: password - host: postgres_alpha + host: localhost port: 5432 pool_size: 5 } diff --git a/docker/federation/lemmy_beta.hjson b/docker/federation/lemmy_beta.hjson index f199055d..4aed8552 100644 --- a/docker/federation/lemmy_beta.hjson +++ b/docker/federation/lemmy_beta.hjson @@ -8,10 +8,10 @@ site_name: lemmy-beta } database: { - database: lemmy + database: lemmy_beta user: lemmy password: password - host: postgres_beta + host: localhost port: 5432 pool_size: 5 } diff --git a/docker/federation/lemmy_delta.hjson b/docker/federation/lemmy_delta.hjson index 98f7606f..e2ed2547 100644 --- a/docker/federation/lemmy_delta.hjson +++ b/docker/federation/lemmy_delta.hjson @@ -8,10 +8,10 @@ site_name: lemmy-delta } database: { - database: lemmy + database: lemmy_delta user: lemmy password: password - host: postgres_delta + host: localhost port: 5432 pool_size: 5 } diff --git a/docker/federation/lemmy_epsilon.hjson b/docker/federation/lemmy_epsilon.hjson index f7c64e2f..cdba0577 100644 --- a/docker/federation/lemmy_epsilon.hjson +++ b/docker/federation/lemmy_epsilon.hjson @@ -8,10 +8,10 @@ site_name: lemmy-epsilon } database: { - database: lemmy + database: lemmy_epsilon user: lemmy password: password - host: postgres_epsilon + host: localhost port: 5432 pool_size: 5 } diff --git a/docker/federation/lemmy_gamma.hjson b/docker/federation/lemmy_gamma.hjson index 632f10df..80c75b25 100644 --- a/docker/federation/lemmy_gamma.hjson +++ b/docker/federation/lemmy_gamma.hjson @@ -8,10 +8,10 @@ site_name: lemmy-gamma } database: { - database: lemmy + database: lemmy_gamma user: lemmy password: password - host: postgres_gamma + host: localhost port: 5432 pool_size: 5 } diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile index 33a77af8..eb6bc215 100644 --- a/docker/prod/Dockerfile +++ b/docker/prod/Dockerfile @@ -1,5 +1,5 @@ # Build the project -FROM clux/muslrust:1.59.0 as builder +FROM clux/muslrust:1.64.0 as builder ARG CARGO_BUILD_TARGET=x86_64-unknown-linux-musl ARG RUSTRELEASEDIR="release" diff --git a/docker/prod/Dockerfile.arm b/docker/prod/Dockerfile.arm index 926fa8a7..62439468 100644 --- a/docker/prod/Dockerfile.arm +++ b/docker/prod/Dockerfile.arm @@ -1,4 +1,4 @@ -ARG RUST_BUILDER_IMAGE=rust:1.60-slim-buster +ARG RUST_BUILDER_IMAGE=rust:1.64-slim-buster # Build Lemmy FROM $RUST_BUILDER_IMAGE as builder diff --git a/src/code_migrations.rs b/src/code_migrations.rs index 159514a6..4f8b2afa 100644 --- a/src/code_migrations.rs +++ b/src/code_migrations.rs @@ -2,8 +2,12 @@ use activitypub_federation::core::signatures::generate_actor_keypair; use diesel::{ sql_types::{Nullable, Text}, - *, + ExpressionMethods, + IntoSql, + QueryDsl, + TextExpressionMethods, }; +use diesel_async::RunQueryDsl; use lemmy_api_common::lemmy_db_views::structs::SiteView; use lemmy_apub::{ generate_followers_url, @@ -27,36 +31,34 @@ use lemmy_db_schema::{ site::{Site, SiteInsertForm, SiteUpdateForm}, }, traits::Crud, - utils::naive_now, + utils::{get_conn, naive_now, DbPool}, }; use lemmy_utils::{error::LemmyError, settings::structs::Settings}; use tracing::info; use url::Url; -pub fn run_advanced_migrations( - conn: &mut PgConnection, - settings: &Settings, -) -> Result<(), LemmyError> { +pub async fn run_advanced_migrations(pool: &DbPool, settings: &Settings) -> Result<(), LemmyError> { let protocol_and_hostname = &settings.get_protocol_and_hostname(); - user_updates_2020_04_02(conn, protocol_and_hostname)?; - community_updates_2020_04_02(conn, protocol_and_hostname)?; - post_updates_2020_04_03(conn, protocol_and_hostname)?; - comment_updates_2020_04_03(conn, protocol_and_hostname)?; - private_message_updates_2020_05_05(conn, protocol_and_hostname)?; - post_thumbnail_url_updates_2020_07_27(conn, protocol_and_hostname)?; - apub_columns_2021_02_02(conn)?; - instance_actor_2022_01_28(conn, protocol_and_hostname)?; - regenerate_public_keys_2022_07_05(conn)?; - initialize_local_site_2022_10_10(conn, settings)?; + user_updates_2020_04_02(pool, protocol_and_hostname).await?; + community_updates_2020_04_02(pool, protocol_and_hostname).await?; + post_updates_2020_04_03(pool, protocol_and_hostname).await?; + comment_updates_2020_04_03(pool, protocol_and_hostname).await?; + private_message_updates_2020_05_05(pool, protocol_and_hostname).await?; + post_thumbnail_url_updates_2020_07_27(pool, protocol_and_hostname).await?; + apub_columns_2021_02_02(pool).await?; + instance_actor_2022_01_28(pool, protocol_and_hostname).await?; + regenerate_public_keys_2022_07_05(pool).await?; + initialize_local_site_2022_10_10(pool, settings).await?; Ok(()) } -fn user_updates_2020_04_02( - conn: &mut PgConnection, +async fn user_updates_2020_04_02( + pool: &DbPool, protocol_and_hostname: &str, ) -> Result<(), LemmyError> { use lemmy_db_schema::schema::person::dsl::*; + let conn = &mut get_conn(pool).await?; info!("Running user_updates_2020_04_02"); @@ -64,7 +66,8 @@ fn user_updates_2020_04_02( let incorrect_persons = person .filter(actor_id.like("http://changeme%")) .filter(local.eq(true)) - .load::(conn)?; + .load::(conn) + .await?; for cperson in &incorrect_persons { let keypair = generate_actor_keypair()?; @@ -80,7 +83,7 @@ fn user_updates_2020_04_02( .last_refreshed_at(Some(naive_now())) .build(); - Person::update(conn, cperson.id, &form)?; + Person::update(pool, cperson.id, &form).await?; } info!("{} person rows updated.", incorrect_persons.len()); @@ -88,11 +91,12 @@ fn user_updates_2020_04_02( Ok(()) } -fn community_updates_2020_04_02( - conn: &mut PgConnection, +async fn community_updates_2020_04_02( + pool: &DbPool, protocol_and_hostname: &str, ) -> Result<(), LemmyError> { use lemmy_db_schema::schema::community::dsl::*; + let conn = &mut get_conn(pool).await?; info!("Running community_updates_2020_04_02"); @@ -100,7 +104,8 @@ fn community_updates_2020_04_02( let incorrect_communities = community .filter(actor_id.like("http://changeme%")) .filter(local.eq(true)) - .load::(conn)?; + .load::(conn) + .await?; for ccommunity in &incorrect_communities { let keypair = generate_actor_keypair()?; @@ -117,7 +122,7 @@ fn community_updates_2020_04_02( .last_refreshed_at(Some(naive_now())) .build(); - Community::update(conn, ccommunity.id, &form)?; + Community::update(pool, ccommunity.id, &form).await?; } info!("{} community rows updated.", incorrect_communities.len()); @@ -125,11 +130,12 @@ fn community_updates_2020_04_02( Ok(()) } -fn post_updates_2020_04_03( - conn: &mut PgConnection, +async fn post_updates_2020_04_03( + pool: &DbPool, protocol_and_hostname: &str, ) -> Result<(), LemmyError> { use lemmy_db_schema::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; info!("Running post_updates_2020_04_03"); @@ -137,7 +143,8 @@ fn post_updates_2020_04_03( let incorrect_posts = post .filter(ap_id.like("http://changeme%")) .filter(local.eq(true)) - .load::(conn)?; + .load::(conn) + .await?; for cpost in &incorrect_posts { let apub_id = generate_local_apub_endpoint( @@ -146,10 +153,11 @@ fn post_updates_2020_04_03( protocol_and_hostname, )?; Post::update( - conn, + pool, cpost.id, &PostUpdateForm::builder().ap_id(Some(apub_id)).build(), - )?; + ) + .await?; } info!("{} post rows updated.", incorrect_posts.len()); @@ -157,11 +165,12 @@ fn post_updates_2020_04_03( Ok(()) } -fn comment_updates_2020_04_03( - conn: &mut PgConnection, +async fn comment_updates_2020_04_03( + pool: &DbPool, protocol_and_hostname: &str, ) -> Result<(), LemmyError> { use lemmy_db_schema::schema::comment::dsl::*; + let conn = &mut get_conn(pool).await?; info!("Running comment_updates_2020_04_03"); @@ -169,7 +178,8 @@ fn comment_updates_2020_04_03( let incorrect_comments = comment .filter(ap_id.like("http://changeme%")) .filter(local.eq(true)) - .load::(conn)?; + .load::(conn) + .await?; for ccomment in &incorrect_comments { let apub_id = generate_local_apub_endpoint( @@ -178,10 +188,11 @@ fn comment_updates_2020_04_03( protocol_and_hostname, )?; Comment::update( - conn, + pool, ccomment.id, &CommentUpdateForm::builder().ap_id(Some(apub_id)).build(), - )?; + ) + .await?; } info!("{} comment rows updated.", incorrect_comments.len()); @@ -189,11 +200,12 @@ fn comment_updates_2020_04_03( Ok(()) } -fn private_message_updates_2020_05_05( - conn: &mut PgConnection, +async fn private_message_updates_2020_05_05( + pool: &DbPool, protocol_and_hostname: &str, ) -> Result<(), LemmyError> { use lemmy_db_schema::schema::private_message::dsl::*; + let conn = &mut get_conn(pool).await?; info!("Running private_message_updates_2020_05_05"); @@ -201,7 +213,8 @@ fn private_message_updates_2020_05_05( let incorrect_pms = private_message .filter(ap_id.like("http://changeme%")) .filter(local.eq(true)) - .load::(conn)?; + .load::(conn) + .await?; for cpm in &incorrect_pms { let apub_id = generate_local_apub_endpoint( @@ -210,12 +223,13 @@ fn private_message_updates_2020_05_05( protocol_and_hostname, )?; PrivateMessage::update( - conn, + pool, cpm.id, &PrivateMessageUpdateForm::builder() .ap_id(Some(apub_id)) .build(), - )?; + ) + .await?; } info!("{} private message rows updated.", incorrect_pms.len()); @@ -223,11 +237,12 @@ fn private_message_updates_2020_05_05( Ok(()) } -fn post_thumbnail_url_updates_2020_07_27( - conn: &mut PgConnection, +async fn post_thumbnail_url_updates_2020_07_27( + pool: &DbPool, protocol_and_hostname: &str, ) -> Result<(), LemmyError> { use lemmy_db_schema::schema::post::dsl::*; + let conn = &mut get_conn(pool).await?; info!("Running post_thumbnail_url_updates_2020_07_27"); @@ -244,7 +259,8 @@ fn post_thumbnail_url_updates_2020_07_27( .concat(thumbnail_url), ), ) - .get_results::(conn)?; + .get_results::(conn) + .await?; info!("{} Post thumbnail_url rows updated.", res.len()); @@ -253,13 +269,15 @@ fn post_thumbnail_url_updates_2020_07_27( /// We are setting inbox and follower URLs for local and remote actors alike, because for now /// all federated instances are also Lemmy and use the same URL scheme. -fn apub_columns_2021_02_02(conn: &mut PgConnection) -> Result<(), LemmyError> { +async fn apub_columns_2021_02_02(pool: &DbPool) -> Result<(), LemmyError> { + let conn = &mut get_conn(pool).await?; info!("Running apub_columns_2021_02_02"); { use lemmy_db_schema::schema::person::dsl::*; let persons = person .filter(inbox_url.like("http://changeme%")) - .load::(conn)?; + .load::(conn) + .await?; for p in &persons { let inbox_url_ = generate_inbox_url(&p.actor_id)?; @@ -269,7 +287,8 @@ fn apub_columns_2021_02_02(conn: &mut PgConnection) -> Result<(), LemmyError> { inbox_url.eq(inbox_url_), shared_inbox_url.eq(shared_inbox_url_), )) - .get_result::(conn)?; + .get_result::(conn) + .await?; } } @@ -277,7 +296,8 @@ fn apub_columns_2021_02_02(conn: &mut PgConnection) -> Result<(), LemmyError> { use lemmy_db_schema::schema::community::dsl::*; let communities = community .filter(inbox_url.like("http://changeme%")) - .load::(conn)?; + .load::(conn) + .await?; for c in &communities { let followers_url_ = generate_followers_url(&c.actor_id)?; @@ -289,7 +309,8 @@ fn apub_columns_2021_02_02(conn: &mut PgConnection) -> Result<(), LemmyError> { inbox_url.eq(inbox_url_), shared_inbox_url.eq(shared_inbox_url_), )) - .get_result::(conn)?; + .get_result::(conn) + .await?; } } @@ -300,12 +321,12 @@ fn apub_columns_2021_02_02(conn: &mut PgConnection) -> Result<(), LemmyError> { /// means we need to add actor columns to the site table, and initialize them with correct values. /// Before this point, there is only a single value in the site table which refers to the local /// Lemmy instance, so thats all we need to update. -fn instance_actor_2022_01_28( - conn: &mut PgConnection, +async fn instance_actor_2022_01_28( + pool: &DbPool, protocol_and_hostname: &str, ) -> Result<(), LemmyError> { info!("Running instance_actor_2021_09_29"); - if let Ok(site_view) = SiteView::read_local(conn) { + if let Ok(site_view) = SiteView::read_local(pool).await { let site = site_view.site; // if site already has public key, we dont need to do anything here if !site.public_key.is_empty() { @@ -320,7 +341,7 @@ fn instance_actor_2022_01_28( .private_key(Some(Some(key_pair.private_key))) .public_key(Some(key_pair.public_key)) .build(); - Site::update(conn, site.id, &site_form)?; + Site::update(pool, site.id, &site_form).await?; } Ok(()) } @@ -330,7 +351,8 @@ fn instance_actor_2022_01_28( /// key field is empty, generate a new keypair. It would be possible to regenerate only the pubkey, /// but thats more complicated and has no benefit, as federation is already broken for these actors. /// https://github.com/LemmyNet/lemmy/issues/2347 -fn regenerate_public_keys_2022_07_05(conn: &mut PgConnection) -> Result<(), LemmyError> { +async fn regenerate_public_keys_2022_07_05(pool: &DbPool) -> Result<(), LemmyError> { + let conn = &mut get_conn(pool).await?; info!("Running regenerate_public_keys_2022_07_05"); { @@ -339,7 +361,8 @@ fn regenerate_public_keys_2022_07_05(conn: &mut PgConnection) -> Result<(), Lemm let communities: Vec = community .filter(local.eq(true)) .filter(public_key.eq("")) - .load::(conn)?; + .load::(conn) + .await?; for community_ in communities { info!( "local community {} has empty public key field, regenerating key", @@ -350,7 +373,7 @@ fn regenerate_public_keys_2022_07_05(conn: &mut PgConnection) -> Result<(), Lemm .public_key(Some(key_pair.public_key)) .private_key(Some(Some(key_pair.private_key))) .build(); - Community::update(conn, community_.id, &form)?; + Community::update(pool, community_.id, &form).await?; } } @@ -360,7 +383,8 @@ fn regenerate_public_keys_2022_07_05(conn: &mut PgConnection) -> Result<(), Lemm let persons = person .filter(local.eq(true)) .filter(public_key.eq("")) - .load::(conn)?; + .load::(conn) + .await?; for person_ in persons { info!( "local user {} has empty public key field, regenerating key", @@ -371,7 +395,7 @@ fn regenerate_public_keys_2022_07_05(conn: &mut PgConnection) -> Result<(), Lemm .public_key(Some(key_pair.public_key)) .private_key(Some(Some(key_pair.private_key))) .build(); - Person::update(conn, person_.id, &form)?; + Person::update(pool, person_.id, &form).await?; } } Ok(()) @@ -381,14 +405,14 @@ fn regenerate_public_keys_2022_07_05(conn: &mut PgConnection) -> Result<(), Lemm /// /// If a site already exists, the DB migration should generate a local_site row. /// This will only be run for brand new sites. -fn initialize_local_site_2022_10_10( - conn: &mut PgConnection, +async fn initialize_local_site_2022_10_10( + pool: &DbPool, settings: &Settings, ) -> Result<(), LemmyError> { info!("Running initialize_local_site_2022_10_10"); // Check to see if local_site exists - if LocalSite::read(conn).is_ok() { + if LocalSite::read(pool).await.is_ok() { return Ok(()); } info!("No Local Site found, creating it."); @@ -398,7 +422,7 @@ fn initialize_local_site_2022_10_10( .expect("must have domain"); // Upsert this to the instance table - let instance = Instance::create(conn, &domain)?; + let instance = Instance::create(pool, &domain).await?; if let Some(setup) = &settings.setup { let person_keypair = generate_actor_keypair()?; @@ -419,14 +443,14 @@ fn initialize_local_site_2022_10_10( .inbox_url(Some(generate_inbox_url(&person_actor_id)?)) .shared_inbox_url(Some(generate_shared_inbox_url(&person_actor_id)?)) .build(); - let person_inserted = Person::create(conn, &person_form)?; + let person_inserted = Person::create(pool, &person_form).await?; let local_user_form = LocalUserInsertForm::builder() .person_id(person_inserted.id) .password_encrypted(setup.admin_password.to_owned()) .email(setup.admin_email.to_owned()) .build(); - LocalUser::create(conn, &local_user_form)?; + LocalUser::create(pool, &local_user_form).await?; }; // Add an entry for the site table @@ -448,14 +472,14 @@ fn initialize_local_site_2022_10_10( .private_key(Some(site_key_pair.private_key)) .public_key(Some(site_key_pair.public_key)) .build(); - let site = Site::create(conn, &site_form)?; + let site = Site::create(pool, &site_form).await?; // Finally create the local_site row let local_site_form = LocalSiteInsertForm::builder() .site_id(site.id) .site_setup(Some(settings.setup.is_some())) .build(); - let local_site = LocalSite::create(conn, &local_site_form)?; + let local_site = LocalSite::create(pool, &local_site_form).await?; // Create the rate limit table let local_site_rate_limit_form = LocalSiteRateLimitInsertForm::builder() @@ -471,7 +495,7 @@ fn initialize_local_site_2022_10_10( .search(Some(999)) .local_site_id(local_site.id) .build(); - LocalSiteRateLimit::create(conn, &local_site_rate_limit_form)?; + LocalSiteRateLimit::create(pool, &local_site_rate_limit_form).await?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 4667df44..fd0f3c70 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,8 @@ #[macro_use] extern crate diesel_migrations; -use crate::diesel_migrations::MigrationHarness; use actix::prelude::*; use actix_web::{web::Data, *}; -use diesel::{ - r2d2::{ConnectionManager, Pool}, - PgConnection, -}; use diesel_migrations::EmbeddedMigrations; use doku::json::{AutoComments, Formatting}; use lemmy_api::match_websocket_operation; @@ -15,13 +10,15 @@ use lemmy_api_common::{ lemmy_db_views::structs::SiteView, request::build_user_agent, utils::{ - blocking, check_private_instance_and_federation_enabled, local_site_rate_limit_to_rate_limit_config, }, }; use lemmy_api_crud::match_websocket_operation_crud; -use lemmy_db_schema::{source::secret::Secret, utils::get_database_url_from_env}; +use lemmy_db_schema::{ + source::secret::Secret, + utils::{build_db_pool, get_database_url, run_migrations}, +}; use lemmy_routes::{feeds, images, nodeinfo, webfinger}; use lemmy_server::{ api_routes, @@ -69,40 +66,28 @@ async fn main() -> Result<(), LemmyError> { init_logging(&settings.opentelemetry_url)?; - // Set up the r2d2 connection pool - let db_url = match get_database_url_from_env() { - Ok(url) => url, - Err(_) => settings.get_database_url(), - }; - let manager = ConnectionManager::::new(&db_url); - let pool = Pool::builder() - .max_size(settings.database.pool_size) - .min_idle(Some(1)) - .build(manager)?; + // Set up the bb8 connection pool + let db_url = get_database_url(Some(&settings)); + run_migrations(&db_url); // Run the migrations from code - let settings_cloned = settings.to_owned(); - blocking(&pool, move |conn| { - let _ = conn - .run_pending_migrations(MIGRATIONS) - .map_err(|_| LemmyError::from_message("Couldn't run migrations"))?; - run_advanced_migrations(conn, &settings_cloned)?; - Ok(()) as Result<(), LemmyError> - }) - .await??; + let pool = build_db_pool(&settings).await?; + run_advanced_migrations(&pool, &settings).await?; // Schedules various cleanup tasks for the DB - let pool2 = pool.clone(); thread::spawn(move || { - scheduled_tasks::setup(pool2).expect("Couldn't set up scheduled_tasks"); + scheduled_tasks::setup(db_url).expect("Couldn't set up scheduled_tasks"); }); // Initialize the secrets - let conn = &mut pool.get()?; - let secret = Secret::init(conn).expect("Couldn't initialize secrets."); + let secret = Secret::init(&pool) + .await + .expect("Couldn't initialize secrets."); // Make sure the local site is set up. - let site_view = SiteView::read_local(conn).expect("local site not set up"); + let site_view = SiteView::read_local(&pool) + .await + .expect("local site not set up"); let local_site = site_view.local_site; let federation_enabled = local_site.federation_enabled; diff --git a/src/scheduled_tasks.rs b/src/scheduled_tasks.rs index 108de672..5173a317 100644 --- a/src/scheduled_tasks.rs +++ b/src/scheduled_tasks.rs @@ -1,17 +1,18 @@ -// Scheduler, and trait for .seconds(), .minutes(), etc. use clokwerk::{Scheduler, TimeUnits}; // Import week days and WeekDay use diesel::{sql_query, PgConnection, RunQueryDsl}; -use lemmy_db_schema::{source::activity::Activity, utils::DbPool}; +use diesel::{Connection, ExpressionMethods, QueryDsl}; use lemmy_utils::error::LemmyError; use std::{thread, time::Duration}; use tracing::info; /// Schedules various cleanup tasks for lemmy in a background thread -pub fn setup(pool: DbPool) -> Result<(), LemmyError> { +pub fn setup(db_url: String) -> Result<(), LemmyError> { + // Setup the connections let mut scheduler = Scheduler::new(); - let mut conn = pool.get()?; + let mut conn = PgConnection::establish(&db_url).expect("could not establish connection"); + active_counts(&mut conn); update_banned_when_expired(&mut conn); @@ -19,13 +20,14 @@ pub fn setup(pool: DbPool) -> Result<(), LemmyError> { // TODO remove this for now, since it slows down startup a lot on lemmy.ml reindex_aggregates_tables(&mut conn, true); scheduler.every(1.hour()).run(move || { - active_counts(&mut conn); - update_banned_when_expired(&mut conn); - reindex_aggregates_tables(&mut conn, true); - drop_ccnew_indexes(&mut conn); + let conn = &mut PgConnection::establish(&db_url) + .unwrap_or_else(|_| panic!("Error connecting to {}", db_url)); + active_counts(conn); + update_banned_when_expired(conn); + reindex_aggregates_tables(conn, true); + drop_ccnew_indexes(conn); }); - let mut conn = pool.get()?; clear_old_activities(&mut conn); scheduler.every(1.weeks()).run(move || { clear_old_activities(&mut conn); @@ -61,8 +63,12 @@ fn reindex_table(conn: &mut PgConnection, table_name: &str, concurrently: bool) /// Clear old activities (this table gets very large) fn clear_old_activities(conn: &mut PgConnection) { + use diesel::dsl::*; + use lemmy_db_schema::schema::activity::dsl::*; info!("Clearing old activities..."); - Activity::delete_olds(conn).expect("clear old activities"); + diesel::delete(activity.filter(published.lt(now - 6.months()))) + .execute(conn) + .expect("clear old activities"); info!("Done."); }