commit b78b84dda46392047c1c797891adff38999ecc86 from: witcher date: Sun Nov 20 16:12:53 2022 UTC Replace diesel with sqlx This replaces the non-async Diesel with the async sqlx to allow for better performance through parallelising the insertion or updating of posts in the database. Migrations have not yet been implemented. Implements: https://todo.sr.ht/~witcher/rss-email/12 Implements: https://todo.sr.ht/~witcher/rss-email/3 commit - e039dc9be309339563524e1606a744336453c5ce commit + b78b84dda46392047c1c797891adff38999ecc86 blob - 06368397a1ad7a4dfe9c33b7086b93885ff67823 blob + cd7812b38aa289f6da7899e9441b4b193006f3d0 --- Cargo.lock +++ Cargo.lock @@ -3,6 +3,17 @@ version = 3 [[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] name = "aho-corasick" version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -27,6 +38,15 @@ source = "registry+https://github.com/rust-lang/crates checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" [[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + +[[package]] name = "atom_syndication" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -69,6 +89,15 @@ source = "registry+https://github.com/rust-lang/crates checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] name = "bumpalo" version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -159,6 +188,59 @@ source = "registry+https://github.com/rust-lang/crates checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff" + +[[package]] +name = "crossbeam-queue" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebb3d1683412e9be6a15533314f00ec223c0762c522a3f77f048b265aab4470c" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] name = "darling" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -225,38 +307,16 @@ dependencies = [ ] [[package]] -name = "diesel" -version = "1.4.8" +name = "digest" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "byteorder", - "diesel_derives", - "libsqlite3-sys", + "block-buffer", + "crypto-common", ] [[package]] -name = "diesel_derives" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "diesel_migrations" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c" -dependencies = [ - "migrations_internals", - "migrations_macros", -] - -[[package]] name = "diligent-date-parser" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -286,6 +346,18 @@ dependencies = [ ] [[package]] +name = "dotenvy" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0" + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] name = "email-encoding" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -324,6 +396,12 @@ dependencies = [ ] [[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] name = "fastrand" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -333,6 +411,18 @@ dependencies = [ ] [[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin 0.9.4", +] + +[[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -355,6 +445,7 @@ source = "registry+https://github.com/rust-lang/crates checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -364,6 +455,28 @@ source = "registry+https://github.com/rust-lang/crates checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] name = "futures-sink" version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -382,12 +495,24 @@ source = "registry+https://github.com/rust-lang/crates checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-core", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] name = "getrandom" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -422,12 +547,27 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] [[package]] +name = "hashlink" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" +dependencies = [ + "hashbrown", +] + +[[package]] name = "heck" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "hermit-abi" @@ -439,6 +579,12 @@ dependencies = [ ] [[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] name = "http" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -571,6 +717,15 @@ source = "registry+https://github.com/rust-lang/crates checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] name = "itoa" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -621,15 +776,26 @@ checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323f [[package]] name = "libsqlite3-sys" -version = "0.22.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290b64917f8b0cb885d9de0f9959fe1f775d7fa12f1da2db9001c1c8ab60f89d" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" dependencies = [ + "cc", "pkg-config", "vcpkg", ] [[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] name = "log" version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -651,27 +817,6 @@ source = "registry+https://github.com/rust-lang/crates checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] -name = "migrations_internals" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860" -dependencies = [ - "diesel", -] - -[[package]] -name = "migrations_macros" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c" -dependencies = [ - "migrations_internals", - "proc-macro2", - "quote", - "syn", -] - -[[package]] name = "mime" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -753,12 +898,63 @@ source = "registry+https://github.com/rust-lang/crates checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" [[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "paste" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" + +[[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "pin-project-lite" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -919,7 +1115,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", + "spin 0.5.2", "untrusted", "web-sys", "winapi", @@ -944,8 +1140,6 @@ dependencies = [ "anyhow", "chrono", "clap", - "diesel", - "diesel_migrations", "directories", "env_logger", "lettre", @@ -953,6 +1147,7 @@ dependencies = [ "reqwest", "rss", "serde", + "sqlx", "tokio", "toml", ] @@ -985,6 +1180,12 @@ source = "registry+https://github.com/rust-lang/crates checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] name = "sct" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1038,6 +1239,17 @@ dependencies = [ ] [[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] name = "slab" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1047,6 +1259,12 @@ dependencies = [ ] [[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] name = "socket2" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1063,6 +1281,122 @@ source = "registry+https://github.com/rust-lang/crates checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sqlformat" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105" +dependencies = [ + "ahash", + "atoi", + "bitflags", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "indexmap", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls", + "rustls-pemfile", + "sha2", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki-roots", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9" +dependencies = [ + "dotenvy", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2", + "sqlx-core", + "sqlx-rt", + "syn", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls", +] + +[[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1181,6 +1515,17 @@ dependencies = [ ] [[package]] +name = "tokio-stream" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] name = "tokio-util" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1236,6 +1581,12 @@ source = "registry+https://github.com/rust-lang/crates checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] name = "unicode-bidi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1257,6 +1608,18 @@ dependencies = [ ] [[package]] +name = "unicode-segmentation" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" blob - dacdd829277c0d5384d2a0a86e198c7bd7533a05 blob + b8cf0dcf0c580aefaf60cb416a914e8802453619 --- Cargo.toml +++ Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" strip = "symbols" [dependencies] -diesel = { version = "1.4", features = ["sqlite"] } rss = "2.0" anyhow = "1.0" reqwest = {version = "0.11", default-features = false, features = ["rustls-tls"]} @@ -17,8 +16,8 @@ chrono = "0.4" toml = "0.5.8" lettre = { version = "0.10.1", default-features = false, features = ["rustls", "rustls-tls", "builder", "smtp-transport"] } serde = { version = "1.0", features = ["derive"] } -diesel_migrations = "1.4.0" directories = "4.0.1" log = "0.4.17" env_logger = "0.9.0" tokio = { version = "1.21.2", default-features = false, features = ["rt-multi-thread", "macros"] } +sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "sqlite"] } blob - 92267c829f2027cdf0e641efa95622d7ddd8bb74 (mode 644) blob + /dev/null --- diesel.toml +++ /dev/null @@ -1,5 +0,0 @@ -# For documentation on how to configure this file, -# see diesel.rs/guides/configuring-diesel-cli - -[print_schema] -file = "src/schema.rs" blob - 32a273010396aa00db232b09bb96c77b06cc5668 blob + ad8c2c8efada1900e403700941516b271040e5b7 --- src/db.rs +++ src/db.rs @@ -1,28 +1,23 @@ use chrono::DateTime; -use diesel::prelude::*; -use diesel::sqlite::SqliteConnection; use rss::Item; +use sqlx::pool::PoolConnection; +use sqlx::Sqlite; -use crate::models::NewPost; -use crate::schema::posts; - // inserts a new post or updates an old one with the same guid -pub fn insert_item(conn: &SqliteConnection, item: &Item) -> anyhow::Result { +pub async fn insert_item(mut conn: PoolConnection, item: &Item) -> anyhow::Result<()> { let time = item .pub_date() .map(|date| DateTime::parse_from_rfc2822(date).unwrap().timestamp()); - let new_post = NewPost { - guid: item.guid().ok_or_else(|| anyhow!("No guid found"))?.value(), - title: item.title(), - author: item.author(), - url: item.link(), - feedurl: item.source().map(|s| s.url()), - pub_date: time, - content: item.content().or_else(|| item.description()), - }; + let guid = item.guid().ok_or_else(|| anyhow!("No guid found"))?.value(); + let title = item.title(); + let author = item.author(); + let url = item.link(); + let feedurl = item.source().map(|s| s.url()); + let pub_date = time; + let content = item.content().or_else(|| item.description()); - Ok(diesel::replace_into(posts::table) - .values(&new_post) - .execute(conn)?) + sqlx::query!("insert into posts (guid, title, author, url, feedurl, pub_date, content) values (?, ?, ?, ?, ?, ?, ?)", guid, title, author, url, feedurl, pub_date, content).execute(&mut conn).await?; + + Ok(()) } blob - b181138712b3a96686ba3774132fc7fa124cfbc2 blob + 0ac9058280a7d2d1449e892283bd7bef9aa08a2a --- src/main.rs +++ src/main.rs @@ -1,11 +1,7 @@ #[macro_use] extern crate log; #[macro_use] -extern crate diesel; -#[macro_use] extern crate anyhow; -#[macro_use] -extern crate diesel_migrations; pub mod cli; pub mod config; @@ -13,22 +9,22 @@ pub mod db; pub mod mail; pub mod models; pub mod rss; -pub mod schema; -use self::diesel::prelude::*; use crate::mail::{get_mailer, send_email}; use anyhow::Context; use config::Config; -use schema::posts::dsl::*; use std::{ fs::File, io::{BufRead, BufReader}, }; + +use sqlx::{pool::PoolConnection, sqlite::SqlitePoolOptions, Sqlite}; use tokio::task::JoinSet; #[tokio::main] async fn main() -> anyhow::Result<()> { - diesel_migrations::embed_migrations!("migrations/"); + // TODO: migrations + //diesel_migrations::embed_migrations!("migrations/"); env_logger::init(); let args = cli::Cli::build_app()?; @@ -44,12 +40,14 @@ async fn main() -> anyhow::Result<()> { .lines() .map(|l| l.unwrap()); - debug!( - "Establishing connection to database at {:?}", - args.database_path.as_ref().unwrap() - ); - let conn = SqliteConnection::establish(args.database_path.unwrap().to_str().unwrap())?; - embedded_migrations::run(&conn)?; + let db_path = args.database_path.unwrap(); + debug!("Establishing connection to database at {:?}", db_path); + let pool = SqlitePoolOptions::new() + .max_connections(5) + .connect(db_path.to_str().unwrap()) + .await?; + // TODO: migrations + //embedded_migrations::run(&conn)?; let mut set = JoinSet::new(); for u in urls { @@ -63,28 +61,31 @@ async fn main() -> anyhow::Result<()> { debug!("Found {} new items", items.len()); for i in items { - let _ = db::insert_item(&conn, i)?; + let conn = pool.acquire().await?; + let _ = db::insert_item(conn, i).await?; } } - let results = posts - .filter(sent.eq(false)) - .order(pub_date.desc()) - .load::(&conn)?; + let results = sqlx::query_as!( + models::Post, + "select * from posts where sent != true order by pub_date desc" + ) + .fetch_all(&pool) + .await?; - send_posts(&conn, &config, results, args.dry_run)?; + send_posts(pool.acquire().await?, &config, results, args.dry_run).await?; Ok(()) } -fn send_posts( - conn: &SqliteConnection, +async fn send_posts( + mut conn: PoolConnection, config: &Config, items: Vec, dry_run: bool, ) -> anyhow::Result<()> { let mailer = get_mailer(config)?; - for mut post in items { + for post in items { if !dry_run { let subject = post.title.unwrap_or_else(|| "No title found".to_string()); let body = match post.content { @@ -93,10 +94,10 @@ fn send_posts( }; send_email(config, subject, body, &mailer)?; } - post.sent = true; - diesel::update(schema::posts::dsl::posts.find(post.guid)) - .set(sent.eq(true)) - .execute(conn)?; + + sqlx::query!("update posts set sent = true where guid = ?", post.guid) + .execute(&mut conn) + .await?; } Ok(()) blob - 903f08c6a1557affb789da7f92d7d48750ff8df0 blob + c3046d7556498281e450586cff8e35cbdc2c9e4f --- src/models.rs +++ src/models.rs @@ -1,6 +1,4 @@ -use super::schema::posts; - -#[derive(Debug, Queryable)] +#[derive(Debug)] pub struct Post { pub guid: String, pub title: Option, @@ -11,15 +9,3 @@ pub struct Post { pub content: Option, pub sent: bool, } - -#[derive(Insertable)] -#[table_name = "posts"] -pub struct NewPost<'a> { - pub guid: &'a str, - pub title: Option<&'a str>, - pub author: Option<&'a str>, - pub url: Option<&'a str>, - pub feedurl: Option<&'a str>, - pub pub_date: Option, - pub content: Option<&'a str>, -} blob - f30fc90dc34796b218720eae7dde22c7fde207f9 (mode 644) blob + /dev/null --- src/schema.rs +++ /dev/null @@ -1,12 +0,0 @@ -table! { - posts (guid) { - guid -> Text, - title -> Nullable, - author -> Nullable, - url -> Nullable, - feedurl -> Nullable, - pub_date -> Nullable, - content -> Nullable, - sent -> Bool, - } -}