Merge pull request #26 from Trivernis/feature/rust-migrations

Feature/rust migrations
develop
Julius Riegel 2 years ago committed by GitHub
commit baab3a25c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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]]
@ -1538,6 +1743,7 @@ version = "0.2.0"
dependencies = [
"chrono",
"mediarepo-core",
"migration",
"sea-orm",
"sqlx",
"tracing",
@ -1629,6 +1835,13 @@ dependencies = [
"syn 1.0.92",
]
[[package]]
name = "migration"
version = "0.1.0"
dependencies = [
"sea-orm-migration",
]
[[package]]
name = "mime"
version = "0.3.16"
@ -2038,6 +2251,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 +2393,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"
@ -2505,9 +2737,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sea-orm"
version = "0.7.1"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27dbb8a742003f8dbf2ba290d128134d4275a6b55fd02f4d728683b6b55ea9bf"
checksum = "51de529763804dd4f74c133055f53eccdda2221bdded94351009be28cc80d2fb"
dependencies = [
"async-stream",
"async-trait",
@ -2529,11 +2761,28 @@ dependencies = [
"uuid",
]
[[package]]
name = "sea-orm-cli"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fca862fdba12c753bffba9c9adf95d3d3f5dcc82fd589b12faeee7068bb173d5"
dependencies = [
"async-std",
"chrono",
"clap",
"dotenv",
"regex",
"sea-schema",
"tracing",
"tracing-subscriber",
"url",
]
[[package]]
name = "sea-orm-macros"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953bf5fb9f6ec985c139c4a98550b600c2f7c97bea74e2acc4025438469cb5a2"
checksum = "9f9378e21366b119d281489013c8170c49972fd3709c2155eb4504a913715d2d"
dependencies = [
"bae",
"heck 0.3.3",
@ -2542,15 +2791,32 @@ dependencies = [
"syn 1.0.92",
]
[[package]]
name = "sea-orm-migration"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15589f057677f57bea393572bd8eb9e8feb843a5f09b4fa518be6cef3a6ffedc"
dependencies = [
"async-trait",
"clap",
"dotenv",
"sea-orm",
"sea-orm-cli",
"sea-schema",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "sea-query"
version = "0.23.0"
version = "0.24.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf24fc03259e206d8cd4c957ce7446fe54ab00ba5ada4cdb028aa3513e26231"
checksum = "6b0fa62db5ae33dfc61e805b0b0c9d579c3733f1ed90326b3779f5b38f30fa2a"
dependencies = [
"chrono",
"rust_decimal",
"sea-query-derive",
"sea-query-driver",
"serde_json",
"time 0.2.27",
"uuid",
@ -2569,6 +2835,40 @@ dependencies = [
"thiserror",
]
[[package]]
name = "sea-query-driver"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3953baee94dcb90f0e19e8b4b91b91e9394867b0fc1886d0221cfc6d0439f5"
dependencies = [
"proc-macro2 1.0.38",
"quote 1.0.18",
"syn 1.0.92",
]
[[package]]
name = "sea-schema"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09fea4b9dccc8b0667f108de2d09bdabd42a137b8437de092374a4e36de8c12f"
dependencies = [
"futures 0.3.21",
"sea-query",
"sea-schema-derive",
]
[[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 +3955,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 +3983,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 +4042,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 +4083,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 +4109,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"

@ -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"

@ -25,7 +25,7 @@ tracing-subscriber = "0.3.11"
trait-bound-typemap = "0.3.3"
[dependencies.sea-orm]
version = "0.7.1"
version = "0.8.0"
default-features = false
[dependencies.sqlx]

@ -18,6 +18,9 @@ version = "0.5.13"
features = ["migrate"]
[dependencies.sea-orm]
version = "0.7.1"
version = "0.8.0"
features = ["sqlx-sqlite", "runtime-tokio-native-tls", "macros"]
default-features = false
[dependencies.migration]
path = "./migration"

@ -0,0 +1,12 @@
[package]
name = "migration"
version = "0.1.0"
edition = "2021"
publish = false
[lib]
name = "migration"
path = "src/lib.rs"
[dependencies]
sea-orm-migration = "0.8.3"

@ -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
```

@ -0,0 +1,13 @@
pub use sea_orm_migration::prelude::*;
mod m20220101_000001_create_table;
mod utils;
pub struct Migrator;
#[async_trait::async_trait]
impl MigratorTrait for Migrator {
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
vec![Box::new(m20220101_000001_create_table::Migration)]
}
}

@ -0,0 +1,490 @@
use crate::drop_tables;
use sea_orm_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?;
manager.create_table(create_sources()).await?;
manager.create_table(create_cd_sources_mappings()).await?;
manager.create_table(create_sorting_presets()).await?;
manager.create_table(create_sort_keys()).await?;
manager.create_table(create_sorting_preset_key()).await?;
manager.create_table(create_job_states()).await?;
manager
.create_index(
Index::create()
.name("index_files_cd_id")
.table(Files::Table)
.col(Files::CdId)
.to_owned(),
)
.await?;
manager
.create_index(
Index::create()
.name("index_tags_name")
.table(Tags::Table)
.col(Tags::Name)
.full_text()
.to_owned(),
)
.await?;
manager
.create_index(
Index::create()
.name("index_cd_tag_mappings_tag_id")
.table(CdTagMappings::Table)
.col(CdTagMappings::TagId)
.to_owned(),
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
drop_tables!(
manager,
ContentDescriptors::Table,
Files::Table,
FileMetadata::Table,
Namespaces::Table,
Tags::Table,
CdTagMappings::Table,
Sources::Table,
CdSourceMappings::Table,
SortingPresets::Table,
SortKeys::Table,
SortingPresetKeys::Table,
JobStates::Table
);
Ok(())
}
}
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)
.on_delete(ForeignKeyAction::Cascade),
)
.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)
.on_delete(ForeignKeyAction::Cascade),
)
.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()
.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)
.on_delete(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.from(CdTagMappings::Table, CdTagMappings::TagId)
.to(Tags::Table, Tags::Id)
.on_delete(ForeignKeyAction::Cascade),
)
.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()
}
fn create_sources() -> TableCreateStatement {
Table::create()
.if_not_exists()
.table(Sources::Table)
.col(
ColumnDef::new(Sources::Id)
.big_integer()
.primary_key()
.auto_increment(),
)
.col(ColumnDef::new(Sources::Url).string_len(512).not_null())
.index(
Index::create()
.unique()
.table(Sources::Table)
.col(Sources::Url)
.full_text(),
)
.to_owned()
}
fn create_cd_sources_mappings() -> TableCreateStatement {
Table::create()
.if_not_exists()
.table(CdSourceMappings::Table)
.col(
ColumnDef::new(CdSourceMappings::CdId)
.big_integer()
.not_null(),
)
.col(
ColumnDef::new(CdSourceMappings::SourceId)
.big_integer()
.not_null(),
)
.foreign_key(
ForeignKey::create()
.from(CdSourceMappings::Table, CdSourceMappings::CdId)
.to(ContentDescriptors::Table, ContentDescriptors::Id)
.on_delete(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.from(CdSourceMappings::Table, CdSourceMappings::SourceId)
.to(Sources::Table, Sources::Id)
.on_delete(ForeignKeyAction::Cascade),
)
.primary_key(
Index::create()
.table(CdSourceMappings::Table)
.col(CdSourceMappings::CdId)
.col(CdSourceMappings::SourceId)
.full_text(),
)
.to_owned()
}
fn create_sorting_presets() -> TableCreateStatement {
Table::create()
.if_not_exists()
.table(SortingPresets::Table)
.col(
ColumnDef::new(SortingPresets::Id)
.big_integer()
.primary_key()
.auto_increment(),
)
.to_owned()
}
fn create_sort_keys() -> TableCreateStatement {
Table::create()
.if_not_exists()
.table(SortKeys::Table)
.col(
ColumnDef::new(SortKeys::Id)
.big_integer()
.primary_key()
.auto_increment(),
)
.col(
ColumnDef::new(SortKeys::KeyType)
.integer()
.not_null()
.default(0),
)
.col(
ColumnDef::new(SortKeys::Ascending)
.boolean()
.not_null()
.default(false),
)
.col(ColumnDef::new(SortKeys::Value).string_len(128))
.to_owned()
}
fn create_sorting_preset_key() -> TableCreateStatement {
Table::create()
.if_not_exists()
.table(SortingPresetKeys::Table)
.col(
ColumnDef::new(SortingPresetKeys::PresetId)
.big_integer()
.not_null(),
)
.col(
ColumnDef::new(SortingPresetKeys::KeyId)
.big_integer()
.not_null(),
)
.col(
ColumnDef::new(SortingPresetKeys::KeyIndex)
.integer()
.default(0)
.not_null(),
)
.primary_key(
Index::create()
.table(SortingPresetKeys::Table)
.col(SortingPresetKeys::PresetId)
.col(SortingPresetKeys::KeyId),
)
.foreign_key(
ForeignKey::create()
.from(SortingPresetKeys::Table, SortingPresetKeys::PresetId)
.to(SortingPresets::Table, SortingPresets::Id)
.on_delete(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.from(SortingPresetKeys::Table, SortingPresetKeys::KeyId)
.to(SortKeys::Table, SortKeys::Id)
.on_delete(ForeignKeyAction::Cascade),
)
.to_owned()
}
fn create_job_states() -> TableCreateStatement {
Table::create()
.if_not_exists()
.table(JobStates::Table)
.col(
ColumnDef::new(JobStates::JobType)
.integer()
.primary_key()
.not_null(),
)
.col(ColumnDef::new(JobStates::Value).binary())
.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 CdSourceMappings {
Table,
CdId,
SourceId,
}
#[derive(Iden)]
enum SortingPresets {
Table,
Id,
}
#[derive(Iden)]
enum SortKeys {
Table,
Id,
KeyType,
Ascending,
Value,
}
#[derive(Iden)]
enum SortingPresetKeys {
Table,
PresetId,
KeyId,
KeyIndex,
}
#[derive(Iden)]
enum JobStates {
Table,
JobType,
Value,
}

@ -0,0 +1,7 @@
use migration::Migrator;
use sea_orm_migration::prelude::*;
#[async_std::main]
async fn main() {
cli::run_cli(Migrator).await;
}

@ -0,0 +1,9 @@
#[macro_export]
macro_rules! drop_tables {
($man:expr, $($tbl:expr),*) => {
use sea_orm_migration::prelude::*;
$(
$man.drop_table(TableDropStatement::new().table($tbl).to_owned()).await?;
)*
}
}

@ -1,81 +0,0 @@
CREATE TABLE storage_locations
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(128) UNIQUE NOT NULL,
path VARCHAR(255) NOT NULL
);
CREATE TABLE hashes
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
value TEXT NOT NULL
);
CREATE UNIQUE INDEX hashes_value_index ON hashes (value);
CREATE TABLE files
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
type INTEGER NOT NULL DEFAULT 0,
name VARCHAR(128),
comment VARCHAR(1024),
storage_id INTEGER NOT NULL,
hash_id INTEGER NOT NULL,
import_time DATETIME NOT NULL,
creation_time DATETIME NOT NULL,
change_time DATETIME NOT NULL,
FOREIGN KEY (storage_id) REFERENCES storage_locations (id),
FOREIGN KEY (hash_id) REFERENCES hashes (id)
);
CREATE TABLE namespaces
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(128) UNIQUE NOT NULL
);
CREATE UNIQUE INDEX namespaces_name_index ON namespaces (name);
CREATE TABLE tags
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
namespace_id INTEGER,
name VARCHAR(128) UNIQUE NOT NULL,
FOREIGN KEY (namespace_id) REFERENCES namespaces (id)
);
CREATE UNIQUE INDEX tag_name_index ON tags (name);
CREATE TABLE sources
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
url VARCHAR(512) NOT NULL
);
CREATE UNIQUE INDEX sources_value_index ON sources (url);
CREATE TABLE hash_tag_mappings
(
hash_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
PRIMARY KEY (hash_id, tag_id),
FOREIGN KEY (hash_id) REFERENCES hashes (id),
FOREIGN KEY (tag_id) REFERENCES tags (id)
);
CREATE TABLE hash_source_mappings
(
hash_id INTEGER NOT NULL,
source_id INTEGER NOT NULL,
PRIMARY KEY (hash_id, source_id),
FOREIGN KEY (hash_id) REFERENCES hashes (id),
FOREIGN KEY (source_id) REFERENCES sources (id)
)

@ -1,3 +0,0 @@
-- Add migration script here
ALTER TABLE files
ADD COLUMN mime_type VARCHAR(128);

@ -1,14 +0,0 @@
-- Add migration script here
CREATE TABLE thumbnails (
id INTEGER PRIMARY KEY AUTOINCREMENT,
hash_id INTEGER UNIQUE NOT NULL,
storage_id INTEGER NOT NULL,
file_id INTEGER NOT NULL,
height INTEGER NOT NULL,
width INTEGER NOT NULL,
FOREIGN KEY (hash_id) REFERENCES hashes (id),
FOREIGN KEY (storage_id) REFERENCES storage_locations (id),
FOREIGN KEY (file_id) REFERENCES files (id)
);
CREATE UNIQUE INDEX thumbnail_file_resolution ON thumbnails (file_id, height, width);

@ -1,3 +0,0 @@
-- Add migration script here
ALTER TABLE thumbnails
ADD COLUMN mime VARCHAR(128);

@ -1,8 +0,0 @@
-- Add migration script here
DELETE FROM thumbnails WHERE file_id NOT IN (SELECT MIN(files.id) FROM files GROUP BY hash_id);
DELETE FROM files WHERE ROWID NOT IN (SELECT MIN(ROWID) FROM files GROUP BY hash_id);
DELETE FROM thumbnails WHERE hash_id NOT IN (SELECT MIN(hashes.id) FROM hashes GROUP BY value);
DELETE FROM files WHERE hash_id NOT IN (SELECT MIN(hashes.id) FROM hashes GROUP BY value);
DELETE FROM hashes WHERE ROWID NOT IN (SELECT MIN(ROWID) FROM hashes GROUP BY value);
CREATE UNIQUE INDEX hash_value_index ON hashes (value);
CREATE UNIQUE INDEX file_hash_id ON files (hash_id);

@ -1,33 +0,0 @@
-- Add migration script here
PRAGMA foreign_keys=off;
ALTER TABLE tags RENAME TO _tags_old;
CREATE TABLE tags
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
namespace_id INTEGER,
name VARCHAR(128),
FOREIGN KEY (namespace_id) REFERENCES namespaces (id)
);
CREATE UNIQUE INDEX tag_namespace_name_index ON tags (namespace_id, name);
INSERT INTO tags SELECT * FROM _tags_old;
DROP TABLE _tags_old;
ALTER TABLE hash_tag_mappings RENAME TO _hash_tag_mappings_old;
CREATE TABLE hash_tag_mappings
(
hash_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
PRIMARY KEY (hash_id, tag_id),
FOREIGN KEY (hash_id) REFERENCES hashes (id),
FOREIGN KEY (tag_id) REFERENCES tags (id)
);
CREATE UNIQUE INDEX hash_tag_mappings_hash_tag ON hash_tag_mappings (hash_id, tag_id);
INSERT INTO hash_tag_mappings SELECT * FROM _hash_tag_mappings_old;
DROP TABLE _hash_tag_mappings_old;
PRAGMA foreign_keys=on;

@ -1,3 +0,0 @@
-- Add migration script here
CREATE INDEX index_hash_tag_mappings_tag_id ON hash_tag_mappings (tag_id);
CREATE INDEX index_tag_name ON tags (name);

@ -1,3 +0,0 @@
-- Add migration script here
ALTER TABLE files
ADD COLUMN size INTEGER;

@ -1,107 +0,0 @@
-- Add migration script here
PRAGMA foreign_keys= off;
-- create backup files table
ALTER TABLE files
RENAME TO _files_old;
-- create backup hashes table
ALTER TABLE hashes
RENAME TO _hashes_old;
-- create backup hash_tag_mappings table
ALTER TABLE hash_tag_mappings
RENAME TO _hash_tag_mappings_old;
-- create backup hash_source_mappings table
ALTER TABLE hash_source_mappings
RENAME TO _hash_source_mappings_old;
-- create content id table
CREATE TABLE content_descriptors
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
descriptor BLOB NOT NULL
);
CREATE UNIQUE INDEX content_descriptor_values ON content_descriptors (descriptor);
-- create content-id tag mappings table
CREATE TABLE cd_tag_mappings
(
cd_id INTEGER NOT NULL REFERENCES content_descriptors (id),
tag_id INTEGER NOT NULL REFERENCES tags (id),
PRIMARY KEY (cd_id, tag_id)
);
CREATE UNIQUE INDEX content_descriptor_tag_mapping_unique ON cd_tag_mappings (cd_id, tag_id);
CREATE INDEX content_descriptor_tag_mapping_tag ON cd_tag_mappings (tag_id);
-- create content-id source mappings table
CREATE TABLE cd_source_mappings
(
cd_id INTEGER NOT NULL REFERENCES content_descriptors (id),
source_id INTEGER NOT NULL REFERENCES sources (id),
PRIMARY KEY (cd_id, source_id)
);
CREATE UNIQUE INDEX content_descriptor_source_mapping_unique ON cd_source_mappings (cd_id, source_id);
-- create new files table
CREATE TABLE files
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
status INTEGER NOT NULL DEFAULT 10,
storage_id INTEGER NOT NULL REFERENCES storage_locations (id),
cd_id INTEGER NOT NULL REFERENCES content_descriptors (id),
mime_type VARCHAR(128) NOT NULL DEFAULT 'application/octet-stream'
);
CREATE INDEX files_contend_descriptor ON files (cd_id);
-- create metadata table
CREATE TABLE file_metadata
(
file_id INTEGER PRIMARY KEY REFERENCES files (id),
size INTEGER NOT NULL,
name VARCHAR(128),
comment VARCHAR(1024),
import_time DATETIME NOT NULL,
creation_time DATETIME NOT NULL,
change_time DATETIME NOT NULL
);
CREATE UNIQUE INDEX file_metadata_file_id_unique ON file_metadata (file_id);
-- add content identifiers from hashes table
INSERT INTO content_descriptors
SELECT id, value
FROM _hashes_old;
-- add files from files table
INSERT INTO files (id, storage_id, cd_id, mime_type)
SELECT id, storage_id, hash_id AS content_id, mime_type
FROM _files_old;
-- add metadata from files table
INSERT INTO file_metadata
SELECT id AS file_id, size, name, comment, import_time, creation_time, change_time
FROM _files_old;
-- add content tag mappings
INSERT INTO cd_tag_mappings
SELECT hash_id AS content_id, tag_id
FROM _hash_tag_mappings_old;
-- add content id source mappings
INSERT INTO cd_source_mappings
SELECT hash_id AS content_id, source_id
FROM _hash_source_mappings_old;
-- drop all old tables
DROP TABLE _hash_source_mappings_old;
DROP TABLE _hash_tag_mappings_old;
DROP TABLE _files_old;
DROP TABLE _hashes_old;
pragma foreign_keys= on;

@ -1,50 +0,0 @@
-- Add migration script here
PRAGMA foreign_keys= off;
-- rename old files table
ALTER TABLE files
RENAME TO _files_old;
-- rename metadata value (because of foreign key constraints)
ALTER TABLE file_metadata
RENAME TO _file_metadata_old;
-- create new files table
CREATE TABLE files
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
status INTEGER NOT NULL DEFAULT 10,
cd_id INTEGER NOT NULL REFERENCES content_descriptors (id),
mime_type VARCHAR(128) NOT NULL DEFAULT 'application/octet-stream'
);
-- add data from files table
INSERT INTO files
SELECT id, status, cd_id, mime_type
FROM _files_old;
-- create metadata table
CREATE TABLE file_metadata
(
file_id INTEGER PRIMARY KEY REFERENCES files (id),
size INTEGER NOT NULL,
name VARCHAR(128),
comment VARCHAR(1024),
import_time DATETIME NOT NULL,
creation_time DATETIME NOT NULL,
change_time DATETIME NOT NULL
);
-- add back the old values
INSERT INTO file_metadata
SELECT *
FROM _file_metadata_old;
-- drop old tables
DROP TABLE _file_metadata_old;
DROP TABLE _files_old;
DROP TABLE storage_locations;
-- create indices on new tables
CREATE UNIQUE INDEX file_metadata_file_id_unique ON file_metadata (file_id);
CREATE INDEX files_content_descriptor ON files (cd_id);
PRAGMA foreign_keys= on;

@ -1,20 +0,0 @@
-- Add migration script here
CREATE TABLE sorting_presets (
id INTEGER PRIMARY KEY AUTOINCREMENT
);
CREATE TABLE sort_keys (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key_type INTEGER NOT NULL DEFAULT 0,
ascending INTEGER NOT NULL CHECK (ascending IN (0, 1)),
value VARCHAR(128)
);
CREATE TABLE sorting_preset_keys (
preset_id INTEGER REFERENCES sorting_presets (id) ON DELETE CASCADE,
key_id INTEGER REFERENCES sort_keys (id),
key_index INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (preset_id, key_id)
);
CREATE INDEX sorting_preset_index ON sorting_preset_keys (preset_id);

@ -1,17 +0,0 @@
PRAGMA foreign_keys= off;
ALTER TABLE sorting_preset_keys
RENAME TO _sorting_preset_keys_old;
CREATE TABLE sorting_preset_keys
(
preset_id INTEGER REFERENCES sorting_presets (id) ON DELETE CASCADE,
key_id INTEGER REFERENCES sort_keys (id),
key_index INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (preset_id, key_id, key_index)
);
INSERT INTO sorting_preset_keys SELECT * FROM _sorting_preset_keys_old;
DROP TABLE _sorting_preset_keys_old;
PRAGMA foreign_keys= on;

@ -1,5 +0,0 @@
CREATE TABLE job_states (
job_type INTEGER NOT NULL,
value BLOB,
PRIMARY KEY (job_type)
);

@ -1,5 +1,6 @@
use std::time::Duration;
use migration::MigratorTrait;
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
use sqlx::migrate::MigrateDatabase;
@ -10,24 +11,16 @@ pub mod queries;
/// Connects to the database, runs migrations and returns the RepoDatabase wrapper type
pub async fn get_database<S: AsRef<str>>(uri: S) -> RepoDatabaseResult<DatabaseConnection> {
migrate(uri.as_ref()).await?;
if !sqlx::Sqlite::database_exists(uri.as_ref()).await? {
sqlx::Sqlite::create_database(uri.as_ref()).await?;
}
let mut opt = ConnectOptions::new(uri.as_ref().to_string());
opt.connect_timeout(Duration::from_secs(10))
.idle_timeout(Duration::from_secs(10))
.sqlx_logging(false);
.sqlx_logging(true);
let conn = Database::connect(opt).await?;
migration::Migrator::up(&conn, None).await?;
Ok(conn)
}
async fn migrate(uri: &str) -> RepoDatabaseResult<()> {
use sqlx::Connection;
if !sqlx::Sqlite::database_exists(uri).await? {
sqlx::Sqlite::create_database(uri).await?;
}
let mut conn = sqlx::SqliteConnection::connect(uri).await?;
sqlx::migrate!().run(&mut conn).await?;
Ok(())
}

@ -21,7 +21,7 @@ path = "../mediarepo-core"
path = "../mediarepo-database"
[dependencies.sea-orm]
version = "0.7.1"
version = "0.8.0"
features = ["runtime-tokio-native-tls", "macros"]
default-features = false

@ -6,7 +6,6 @@ use tokio::task::JoinHandle;
use crate::encrypted::{EncryptedListener, Keys};
use crate::prelude::utils::generate_secret;
use mediarepo_core::bromine::prelude::encrypted::EncryptionOptions;
use mediarepo_core::bromine::prelude::tcp::TcpOptions;
use mediarepo_core::bromine::prelude::*;
use mediarepo_core::error::{RepoError, RepoResult};
use mediarepo_core::mediarepo_api::types::misc::InfoResponse;

Loading…
Cancel
Save