diff --git a/Cargo.lock b/Cargo.lock index 002173cd..de4519ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,10 +79,12 @@ dependencies = [ "ahash 0.8.3", "base64 0.21.0", "bitflags 1.3.2", + "brotli", "bytes", "bytestring", "derive_more", "encoding_rs", + "flate2", "futures-core", "h2", "http", @@ -100,6 +102,17 @@ dependencies = [ "tokio", "tokio-util", "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +dependencies = [ + "quote 1.0.26", + "syn 1.0.109", ] [[package]] @@ -159,6 +172,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" dependencies = [ + "actix-macros", "futures-core", "tokio", ] @@ -210,15 +224,18 @@ checksum = "cd3cb42f9566ab176e1ef0b8b3a896529062b4efc6be0123046095914c4c1c96" dependencies = [ "actix-codec", "actix-http", + "actix-macros", "actix-router", "actix-rt", "actix-server", "actix-service", "actix-utils", + "actix-web-codegen", "ahash 0.7.6", "bytes", "bytestring", - "cfg-if 1.0.0", + "cfg-if", + "cookie", "derive_more", "encoding_rs", "futures-core", @@ -240,6 +257,36 @@ dependencies = [ "url", ] +[[package]] +name = "actix-web-actors" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf6e9ccc371cfddbed7aa842256a4abc7a6dcac9f3fce392fe1d0f68cfd136b2" +dependencies = [ + "actix", + "actix-codec", + "actix-http", + "actix-web", + "bytes", + "bytestring", + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "actix-web-codegen" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2262160a7ae29e3415554a3f1fc04c764b1540c116aa524683208078b7a75bc9" +dependencies = [ + "actix-router", + "proc-macro2 1.0.54", + "quote 1.0.26", + "syn 1.0.109", +] + [[package]] name = "actix_derive" version = "0.6.0" @@ -274,7 +321,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "getrandom", "once_cell", "version_check 0.9.4", @@ -289,6 +336,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "amazon-actor" version = "0.1.0" @@ -296,7 +358,6 @@ dependencies = [ "actix", "bitque-config", "bytes", - "common", "futures", "libc", "openssl-sys", @@ -305,6 +366,7 @@ dependencies = [ "rusoto_signature", "serde", "tokio", + "tracing", "uuid 1.3.0", ] @@ -478,10 +540,11 @@ name = "bitque" version = "0.1.0" dependencies = [ "actix", + "actix-rt", + "actix-web", "amazon-actor", "bitque-config", "bitque-data", - "common", "database-actor", "dotenv", "filesystem-actor", @@ -494,6 +557,8 @@ dependencies = [ "serde_json", "tokio", "toml", + "tracing", + "tracing-subscriber", "web-actor", "websocket-actor", ] @@ -516,7 +581,7 @@ dependencies = [ "actix", "chrono", "diesel 2.0.3", - "diesel-derive-enum", + "diesel-derive-enum 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "diesel-derive-more", "diesel-derive-newtype", "serde", @@ -525,38 +590,12 @@ dependencies = [ "uuid 1.3.0", ] -[[package]] -name = "bitque_client" -version = "0.1.0" -dependencies = [ - "bincode", - "bitque-data", - "chrono", - "console_error_panic_hook", - "derive_enum_iter", - "derive_enum_primitive", - "dotenv", - "futures", - "js-sys", - "seed", - "serde", - "serde_json", - "tracing", - "uuid 1.3.0", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", - "wee_alloc", -] - [[package]] name = "bitquec" version = "0.1.0" dependencies = [ "actix", "clap", - "common", "termion 2.0.1", "tui", ] @@ -579,6 +618,27 @@ dependencies = [ "generic-array", ] +[[package]] +name = "brotli" +version = "3.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.12.0" @@ -617,12 +677,9 @@ name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -708,10 +765,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "common" -version = "0.1.0" - [[package]] name = "comrak" version = "0.18.0" @@ -746,22 +799,23 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen", -] - [[package]] name = "convert_case" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "percent-encoding", + "time 0.3.20", + "version_check 0.9.4", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -793,7 +847,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -802,7 +856,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -812,7 +866,7 @@ version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -951,7 +1005,6 @@ dependencies = [ "bitque-data", "byteorder", "chrono", - "common", "derive_db_execute", "diesel 2.0.3", "dotenv", @@ -985,10 +1038,6 @@ version = "0.1.0" name = "derive_enum_primitive" version = "0.1.0" -[[package]] -name = "derive_enum_sql" -version = "0.1.0" - [[package]] name = "derive_more" version = "0.99.17" @@ -1041,6 +1090,16 @@ dependencies = [ "uuid 1.3.0", ] +[[package]] +name = "diesel-derive-enum" +version = "2.0.1" +dependencies = [ + "heck", + "proc-macro2 1.0.54", + "quote 1.0.26", + "syn 1.0.109", +] + [[package]] name = "diesel-derive-enum" version = "2.0.1" @@ -1132,7 +1191,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "dirs-sys-next", ] @@ -1195,12 +1254,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112" -[[package]] -name = "enclose" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1056f553da426e9c025a662efa48b52e62e0a3a7648aa2d15aeaaf7f0d329357" - [[package]] name = "encoding" version = "0.2.33" @@ -1271,7 +1324,7 @@ version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1348,7 +1401,6 @@ dependencies = [ "actix-files", "bitque-config", "bytes", - "common", "futures", "tokio", ] @@ -1504,59 +1556,9 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ - "cfg-if 1.0.0", - "js-sys", + "cfg-if", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "gloo-events" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-file" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" -dependencies = [ - "futures-channel", - "gloo-events", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-utils" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -1619,7 +1621,6 @@ dependencies = [ "bincode", "bitque-config", "bitque-data", - "common", "flate2", "lazy_static", "serde", @@ -1782,7 +1783,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1823,6 +1824,15 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.61" @@ -1967,7 +1977,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1976,7 +1986,6 @@ version = "0.1.0" dependencies = [ "actix", "bitque-config", - "common", "dotenv", "futures", "lettre 0.10.3", @@ -1995,6 +2004,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "md-5" version = "0.9.1" @@ -2012,12 +2030,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "mime" version = "0.3.17" @@ -2089,6 +2101,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" @@ -2176,7 +2198,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" dependencies = [ "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -2224,6 +2246,12 @@ dependencies = [ "vcpkg", ] +[[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" @@ -2240,7 +2268,7 @@ version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall 0.2.16", "smallvec", @@ -2623,6 +2651,15 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -2793,12 +2830,6 @@ dependencies = [ "parking_lot", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.1.0" @@ -2834,28 +2865,6 @@ dependencies = [ "libc", ] -[[package]] -name = "seed" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c0e296ea0569d20467e9a1df3cb6ed66ce3b791a7eaf1e1110ae231f75e2b46" -dependencies = [ - "enclose", - "futures", - "getrandom", - "gloo-file", - "gloo-timers", - "gloo-utils", - "indexmap", - "js-sys", - "rand 0.8.5", - "uuid 1.3.0", - "version_check 0.9.4", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "semver" version = "1.0.17" @@ -2929,7 +2938,7 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.10.6", ] @@ -2947,12 +2956,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.9.0", "opaque-debug", ] +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + [[package]] name = "shell-words" version = "1.1.0" @@ -3039,12 +3057,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "strsim" version = "0.10.0" @@ -3153,7 +3165,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "fastrand", "redox_syscall 0.3.5", "rustix 0.37.5", @@ -3223,6 +3235,16 @@ dependencies = [ "syn 2.0.12", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.1.45" @@ -3376,7 +3398,7 @@ version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -3401,6 +3423,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -3532,6 +3585,12 @@ dependencies = [ "sha1_smol", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" @@ -3588,7 +3647,7 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -3607,18 +3666,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.84" @@ -3648,41 +3695,19 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" -[[package]] -name = "wasm-bindgen-test" -version = "0.3.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db36fc0f9fb209e88fb3642590ae0205bb5a56216dabd963ba15879fe53a30b" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0734759ae6b3b1717d661fe4f016efcfb9828f5edb4520c18eaee05af3b43be9" -dependencies = [ - "proc-macro2 1.0.54", - "quote 1.0.26", -] - [[package]] name = "web-actor" version = "0.1.0" dependencies = [ "actix", "actix-multipart", + "actix-web", + "actix-web-actors", "amazon-actor", "bincode", "bitque-config", "bitque-data", - "common", + "bytes", "database-actor", "filesystem-actor", "futures", @@ -3692,30 +3717,22 @@ dependencies = [ "serde", "tokio", "toml", + "tracing", "uuid 1.3.0", "websocket-actor", ] -[[package]] -name = "web-sys" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "websocket-actor" version = "0.1.0" dependencies = [ "actix", + "actix-web", + "actix-web-actors", "async-trait", "bincode", "bitque-config", "bitque-data", - "common", "comrak", "database-actor", "flate2", @@ -3728,22 +3745,10 @@ dependencies = [ "serde", "syntect", "toml", + "tracing", "uuid 1.3.0", ] -[[package]] -name = "wee_alloc" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "memory_units", - "spin", - "winapi", -] - [[package]] name = "winapi" version = "0.3.9" @@ -3960,3 +3965,33 @@ name = "zeroize" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" + +[[package]] +name = "zstd" +version = "0.12.3+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "6.0.4+zstd.1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.7+zstd.1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" +dependencies = [ + "cc", + "libc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 9e72e539..973862dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ [workspace] members = [ - "./crates/common", "./crates/bitque-cli", "./crates/bitque-server", "./crates/bitque-config", @@ -27,11 +26,14 @@ members = [ "./crates/amazon-actor", "./crates/filesystem-actor", # Client - "./crates/web" +# "./crates/web" +] +exclude = [ + "crates/bitque-cli", + "crates/web", ] [workspace.dependencies] -common = { path = "./crates/common" } bitque-cli = { path = "./crates/bitque-cli" } bitque-server = { path = "./crates/bitque-server" } bitque-config = { path = "./crates/bitque-config" } diff --git a/crates/amazon-actor/Cargo.toml b/crates/amazon-actor/Cargo.toml index a33cb5fb..a96d8982 100644 --- a/crates/amazon-actor/Cargo.toml +++ b/crates/amazon-actor/Cargo.toml @@ -15,8 +15,7 @@ path = "./src/lib.rs" [dependencies] actix = { version = "0.13.0" } bitque-config = { workspace = true, features = ["mail", "web", "local-storage"] } -bytes = { version = "1.0.0" } -common = { workspace = true } +bytes = { version = "1" } futures = { version = "0.3.8" } libc = { version = "0.2.0", default-features = false } openssl-sys = { version = "*", features = ["vendored"] } @@ -25,4 +24,5 @@ rusoto_s3 = { version = "0.48.0" } rusoto_signature = { version = "0.48.0" } serde = { version = "*" } tokio = { version = "1", features = ["full"] } +tracing = { version = "0.1.37" } uuid = { version = "1.3.0", features = ["serde", "v4", "v5"] } diff --git a/crates/amazon-actor/src/lib.rs b/crates/amazon-actor/src/lib.rs index 76f2f583..ba865303 100644 --- a/crates/amazon-actor/src/lib.rs +++ b/crates/amazon-actor/src/lib.rs @@ -1,4 +1,3 @@ -extern crate common; use rusoto_s3::{PutObjectRequest, S3Client, S3}; #[derive(Debug)] @@ -21,7 +20,7 @@ impl actix::Actor for AmazonExecutor { #[derive(actix::Message)] #[rtype(result = "Result")] pub struct S3PutObject { - pub source: tokio::sync::broadcast::Receiver, + pub source: tokio::sync::broadcast::Receiver, pub file_name: String, } @@ -40,7 +39,7 @@ impl actix::Handler for AmazonExecutor { .expect("Failed to start amazon agent") .block_on(async { let s3 = bitque_config::amazon::config(); - ::tracing::debug!("{:?}", s3); + tracing::debug!("{:?}", s3); // TODO: Unable to upload as stream because there is no size_hint // let stream = source @@ -50,10 +49,9 @@ impl actix::Handler for AmazonExecutor { // use common::bytes::Buf; // ::bytes::Bytes::from(b.bytes()) // }); - use common::bytes::Buf; let mut v: Vec = vec![]; while let Ok(b) = source.recv().await { - v.extend_from_slice(b.bytes()) + v.extend_from_slice(&b) } let client = S3Client::new(s3.region()); diff --git a/crates/bitque-cli/Cargo.toml b/crates/bitque-cli/Cargo.toml index 63b081b9..9fc9b08f 100644 --- a/crates/bitque-cli/Cargo.toml +++ b/crates/bitque-cli/Cargo.toml @@ -7,6 +7,5 @@ edition = "2018" [dependencies] actix = { version = "0.13.0" } clap = { version = "4.1.13" } -common = { workspace = true } termion = { version = "*" } tui = { version = "0.19.0", features = ["termion"] } diff --git a/crates/bitque-cli/src/main.rs b/crates/bitque-cli/src/main.rs index 1bcaecd0..04050e21 100644 --- a/crates/bitque-cli/src/main.rs +++ b/crates/bitque-cli/src/main.rs @@ -5,12 +5,11 @@ use std::sync::{mpsc, Arc}; use std::time::Duration; use termion::event::Key; -use termion::input::MouseTerminal; -use termion::raw::IntoRawMode; -use termion::screen::AlternateScreen; +use termion::screen::IntoAlternateScreen; use tui::backend::TermionBackend; use tui::layout::{Constraint, Direction, Layout}; use tui::style::{Color, Style}; +use tui::text::{Span, Spans}; use tui::widgets::{Block, Borders, Tabs}; use tui::Terminal; @@ -126,9 +125,7 @@ struct App<'a> { fn main() -> Result<(), Box> { // Terminal initialization - let stdout = io::stdout().into_raw_mode()?; - let stdout = MouseTerminal::from(stdout); - let stdout = AlternateScreen::from(stdout); + let stdout = io::stdout().into_alternate_screen().unwrap(); let backend = TermionBackend::new(stdout); let mut terminal = Terminal::new(backend)?; terminal.hide_cursor()?; @@ -142,7 +139,7 @@ fn main() -> Result<(), Box> { // Main loop loop { - terminal.draw(|mut f| { + terminal.draw(|f| { let size = f.size(); let chunks = Layout::default() .direction(Direction::Vertical) @@ -152,12 +149,17 @@ fn main() -> Result<(), Box> { let block = Block::default().style(Style::default().bg(Color::White)); f.render_widget(block, size); - let tabs = Tabs::default() - .block(Block::default().borders(Borders::ALL).title("Tabs")) - .titles(&app.tabs.titles) - .select(app.tabs.index) - .style(Style::default().fg(Color::Cyan)) - .highlight_style(Style::default().fg(Color::Yellow)); + let tabs = Tabs::new( + app.tabs + .titles + .iter() + .map(|s| Spans::from(vec![Span::styled(*s, Style::default())])) + .collect(), + ) + .block(Block::default().borders(Borders::ALL).title("Tabs")) + .select(app.tabs.index) + .style(Style::default().fg(Color::Cyan)) + .highlight_style(Style::default().fg(Color::Yellow)); f.render_widget(tabs, chunks[0]); let inner = match app.tabs.index { 0 => Block::default().title("Inner 0").borders(Borders::ALL), diff --git a/crates/bitque-data/Cargo.toml b/crates/bitque-data/Cargo.toml index 86848806..ffe9c934 100644 --- a/crates/bitque-data/Cargo.toml +++ b/crates/bitque-data/Cargo.toml @@ -21,6 +21,7 @@ actix = { version = "0.13.0", optional = true } chrono = { version = "*", features = ["serde"] } diesel = { version = "2.0.3", features = ["postgres", "numeric", "uuid", "r2d2"], optional = true } diesel-derive-enum = { version = "2.0.1", features = ["postgres"] } +#diesel-derive-enum = { path = "../derive_enum_sql", features = ["postgres"] } diesel-derive-more = { version = "1.1.3" } diesel-derive-newtype = { version = "2.0.0-rc.0", optional = true } serde = { version = "*" } diff --git a/crates/bitque-data/src/lib.rs b/crates/bitque-data/src/lib.rs index 9e80459d..b974f9a4 100644 --- a/crates/bitque-data/src/lib.rs +++ b/crates/bitque-data/src/lib.rs @@ -2,15 +2,15 @@ use std::cmp::Ordering; use chrono::NaiveDateTime; #[cfg(feature = "backend")] -use diesel_derive_enum::DbEnum; -#[cfg(feature = "backend")] use diesel::*; +#[cfg(feature = "backend")] +use diesel_derive_enum::DbEnum; pub use fields::*; pub use msg::WsMsg; pub use payloads::*; use serde::{Deserialize, Serialize}; -use uuid::Uuid; use strum::*; +use uuid::Uuid; pub mod fields; pub mod msg; @@ -52,7 +52,18 @@ pub type EndsAt = NaiveDateTime; #[cfg_attr(feature = "backend", derive(DbEnum))] #[derive( - Clone, Copy, Debug, Deserialize, Display, EnumIter, EnumString, Hash, IntoStaticStr, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + Display, + EnumIter, + EnumString, + Hash, + IntoStaticStr, + PartialEq, + PartialOrd, + Serialize, )] #[strum(serialize_all = "snake_case")] pub enum IssueType { @@ -69,7 +80,18 @@ impl Default for IssueType { #[cfg_attr(feature = "backend", derive(DbEnum))] #[derive( -Clone, Copy, Debug, Deserialize, Display, EnumIter, EnumString, Hash, IntoStaticStr, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + Display, + EnumIter, + EnumString, + Hash, + IntoStaticStr, + PartialEq, + PartialOrd, + Serialize, )] #[strum(serialize_all = "snake_case")] pub enum IssuePriority { @@ -87,7 +109,19 @@ impl Default for IssuePriority { } #[cfg_attr(feature = "backend", derive(DbEnum))] -#[derive(Clone, Copy, Debug, Deserialize, Display, EnumIter, EnumString, Hash, IntoStaticStr, PartialEq, Serialize)] +#[derive( + Clone, + Copy, + Debug, + Deserialize, + Display, + EnumIter, + EnumString, + Hash, + IntoStaticStr, + PartialEq, + Serialize, +)] #[strum(serialize_all = "snake_case")] pub enum UserRole { User, @@ -117,8 +151,20 @@ impl Default for UserRole { } #[cfg_attr(feature = "backend", derive(DbEnum))] +#[cfg_attr(feature = "backend", PgType = "ProjectCategoryMapping")] #[derive( - Clone, Copy, Debug, Deserialize, Display, EnumIter, EnumString, Hash, IntoStaticStr, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + Display, + EnumIter, + EnumString, + Hash, + IntoStaticStr, + PartialEq, + PartialOrd, + Serialize, )] #[strum(serialize_all = "snake_case")] pub enum ProjectCategory { @@ -134,8 +180,20 @@ impl Default for ProjectCategory { } #[cfg_attr(feature = "backend", derive(DbEnum))] +#[cfg_attr(feature = "backend", PgType = "InvitationStateMapping")] #[derive( - Clone, Copy, Debug, Deserialize, Display, EnumIter, EnumString, Hash, IntoStaticStr, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + Display, + EnumIter, + EnumString, + Hash, + IntoStaticStr, + PartialEq, + PartialOrd, + Serialize, )] #[strum(serialize_all = "snake_case")] pub enum InvitationState { @@ -151,8 +209,20 @@ impl Default for InvitationState { } #[cfg_attr(feature = "backend", derive(DbEnum))] +#[cfg_attr(feature = "backend", PgType = "TimeTrackingMapping")] #[derive( - Clone, Copy, Debug, Deserialize, Display, EnumIter, EnumString, Hash, IntoStaticStr, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + Display, + EnumIter, + EnumString, + Hash, + IntoStaticStr, + PartialEq, + PartialOrd, + Serialize, )] #[strum(serialize_all = "snake_case")] pub enum TimeTracking { @@ -311,8 +381,19 @@ pub struct IssueAssignee { } #[cfg_attr(feature = "backend", derive(DbEnum))] +#[cfg_attr(feature = "backend", PgType = "MessageTypeMapping")] #[derive( - Clone, Copy, Debug, Deserialize, Display, EnumString, Hash, IntoStaticStr, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + Display, + EnumString, + Hash, + IntoStaticStr, + PartialEq, + PartialOrd, + Serialize, )] #[strum(serialize_all = "snake_case")] pub enum MessageType { @@ -391,9 +472,21 @@ pub struct HighlightedCode { #[cfg_attr(feature = "backend", derive(DbEnum))] #[derive( - Clone, Copy, Debug, Deserialize, Display, EnumIter, EnumString, Hash, IntoStaticStr, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + Display, + EnumIter, + EnumString, + Hash, + IntoStaticStr, + PartialEq, + PartialOrd, + Serialize, )] #[strum(serialize_all = "snake_case")] +#[cfg_attr(feature = "backend", PgType = "TextEditorModeMapping")] #[repr(C)] pub enum TextEditorMode { MdOnly, diff --git a/crates/bitque-server/Cargo.toml b/crates/bitque-server/Cargo.toml index aded7374..941c5eac 100644 --- a/crates/bitque-server/Cargo.toml +++ b/crates/bitque-server/Cargo.toml @@ -15,10 +15,11 @@ default = ["local-storage"] [dependencies] actix = { version = "0" } +actix-rt = { version = "2" } +actix-web = { version = "4" } amazon-actor = { workspace = true, optional = true } bitque-config = { workspace = true, features = ["web", "websocket", "local-storage", "hi", "database"] } bitque-data = { workspace = true, features = ["backend"] } -common = { workspace = true } database-actor = { workspace = true } dotenv = { version = "*" } filesystem-actor = { workspace = true, optional = true } @@ -31,5 +32,7 @@ serde = { version = "*", features = ["derive"] } serde_json = { version = ">=0.8.0, <2.0" } tokio = { version = "1", features = ["full"] } toml = { version = "0.7.3" } +tracing = "0" +tracing-subscriber = { version = "0", features = ['env-filter', 'thread_local', 'serde_json'] } web-actor = { workspace = true, features = ["local-storage"] } websocket-actor = { workspace = true } diff --git a/crates/bitque-server/LICENSE b/crates/bitque-server/LICENSE deleted file mode 120000 index ea5b6064..00000000 --- a/crates/bitque-server/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE \ No newline at end of file diff --git a/crates/bitque-server/src/errors.rs b/crates/bitque-server/src/errors.rs index 26c51839..85dcf5cd 100644 --- a/crates/bitque-server/src/errors.rs +++ b/crates/bitque-server/src/errors.rs @@ -1,5 +1,4 @@ use actix_web::HttpResponse; -use common::*; use bitque_data::msg::WsError; use bitque_data::ErrorResponse; diff --git a/crates/bitque-server/src/main.rs b/crates/bitque-server/src/main.rs index 7d68b5de..7659d958 100644 --- a/crates/bitque-server/src/main.rs +++ b/crates/bitque-server/src/main.rs @@ -1,11 +1,9 @@ #![feature(async_closure)] #![recursion_limit = "256"] -extern crate common; - use actix::Actor; use actix_web::{App, HttpServer}; -use common::*; +use tracing_subscriber::util::SubscriberInitExt; pub mod errors; @@ -19,7 +17,10 @@ macro_rules! featured { #[actix_rt::main] async fn main() -> Result<(), String> { dotenv::dotenv().ok(); - pretty_env_logger::init(); + tracing_subscriber::fmt::fmt() + .with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env()) + .finish() + .init(); let web_config = bitque_config::web::Configuration::read(); @@ -53,12 +54,12 @@ async fn main() -> Result<(), String> { // data step let app = app - .data(ws_server.clone()) - .data(db_addr.clone()) - .data(mail_addr.clone()) - .data(hi_addr.clone()) - .data(database_actor::build_pool()); - featured! { app, "local-storage", app.data(fs_addr.clone()) }; + .app_data(ws_server.clone()) + .app_data(db_addr.clone()) + .app_data(mail_addr.clone()) + .app_data(hi_addr.clone()) + .app_data(database_actor::build_pool()); + featured! { app, "local-storage", app.app_data(fs_addr.clone()) }; featured! { app, "aws-s3", app.data(amazon_addr.clone()) }; // services step diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml deleted file mode 100644 index 2555e22d..00000000 --- a/crates/common/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "common" -version = "0.1.0" -authors = ["Adrian Wozniak "] -edition = "2018" -description = "JIRS (Simplified JIRA in Rust) Actix server" -repository = "https://gitlab.com/adrian.wozniak/bitque" -license = "MPL-2.0" - -[dependencies] diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/crates/database-actor/Cargo.toml b/crates/database-actor/Cargo.toml index 4d72cb1f..6c3fd999 100644 --- a/crates/database-actor/Cargo.toml +++ b/crates/database-actor/Cargo.toml @@ -21,7 +21,6 @@ bitque-config = { workspace = true, features = ["database"] } bitque-data = { workspace = true, features = ["backend"] } byteorder = { version = "1.0" } chrono = { version = "0.4", features = ["serde"] } -common = { workspace = true } derive_db_execute = { workspace = true } diesel = { version = "2.0.3", features = ["postgres", "numeric", "uuid", "r2d2", "chrono"] } dotenv = { version = "*" } diff --git a/crates/database-actor/schema.patch b/crates/database-actor/schema.patch new file mode 100644 index 00000000..dd926d70 --- /dev/null +++ b/crates/database-actor/schema.patch @@ -0,0 +1,141 @@ +diff --git a/crates/database-actor/src/schema.rs b/crates/database-actor/src/schema.rs +index 34a35365..a8f775b2 100644 +--- a/crates/database-actor/src/schema.rs ++++ b/crates/database-actor/src/schema.rs +@@ -37,19 +37,19 @@ diesel::table! { + use bitque_data::*; + + invitations (id) { + id -> Int4, + name -> Text, + email -> Text, +- state -> InvitationState, ++ state -> InvitationStateMapping, + project_id -> Int4, + invited_by_id -> Int4, + created_at -> Timestamp, + updated_at -> Timestamp, + bind_token -> Uuid, +- role -> UserRole, ++ role -> UserRoleMapping, + } + } + + diesel::table! { + use diesel::sql_types::*; + use bitque_data::*; +@@ -81,14 +81,14 @@ diesel::table! { + use diesel::sql_types::*; + use bitque_data::*; + + issues (id) { + id -> Int4, + title -> Text, +- issue_type -> IssueType, +- priority -> IssuePriority, ++ issue_type -> IssueTypeMapping, ++ priority -> IssuePriorityMapping, + list_position -> Int4, + description -> Nullable, + description_text -> Nullable, + estimate -> Nullable, + time_spent -> Nullable, + time_remaining -> Nullable, +@@ -108,13 +108,13 @@ diesel::table! { + messages (id) { + id -> Int4, + receiver_id -> Int4, + sender_id -> Int4, + summary -> Text, + description -> Text, +- message_type -> MessageType, ++ message_type -> MessageTypeMapping, + hyper_link -> Text, + created_at -> Timestamp, + updated_at -> Timestamp, + } + } + +@@ -124,16 +124,16 @@ diesel::table! { + + projects (id) { + id -> Int4, + name -> Text, + url -> Text, + description -> Text, +- category -> ProjectCategory, ++ category -> ProjectCategoryMapping, + created_at -> Timestamp, + updated_at -> Timestamp, +- time_tracking -> TimeTracking, ++ time_tracking -> TimeTrackingMapping, + } + } + + diesel::table! { + use diesel::sql_types::*; + use bitque_data::*; +@@ -156,26 +156,26 @@ diesel::table! { + user_projects (id) { + id -> Int4, + user_id -> Int4, + project_id -> Int4, + is_default -> Bool, + is_current -> Bool, +- role -> UserRole, ++ role -> UserRoleMapping, + created_at -> Timestamp, + updated_at -> Timestamp, + } + } + + diesel::table! { + use diesel::sql_types::*; + use bitque_data::*; + + user_settings (id) { + id -> Int4, + user_id -> Int4, +- text_editor_mode -> TextEditorMode, ++ text_editor_mode -> TextEditorModeMapping, + } + } + + diesel::table! { + use diesel::sql_types::*; + use bitque_data::*; +@@ -205,20 +205,20 @@ diesel::joinable!(issues -> projects (project_id)); + diesel::joinable!(issues -> users (reporter_id)); + diesel::joinable!(tokens -> users (user_id)); + diesel::joinable!(user_projects -> projects (project_id)); + diesel::joinable!(user_projects -> users (user_id)); + diesel::joinable!(user_settings -> users (user_id)); + +-diesel::allow_tables_to_appear_in_same_query!( +- comments, +- epics, +- invitations, +- issue_assignees, +- issue_statuses, +- issues, +- messages, +- projects, +- tokens, +- user_projects, +- user_settings, +- users, +-); ++// diesel::allow_tables_to_appear_in_same_query!( ++// comments, ++// epics, ++// invitations, ++// issue_assignees, ++// issue_statuses, ++// issues, ++// messages, ++// projects, ++// tokens, ++// user_projects, ++// user_settings, ++// users, ++// ); diff --git a/crates/database-actor/src/authorize_user.rs b/crates/database-actor/src/authorize_user.rs index 92ba6ba7..27d8cbe7 100644 --- a/crates/database-actor/src/authorize_user.rs +++ b/crates/database-actor/src/authorize_user.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::User; +use diesel::prelude::*; use crate::db_find; use crate::tokens::FindAccessToken; diff --git a/crates/database-actor/src/comments.rs b/crates/database-actor/src/comments.rs index 29340c66..aa587849 100644 --- a/crates/database-actor/src/comments.rs +++ b/crates/database-actor/src/comments.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::{Comment, CommentId, IssueId, UserId}; +use diesel::prelude::*; use crate::{db_create, db_delete, db_load, db_update}; diff --git a/crates/database-actor/src/epics.rs b/crates/database-actor/src/epics.rs index dbaa859a..48e9c515 100644 --- a/crates/database-actor/src/epics.rs +++ b/crates/database-actor/src/epics.rs @@ -1,10 +1,9 @@ -use derive_db_execute::Execute; -use diesel::prelude::*; use bitque_data::{DescriptionString, EndsAt, Epic, EpicId, ProjectId, StartsAt}; +use diesel::prelude::*; use crate::{db_create, db_delete, db_load, db_update}; -#[derive(Execute)] +#[derive(derive_db_execute::Execute)] #[db_exec(schema = "epics", result = "Epic", find = "epics.find(msg.epic_id)")] pub struct FindEpic { pub epic_id: EpicId, diff --git a/crates/database-actor/src/invitations.rs b/crates/database-actor/src/invitations.rs index 926013fe..8c3f53be 100644 --- a/crates/database-actor/src/invitations.rs +++ b/crates/database-actor/src/invitations.rs @@ -1,15 +1,15 @@ use actix::{Handler, Message}; -use diesel::prelude::*; use bitque_data::{ EmailString, Invitation, InvitationId, InvitationState, InvitationToken, ProjectId, Token, User, UserId, UserRole, UsernameString, }; +use diesel::prelude::*; use crate::tokens::CreateBindToken; use crate::users::{LookupUser, Register}; use crate::{ - db_create, db_delete, db_find, db_load, db_pool, db_update, DbExecutor, DbPooledConn, - InvitationError, + db_create, db_delete, db_find, db_load, db_pool, db_update, DatabaseError, DbExecutor, + DbPooledConn, InvitationError, }; db_find! { @@ -80,12 +80,12 @@ impl Handler for DbExecutor { type Result = Result<(), crate::DatabaseError>; fn handle(&mut self, msg: RevokeInvitation, _ctx: &mut Self::Context) -> Self::Result { - let conn = db_pool!(self); + let mut conn = db_pool!(self); UpdateInvitationState { id: msg.id, state: InvitationState::Revoked, } - .execute(conn)?; + .execute(&mut conn)?; Ok(()) } } @@ -95,63 +95,75 @@ pub struct AcceptInvitation { } impl AcceptInvitation { - pub fn execute(self, conn: &DbPooledConn) -> Result { - crate::Guard::new(conn)?.run::(|_guard| { - let invitation = crate::invitations::FindByBindToken { - token: self.invitation_token, + pub fn execute(self, conn: &mut DbPooledConn) -> Result { + let mut res = Err(DatabaseError::DatabaseConnectionLost); + conn.transaction(|conn| { + res = self.exec_in_transaction(conn); + if res.is_err() { + Err(diesel::NotFound) + } else { + Ok(()) } - .execute(conn)?; + }) + .ok(); + res + } - if invitation.state == InvitationState::Revoked { - return Err(crate::DatabaseError::Invitation( - InvitationError::InvitationRevoked, - )); - } + fn exec_in_transaction(self, conn: &mut DbPooledConn) -> Result { + let invitation = FindByBindToken { + token: self.invitation_token, + } + .execute(conn)?; - crate::invitations::UpdateInvitationState { - id: invitation.id, - state: InvitationState::Accepted, - } - .execute(conn)?; + if invitation.state == InvitationState::Revoked { + return Err(crate::DatabaseError::Invitation( + InvitationError::InvitationRevoked, + )); + } - UpdateInvitationState { - id: invitation.id, - state: InvitationState::Accepted, - } - .execute(conn)?; + UpdateInvitationState { + id: invitation.id, + state: InvitationState::Accepted, + } + .execute(conn)?; - match { - Register { - name: invitation.name.clone(), - email: invitation.email.clone(), - project_id: Some(invitation.project_id), - role: UserRole::User, - } - .execute(conn) - } { - Ok(_) => (), - Err(crate::DatabaseError::User(crate::UserError::InvalidPair(..))) => (), - Err(e) => return Err(e), - }; + UpdateInvitationState { + id: invitation.id, + state: InvitationState::Accepted, + } + .execute(conn)?; - let user: User = LookupUser { + match { + Register { name: invitation.name.clone(), email: invitation.email.clone(), + project_id: Some(invitation.project_id), + role: UserRole::User, } - .execute(conn)?; - CreateBindToken { user_id: user.id }.execute(conn)?; + .execute(conn) + } { + Ok(_) => (), + Err(crate::DatabaseError::User(crate::UserError::InvalidPair(..))) => (), + Err(e) => return Err(e), + }; - crate::user_projects::CreateUserProject { - user_id: user.id, - project_id: invitation.project_id, - is_current: false, - is_default: false, - role: invitation.role, - } - .execute(conn)?; + let user: User = LookupUser { + name: invitation.name.clone(), + email: invitation.email.clone(), + } + .execute(conn)?; + CreateBindToken { user_id: user.id }.execute(conn)?; - crate::tokens::FindUserId { user_id: user.id }.execute(conn) - }) + crate::user_projects::CreateUserProject { + user_id: user.id, + project_id: invitation.project_id, + is_current: false, + is_default: false, + role: invitation.role, + } + .execute(conn)?; + + crate::tokens::FindUserId { user_id: user.id }.execute(conn) } } @@ -163,8 +175,8 @@ impl Handler for DbExecutor { type Result = Result; fn handle(&mut self, msg: AcceptInvitation, _ctx: &mut Self::Context) -> Self::Result { - let conn = db_pool!(self); + let mut conn = db_pool!(self); - msg.execute(conn) + msg.execute(&mut conn) } } diff --git a/crates/database-actor/src/issue_assignees.rs b/crates/database-actor/src/issue_assignees.rs index 9a30f54b..8e1ee142 100644 --- a/crates/database-actor/src/issue_assignees.rs +++ b/crates/database-actor/src/issue_assignees.rs @@ -1,6 +1,6 @@ -use diesel::prelude::*; -use diesel::dsl::not; use bitque_data::{IssueAssignee, IssueId, UserId}; +use diesel::dsl::not; +use diesel::prelude::*; use crate::{db_create, db_delete, db_load, db_load_field}; diff --git a/crates/database-actor/src/issue_statuses.rs b/crates/database-actor/src/issue_statuses.rs index c1927065..e9084ee5 100644 --- a/crates/database-actor/src/issue_statuses.rs +++ b/crates/database-actor/src/issue_statuses.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::{IssueStatus, IssueStatusId, Position, ProjectId, TitleString}; +use diesel::prelude::*; use crate::{db_create, db_delete, db_load, db_update}; diff --git a/crates/database-actor/src/issues.rs b/crates/database-actor/src/issues.rs index d5d2c3a5..f1cc4c1e 100644 --- a/crates/database-actor/src/issues.rs +++ b/crates/database-actor/src/issues.rs @@ -1,11 +1,10 @@ -use derive_db_execute::Execute; +use bitque_data::{IssueId, IssuePriority, IssueStatusId, IssueType, ProjectId, UserId}; use diesel::dsl::sql; use diesel::prelude::*; -use bitque_data::{IssueId, IssuePriority, IssueStatusId, IssueType, ProjectId, UserId}; use crate::models::Issue; -#[derive(Default, Execute)] +#[derive(derive_db_execute::Execute, Default)] #[db_exec( result = "Issue", schema = "issues", @@ -15,7 +14,7 @@ pub struct LoadIssue { pub issue_id: IssueId, } -#[derive(Execute)] +#[derive(derive_db_execute::Execute)] #[db_exec( result = "Issue", schema = "issues", @@ -25,7 +24,7 @@ pub struct LoadProjectIssues { pub project_id: ProjectId, } -#[derive(Default, Execute)] +#[derive(derive_db_execute::Execute, Default)] #[db_exec(result = "Issue", schema = "issues")] pub struct UpdateIssue { pub issue_id: bitque_data::IssueId, @@ -46,7 +45,7 @@ pub struct UpdateIssue { } impl UpdateIssue { - fn execute(self, conn: &crate::DbPooledConn) -> Result { + fn execute(self, conn: &mut crate::DbPooledConn) -> Result { let msg = self; use crate::schema::issues::dsl::*; if let Some(user_ids) = msg.user_ids { @@ -97,7 +96,7 @@ impl UpdateIssue { } } -#[derive(Execute)] +#[derive(derive_db_execute::Execute)] #[db_exec( result = "Issue", schema = "issues", @@ -112,9 +111,9 @@ pub struct DeleteIssue { } mod inner { + use bitque_data::{IssuePriority, IssueStatusId, IssueType}; use derive_db_execute::Execute; use diesel::prelude::*; - use bitque_data::{IssuePriority, IssueStatusId, IssueType}; use crate::models::Issue; @@ -159,7 +158,7 @@ mod inner { } } -#[derive(Execute)] +#[derive(derive_db_execute::Execute)] #[db_exec(result = "Issue", schema = "issues")] pub struct CreateIssue { pub title: String, @@ -171,19 +170,21 @@ pub struct CreateIssue { pub estimate: Option, pub time_spent: Option, pub time_remaining: Option, - pub project_id: bitque_data::ProjectId, - pub reporter_id: bitque_data::UserId, - pub user_ids: Vec, + pub project_id: ProjectId, + pub reporter_id: UserId, + pub user_ids: Vec, pub epic_id: Option, } impl CreateIssue { - fn execute(self, conn: &crate::DbPooledConn) -> Result { + fn execute(self, conn: &mut crate::DbPooledConn) -> Result { use crate::schema::issues::dsl::*; let msg = self; let pos = issues - .select(sql("COALESCE(max(list_position), 0) + 1")) + .select(sql::( + "COALESCE(max(list_position), 0) + 1", + )) .get_result::(conn) .map_err(|e| { ::tracing::error!("resolve new issue position failed {}", e); diff --git a/crates/database-actor/src/lib.rs b/crates/database-actor/src/lib.rs index a049a9ed..21f475ee 100644 --- a/crates/database-actor/src/lib.rs +++ b/crates/database-actor/src/lib.rs @@ -63,47 +63,3 @@ pub trait SyncQuery { fn handle(&self, pool: &DbPool) -> Self::Result; } - -pub struct Guard<'l> { - conn: &'l crate::DbPooledConn, - tm: &'l diesel::connection::AnsiTransactionManager, -} - -impl<'l> Guard<'l> { - pub fn new(conn: &'l DbPooledConn) -> Result { - use diesel::connection::TransactionManager; - use diesel::prelude::*; - let tm = conn.transaction_manager(); - tm.begin_transaction(conn).map_err(|e| { - ::tracing::error!("{:?}", e); - crate::DatabaseError::DatabaseConnectionLost - })?; - Ok(Self { conn, tm }) - } - - pub fn run Result>( - &self, - f: F, - ) -> Result { - use diesel::connection::TransactionManager; - - let r = f(self); - match r { - Ok(r) => { - self.tm.commit_transaction(self.conn).map_err(|e| { - ::tracing::error!("{:?}", e); - crate::DatabaseError::DatabaseConnectionLost - })?; - Ok(r) - } - Err(e) => { - ::tracing::error!("{:?}", e); - self.tm.rollback_transaction(self.conn).map_err(|e| { - ::tracing::error!("{:?}", e); - crate::DatabaseError::DatabaseConnectionLost - })?; - Err(e) - } - } - } -} diff --git a/crates/database-actor/src/messages.rs b/crates/database-actor/src/messages.rs index a0c904d0..69476433 100644 --- a/crates/database-actor/src/messages.rs +++ b/crates/database-actor/src/messages.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::{BindToken, Message, MessageId, MessageType, User, UserId}; +use diesel::prelude::*; use crate::users::{FindUser, LookupUser}; use crate::{db_create, db_delete, db_load}; diff --git a/crates/database-actor/src/models.rs b/crates/database-actor/src/models.rs index cd7f4bb5..c2378291 100644 --- a/crates/database-actor/src/models.rs +++ b/crates/database-actor/src/models.rs @@ -1,8 +1,8 @@ -use chrono::NaiveDateTime; use bitque_data::{ EpicId, InvitationState, IssuePriority, IssueStatusId, IssueType, ProjectCategory, ProjectId, TimeTracking, UserId, }; +use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; use crate::schema::*; diff --git a/crates/database-actor/src/prelude.rs b/crates/database-actor/src/prelude.rs index a07cb2e4..775a011a 100644 --- a/crates/database-actor/src/prelude.rs +++ b/crates/database-actor/src/prelude.rs @@ -1,13 +1,13 @@ #[macro_export] macro_rules! db_pool { ($self: expr) => { - &$self.pool.get().map_err(|e| { + $self.pool.get().map_err(|e| { ::tracing::error!("{:?}", e); $crate::DatabaseError::DatabaseConnectionLost })? }; ($self: expr, $pool: expr) => { - &$pool.get().map_err(|e| { + $pool.get().map_err(|e| { ::tracing::error!("{:?}", e); $crate::DatabaseError::DatabaseConnectionLost })? @@ -34,7 +34,7 @@ macro_rules! db_find { } impl $action { - pub fn execute(self, $conn: &$crate::DbPooledConn) -> Result<$resource, crate::DatabaseError> { + pub fn execute(self, $conn: &mut $crate::DbPooledConn) -> Result<$resource, crate::DatabaseError> { use crate::schema:: $schema ::dsl::*; let $self = self; $crate::q!($q) @@ -57,8 +57,8 @@ macro_rules! db_find { type Result = Result<$resource, $crate::DatabaseError>; fn handle(&mut self, msg: $action, _ctx: &mut Self::Context) -> Self::Result { - let $conn = $crate::db_pool!(self); - msg.execute($conn) + let mut $conn = $crate::db_pool!(self); + msg.execute(&mut $conn) } } }; @@ -75,7 +75,7 @@ macro_rules! db_load { } impl $action { - pub fn execute(self, conn: &$crate::DbPooledConn) -> Result, $crate::DatabaseError> { + pub fn execute(self, conn: &mut $crate::DbPooledConn) -> Result, $crate::DatabaseError> { use crate::schema:: $schema ::dsl::*; let $self = self; $crate::q!($q) @@ -98,9 +98,9 @@ macro_rules! db_load { type Result = Result, $crate::DatabaseError>; fn handle(&mut self, msg: $action, _ctx: &mut Self::Context) -> Self::Result { - let conn = $crate::db_pool!(self); + let mut conn = $crate::db_pool!(self); - msg.execute(conn) + msg.execute(&mut conn) } } }; @@ -114,7 +114,7 @@ macro_rules! db_load_field { } impl $action { - pub fn execute(self, conn: &$crate::DbPooledConn) -> Result, $crate::DatabaseError> { + pub fn execute(self, conn: &mut $crate::DbPooledConn) -> Result, $crate::DatabaseError> { use crate::schema:: $schema ::dsl::*; let $self = self; $crate::q!($q) @@ -137,9 +137,9 @@ macro_rules! db_load_field { type Result = Result, $crate::DatabaseError>; fn handle(&mut self, msg: $action, _ctx: &mut Self::Context) -> Self::Result { - let conn = $crate::db_pool!(self); + let mut conn = $crate::db_pool!(self); - msg.execute(conn) + msg.execute(&mut conn) } } }; @@ -151,25 +151,34 @@ macro_rules! db_create { }; ($action: ident, $self: ident => $conn: ident => $schema: ident => $q: expr, $resource: ident, $($field: ident => $ty: ty),+) => { pub struct $action { - $(pub $field : $ty),+ + $(pub $field : $ty),+ } impl $action { - pub fn execute(self, $conn: &$crate::DbPooledConn) -> Result<$resource, crate::DatabaseError> { - crate::Guard::new($conn)?.run(|_guard| { - use crate::schema:: $schema ::dsl::*; - let $self = self; - $crate::q!($q) - .get_result::<$resource>($conn) - .map_err(|e| { + pub fn execute(self, conn: &mut $crate::DbPooledConn) -> Result<$resource, crate::DatabaseError> { + let mut res = Err(crate::DatabaseError::DatabaseConnectionLost); + conn.transaction(|conn| { + res = self.exec_with_transaction(conn); + if res.is_err() { + Err(diesel::NotFound) + } else { + Ok(()) + } + }).ok(); + res + } + + fn exec_with_transaction(self, $conn: &mut $crate::DbPooledConn) -> Result<$resource, crate::DatabaseError> { + use crate::schema:: $schema ::dsl::*; + let $self = self; + $crate::q!($q).get_result::<$resource>($conn).map_err(|e| { ::tracing::error!("{:?}", e); $crate::DatabaseError::GenericFailure( $crate::OperationError::Create, $crate::ResourceKind::$resource, ) }) - }) - } + } } impl actix::Message for $action { @@ -180,9 +189,9 @@ macro_rules! db_create { type Result = Result<$resource, $crate::DatabaseError>; fn handle(&mut self, msg: $action, _ctx: &mut Self::Context) -> Self::Result { - let $conn = $crate::db_pool!(self); + let mut $conn = $crate::db_pool!(self); - msg.execute($conn) + msg.execute(&mut $conn) } } }; @@ -199,7 +208,7 @@ macro_rules! db_update { } impl $action { - pub fn execute(self, $conn: &$crate::DbPooledConn) -> Result<$resource, crate::DatabaseError> { + pub fn execute(self, $conn: &mut $crate::DbPooledConn) -> Result<$resource, crate::DatabaseError> { use crate::schema:: $schema ::dsl::*; let $self = self; $crate::q!($q) @@ -222,9 +231,9 @@ macro_rules! db_update { type Result = Result<$resource, $crate::DatabaseError>; fn handle(&mut self, msg: $action, _ctx: &mut Self::Context) -> Self::Result { - let $conn = $crate::db_pool!(self); + let mut $conn = $crate::db_pool!(self); - msg.execute ( $conn ) + msg.execute ( &mut $conn ) } } }; @@ -241,7 +250,7 @@ macro_rules! db_delete { } impl $action { - pub fn execute(self, $conn: &$crate::DbPooledConn) -> Result { + pub fn execute(self, $conn: &mut $crate::DbPooledConn) -> Result { use $crate::schema:: $schema ::dsl::*; let $self = self; $crate::q!($q) @@ -264,9 +273,9 @@ macro_rules! db_delete { type Result = Result; fn handle(&mut self, msg: $action, _ctx: &mut Self::Context) -> Self::Result { - let $conn = $crate::db_pool!(self); + let mut $conn = $crate::db_pool!(self); - msg.execute($conn) + msg.execute(&mut $conn) } } }; diff --git a/crates/database-actor/src/projects.rs b/crates/database-actor/src/projects.rs index e5e2f360..4e7dc556 100644 --- a/crates/database-actor/src/projects.rs +++ b/crates/database-actor/src/projects.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::{NameString, Project, ProjectCategory, ProjectId, TimeTracking, UserId}; +use diesel::prelude::*; use crate::{db_create, db_find, db_load, db_update}; @@ -11,8 +11,8 @@ db_find! { } mod inner { - use diesel::prelude::*; use bitque_data::{NameString, Project, ProjectCategory, TimeTracking}; + use diesel::prelude::*; use crate::db_create; diff --git a/crates/database-actor/src/schema.rs b/crates/database-actor/src/schema.rs index 34a35365..02238865 100644 --- a/crates/database-actor/src/schema.rs +++ b/crates/database-actor/src/schema.rs @@ -40,13 +40,13 @@ diesel::table! { id -> Int4, name -> Text, email -> Text, - state -> InvitationState, + state -> InvitationStateMapping, project_id -> Int4, invited_by_id -> Int4, created_at -> Timestamp, updated_at -> Timestamp, bind_token -> Uuid, - role -> UserRole, + role -> UserRoleMapping, } } @@ -84,8 +84,8 @@ diesel::table! { issues (id) { id -> Int4, title -> Text, - issue_type -> IssueType, - priority -> IssuePriority, + issue_type -> IssueTypeMapping, + priority -> IssuePriorityMapping, list_position -> Int4, description -> Nullable, description_text -> Nullable, @@ -111,7 +111,7 @@ diesel::table! { sender_id -> Int4, summary -> Text, description -> Text, - message_type -> MessageType, + message_type -> MessageTypeMapping, hyper_link -> Text, created_at -> Timestamp, updated_at -> Timestamp, @@ -127,10 +127,10 @@ diesel::table! { name -> Text, url -> Text, description -> Text, - category -> ProjectCategory, + category -> ProjectCategoryMapping, created_at -> Timestamp, updated_at -> Timestamp, - time_tracking -> TimeTracking, + time_tracking -> TimeTrackingMapping, } } @@ -159,7 +159,7 @@ diesel::table! { project_id -> Int4, is_default -> Bool, is_current -> Bool, - role -> UserRole, + role -> UserRoleMapping, created_at -> Timestamp, updated_at -> Timestamp, } @@ -172,7 +172,7 @@ diesel::table! { user_settings (id) { id -> Int4, user_id -> Int4, - text_editor_mode -> TextEditorMode, + text_editor_mode -> TextEditorModeMapping, } } diff --git a/crates/database-actor/src/tokens.rs b/crates/database-actor/src/tokens.rs index 19b6c2e6..7b134c44 100644 --- a/crates/database-actor/src/tokens.rs +++ b/crates/database-actor/src/tokens.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::{Token, UserId}; +use diesel::prelude::*; use crate::{db_create, db_find, db_update}; diff --git a/crates/database-actor/src/user_projects.rs b/crates/database-actor/src/user_projects.rs index a6c5d29b..026ab1c1 100644 --- a/crates/database-actor/src/user_projects.rs +++ b/crates/database-actor/src/user_projects.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::{ProjectId, UserId, UserProject, UserProjectId, UserRole}; +use diesel::prelude::*; use crate::{db_create, db_delete, db_find, db_load, db_update}; @@ -26,8 +26,8 @@ db_load! { } mod inner { - use diesel::prelude::*; use bitque_data::{UserId, UserProject, UserProjectId}; + use diesel::prelude::*; use crate::db_update; diff --git a/crates/database-actor/src/user_settings.rs b/crates/database-actor/src/user_settings.rs index 0bce0f2b..72987d89 100644 --- a/crates/database-actor/src/user_settings.rs +++ b/crates/database-actor/src/user_settings.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::{TextEditorMode, UserId, UserSetting}; +use diesel::prelude::*; use crate::{db_find, db_update}; @@ -29,8 +29,8 @@ db_update! { } mod inner { - use diesel::prelude::*; use bitque_data::{TextEditorMode, UserId, UserSetting}; + use diesel::prelude::*; use crate::{db_create, db_update}; diff --git a/crates/database-actor/src/users.rs b/crates/database-actor/src/users.rs index 558b6583..bee9ab6e 100644 --- a/crates/database-actor/src/users.rs +++ b/crates/database-actor/src/users.rs @@ -1,5 +1,5 @@ -use diesel::prelude::*; use bitque_data::{EmailString, IssueId, ProjectId, User, UserId, UserRole, UsernameString}; +use diesel::prelude::*; use crate::projects::CreateProject; use crate::user_projects::CreateUserProject; @@ -120,7 +120,7 @@ db_load! { user_id => UserId } -fn count_matching_users(name: &str, email: &str, conn: &DbPooledConn) -> i64 { +fn count_matching_users(name: &str, email: &str, conn: &mut DbPooledConn) -> i64 { use crate::schema::users::dsl; q!(dsl::users @@ -153,7 +153,6 @@ db_update! { #[cfg(test)] mod tests { - use diesel::connection::TransactionManager; use bitque_data::{Project, ProjectCategory}; use super::*; @@ -166,11 +165,9 @@ mod tests { use crate::schema::users::dsl::users; let pool = build_pool(); - let conn = &pool.get().unwrap(); - - let tm = conn.transaction_manager(); - - tm.begin_transaction(conn).unwrap(); + let mut conn = pool.get().unwrap(); + let conn = &mut conn; + conn.begin_test_transaction().unwrap(); diesel::delete(user_projects).execute(conn).unwrap(); diesel::delete(users).execute(conn).unwrap(); @@ -218,8 +215,6 @@ mod tests { let res2 = count_matching_users("Bar", "foo@example.com", conn); let res3 = count_matching_users("Foo", "foo@example.com", conn); - tm.rollback_transaction(conn).unwrap(); - assert_eq!(res1, 1); assert_eq!(res2, 1); assert_eq!(res3, 1); diff --git a/crates/derive_db_execute/src/lib.rs b/crates/derive_db_execute/src/lib.rs index 3a5a97c2..891c01e0 100644 --- a/crates/derive_db_execute/src/lib.rs +++ b/crates/derive_db_execute/src/lib.rs @@ -35,8 +35,11 @@ fn parse_meta(mut it: Peekable) -> (Peekable, Option) -> (Peekable, Option TokenStream { type Result = Result<{action_result}, crate::DatabaseError>; fn handle(&mut self, msg: {name}, _ctx: &mut Self::Context) -> Self::Result {{ - let conn = crate::db_pool!(self); + let mut conn = crate::db_pool!(self); - msg.execute(conn) + msg.execute(&mut conn) }} }} @@ -151,18 +154,18 @@ fn build_create_exec( impl {name} {{ pub fn execute( self, - conn: &crate::DbPooledConn, + conn: &mut crate::DbPooledConn, ) -> Result<{action_result}, crate::DatabaseError> {{ - crate::Guard::new(conn)?.run(|_guard| {{ + conn.transaction(|conn| {{ use crate::schema::{schema}::dsl::*; let msg = self; - crate::q!({query}).get_result(conn).map_err(|e| {{ - ::tracing::error!("{{:?}}", e); - crate::DatabaseError::GenericFailure( - crate::OperationError::Create, - crate::ResourceKind::{resource}, - ) - }}) + crate::q!({query}).get_result(conn) + }}).map_err(|e| {{ + ::tracing::error!("{{:?}}", e); + crate::DatabaseError::GenericFailure( + crate::OperationError::Create, + crate::ResourceKind::{resource}, + ) }}) }} }} @@ -187,7 +190,7 @@ fn build_find_exec( impl {name} {{ pub fn execute( self, - conn: &crate::DbPooledConn, + conn: &mut crate::DbPooledConn, ) -> Result<{action_result}, crate::DatabaseError> {{ use crate::schema::{schema}::dsl::*; let msg = self; @@ -221,7 +224,7 @@ fn build_load_exec( impl {name} {{ pub fn execute( self, - conn: &crate::DbPooledConn, + conn: &mut crate::DbPooledConn, ) -> Result<{action_result}, crate::DatabaseError> {{ use crate::schema::{schema}::dsl::*; let msg = self; @@ -255,7 +258,7 @@ fn build_update_exec( impl {name} {{ pub fn execute( self, - conn: &crate::DbPooledConn, + conn: &mut crate::DbPooledConn, ) -> Result<{action_result}, crate::DatabaseError> {{ use crate::schema::{schema}::dsl::*; let msg = self; @@ -289,7 +292,7 @@ fn build_destroy_exec( impl {name} {{ pub fn execute( self, - conn: &crate::DbPooledConn, + conn: &mut crate::DbPooledConn, ) -> Result<{action_result}, crate::DatabaseError> {{ use crate::schema::{schema}::dsl::*; let msg = self; diff --git a/crates/derive_enum_iter/src/lib.rs b/crates/derive_enum_iter/src/lib.rs index 80e8d148..22375758 100644 --- a/crates/derive_enum_iter/src/lib.rs +++ b/crates/derive_enum_iter/src/lib.rs @@ -27,7 +27,7 @@ fn consume_ident(mut it: Peekable, name: &str) -> Peekable { it } -pub(in crate) fn codegen(mut it: Peekable) -> Result { +pub(crate) fn codegen(mut it: Peekable) -> Result { let name = it .next() .expect("Expect to struct name but nothing was found"); diff --git a/crates/derive_enum_sql/Cargo.toml b/crates/derive_enum_sql/Cargo.toml index d7cf196a..d46dbb9e 100644 --- a/crates/derive_enum_sql/Cargo.toml +++ b/crates/derive_enum_sql/Cargo.toml @@ -1,16 +1,26 @@ [package] -name = "derive_enum_sql" -version = "0.1.0" -authors = ["Adrian Wozniak "] -edition = "2018" -description = "JIRS (Simplified JIRA in Rust) shared data types" -repository = "https://gitlab.com/adrian.wozniak/bitque" -license = "MPL-2.0" -#license-file = "../LICENSE" - -[lib] -name = "derive_enum_sql" -path = "./src/lib.rs" -proc-macro = true +name = "diesel-derive-enum" +version = "2.0.1" +description = "Derive diesel boilerplate for using enums in databases" +authors = ["Alex Whitney "] +repository = "http://github.com/adwhit/diesel-derive-enum" +homepage = "http://github.com/adwhit/diesel-derive-enum" +keywords = ["diesel", "postgres", "sqlite", "mysql", "sql"] +license = "MIT OR Apache-2.0" +readme = "README.md" +edition = "2021" [dependencies] +quote = "1" +syn = "1" +heck = "0.4.0" +proc-macro2 = "1" + +[features] +postgres = [] +sqlite = [] +mysql = [] + +[lib] +name = "diesel_derive_enum" +proc-macro = true diff --git a/crates/derive_enum_sql/src/lib.rs b/crates/derive_enum_sql/src/lib.rs index 16aa27c3..b305ed4b 100644 --- a/crates/derive_enum_sql/src/lib.rs +++ b/crates/derive_enum_sql/src/lib.rs @@ -1,155 +1,500 @@ +#![recursion_limit = "1024"] + extern crate proc_macro; -use proc_macro::{TokenStream, TokenTree}; +use heck::{ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToUpperCamelCase}; +use proc_macro::TokenStream; +use proc_macro2::{Ident, Span}; +use quote::quote; +use syn::*; -fn to_lower_case(s: &str) -> String { - let mut lower = String::new(); - for (idx, c) in s.chars().enumerate() { - if idx > 0 && c.is_uppercase() { - lower.push('_'); - } - lower.push_str(c.to_lowercase().to_string().as_str()); - } - lower -} +/// Implement the traits necessary for inserting the enum directly into a +/// database +/// +/// # Attributes +/// +/// ## Type attributes +/// +/// * `#[ExistingTypePath = "crate::schema::sql_types::NewEnum"]` specifies the +/// path to a corresponding diesel type that was already created by the diesel +/// CLI. If omitted, the type will be generated by this macro. *Note*: Only +/// applies to `postgres`, will error if specified for other databases +/// * `#[DieselType = "NewEnumMapping"]` specifies the name for the diesel type +/// to create. If omitted, uses `Mapping`. *Note*: Cannot be +/// specified alongside `ExistingTypePath` +/// * `#[DbValueStyle = "snake_case"]` specifies a renaming style from each of +/// the rust enum variants to each of the database variants. Either +/// `camelCase`, `kebab-case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, +/// `snake_case`, `verbatim`. If omitted, uses `snake_case`. +/// +/// ## Variant attributes +/// +/// * `#[db_rename = "variant"]` specifies the db name for a specific variant. +#[proc_macro_derive( + DbEnum, + attributes(PgType, DieselType, ExistingTypePath, DbValueStyle, db_rename) +)] +pub fn derive(input: TokenStream) -> TokenStream { + let input: DeriveInput = parse_macro_input!(input as DeriveInput); -fn into_str(name: &str, variants: &[String]) -> String { - let mut code = format!( - r#" -#[cfg(feature = "backend")] -impl diesel::serialize::ToSql<{name}Type, diesel::pg::Pg> for {name} {{ - fn to_sql(&self, out: &mut diesel::serialize::Output) -> diesel::serialize::Result {{ - match *self {{ -"#, - name = name, - ); - - for variant in variants { - let lower = to_lower_case(&variant); - code.push_str( - format!( - " {name}::{variant} => out.write_all(b\"{lower}\")?,\n", - variant = variant, - name = name, - lower = lower - ) - .as_str(), - ); - } - code.push_str(" };\n Ok(diesel::serialize::IsNull::No)\n }\n}"); - code -} - -fn from_str(name: &str, variants: &[String]) -> String { - let mut code = format!( - r#" -#[cfg(feature = "backend")] -impl {name} {{ - fn from_diesel_bytes(bytes: Option<&[u8]>) -> diesel::deserialize::Result<{name}> {{ - match diesel::not_none!(bytes) {{ -"#, - name = name, - ); - - for variant in variants { - let lower = to_lower_case(&variant); - code.push_str( - format!( - " b\"{lower}\" => Ok({name}::{variant}),\n", - variant = variant, - name = name, - lower = lower - ) - .as_str(), - ); + let existing_mapping_path = val_from_attrs(&input.attrs, "ExistingTypePath"); + if !cfg!(feature = "postgres") && existing_mapping_path.is_some() { + panic!("ExistingTypePath attribute only applies when the 'postgres' feature is enabled"); } - code.push_str(format!(" _ => Ok({name}::default()),", name = name).as_str()); - code.push_str(" }\n }\n}"); - code.push_str( - format!( - r#" -#[cfg(feature = "backend")] -impl diesel::deserialize::FromSql<{name}Type, diesel::pg::Pg> for {name} {{ - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result {{ - {name}::from_diesel_bytes(bytes) - }} -}} + // we could allow a default value here but... I'm not very keen + // let existing_mapping_path = existing_mapping_path + // .unwrap_or_else(|| format!("crate::schema::sql_types::{}", input.ident)); -#[cfg(feature = "backend")] -impl diesel::deserialize::FromSql for {name} {{ - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result {{ - {name}::from_diesel_bytes(bytes) - }} -}} - "#, - name = name + let pg_internal_type = val_from_attrs(&input.attrs, "PgType"); + + if existing_mapping_path.is_some() && pg_internal_type.is_some() { + panic!("Cannot specify both `ExistingTypePath` and `PgType` attributes"); + } + + let pg_internal_type = pg_internal_type.unwrap_or(input.ident.to_string().to_snake_case()); + + let new_diesel_mapping = val_from_attrs(&input.attrs, "DieselType"); + if existing_mapping_path.is_some() && new_diesel_mapping.is_some() { + panic!("Cannot specify both `ExistingTypePath` and `DieselType` attributes"); + } + let new_diesel_mapping = new_diesel_mapping.unwrap_or_else(|| format!("{}Type", input.ident)); + + // Maintain backwards compatibility by defaulting to snake case. + let case_style = + val_from_attrs(&input.attrs, "DbValueStyle").unwrap_or_else(|| "snake_case".to_string()); + let case_style = CaseStyle::from_string(&case_style); + + let existing_mapping_path = existing_mapping_path.map(|v| { + v.parse::() + .expect("ExistingTypePath is not a valid token") + }); + let new_diesel_mapping = Ident::new(new_diesel_mapping.as_ref(), Span::call_site()); + if let Data::Enum(syn::DataEnum { + variants: data_variants, + .. + }) = input.data + { + generate_derive_enum_impls( + &existing_mapping_path, + &new_diesel_mapping, + &pg_internal_type, + case_style, + &input.ident, + &data_variants, ) - .as_str(), - ); - code + } else { + syn::Error::new( + Span::call_site(), + "derive(DbEnum) can only be applied to enums", + ) + .to_compile_error() + .into() + } } -#[proc_macro_derive(EnumSql)] -pub fn derive_enum_sql(item: TokenStream) -> TokenStream { - let mut it = item.into_iter().peekable(); - while let Some(token) = it.peek() { - if let TokenTree::Ident(_) = token { - break; - } else { - it.next(); - } - } - if let Some(TokenTree::Ident(ident)) = it.next() { - if ident.to_string().as_str() != "pub" { - panic!("Expect to find keyword pub but was found {:?}", ident) - } - } else { - panic!("Expect to find keyword pub but nothing was found") - } - if let Some(TokenTree::Ident(ident)) = it.next() { - if ident.to_string().as_str() != "enum" { - panic!("Expect to find keyword struct but was found {:?}", ident) - } - } else { - panic!("Expect to find keyword struct but nothing was found") - } - let name = it - .next() - .expect("Expect to struct name but nothing was found") - .to_string(); - - let mut variants = vec![]; - if let Some(TokenTree::Group(group)) = it.next() { - for token in group.stream() { - if let TokenTree::Ident(ident) = token { - variants.push(ident.to_string()) +fn val_from_attrs(attrs: &[Attribute], attr_name: &str) -> Option { + for attr in attrs { + if attr.path.is_ident(attr_name) { + match attr.parse_meta().ok()? { + Meta::NameValue(MetaNameValue { + lit: Lit::Str(lit_str), + .. + }) => return Some(lit_str.value()), + _ => panic!( + "Attribute '{}' must have form: {} = \"value\"", + attr_name, attr_name + ), + } + } + } + None +} + +/// Defines the casing for the database representation. Follows serde naming +/// convention. +#[derive(Copy, Clone, Debug, PartialEq)] +enum CaseStyle { + Camel, + Kebab, + Pascal, + Upper, + ScreamingSnake, + Snake, + Verbatim, +} + +impl CaseStyle { + fn from_string(name: &str) -> Self { + match name { + "camelCase" => CaseStyle::Camel, + "kebab-case" => CaseStyle::Kebab, + "PascalCase" => CaseStyle::Pascal, + "SCREAMING_SNAKE_CASE" => CaseStyle::ScreamingSnake, + "UPPERCASE" => CaseStyle::Upper, + "snake_case" => CaseStyle::Snake, + "verbatim" | "verbatimcase" => CaseStyle::Verbatim, + s => panic!("unsupported casing: `{}`", s), + } + } +} + +fn generate_derive_enum_impls( + existing_mapping_path: &Option, + new_diesel_mapping: &Ident, + pg_internal_type: &str, + case_style: CaseStyle, + enum_ty: &Ident, + variants: &syn::punctuated::Punctuated, +) -> TokenStream { + let modname = Ident::new(&format!("db_enum_impl_{}", enum_ty), Span::call_site()); + let variant_ids: Vec = variants + .iter() + .map(|variant| { + if let Fields::Unit = variant.fields { + let id = &variant.ident; + quote! { + #enum_ty::#id + } + } else { + panic!("Variants must be fieldless") + } + }) + .collect(); + + let variants_db: Vec = variants + .iter() + .map(|variant| { + val_from_attrs(&variant.attrs, "db_rename") + .unwrap_or_else(|| stylize_value(&variant.ident.to_string(), case_style)) + }) + .collect(); + let variants_db_bytes: Vec = variants_db + .iter() + .map(|variant_str| LitByteStr::new(variant_str.as_bytes(), Span::call_site())) + .collect(); + + let common = generate_common(enum_ty, &variant_ids, &variants_db, &variants_db_bytes); + let (diesel_mapping_def, diesel_mapping_use) = + // Skip this part if we already have an existing mapping + if existing_mapping_path.is_some() { + (None, None) + } else { + let new_diesel_mapping_def = generate_new_diesel_mapping(new_diesel_mapping, pg_internal_type); + let common_impls_on_new_diesel_mapping = + generate_common_impls("e! { #new_diesel_mapping }, enum_ty); + ( + Some(quote! { + #new_diesel_mapping_def + #common_impls_on_new_diesel_mapping + }), + Some(quote! { + pub use self::#modname::#new_diesel_mapping; + }), + ) + }; + + let pg_impl = if cfg!(feature = "postgres") { + match existing_mapping_path { + Some(path) => { + let common_impls_on_existing_diesel_mapping = generate_common_impls(path, enum_ty); + let postgres_impl = generate_postgres_impl(path, enum_ty, true); + Some(quote! { + #common_impls_on_existing_diesel_mapping + #postgres_impl + }) + } + None => Some(generate_postgres_impl( + "e! { #new_diesel_mapping }, + enum_ty, + false, + )), + } + } else { + None + }; + + let mysql_impl = if cfg!(feature = "mysql") { + Some(generate_mysql_impl(new_diesel_mapping, enum_ty)) + } else { + None + }; + + let sqlite_impl = if cfg!(feature = "sqlite") { + Some(generate_sqlite_impl(new_diesel_mapping, enum_ty)) + } else { + None + }; + + let imports = quote! { + use super::*; + use diesel::{ + backend::{self, Backend}, + deserialize::{self, FromSql}, + expression::AsExpression, + internal::derives::as_expression::Bound, + query_builder::{bind_collector::RawBytesBindCollector, QueryId}, + row::Row, + serialize::{self, IsNull, Output, ToSql}, + sql_types::*, + Queryable, + }; + use std::io::Write; + }; + + let quoted = quote! { + #diesel_mapping_use + #[allow(non_snake_case)] + mod #modname { + #imports + + #common + #diesel_mapping_def + #pg_impl + #mysql_impl + #sqlite_impl + } + }; + + quoted.into() +} + +fn stylize_value(value: &str, style: CaseStyle) -> String { + match style { + CaseStyle::Camel => value.to_lower_camel_case(), + CaseStyle::Kebab => value.to_kebab_case(), + CaseStyle::Pascal => value.to_upper_camel_case(), + CaseStyle::Upper => value.to_uppercase(), + CaseStyle::ScreamingSnake => value.to_shouty_snake_case(), + CaseStyle::Snake => value.to_snake_case(), + CaseStyle::Verbatim => value.to_string(), + } +} + +fn generate_common( + enum_ty: &Ident, + variants_rs: &[proc_macro2::TokenStream], + variants_db: &[String], + variants_db_bytes: &[LitByteStr], +) -> proc_macro2::TokenStream { + quote! { + fn db_str_representation(e: &#enum_ty) -> &'static str { + match *e { + #(#variants_rs => #variants_db,)* + } + } + + fn from_db_binary_representation(bytes: &[u8]) -> deserialize::Result<#enum_ty> { + match bytes { + #(#variants_db_bytes => Ok(#variants_rs),)* + v => Err(format!("Unrecognized enum variant: '{}'", + String::from_utf8_lossy(v)).into()), + } + } + } +} + +fn generate_new_diesel_mapping( + new_diesel_mapping: &Ident, + pg_internal_type: &str, +) -> proc_macro2::TokenStream { + // Note - we only generate a new mapping for mysql and sqlite, postgres + // should already have one + quote! { + #[derive(SqlType, Clone)] + #[diesel(mysql_type(name = "Enum"))] + #[diesel(sqlite_type(name = "Text"))] + #[diesel(postgres_type(name = #pg_internal_type))] + pub struct #new_diesel_mapping; + } +} + +fn generate_common_impls( + diesel_mapping: &proc_macro2::TokenStream, + enum_ty: &Ident, +) -> proc_macro2::TokenStream { + quote! { + + // NOTE: at some point this impl will no longer be necessary + // for diesel-cli schemas + // See https://github.com/adwhit/diesel-derive-enum/issues/10 + // and https://github.com/adwhit/diesel-derive-enum/pull/79 + impl QueryId for #diesel_mapping { + type QueryId = #diesel_mapping; + const HAS_STATIC_QUERY_ID: bool = true; + } + + impl AsExpression<#diesel_mapping> for #enum_ty { + type Expression = Bound<#diesel_mapping, Self>; + + fn as_expression(self) -> Self::Expression { + Bound::new(self) + } + } + + impl AsExpression> for #enum_ty { + type Expression = Bound, Self>; + + fn as_expression(self) -> Self::Expression { + Bound::new(self) + } + } + + impl<'a> AsExpression<#diesel_mapping> for &'a #enum_ty { + type Expression = Bound<#diesel_mapping, Self>; + + fn as_expression(self) -> Self::Expression { + Bound::new(self) + } + } + + impl<'a> AsExpression> for &'a #enum_ty { + type Expression = Bound, Self>; + + fn as_expression(self) -> Self::Expression { + Bound::new(self) + } + } + + impl<'a, 'b> AsExpression<#diesel_mapping> for &'a &'b #enum_ty { + type Expression = Bound<#diesel_mapping, Self>; + + fn as_expression(self) -> Self::Expression { + Bound::new(self) + } + } + + impl<'a, 'b> AsExpression> for &'a &'b #enum_ty { + type Expression = Bound, Self>; + + fn as_expression(self) -> Self::Expression { + Bound::new(self) + } + } + + impl ToSql, DB> for #enum_ty + where + DB: Backend, + Self: ToSql<#diesel_mapping, DB>, + { + fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result { + ToSql::<#diesel_mapping, DB>::to_sql(self, out) + } + } + } +} + +fn generate_postgres_impl( + diesel_mapping: &proc_macro2::TokenStream, + enum_ty: &Ident, + with_clone: bool, +) -> proc_macro2::TokenStream { + // If the type was generated by postgres, we have to manually add a clone impl, + // if generated by 'us' it has already been done + let clone_impl = if with_clone { + Some(quote! { + impl Clone for #diesel_mapping { + fn clone(&self) -> Self { + #diesel_mapping + } + } + }) + } else { + None + }; + + quote! { + mod pg_impl { + use super::*; + use diesel::pg::{Pg, PgValue}; + + #clone_impl + + impl FromSql<#diesel_mapping, Pg> for #enum_ty { + fn from_sql(raw: PgValue) -> deserialize::Result { + from_db_binary_representation(raw.as_bytes()) + } + } + + impl ToSql<#diesel_mapping, Pg> for #enum_ty + { + fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result { + out.write_all(db_str_representation(self).as_bytes())?; + Ok(IsNull::No) + } + } + + impl Queryable<#diesel_mapping, Pg> for #enum_ty { + type Row = Self; + + fn build(row: Self::Row) -> deserialize::Result { + Ok(row) + } + } + } + } +} + +fn generate_mysql_impl(diesel_mapping: &Ident, enum_ty: &Ident) -> proc_macro2::TokenStream { + quote! { + mod mysql_impl { + use super::*; + use diesel; + use diesel::mysql::{Mysql, MysqlValue}; + + impl FromSql<#diesel_mapping, Mysql> for #enum_ty { + fn from_sql(raw: MysqlValue) -> deserialize::Result { + from_db_binary_representation(raw.as_bytes()) + } + } + + impl ToSql<#diesel_mapping, Mysql> for #enum_ty + { + fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> serialize::Result { + out.write_all(db_str_representation(self).as_bytes())?; + Ok(IsNull::No) + } + } + + impl Queryable<#diesel_mapping, Mysql> for #enum_ty { + type Row = Self; + + fn build(row: Self::Row) -> deserialize::Result { + Ok(row) + } + } + } + } +} + +fn generate_sqlite_impl(diesel_mapping: &Ident, enum_ty: &Ident) -> proc_macro2::TokenStream { + quote! { + mod sqlite_impl { + use super::*; + use diesel; + use diesel::sql_types; + use diesel::sqlite::Sqlite; + + impl FromSql<#diesel_mapping, Sqlite> for #enum_ty { + fn from_sql(value: backend::RawValue) -> deserialize::Result { + let bytes = as FromSql>::from_sql(value)?; + from_db_binary_representation(bytes.as_slice()) + } + } + + impl ToSql<#diesel_mapping, Sqlite> for #enum_ty { + fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result { + >::to_sql(db_str_representation(self), out) + } + } + + impl Queryable<#diesel_mapping, Sqlite> for #enum_ty { + type Row = Self; + + fn build(row: Self::Row) -> deserialize::Result { + Ok(row) + } } } - } else { - panic!("Enum variants group expected"); } - if variants.is_empty() { - panic!("Enum cannot be empty") - } - - let mut code = format!( - r#" -#[cfg(feature = "backend")] -#[derive(diesel::SqlType)] -#[postgres(type_name = "{name}Type")] -pub struct {name}Type; - -#[cfg(feature = "backend")] -impl diesel::query_builder::QueryId for {name}Type {{ - type QueryId = {name}; -}} - "#, - name = name - ); - - code.push_str(from_str(&name, &variants).as_str()); - code.push_str(into_str(&name, &variants).as_str()); - - code.parse().unwrap() } diff --git a/crates/filesystem-actor/Cargo.toml b/crates/filesystem-actor/Cargo.toml index 13da0df9..656d796c 100644 --- a/crates/filesystem-actor/Cargo.toml +++ b/crates/filesystem-actor/Cargo.toml @@ -17,6 +17,5 @@ actix = { version = "0.13.0" } actix-files = { version = "0.6.2" } bitque-config = { workspace = true, features = ["local-storage"] } bytes = { version = "1.4.0" } -common = { workspace = true } futures = { version = "0.3.8" } tokio = { version = "1", features = ["full"] } diff --git a/crates/highlight-actor/Cargo.toml b/crates/highlight-actor/Cargo.toml index ce93706f..1d7f5a7c 100644 --- a/crates/highlight-actor/Cargo.toml +++ b/crates/highlight-actor/Cargo.toml @@ -17,7 +17,6 @@ actix = { version = "0.13.0" } bincode = { version = "*" } bitque-config = { workspace = true, features = ["hi"] } bitque-data = { workspace = true, features = ["backend"] } -common = { workspace = true } flate2 = { version = "*" } lazy_static = { version = "*" } serde = { version = "*" } diff --git a/crates/highlight-actor/src/lib.rs b/crates/highlight-actor/src/lib.rs index c55d869e..19aa96a6 100644 --- a/crates/highlight-actor/src/lib.rs +++ b/crates/highlight-actor/src/lib.rs @@ -82,9 +82,11 @@ impl HighlightActor { let mut res = Vec::with_capacity(code.split_ascii_whitespace().count()); for line in code.lines() { - res.extend(hi.highlight_line(line, self.syntax_set.as_ref()).map_err(|_e| { - HighlightError::UnknownLanguage - })?.iter()); + res.extend( + hi.highlight_line(line, self.syntax_set.as_ref()) + .map_err(|_e| HighlightError::UnknownLanguage)? + .iter(), + ); } Ok(res) } diff --git a/crates/mail-actor/Cargo.toml b/crates/mail-actor/Cargo.toml index aaafdac2..c17efb95 100644 --- a/crates/mail-actor/Cargo.toml +++ b/crates/mail-actor/Cargo.toml @@ -15,7 +15,6 @@ path = "./src/lib.rs" [dependencies] actix = { version = "0.13.0" } bitque-config = { workspace = true, features = ["mail", "web"] } -common = { workspace = true } dotenv = { version = "*" } futures = { version = "*" } lettre = { version = "0.10.0-rc.3" } diff --git a/crates/web-actor/Cargo.toml b/crates/web-actor/Cargo.toml index 89da13d8..ba2b7c52 100644 --- a/crates/web-actor/Cargo.toml +++ b/crates/web-actor/Cargo.toml @@ -20,11 +20,13 @@ default = ["local-storage"] [dependencies] actix = { version = "0.13.0" } actix-multipart = { version = "*" } +actix-web = { version = "4" } +actix-web-actors = { version = "4" } amazon-actor = { workspace = true, optional = true } bincode = { version = "*" } bitque-config = { workspace = true, features = ["mail", "web", "local-storage"] } bitque-data = { workspace = true, features = ["backend"] } -common = { workspace = true } +bytes = { version = "1" } database-actor = { workspace = true } filesystem-actor = { workspace = true, optional = true } futures = { version = "0.3.8" } @@ -34,5 +36,6 @@ openssl-sys = { version = "*", features = ["vendored"] } serde = { version = "*" } tokio = { version = "1", features = ["full"] } toml = { version = "*" } +tracing = { version = "0.1.37" } uuid = { version = "1.3.0", features = ["serde", "v4", "v5"] } websocket-actor = { workspace = true } diff --git a/crates/web-actor/src/avatar.rs b/crates/web-actor/src/avatar.rs index 3df8b081..d053a3cf 100644 --- a/crates/web-actor/src/avatar.rs +++ b/crates/web-actor/src/avatar.rs @@ -2,10 +2,10 @@ use std::io::Write; use actix::Addr; use actix_multipart::{Field, Multipart}; -use actix_web::http::header::ContentDisposition; use actix_web::web::Data; use actix_web::{post, web, Error, HttpResponse}; -use common::*; +use bitque_data::msg::{WsMsg, WsMsgUser}; +use bitque_data::{User, UserId}; use database_actor::authorize_user::AuthorizeUser; use database_actor::user_projects::CurrentUserProject; use database_actor::users::UpdateAvatarUrl; @@ -13,11 +13,12 @@ use database_actor::DbExecutor; #[cfg(feature = "local-storage")] use futures::executor::block_on; use futures::{StreamExt, TryStreamExt}; -use bitque_data::msg::{WsMsg, WsMsgUser}; -use bitque_data::{User, UserId}; +use tracing::error; use websocket_actor::server::InnerMsg::BroadcastToChannel; use websocket_actor::server::WsServer; +use crate::ServiceError; + #[cfg(feature = "aws-s3")] #[post("/")] pub async fn upload( @@ -31,10 +32,7 @@ pub async fn upload( let mut avatar_url: Option = None; while let Ok(Some(field)) = payload.try_next().await { - let disposition: ContentDisposition = match field.content_disposition() { - Some(d) => d, - _ => continue, - }; + let disposition = field.content_disposition(); if !disposition.is_form_data() { return Ok(HttpResponse::BadRequest().finish()); } @@ -48,7 +46,7 @@ pub async fn upload( crate::handlers::upload_avatar_image::handle_image( id, field, - disposition, + disposition.clone(), fs.clone(), amazon.clone(), ) @@ -95,10 +93,7 @@ pub async fn upload( let mut avatar_url: Option = None; while let Ok(Some(field)) = payload.try_next().await { - let disposition: ContentDisposition = match field.content_disposition() { - Some(d) => d, - _ => continue, - }; + let disposition = field.content_disposition(); if !disposition.is_form_data() { return Ok(HttpResponse::BadRequest().finish()); } @@ -107,15 +102,10 @@ pub async fn upload( user_id = Some(handle_token(field, db.clone()).await?); } Some("avatar") => { - let id = user_id.ok_or_else(|| HttpResponse::Unauthorized().finish())?; + let Some(id) = user_id else { return Ok(HttpResponse::Unauthorized().finish()); }; avatar_url = Some( - crate::handlers::upload_avatar_image::handle_image( - id, - field, - disposition, - fs.clone(), - ) - .await?, + crate::handlers::upload_avatar_image::handle_image(id, field, fs.clone()) + .await?, ); } _ => continue, @@ -134,12 +124,16 @@ pub async fn upload( match (user_id, avatar_url) { (user_id, Some(avatar_url)) => { let user = update_user_avatar(user_id, avatar_url.clone(), db).await?; - ws.send(BroadcastToChannel( - project_id, - WsMsg::User(WsMsgUser::AvatarUrlChanged(user.id, avatar_url)), - )) - .await - .map_err(|_| HttpResponse::UnprocessableEntity().finish())?; + if ws + .send(BroadcastToChannel( + project_id, + WsMsg::User(WsMsgUser::AvatarUrlChanged(user.id, avatar_url)), + )) + .await + .is_err() + { + return Ok(HttpResponse::UnprocessableEntity().finish()); + }; Ok(HttpResponse::NoContent().finish()) } _ => Ok(HttpResponse::UnprocessableEntity().finish()), @@ -162,42 +156,41 @@ async fn update_user_avatar( Ok(Err(e)) => { ::tracing::error!("{:?}", e); - Err(actix_web::Error::from( - HttpResponse::Unauthorized().finish(), - )) + Err(ServiceError::Unauthorized.into()) } Err(e) => { ::tracing::error!("{:?}", e); - Err(actix_web::Error::from( - HttpResponse::Unauthorized().finish(), - )) + Err(ServiceError::Unauthorized.into()) } } } -async fn handle_token( - mut field: Field, - db: Data>, -) -> Result { +async fn handle_token(mut field: Field, db: Data>) -> Result { let mut f: Vec = vec![]; while let Some(chunk) = field.next().await { let data = chunk.unwrap(); - f = web::block(move || f.write_all(&data).map(|_| f)).await?; + f = web::block(move || { + if let Err(e) = f.write_all(&data) { + error!("{e}"); + } + f + }) + .await?; } let access_token = String::from_utf8(f) .unwrap_or_default() .parse::() - .map_err(|_| HttpResponse::Unauthorized().finish())?; + .map_err(|_| ServiceError::Unauthorized)?; match db.send(AuthorizeUser { access_token }).await { Ok(Ok(user)) => Ok(user.id), Ok(Err(e)) => { ::tracing::error!("{:?}", e); - Err(HttpResponse::Unauthorized().finish().into()) + Err(ServiceError::Unauthorized.into()) } Err(e) => { ::tracing::error!("{:?}", e); - Err(HttpResponse::Unauthorized().finish().into()) + Err(ServiceError::Unauthorized.into()) } } } diff --git a/crates/web-actor/src/errors.rs b/crates/web-actor/src/errors.rs index 26c51839..62400f6b 100644 --- a/crates/web-actor/src/errors.rs +++ b/crates/web-actor/src/errors.rs @@ -1,19 +1,21 @@ -use actix_web::HttpResponse; -use common::*; +use std::fmt::{Display, Formatter}; + +use actix_web::body::BoxBody; +use actix_web::{HttpResponse, ResponseError}; use bitque_data::msg::WsError; use bitque_data::ErrorResponse; const TOKEN_NOT_FOUND: &str = "Token not found"; const DATABASE_CONNECTION_FAILED: &str = "Database connection failed"; -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum HighlightError { UnknownLanguage, UnknownTheme, ResultUnserializable, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum ServiceError { Unauthorized, DatabaseConnectionLost, @@ -30,6 +32,18 @@ impl ServiceError { } } +impl Display for ServiceError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str("") + } +} + +impl ResponseError for ServiceError { + fn error_response(&self) -> HttpResponse { + self.clone().into() + } +} + impl Into for ServiceError { fn into(self) -> HttpResponse { match self { diff --git a/crates/web-actor/src/handlers/upload_avatar_image.rs b/crates/web-actor/src/handlers/upload_avatar_image.rs index 60a78e41..65792bb7 100644 --- a/crates/web-actor/src/handlers/upload_avatar_image.rs +++ b/crates/web-actor/src/handlers/upload_avatar_image.rs @@ -1,22 +1,20 @@ use actix::Addr; use actix_multipart::Field; -use actix_web::http::header::ContentDisposition; use actix_web::web::Data; use actix_web::Error; -use common::*; -use futures::StreamExt; use bitque_data::UserId; +use futures::StreamExt; use tokio::sync::broadcast::{Receiver, Sender}; +use tracing::error; #[cfg(all(feature = "local-storage", feature = "aws-s3"))] pub(crate) async fn handle_image( user_id: UserId, mut field: Field, - disposition: ContentDisposition, fs: Data>, amazon: Data>, ) -> Result { - let filename = disposition.get_filename().unwrap(); + let filename = field.content_disposition().get_filename().unwrap(); let system_file_name = format!("{}-{}", user_id, filename); let (sender, receiver) = tokio::sync::broadcast::channel(64); @@ -46,10 +44,9 @@ pub(crate) async fn handle_image( pub(crate) async fn handle_image( user_id: UserId, mut field: Field, - disposition: ContentDisposition, amazon: Data>, ) -> Result { - let filename = disposition.get_filename().unwrap(); + let filename = field.content_disposition().get_filename().unwrap(); let system_file_name = format!("{}-{}", user_id, filename); let (sender, receiver) = tokio::sync::broadcast::channel(64); @@ -73,10 +70,9 @@ pub(crate) async fn handle_image( pub(crate) async fn handle_image( user_id: UserId, mut field: Field, - disposition: ContentDisposition, fs: Data>, ) -> Result { - let filename = disposition.get_filename().unwrap(); + let filename = field.content_disposition().get_filename().unwrap(); let system_file_name = format!("{}-{}", user_id, filename); let (sender, _receiver) = tokio::sync::broadcast::channel(64); @@ -97,11 +93,11 @@ pub(crate) async fn handle_image( } /// Read file from client -async fn read_form_data(field: &mut Field, sender: Sender) { +async fn read_form_data(field: &mut Field, sender: Sender) { while let Some(chunk) = field.next().await { let data = chunk.unwrap(); if let Err(err) = sender.send(data) { - log::error!("{:?}", err); + error!("{:?}", err); } } } diff --git a/crates/web-actor/src/lib.rs b/crates/web-actor/src/lib.rs index 651a4485..19866c50 100644 --- a/crates/web-actor/src/lib.rs +++ b/crates/web-actor/src/lib.rs @@ -1,11 +1,12 @@ +extern crate core; + use actix::Addr; use actix_web::web::Data; use actix_web::{HttpRequest, HttpResponse}; -use common::*; +use bitque_data::User; use database_actor::authorize_user::AuthorizeUser; use database_actor::DbExecutor; pub use errors::*; -use bitque_data::User; use crate::middleware::authorize::token_from_headers; diff --git a/crates/web-actor/src/middleware/authorize.rs b/crates/web-actor/src/middleware/authorize.rs index e131be01..612bdd87 100644 --- a/crates/web-actor/src/middleware/authorize.rs +++ b/crates/web-actor/src/middleware/authorize.rs @@ -1,10 +1,6 @@ -use actix_web::http::header::{self}; -use actix_web::http::HeaderMap; -use common::*; +use actix_web::http::header::{self, HeaderMap}; -pub fn token_from_headers( - headers: &HeaderMap, -) -> std::result::Result { +pub fn token_from_headers(headers: &HeaderMap) -> Result { headers .get(header::AUTHORIZATION) .ok_or(crate::errors::ServiceError::Unauthorized) diff --git a/crates/web/.env b/crates/web/.env deleted file mode 120000 index 4a82335f..00000000 --- a/crates/web/.env +++ /dev/null @@ -1 +0,0 @@ -../.env \ No newline at end of file diff --git a/crates/web/Cargo.toml b/crates/web/Cargo.toml index cf55d68a..8db38dcf 100644 --- a/crates/web/Cargo.toml +++ b/crates/web/Cargo.toml @@ -27,8 +27,8 @@ derive_enum_primitive = { workspace = true } dotenv = { version = "*" } futures = "0.3.6" js-sys = { version = "*", default-features = false } -seed = { version = "0.10.0" } -serde = { version = "*" } +seed = { version = "0" } +serde = { version = "1", features = [] } serde_json = { version = "*" } tracing = { version = "0.1.37" } uuid = { version = "1.3.0", features = ["serde"] } diff --git a/crates/web/LICENSE b/crates/web/LICENSE deleted file mode 120000 index ea5b6064..00000000 --- a/crates/web/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE \ No newline at end of file diff --git a/crates/web/src/changes.rs b/crates/web/src/changes.rs index f5b0afba..e7833a2d 100644 --- a/crates/web/src/changes.rs +++ b/crates/web/src/changes.rs @@ -1,5 +1,4 @@ use bitque_data::{EpicId, IssueStatusId, WsMsg}; -use seed::prelude::WebSocketMessage; use crate::components::styled_md_editor::MdEditorMode as TabMode; use crate::FieldId; diff --git a/crates/web/src/components/mod.rs b/crates/web/src/components/mod.rs index a8127081..6047e750 100644 --- a/crates/web/src/components/mod.rs +++ b/crates/web/src/components/mod.rs @@ -1,3 +1,4 @@ +mod events; pub mod styled_avatar; pub mod styled_button; pub mod styled_checkbox; @@ -18,4 +19,3 @@ pub mod styled_select_child; pub mod styled_textarea; pub mod styled_tip; pub mod styled_tooltip; -mod events; diff --git a/crates/web/src/components/styled_image_input.rs b/crates/web/src/components/styled_image_input.rs index 838fb163..8982761a 100644 --- a/crates/web/src/components/styled_image_input.rs +++ b/crates/web/src/components/styled_image_input.rs @@ -1,5 +1,5 @@ -use seed::*; use seed::prelude::*; +use seed::*; use web_sys::File; use crate::{FieldId, Msg}; diff --git a/crates/web/src/components/styled_link.rs b/crates/web/src/components/styled_link.rs index 76bcbe64..69ebd262 100644 --- a/crates/web/src/components/styled_link.rs +++ b/crates/web/src/components/styled_link.rs @@ -1,5 +1,5 @@ -use seed::*; use seed::prelude::*; +use seed::*; use crate::Msg; diff --git a/crates/web/src/components/styled_modal.rs b/crates/web/src/components/styled_modal.rs index 54164feb..2d45f21a 100644 --- a/crates/web/src/components/styled_modal.rs +++ b/crates/web/src/components/styled_modal.rs @@ -1,5 +1,5 @@ -use seed::*; use seed::prelude::*; +use seed::*; use crate::components::styled_icon::{Icon, StyledIcon}; use crate::Msg; diff --git a/crates/web/src/lib.rs b/crates/web/src/lib.rs index 863a7b17..60928744 100644 --- a/crates/web/src/lib.rs +++ b/crates/web/src/lib.rs @@ -1,11 +1,11 @@ #![feature(type_ascription, trait_alias, drain_filter)] +use bitque_data::msg::WsMsgSession; +use bitque_data::*; pub use changes::*; pub use components::*; pub use fields::*; pub use images::*; -use bitque_data::msg::WsMsgSession; -use bitque_data::*; use seed::prelude::*; use web_sys::File; diff --git a/crates/web/src/modals/issues_create/model.rs b/crates/web/src/modals/issues_create/model.rs index 5e43bfd6..fb8ad0c6 100644 --- a/crates/web/src/modals/issues_create/model.rs +++ b/crates/web/src/modals/issues_create/model.rs @@ -1,6 +1,6 @@ +use bitque_data::{IssueFieldId, IssuePriority}; use derive_enum_iter::EnumIter; use derive_enum_primitive::EnumPrimitive; -use bitque_data::{IssueFieldId, IssuePriority}; use seed::prelude::*; use crate::components::styled_date_time_input::*; diff --git a/crates/web/src/modals/issues_edit/view.rs b/crates/web/src/modals/issues_edit/view.rs index 64d3fa54..0519fa83 100644 --- a/crates/web/src/modals/issues_edit/view.rs +++ b/crates/web/src/modals/issues_edit/view.rs @@ -1,8 +1,8 @@ -use comments::*; use bitque_data::{ CommentFieldId, IssueFieldId, IssuePriority, IssueStatus, IssueType, TimeTracking, UpdateIssuePayload, User, }; +use comments::*; use seed::prelude::*; use seed::*; diff --git a/crates/web/src/pages/epics_page/view.rs b/crates/web/src/pages/epics_page/view.rs index 6ddbd6be..e6553338 100644 --- a/crates/web/src/pages/epics_page/view.rs +++ b/crates/web/src/pages/epics_page/view.rs @@ -1,5 +1,5 @@ -use chrono::NaiveDateTime; use bitque_data::{Issue, IssueStatus}; +use chrono::NaiveDateTime; use seed::prelude::*; use seed::*; diff --git a/crates/web/src/pages/issues_and_filters/view/issue_info.rs b/crates/web/src/pages/issues_and_filters/view/issue_info.rs index cf7e595a..8ec0a881 100644 --- a/crates/web/src/pages/issues_and_filters/view/issue_info.rs +++ b/crates/web/src/pages/issues_and_filters/view/issue_info.rs @@ -1,7 +1,6 @@ -use seed::*; -use seed::prelude::*; - use bitque_data::{Issue, IssueId}; +use seed::prelude::*; +use seed::*; use crate::components::styled_icon::*; use crate::components::styled_link::*; diff --git a/crates/web/src/pages/project_page/model.rs b/crates/web/src/pages/project_page/model.rs index 6c047ba5..24cb4edc 100644 --- a/crates/web/src/pages/project_page/model.rs +++ b/crates/web/src/pages/project_page/model.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; -use chrono::NaiveDateTime; use bitque_data::*; +use chrono::NaiveDateTime; use crate::shared::drag::DragState; diff --git a/crates/web/src/pages/project_page/view/board.rs b/crates/web/src/pages/project_page/view/board.rs index c38d98d2..612dbef0 100644 --- a/crates/web/src/pages/project_page/view/board.rs +++ b/crates/web/src/pages/project_page/view/board.rs @@ -1,14 +1,13 @@ -use seed::*; -use seed::prelude::*; - use bitque_data::*; +use seed::prelude::*; +use seed::*; -use crate::{match_page, Model, Msg}; use crate::components::styled_avatar::*; use crate::components::styled_button::{ButtonVariant, StyledButton}; use crate::components::styled_icon::*; use crate::model::PageContent; use crate::pages::project_page::{events, StatusIssueIds}; +use crate::{match_page, Model, Msg}; #[inline(always)] pub fn project_board_lists(model: &Model) -> Node { diff --git a/crates/web/src/pages/reports_page/view.rs b/crates/web/src/pages/reports_page/view.rs index e7a3a9e9..74d21bf9 100644 --- a/crates/web/src/pages/reports_page/view.rs +++ b/crates/web/src/pages/reports_page/view.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; -use chrono::Datelike; use bitque_data::Issue; +use chrono::Datelike; use seed::prelude::*; use seed::*; diff --git a/crates/web/src/ws/mod.rs b/crates/web/src/ws/mod.rs index 1a376281..3d8a9e4b 100644 --- a/crates/web/src/ws/mod.rs +++ b/crates/web/src/ws/mod.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; -pub use init_load_sets::*; use bitque_data::msg::{ WsError, WsMsgComment, WsMsgEpic, WsMsgIssue, WsMsgIssueStatus, WsMsgMessage, WsMsgProject, WsMsgSession, WsMsgUser, }; use bitque_data::*; +pub use init_load_sets::*; use seed::prelude::*; use crate::model::*; diff --git a/crates/websocket-actor/Cargo.toml b/crates/websocket-actor/Cargo.toml index e04036b0..84e160e5 100644 --- a/crates/websocket-actor/Cargo.toml +++ b/crates/websocket-actor/Cargo.toml @@ -14,11 +14,12 @@ path = "./src/lib.rs" [dependencies] actix = { version = "0.13.0" } +actix-web = { version = "4" } +actix-web-actors = { version = "4" } async-trait = { version = "*" } bincode = { version = "*" } bitque-config = { workspace = true, features = ["websocket"] } bitque-data = { workspace = true, features = ["backend"] } -common = { workspace = true } comrak = { version = "*" } database-actor = { workspace = true } flate2 = { version = "*" } @@ -31,4 +32,5 @@ openssl-sys = { version = "*", features = ["vendored"] } serde = { version = "*" } syntect = { version = "*" } toml = { version = "*" } +tracing = { version = "0.1.37" } uuid = { version = "1.3.0", features = ["serde", "v4", "v5"] } diff --git a/crates/websocket-actor/src/handlers/auth.rs b/crates/websocket-actor/src/handlers/auth.rs index 04cd1819..0269549f 100644 --- a/crates/websocket-actor/src/handlers/auth.rs +++ b/crates/websocket-actor/src/handlers/auth.rs @@ -1,10 +1,10 @@ use actix::AsyncContext; +use bitque_data::msg::{WsError, WsMsgSession}; +use bitque_data::{Token, WsMsg}; use database_actor::authorize_user::AuthorizeUser; use database_actor::tokens::{CreateBindToken, FindBindToken}; use database_actor::users::LookupUser; use futures::executor::block_on; -use bitque_data::msg::{WsError, WsMsgSession}; -use bitque_data::{Token, WsMsg}; use mail_actor::welcome::Welcome; use crate::server::InnerMsg; diff --git a/crates/websocket-actor/src/handlers/invitations.rs b/crates/websocket-actor/src/handlers/invitations.rs index 1a75c8d4..78d423ad 100644 --- a/crates/websocket-actor/src/handlers/invitations.rs +++ b/crates/websocket-actor/src/handlers/invitations.rs @@ -1,10 +1,10 @@ -use database_actor::invitations; -use database_actor::messages::CreateMessageReceiver; -use futures::executor::block_on; use bitque_data::msg::{WsMsgInvitation, WsMsgMessage}; use bitque_data::{ EmailString, InvitationId, InvitationToken, MessageType, UserRole, UsernameString, WsMsg, }; +use database_actor::invitations; +use database_actor::messages::CreateMessageReceiver; +use futures::executor::block_on; use crate::handlers::{LoadInvitedUsers, RemoveInvitedUser}; use crate::server::InnerMsg; diff --git a/crates/websocket-actor/src/handlers/issue_statuses.rs b/crates/websocket-actor/src/handlers/issue_statuses.rs index bbc55751..5d4323a6 100644 --- a/crates/websocket-actor/src/handlers/issue_statuses.rs +++ b/crates/websocket-actor/src/handlers/issue_statuses.rs @@ -1,6 +1,6 @@ -use database_actor::issue_statuses; use bitque_data::msg::WsMsgIssueStatus; use bitque_data::{IssueStatusId, Position, TitleString, WsMsg}; +use database_actor::issue_statuses; use crate::{db_or_debug_and_return, AsyncHandler, WebSocketActor, WsResult}; diff --git a/crates/websocket-actor/src/handlers/issues.rs b/crates/websocket-actor/src/handlers/issues.rs index 490b9dc3..7a657513 100644 --- a/crates/websocket-actor/src/handlers/issues.rs +++ b/crates/websocket-actor/src/handlers/issues.rs @@ -1,9 +1,11 @@ use std::collections::HashMap; +use bitque_data::msg::{IssueSync, WsMsgIssue, WsMsgProject}; +use bitque_data::{ + CreateIssuePayload, IssueAssignee, IssueFieldId, IssueId, PayloadVariant, WsMsg, +}; use database_actor::issue_assignees::LoadAssignees; use database_actor::issues::{LoadProjectIssues, UpdateIssue}; -use bitque_data::msg::{IssueSync, WsMsgIssue, WsMsgProject}; -use bitque_data::{CreateIssuePayload, IssueAssignee, IssueFieldId, IssueId, PayloadVariant, WsMsg}; use crate::{db_or_debug_and_return, AsyncHandler, WebSocketActor, WsResult}; diff --git a/crates/websocket-actor/src/handlers/messages.rs b/crates/websocket-actor/src/handlers/messages.rs index 9b8299fa..61c3935d 100644 --- a/crates/websocket-actor/src/handlers/messages.rs +++ b/crates/websocket-actor/src/handlers/messages.rs @@ -1,6 +1,6 @@ -use database_actor::messages; use bitque_data::msg::WsMsgMessage; use bitque_data::MessageId; +use database_actor::messages; use crate::{db_or_debug_and_return, AsyncHandler, WebSocketActor, WsResult}; diff --git a/crates/websocket-actor/src/handlers/projects.rs b/crates/websocket-actor/src/handlers/projects.rs index 786c48e1..6450fe34 100644 --- a/crates/websocket-actor/src/handlers/projects.rs +++ b/crates/websocket-actor/src/handlers/projects.rs @@ -1,6 +1,6 @@ -use database_actor as db; use bitque_data::msg::WsMsgProject; use bitque_data::{UpdateProjectPayload, UserProject, WsMsg}; +use database_actor as db; use crate::handlers::{LoadIssues, LoadProjectUsers}; use crate::{db_or_debug_and_return, AsyncHandler, WebSocketActor, WsResult}; diff --git a/crates/websocket-actor/src/handlers/user_projects.rs b/crates/websocket-actor/src/handlers/user_projects.rs index b0a74008..e5140d32 100644 --- a/crates/websocket-actor/src/handlers/user_projects.rs +++ b/crates/websocket-actor/src/handlers/user_projects.rs @@ -1,5 +1,5 @@ -use database_actor as db; use bitque_data::{UserProjectId, WsMsg}; +use database_actor as db; use crate::{db_or_debug_and_return, AsyncHandler, WebSocketActor, WsResult}; diff --git a/crates/websocket-actor/src/handlers/users.rs b/crates/websocket-actor/src/handlers/users.rs index 5b93e353..c814df22 100644 --- a/crates/websocket-actor/src/handlers/users.rs +++ b/crates/websocket-actor/src/handlers/users.rs @@ -1,7 +1,7 @@ -use database_actor::users::Register as DbRegister; -use database_actor::{self}; use bitque_data::msg::{WsMsgInvitation, WsMsgProject, WsMsgSession, WsMsgUser}; use bitque_data::{UserId, UserProject, UserRole, WsMsg}; +use database_actor::users::Register as DbRegister; +use database_actor::{self}; use crate::handlers::auth::Authenticate; use crate::handlers::user_settings; diff --git a/crates/websocket-actor/src/lib.rs b/crates/websocket-actor/src/lib.rs index 1cc5b744..e7005ee1 100644 --- a/crates/websocket-actor/src/lib.rs +++ b/crates/websocket-actor/src/lib.rs @@ -2,15 +2,14 @@ use actix::{Actor, ActorContext, Addr, AsyncContext, Handler, Recipient, StreamH use actix_web::web::{self, Data}; use actix_web::{get, Error, HttpRequest, HttpResponse}; use actix_web_actors::ws; -use ::tracing::*; -use common::{actix_web, actix_web_actors}; +use bitque_data::msg::{WsMsgInvitation, WsMsgSession}; +use bitque_data::{Project, User, UserProject, WsMsg}; use database_actor::projects::LoadCurrentProject; use database_actor::user_projects::CurrentUserProject; use database_actor::DbExecutor; use futures::executor::block_on as wait; -use bitque_data::msg::{WsMsgInvitation, WsMsgSession}; -use bitque_data::{Project, User, UserProject, WsMsg}; use mail_actor::MailExecutor; +use tracing::*; use crate::handlers::*; use crate::server::{InnerMsg, WsServer}; diff --git a/crates/websocket-actor/src/server/mod.rs b/crates/websocket-actor/src/server/mod.rs index 508e4310..ce8d3b85 100644 --- a/crates/websocket-actor/src/server/mod.rs +++ b/crates/websocket-actor/src/server/mod.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; -use actix::{Actor, Context, Recipient}; use ::tracing::*; +use actix::{Actor, Context, Recipient}; use bitque_data::{ProjectId, UserId, WsMsg}; #[derive(Debug, actix::Message)] @@ -110,10 +110,7 @@ impl WsServer { fn send_to_recipients(&self, recipients: &[Recipient], msg: &WsMsg) { for recipient in recipients.iter() { - match recipient.do_send(InnerMsg::Transfer(msg.clone())) { - Ok(_) => ::tracing::debug!("msg sent"), - Err(e) => ::tracing::error!("{}", e), - }; + recipient.do_send(InnerMsg::Transfer(msg.clone())); } } } diff --git a/migrations/2020-03-25-150002_create__project_category_type/down.sql b/migrations/2020-03-25-150002_create__project_category_type/down.sql index f1cb3f4a..adcf4f26 100644 --- a/migrations/2020-03-25-150002_create__project_category_type/down.sql +++ b/migrations/2020-03-25-150002_create__project_category_type/down.sql @@ -1 +1 @@ -DROP TYPE IF EXISTS "ProjectCategory" CASCADE; +DROP TYPE IF EXISTS "ProjectCategoryMapping" CASCADE; diff --git a/migrations/2020-03-25-150002_create__project_category_type/up.sql b/migrations/2020-03-25-150002_create__project_category_type/up.sql index 06a9201b..36a5adae 100644 --- a/migrations/2020-03-25-150002_create__project_category_type/up.sql +++ b/migrations/2020-03-25-150002_create__project_category_type/up.sql @@ -1,5 +1,5 @@ -DROP TYPE IF EXISTS "ProjectCategory" CASCADE; -CREATE TYPE "ProjectCategory" as ENUM ( +DROP TYPE IF EXISTS "ProjectCategoryMapping" CASCADE; +CREATE TYPE "ProjectCategoryMapping" as ENUM ( 'software', 'marketing', 'business' diff --git a/migrations/2020-03-25-150003_crate__issue_priority_type/down.sql b/migrations/2020-03-25-150003_crate__issue_priority_type/down.sql index db135684..5bf9f100 100644 --- a/migrations/2020-03-25-150003_crate__issue_priority_type/down.sql +++ b/migrations/2020-03-25-150003_crate__issue_priority_type/down.sql @@ -1 +1 @@ -DROP TYPE IF EXISTS "IssuePriority" CASCADE; +DROP TYPE IF EXISTS "IssuePriorityMapping" CASCADE; diff --git a/migrations/2020-03-25-150003_crate__issue_priority_type/up.sql b/migrations/2020-03-25-150003_crate__issue_priority_type/up.sql index af7715cf..f7df0d22 100644 --- a/migrations/2020-03-25-150003_crate__issue_priority_type/up.sql +++ b/migrations/2020-03-25-150003_crate__issue_priority_type/up.sql @@ -1,5 +1,5 @@ -DROP TYPE IF EXISTS "IssuePriority" CASCADE; -CREATE TYPE "IssuePriority" as ENUM ( +DROP TYPE IF EXISTS "IssuePriorityMapping" CASCADE; +CREATE TYPE "IssuePriorityMapping" as ENUM ( 'highest', 'high', 'medium', diff --git a/migrations/2020-03-25-150004_create__issue_type_type/down.sql b/migrations/2020-03-25-150004_create__issue_type_type/down.sql index d8077f66..c0cf5773 100644 --- a/migrations/2020-03-25-150004_create__issue_type_type/down.sql +++ b/migrations/2020-03-25-150004_create__issue_type_type/down.sql @@ -1 +1 @@ -DROP TYPE IF EXISTS "IssueType" CASCADE; +DROP TYPE IF EXISTS "IssueTypeMapping" CASCADE; diff --git a/migrations/2020-03-25-150004_create__issue_type_type/up.sql b/migrations/2020-03-25-150004_create__issue_type_type/up.sql index d569033e..d13e7e29 100644 --- a/migrations/2020-03-25-150004_create__issue_type_type/up.sql +++ b/migrations/2020-03-25-150004_create__issue_type_type/up.sql @@ -1,5 +1,5 @@ -DROP TYPE IF EXISTS "IssueType" CASCADE; -CREATE TYPE "IssueType" AS ENUM ( +DROP TYPE IF EXISTS "IssueTypeMapping" CASCADE; +CREATE TYPE "IssueTypeMapping" AS ENUM ( 'task', 'bug', 'story' diff --git a/migrations/2020-03-25-150005_create__issue_status/down.sql b/migrations/2020-03-25-150005_create__issue_status/down.sql index f6added6..fb2d34a7 100644 --- a/migrations/2020-03-25-150005_create__issue_status/down.sql +++ b/migrations/2020-03-25-150005_create__issue_status/down.sql @@ -1 +1 @@ -DROP TYPE IF EXISTS "IssueStatus" CASCADE; +DROP TYPE IF EXISTS "IssueStatusMapping" CASCADE; diff --git a/migrations/2020-03-25-150005_create__issue_status/up.sql b/migrations/2020-03-25-150005_create__issue_status/up.sql index f599f5dc..d1299f0e 100644 --- a/migrations/2020-03-25-150005_create__issue_status/up.sql +++ b/migrations/2020-03-25-150005_create__issue_status/up.sql @@ -1,5 +1,5 @@ -DROP TYPE IF EXISTS "IssueStatus" CASCADE; -CREATE TYPE "IssueStatus" AS ENUM ( +DROP TYPE IF EXISTS "IssueStatusMapping" CASCADE; +CREATE TYPE "IssueStatusMapping" AS ENUM ( 'backlog', 'selected', 'in_progress', diff --git a/migrations/2020-03-25-150008_create_issues/up.sql b/migrations/2020-03-25-150008_create_issues/up.sql index bc809202..bfd4928f 100644 --- a/migrations/2020-03-25-150008_create_issues/up.sql +++ b/migrations/2020-03-25-150008_create_issues/up.sql @@ -1,9 +1,9 @@ CREATE TABLE issues ( id serial primary key not null, title text not null, - issue_type "IssueType" NOT NULL DEFAULT 'task', - status "IssueStatus" NOT NULL DEFAULT 'backlog', - priority "IssuePriority" NOT NULL DEFAULT 'low', + issue_type "IssueTypeMapping" NOT NULL DEFAULT 'task', + status "IssueStatusMapping" NOT NULL DEFAULT 'backlog', + priority "IssuePriorityMapping" NOT NULL DEFAULT 'low', list_position double precision not null default 0, description text, description_text text, diff --git a/migrations/2020-04-14-090059_change_project_type_field/up.sql b/migrations/2020-04-14-090059_change_project_type_field/up.sql index 6451a772..3c7e7199 100644 --- a/migrations/2020-04-14-090059_change_project_type_field/up.sql +++ b/migrations/2020-04-14-090059_change_project_type_field/up.sql @@ -4,8 +4,8 @@ DROP DEFAULT; ALTER TABLE projects ALTER COLUMN category -SET DATA TYPE "ProjectCategory" -USING category::text::"ProjectCategory"; +SET DATA TYPE "ProjectCategoryMapping" +USING category::text::"ProjectCategoryMapping"; ALTER TABLE projects ALTER COLUMN category diff --git a/migrations/2020-04-20-071751_add_roles/down.sql b/migrations/2020-04-20-071751_add_roles/down.sql index 220ff369..b29a4674 100644 --- a/migrations/2020-04-20-071751_add_roles/down.sql +++ b/migrations/2020-04-20-071751_add_roles/down.sql @@ -1,2 +1,2 @@ ALTER TABLE IF EXISTS users DROP COLUMN role; -DROP TYPE IF EXISTS "UserRole"; +DROP TYPE IF EXISTS "UserRoleMapping"; diff --git a/migrations/2020-04-20-071751_add_roles/up.sql b/migrations/2020-04-20-071751_add_roles/up.sql index 4a3a4b3d..bbd31acc 100644 --- a/migrations/2020-04-20-071751_add_roles/up.sql +++ b/migrations/2020-04-20-071751_add_roles/up.sql @@ -1,8 +1,8 @@ -DROP TYPE IF EXISTS "UserRole" CASCADE; -CREATE TYPE "UserRole" AS ENUM ( +DROP TYPE IF EXISTS "UserRoleMapping" CASCADE; +CREATE TYPE "UserRoleMapping" AS ENUM ( 'user', 'manager', 'owner' ); -ALTER TABLE users ADD COLUMN role "UserRole" DEFAULT 'user' NOT NULL; +ALTER TABLE users ADD COLUMN role "UserRoleMapping" DEFAULT 'user' NOT NULL; diff --git a/migrations/2020-04-20-172406_create_invitations/down.sql b/migrations/2020-04-20-172406_create_invitations/down.sql index 118a2e13..1cb78dad 100644 --- a/migrations/2020-04-20-172406_create_invitations/down.sql +++ b/migrations/2020-04-20-172406_create_invitations/down.sql @@ -1,2 +1,2 @@ drop TABLE IF EXISTS invitations CASCADE; -drop TYPE IF EXISTS "InvitationState" CASCADE; +drop TYPE IF EXISTS "InvitationStateMapping" CASCADE; diff --git a/migrations/2020-04-20-172406_create_invitations/up.sql b/migrations/2020-04-20-172406_create_invitations/up.sql index 9f85a86e..559aae19 100644 --- a/migrations/2020-04-20-172406_create_invitations/up.sql +++ b/migrations/2020-04-20-172406_create_invitations/up.sql @@ -1,4 +1,4 @@ -create type "InvitationState" AS ENUM ( +create type "InvitationStateMapping" AS ENUM ( 'sent', 'accepted', 'revoked' @@ -8,7 +8,7 @@ create table invitations ( id serial primary key not null, name text not null, email text not null, - state "InvitationState" not null default 'sent', + state "InvitationStateMapping" not null default 'sent', project_id integer not null references projects (id), invited_by_id integer not null references users (id), created_at timestamp not null default now(), diff --git a/migrations/2020-04-24-163323_add_settings/down.sql b/migrations/2020-04-24-163323_add_settings/down.sql index 76d05b9c..063fc885 100644 --- a/migrations/2020-04-24-163323_add_settings/down.sql +++ b/migrations/2020-04-24-163323_add_settings/down.sql @@ -1,3 +1,3 @@ alter TABLE projects drop COLUMN time_tracking; -drop TYPE IF EXISTS "TimeTracking"; +drop TYPE IF EXISTS "TimeTrackingMapping"; diff --git a/migrations/2020-04-24-163323_add_settings/up.sql b/migrations/2020-04-24-163323_add_settings/up.sql index 96f12910..64b23bda 100644 --- a/migrations/2020-04-24-163323_add_settings/up.sql +++ b/migrations/2020-04-24-163323_add_settings/up.sql @@ -1,7 +1,7 @@ -CREATE TYPE "TimeTracking" AS ENUM ( +CREATE TYPE "TimeTrackingMapping" AS ENUM ( 'untracked', 'fibonacci', 'hourly' ); -ALTER TABLE projects ADD COLUMN time_tracking "TimeTracking" NOT NULL DEFAULT 'untracked'; +ALTER TABLE projects ADD COLUMN time_tracking "TimeTrackingMapping" NOT NULL DEFAULT 'untracked'; diff --git a/migrations/2020-05-06-130610_add_custom_columns/down.sql b/migrations/2020-05-06-130610_add_custom_columns/down.sql index 2a5a59c9..aae6d684 100644 --- a/migrations/2020-05-06-130610_add_custom_columns/down.sql +++ b/migrations/2020-05-06-130610_add_custom_columns/down.sql @@ -1,13 +1,13 @@ -DROP TYPE IF EXISTS "IssueStatus" CASCADE; -CREATE TYPE "IssueStatus" AS ENUM ( +DROP TYPE IF EXISTS "IssueStatusMapping" CASCADE; +CREATE TYPE "IssueStatusMapping" AS ENUM ( 'backlog', 'selected', 'in_progress', 'done' ); -ALTER TABLE issues ADD COLUMN status "IssueStatus"; +ALTER TABLE issues ADD COLUMN status "IssueStatusMapping"; UPDATE issues -SET status = issue_statuses.name :: "IssueStatus" +SET status = issue_statuses.name :: "IssueStatusMapping" FROM issue_statuses WHERE issue_statuses.id = issues.issue_status_id; diff --git a/migrations/2020-05-06-130610_add_custom_columns/up.sql b/migrations/2020-05-06-130610_add_custom_columns/up.sql index b375f591..6dc09ab4 100644 --- a/migrations/2020-05-06-130610_add_custom_columns/up.sql +++ b/migrations/2020-05-06-130610_add_custom_columns/up.sql @@ -34,4 +34,4 @@ WHERE issue_statuses.name = issues.status :: text AND issues.project_id = issue_ ALTER TABLE issues DROP COLUMN status; ALTER TABLE issues ALTER COLUMN issue_status_id SET NOT NULL; -DROP TYPE IF EXISTS "IssueStatus"; +DROP TYPE IF EXISTS "IssueStatusMapping"; diff --git a/migrations/2020-05-21-051229_multi_project_users/down.sql b/migrations/2020-05-21-051229_multi_project_users/down.sql index 7110544e..67cea15f 100644 --- a/migrations/2020-05-21-051229_multi_project_users/down.sql +++ b/migrations/2020-05-21-051229_multi_project_users/down.sql @@ -1,6 +1,6 @@ BEGIN; -ALTER TABLE users ADD COLUMN role "UserRole" DEFAULT 'user' NOT NULL; +ALTER TABLE users ADD COLUMN role "UserRoleMapping" DEFAULT 'user' NOT NULL; ALTER TABLE users ADD COLUMN project_id int; UPDATE users diff --git a/migrations/2020-05-21-051229_multi_project_users/up.sql b/migrations/2020-05-21-051229_multi_project_users/up.sql index 3c3e7678..39657662 100644 --- a/migrations/2020-05-21-051229_multi_project_users/up.sql +++ b/migrations/2020-05-21-051229_multi_project_users/up.sql @@ -7,7 +7,7 @@ CREATE TABLE user_projects ( project_id int not null references projects (id), is_default bool not null default false, is_current bool not null default false, - role "UserRole" not null default 'user', + role "UserRoleMapping" not null default 'user', created_at timestamp not null default now(), updated_at timestamp not null default now() ); diff --git a/migrations/2020-05-21-160206_add_role_to_invitation/up.sql b/migrations/2020-05-21-160206_add_role_to_invitation/up.sql index 30fdac5f..228129cb 100644 --- a/migrations/2020-05-21-160206_add_role_to_invitation/up.sql +++ b/migrations/2020-05-21-160206_add_role_to_invitation/up.sql @@ -1 +1 @@ -ALTER TABLE invitations ADD COLUMN role "UserRole" NOT NULL DEFAULT 'user'; +ALTER TABLE invitations ADD COLUMN role "UserRoleMapping" NOT NULL DEFAULT 'user'; diff --git a/migrations/2020-05-24-081604_add_message_types/down.sql b/migrations/2020-05-24-081604_add_message_types/down.sql index e1195b15..1e83121a 100644 --- a/migrations/2020-05-24-081604_add_message_types/down.sql +++ b/migrations/2020-05-24-081604_add_message_types/down.sql @@ -1,4 +1,4 @@ ALTER TABLE messages ALTER COLUMN message_type SET DATA TYPE text; -DROP TYPE "MessageType"; +DROP TYPE "MessageTypeMapping"; diff --git a/migrations/2020-05-24-081604_add_message_types/up.sql b/migrations/2020-05-24-081604_add_message_types/up.sql index 9008d516..f01cdf0a 100644 --- a/migrations/2020-05-24-081604_add_message_types/up.sql +++ b/migrations/2020-05-24-081604_add_message_types/up.sql @@ -1,4 +1,4 @@ -CREATE TYPE "MessageType" AS ENUM ( +CREATE TYPE "MessageTypeMapping" AS ENUM ( 'received_invitation', 'assigned_to_issue', 'mention' @@ -6,5 +6,5 @@ CREATE TYPE "MessageType" AS ENUM ( ALTER TABLE messages ALTER COLUMN message_type -SET DATA TYPE "MessageType" -USING message_type::text::"MessageType"; +SET DATA TYPE "MessageTypeMapping" +USING message_type::text::"MessageTypeMapping"; diff --git a/migrations/2020-08-10-133733_add_epic_issue_type/down.sql b/migrations/2020-08-10-133733_add_epic_issue_type/down.sql index 644f3c4e..79e3897d 100644 --- a/migrations/2020-08-10-133733_add_epic_issue_type/down.sql +++ b/migrations/2020-08-10-133733_add_epic_issue_type/down.sql @@ -7,8 +7,8 @@ UPDATE "issues" SET "issue_type" = 'task' WHERE "issue_type" = 'epic'; -DROP TYPE IF EXISTS "IssueType" CASCADE; -CREATE TYPE "IssueType" AS ENUM ( +DROP TYPE IF EXISTS "IssueTypeMapping" CASCADE; +CREATE TYPE "IssueTypeMapping" AS ENUM ( 'task', 'bug', 'story' @@ -16,5 +16,5 @@ CREATE TYPE "IssueType" AS ENUM ( ALTER TABLE "issues" ALTER COLUMN "issue_type" - SET DATA TYPE "IssueType" - USING "issue_type"::"IssueType"; + SET DATA TYPE "IssueTypeMapping" + USING "issue_type"::"IssueTypeMapping"; diff --git a/migrations/2020-08-10-133733_add_epic_issue_type/up.sql b/migrations/2020-08-10-133733_add_epic_issue_type/up.sql index e6dce4cb..399c43c1 100644 --- a/migrations/2020-08-10-133733_add_epic_issue_type/up.sql +++ b/migrations/2020-08-10-133733_add_epic_issue_type/up.sql @@ -3,8 +3,8 @@ ALTER TABLE "issues" SET DATA TYPE TEXT USING "issue_type"::TEXT; -DROP TYPE IF EXISTS "IssueType" CASCADE; -CREATE TYPE "IssueType" AS ENUM ( +DROP TYPE IF EXISTS "IssueTypeMapping" CASCADE; +CREATE TYPE "IssueTypeMapping" AS ENUM ( 'task', 'bug', 'story', @@ -13,5 +13,5 @@ CREATE TYPE "IssueType" AS ENUM ( ALTER TABLE "issues" ALTER COLUMN "issue_type" - SET DATA TYPE "IssueType" - USING "issue_type"::"IssueType"; + SET DATA TYPE "IssueTypeMapping" + USING "issue_type"::"IssueTypeMapping"; diff --git a/migrations/2020-08-10-194809_change_epic/down.sql b/migrations/2020-08-10-194809_change_epic/down.sql index 1b807727..7216c82a 100644 --- a/migrations/2020-08-10-194809_change_epic/down.sql +++ b/migrations/2020-08-10-194809_change_epic/down.sql @@ -3,8 +3,8 @@ ALTER TABLE "issues" SET DATA TYPE TEXT USING "issue_type"::TEXT; -DROP TYPE IF EXISTS "IssueType" CASCADE; -CREATE TYPE "IssueType" AS ENUM ( +DROP TYPE IF EXISTS "IssueTypeMapping" CASCADE; +CREATE TYPE "IssueTypeMapping" AS ENUM ( 'task', 'bug', 'story', @@ -13,8 +13,8 @@ CREATE TYPE "IssueType" AS ENUM ( ALTER TABLE "issues" ALTER COLUMN "issue_type" - SET DATA TYPE "IssueType" - USING "issue_type"::"IssueType"; + SET DATA TYPE "IssueTypeMapping" + USING "issue_type"::"IssueTypeMapping"; ALTER TABLE "issues" DROP COLUMN "epic_id"; diff --git a/migrations/2020-08-10-194809_change_epic/up.sql b/migrations/2020-08-10-194809_change_epic/up.sql index 4c001fda..11858e4b 100644 --- a/migrations/2020-08-10-194809_change_epic/up.sql +++ b/migrations/2020-08-10-194809_change_epic/up.sql @@ -7,8 +7,8 @@ UPDATE "issues" SET "issue_type" = 'task' WHERE "issue_type" = 'epic'; -DROP TYPE IF EXISTS "IssueType" CASCADE; -CREATE TYPE "IssueType" AS ENUM ( +DROP TYPE IF EXISTS "IssueTypeMapping" CASCADE; +CREATE TYPE "IssueTypeMapping" AS ENUM ( 'task', 'bug', 'story' @@ -16,8 +16,8 @@ CREATE TYPE "IssueType" AS ENUM ( ALTER TABLE "issues" ALTER COLUMN "issue_type" - SET DATA TYPE "IssueType" - USING "issue_type"::"IssueType"; + SET DATA TYPE "IssueTypeMapping" + USING "issue_type"::"IssueTypeMapping"; CREATE TABLE epics ( id serial primary key not null, diff --git a/migrations/2021-04-26-100410_add_user_settings/down.sql b/migrations/2021-04-26-100410_add_user_settings/down.sql index b9c94475..19c20608 100644 --- a/migrations/2021-04-26-100410_add_user_settings/down.sql +++ b/migrations/2021-04-26-100410_add_user_settings/down.sql @@ -1,2 +1,2 @@ DROP TABLE IF EXISTS user_settings; -DROP TYPE "TextEditorMode"; +DROP TYPE "TextEditorModeMapping"; diff --git a/migrations/2021-04-26-100410_add_user_settings/up.sql b/migrations/2021-04-26-100410_add_user_settings/up.sql index 7b051276..4d235309 100644 --- a/migrations/2021-04-26-100410_add_user_settings/up.sql +++ b/migrations/2021-04-26-100410_add_user_settings/up.sql @@ -1,4 +1,4 @@ -CREATE TYPE "TextEditorMode" AS ENUM ( +CREATE TYPE "TextEditorModeMapping" AS ENUM ( 'md_only', 'rte_only', 'mixed' @@ -8,5 +8,5 @@ CREATE TABLE IF NOT EXISTS user_settings ( id serial not null unique primary key, user_id int references users (id) not null, - text_editor_mode "TextEditorMode" DEFAULT 'md_only' NOT NULL + text_editor_mode "TextEditorModeMapping" DEFAULT 'md_only' NOT NULL );