diff --git a/mediarepo-daemon/Cargo.lock b/mediarepo-daemon/Cargo.lock index 20be5d8..b7bfd18 100644 --- a/mediarepo-daemon/Cargo.lock +++ b/mediarepo-daemon/Cargo.lock @@ -91,6 +91,95 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote 1.0.18", + "syn 1.0.92", +] + +[[package]] +name = "async-channel" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c290043c9a95b05d45e952fb6383c67bcb61471f60cfa21e890dba6654234f43" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-mutex", + "blocking", + "futures-lite", + "num_cpus", + "once_cell", + "tokio", +] + +[[package]] +name = "async-io" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" +dependencies = [ + "concurrent-queue", + "futures-lite", + "libc", + "log", + "once_cell", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "winapi", +] + +[[package]] +name = "async-lock" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + [[package]] name = "async-recursion" version = "1.0.0" @@ -102,6 +191,34 @@ dependencies = [ "syn 1.0.92", ] +[[package]] +name = "async-std" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52580991739c5cdb36cde8b2a516371c0a3b70dda36d916cc08b82372916808c" +dependencies = [ + "async-attributes", + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils 0.8.8", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "num_cpus", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + [[package]] name = "async-stream" version = "0.3.3" @@ -123,6 +240,12 @@ dependencies = [ "syn 1.0.92", ] +[[package]] +name = "async-task" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" + [[package]] name = "async-trait" version = "0.1.53" @@ -143,6 +266,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + [[package]] name = "atty" version = "0.2.14" @@ -329,6 +458,20 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "blocking" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" +dependencies = [ + "async-channel", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "once_cell", +] + [[package]] name = "bromine" version = "0.21.0" @@ -385,6 +528,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "cache-padded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" + [[package]] name = "cc" version = "1.0.73" @@ -481,6 +630,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "120133d4db2ec47efe2e26502ee984747630c67f51974fca0b6c1340cf2368d3" +[[package]] +name = "concurrent-queue" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +dependencies = [ + "cache-padded", +] + [[package]] name = "config" version = "0.13.1" @@ -682,6 +840,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctor" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +dependencies = [ + "quote 1.0.18", + "syn 1.0.92", +] + [[package]] name = "curve25519-dalek" version = "3.2.1" @@ -951,6 +1119,21 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.21" @@ -1057,6 +1240,18 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "gloo-timers" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "h2" version = "0.3.13" @@ -1376,6 +1571,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1437,6 +1641,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if 1.0.0", + "value-bag", ] [[package]] @@ -1629,6 +1834,13 @@ dependencies = [ "syn 1.0.92", ] +[[package]] +name = "migration" +version = "0.1.0" +dependencies = [ + "sea-schema", +] + [[package]] name = "mime" version = "0.3.16" @@ -2038,6 +2250,12 @@ dependencies = [ "syn 1.0.92", ] +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + [[package]] name = "parking_lot" version = "0.11.2" @@ -2174,6 +2392,19 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "log", + "wepoll-ffi", + "winapi", +] + [[package]] name = "poly1305" version = "0.7.2" @@ -2518,7 +2749,7 @@ dependencies = [ "ouroboros", "rust_decimal", "sea-orm-macros", - "sea-query", + "sea-query 0.23.0", "sea-strum", "serde", "serde_json", @@ -2542,6 +2773,15 @@ dependencies = [ "syn 1.0.92", ] +[[package]] +name = "sea-query" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727090e8d1e61edd07305d237664315226748ad559e16daa6293fa26c4e7a3c3" +dependencies = [ + "sea-query-derive", +] + [[package]] name = "sea-query" version = "0.23.0" @@ -2569,6 +2809,36 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sea-schema" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d492f4550a428d2be29e4df8e43b2e9e46717424c9603fafa3365ae6079bd73" +dependencies = [ + "async-std", + "async-trait", + "clap", + "dotenv", + "log", + "sea-orm", + "sea-query 0.22.0", + "sea-schema-derive", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "sea-schema-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56821b7076f5096b8f726e2791ad255a99c82498e08ec477a65a96c461ff1927" +dependencies = [ + "heck 0.3.3", + "proc-macro2 1.0.38", + "quote 1.0.18", + "syn 1.0.92", +] + [[package]] name = "sea-strum" version = "0.23.0" @@ -3655,6 +3925,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-bag" +version = "1.0.0-alpha.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" +dependencies = [ + "ctor", + "version_check", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -3673,6 +3953,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "want" version = "0.3.0" @@ -3726,6 +4012,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.80" @@ -3755,6 +4053,16 @@ version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +[[package]] +name = "web-sys" +version = "0.3.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webp" version = "0.2.2" @@ -3771,6 +4079,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4" +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/mediarepo-daemon/Cargo.toml b/mediarepo-daemon/Cargo.toml index 7954b54..eeb6ea2 100644 --- a/mediarepo-daemon/Cargo.toml +++ b/mediarepo-daemon/Cargo.toml @@ -1,6 +1,5 @@ [workspace] -members = ["mediarepo-core", "mediarepo-database", "mediarepo-logic", "mediarepo-socket", "mediarepo-worker", "."] -default-members = ["mediarepo-core", "mediarepo-database", "mediarepo-logic", "mediarepo-socket", "mediarepo-worker", "."] +members = ["mediarepo-core", "mediarepo-database", "mediarepo-database/migration", "mediarepo-logic", "mediarepo-socket", "mediarepo-worker", "."] [package] name = "mediarepo-daemon" diff --git a/mediarepo-daemon/mediarepo-database/migration/Cargo.toml b/mediarepo-daemon/mediarepo-database/migration/Cargo.toml new file mode 100644 index 0000000..73d34bf --- /dev/null +++ b/mediarepo-daemon/mediarepo-database/migration/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "migration" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +name = "migration" +path = "src/lib.rs" + +[dependencies] +sea-schema = { version = "^0.7.0", default-features = false, features = [ "migration", "debug-print" ] } diff --git a/mediarepo-daemon/mediarepo-database/migration/README.md b/mediarepo-daemon/mediarepo-database/migration/README.md new file mode 100644 index 0000000..963caae --- /dev/null +++ b/mediarepo-daemon/mediarepo-database/migration/README.md @@ -0,0 +1,37 @@ +# Running Migrator CLI + +- Apply all pending migrations + ```sh + cargo run + ``` + ```sh + cargo run -- up + ``` +- Apply first 10 pending migrations + ```sh + cargo run -- up -n 10 + ``` +- Rollback last applied migrations + ```sh + cargo run -- down + ``` +- Rollback last 10 applied migrations + ```sh + cargo run -- down -n 10 + ``` +- Drop all tables from the database, then reapply all migrations + ```sh + cargo run -- fresh + ``` +- Rollback all applied migrations, then reapply all migrations + ```sh + cargo run -- refresh + ``` +- Rollback all applied migrations + ```sh + cargo run -- reset + ``` +- Check the status of all migrations + ```sh + cargo run -- status + ``` diff --git a/mediarepo-daemon/mediarepo-database/migration/src/lib.rs b/mediarepo-daemon/mediarepo-database/migration/src/lib.rs new file mode 100644 index 0000000..3cabe22 --- /dev/null +++ b/mediarepo-daemon/mediarepo-database/migration/src/lib.rs @@ -0,0 +1,12 @@ +pub use sea_schema::migration::prelude::*; + +mod m20220101_000001_create_table; + +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![Box::new(m20220101_000001_create_table::Migration)] + } +} diff --git a/mediarepo-daemon/mediarepo-database/migration/src/m20220101_000001_create_table.rs b/mediarepo-daemon/mediarepo-database/migration/src/m20220101_000001_create_table.rs new file mode 100644 index 0000000..f9ae846 --- /dev/null +++ b/mediarepo-daemon/mediarepo-database/migration/src/m20220101_000001_create_table.rs @@ -0,0 +1,296 @@ +use crate::async_std::task::Task; +use crate::sea_orm::tests_cfg::cake_filling::PrimaryKey; +use sea_schema::migration::prelude::*; + +pub struct Migration; + +impl MigrationName for Migration { + fn name(&self) -> &str { + "m20220101_000001_create_table" + } +} + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager.create_table(create_content_descriptors()).await?; + manager.create_table(create_files()).await?; + manager.create_table(create_file_metadata()).await?; + manager.create_table(create_namespaces()).await?; + manager.create_table(create_tags()).await?; + manager.create_table(create_cd_tag_mappings()).await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + todo!() + } +} + +fn create_file_metadata() -> TableCreateStatement { + Table::create() + .if_not_exists() + .table(FileMetadata::Table) + .col( + ColumnDef::new(FileMetadata::FileId) + .big_integer() + .not_null() + .primary_key(), + ) + .col(ColumnDef::new(FileMetadata::Size).integer().not_null()) + .col(ColumnDef::new(FileMetadata::Name).string_len(128)) + .col(ColumnDef::new(FileMetadata::Comment).string_len(1024)) + .col( + ColumnDef::new(FileMetadata::ImportTime) + .date_time() + .not_null(), + ) + .col( + ColumnDef::new(FileMetadata::CreationTime) + .date_time() + .not_null(), + ) + .col( + ColumnDef::new(FileMetadata::ChangeTime) + .date_time() + .not_null(), + ) + .foreign_key( + ForeignKey::create() + .from(FileMetadata::Table, FileMetadata::FileId) + .to(Files::Table, Files::Id), + ) + .to_owned() +} + +fn create_files() -> TableCreateStatement { + Table::create() + .if_not_exists() + .table(Files::Table) + .col( + ColumnDef::new(Files::Id) + .big_integer() + .primary_key() + .auto_increment(), + ) + .col( + ColumnDef::new(Files::Status) + .integer() + .default(10) + .not_null(), + ) + .col(ColumnDef::new(Files::CdId).big_integer().not_null()) + .col( + ColumnDef::new(Files::MimeType) + .string_len(128) + .default("application/octet-stream") + .not_null(), + ) + .foreign_key( + ForeignKey::create() + .from(Files::Table, Files::CdId) + .to(ContentDescriptors::Table, ContentDescriptors::Id), + ) + .index(Index::create().table(Files::Table).col(Files::CdId)) + .to_owned() +} + +fn create_content_descriptors() -> TableCreateStatement { + Table::create() + .if_not_exists() + .table(ContentDescriptors::Table) + .col( + ColumnDef::new(ContentDescriptors::Id) + .big_integer() + .primary_key() + .auto_increment(), + ) + .col( + ColumnDef::new(ContentDescriptors::Descriptor) + .binary() + .unique_key(), + ) + .to_owned() +} + +fn create_tags() -> TableCreateStatement { + Table::create() + .if_not_exists() + .table(Tags::Table) + .col( + ColumnDef::new(Tags::Id) + .integer() + .primary_key() + .auto_increment(), + ) + .col(ColumnDef::new(Tags::NamespaceId).big_integer()) + .col(ColumnDef::new(Tags::Name).string_len(128).not_null()) + .foreign_key( + ForeignKey::create() + .from(Tags::Table, Tags::NamespaceId) + .to(Namespaces::Table, Namespaces::Id), + ) + .index( + Index::create() + .table(Tags::Table) + .col(Tags::Name) + .full_text(), + ) + .index( + Index::create() + .unique() + .table(Tags::Table) + .col(Tags::NamespaceId) + .col(Tags::Name), + ) + .to_owned() +} + +fn create_cd_tag_mappings() -> TableCreateStatement { + Table::create() + .if_not_exists() + .table(CdTagMappings::Table) + .col(ColumnDef::new(CdTagMappings::CdId).big_integer().not_null()) + .col( + ColumnDef::new(CdTagMappings::TagId) + .big_integer() + .not_null(), + ) + .primary_key( + Index::create() + .table(CdTagMappings::TagId) + .col(CdTagMappings::CdId) + .col(CdTagMappings::TagId), + ) + .foreign_key( + ForeignKey::create() + .from(CdTagMappings::Table, CdTagMappings::CdId) + .to(ContentDescriptors::Table, ContentDescriptors::Id), + ) + .foreign_key( + ForeignKey::create() + .from(CdTagMappings::Table, CdTagMappings::TagId) + .to(Tags::Table, Tags::Id), + ) + .index( + Index::create() + .table(CdTagMappings::Table) + .col(CdTagMappings::TagId), + ) + .to_owned() +} + +fn create_namespaces() -> TableCreateStatement { + Table::create() + .if_not_exists() + .table(Namespaces::Table) + .col( + ColumnDef::new(Namespaces::Id) + .big_integer() + .primary_key() + .auto_increment(), + ) + .col(ColumnDef::new(Namespaces::Name).string_len(128).not_null()) + .index( + Index::create() + .unique() + .table(Namespaces::Table) + .col(Namespaces::Name) + .full_text(), + ) + .to_owned() +} + +#[derive(Iden)] +enum FileMetadata { + Table, + FileId, + Size, + Name, + Comment, + ImportTime, + CreationTime, + ChangeTime, +} + +#[derive(Iden)] +enum Files { + Table, + Id, + Status, + CdId, + MimeType, +} + +#[derive(Iden)] +enum ContentDescriptors { + Table, + Id, + Descriptor, +} + +#[derive(Iden)] +enum Tags { + Table, + Id, + NamespaceId, + Name, +} + +#[derive(Iden)] +enum CdTagMappings { + Table, + CdId, + TagId, +} + +#[derive(Iden)] +enum Namespaces { + Table, + Id, + Name, +} + +#[derive(Iden)] +enum Sources { + Table, + Id, + Url, +} + +#[derive(Iden)] +enum CdSourceMapping { + Table, + CdId, + SourceId, +} + +#[derive(Iden)] +enum SortingPreset { + Table, + Id, +} + +#[derive(Iden)] +enum SortKeys { + Table, + KeyType, + Ascending, + Value, +} + +#[derive(Iden)] +enum SortingPresetKey { + Table, + PresetId, + KeyId, + KeyIndex, +} + +#[derive(Iden)] +enum JobStates { + Table, + JobType, + Value, +} diff --git a/mediarepo-daemon/mediarepo-database/migration/src/main.rs b/mediarepo-daemon/mediarepo-database/migration/src/main.rs new file mode 100644 index 0000000..89b349c --- /dev/null +++ b/mediarepo-daemon/mediarepo-database/migration/src/main.rs @@ -0,0 +1,7 @@ +use migration::Migrator; +use sea_schema::migration::prelude::*; + +#[async_std::main] +async fn main() { + cli::run_cli(Migrator).await; +}