From b1770fc17e921eb2f438f7895e8d0ba34779fd4a Mon Sep 17 00:00:00 2001
From: Antoine Gersant <antoine.gersant@lesforges.org>
Date: Thu, 16 Jan 2025 00:14:53 -0800
Subject: [PATCH] Migrate to native_db 0.8.1

---
 Cargo.lock          | 87 ++++++++++++++++++++++++++++-----------------
 Cargo.toml          |  4 +--
 src/app/playlist.rs | 32 ++++++++++-------
 3 files changed, 77 insertions(+), 46 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 08366df..16a2a34 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,7 +26,7 @@ dependencies = [
  "cfg-if",
  "once_cell",
  "version_check",
- "zerocopy",
+ "zerocopy 0.7.35",
 ]
 
 [[package]]
@@ -372,9 +372,9 @@ dependencies = [
 
 [[package]]
 name = "cargo-platform"
-version = "0.1.8"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
+checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
 dependencies = [
  "serde",
 ]
@@ -602,12 +602,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
 
 [[package]]
 name = "errno"
-version = "0.3.9"
+version = "0.3.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
 dependencies = [
  "libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -639,9 +639,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
 
 [[package]]
 name = "fastrand"
-version = "2.1.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
 [[package]]
 name = "fdeflate"
@@ -842,9 +842,9 @@ checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94"
 
 [[package]]
 name = "glob"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
 
 [[package]]
 name = "hashbrown"
@@ -1308,9 +1308,9 @@ dependencies = [
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
 
 [[package]]
 name = "litemap"
@@ -1467,13 +1467,14 @@ dependencies = [
 
 [[package]]
 name = "native_db"
-version = "0.7.1"
-source = "git+https://github.com/vincent-herlemont/native_db#6daae43c5461e5944f076d40b4026be6c9730107"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db7c6b50f9889052a3c1bbd3aa70cc33b76ec1761092aeb0ec0e1ac3cfdb881a"
 dependencies = [
  "native_db_macro",
  "native_model",
  "redb 1.5.1",
- "redb 2.1.3",
+ "redb 2.4.0",
  "semver",
  "serde",
  "skeptic",
@@ -1482,8 +1483,9 @@ dependencies = [
 
 [[package]]
 name = "native_db_macro"
-version = "0.7.1"
-source = "git+https://github.com/vincent-herlemont/native_db#6daae43c5461e5944f076d40b4026be6c9730107"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "434acde56fc4485e0b62533bb2fbc08155ee7e47408b1358348acff556c31b3c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1492,9 +1494,9 @@ dependencies = [
 
 [[package]]
 name = "native_model"
-version = "0.4.19"
+version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "360da481893ec9bfa71593193b796400d8616c3b2aa8145b7b72e561224e6259"
+checksum = "c10f4542302b7fa69ef18b49d93106e27f20b59d695555121d9ed22fe5d716a8"
 dependencies = [
  "anyhow",
  "bincode",
@@ -1502,14 +1504,14 @@ dependencies = [
  "serde",
  "skeptic",
  "thiserror",
- "zerocopy",
+ "zerocopy 0.8.14",
 ]
 
 [[package]]
 name = "native_model_macro"
-version = "0.4.19"
+version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35ade955118c8776435064b3c0e95b75e89867ed19eaaf6709a2f3eea9c46420"
+checksum = "2f385f3d57adaea8d8868e65a0bc821bcb8ba2228bbf87a1c3c6144ac48f3791"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1835,7 +1837,7 @@ version = "0.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
 dependencies = [
- "zerocopy",
+ "zerocopy 0.7.35",
 ]
 
 [[package]]
@@ -1965,9 +1967,9 @@ dependencies = [
 
 [[package]]
 name = "redb"
-version = "2.1.3"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4760ad04a88ef77075ba86ba9ea79b919e6bab29c1764c5747237cd6eaedcaa"
+checksum = "ea0a72cd7140de9fc3e318823b883abf819c20d478ec89ce880466dc2ef263c6"
 dependencies = [
  "libc",
 ]
@@ -2097,15 +2099,15 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.34"
+version = "0.38.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
 dependencies = [
  "bitflags 2.6.0",
  "errno",
  "libc",
  "linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -2598,15 +2600,16 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.11.0"
+version = "3.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
+checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
 dependencies = [
  "cfg-if",
  "fastrand",
+ "getrandom",
  "once_cell",
  "rustix",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -3365,7 +3368,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
 dependencies = [
  "byteorder",
- "zerocopy-derive",
+ "zerocopy-derive 0.7.35",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
+dependencies = [
+ "zerocopy-derive 0.8.14",
 ]
 
 [[package]]
@@ -3379,6 +3391,17 @@ dependencies = [
  "syn 2.0.96",
 ]
 
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
 [[package]]
 name = "zerofrom"
 version = "0.1.4"
diff --git a/Cargo.toml b/Cargo.toml
index b8b80cb..a7d9d96 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,8 +30,8 @@ log = "0.4.22"
 metaflac = "0.2.7"
 mp3-duration = "0.1.10"
 mp4ameta = "0.11.0"
-native_db = { git = "https://github.com/vincent-herlemont/native_db" }
-native_model = "0.4.19"
+native_db = "0.8.1"
+native_model = "0.4.20"
 nohash-hasher = "0.2.0"
 notify = { version = "6.1.1", default-features = false }
 notify-debouncer-full = { version = "0.3.1", default-features = false }
diff --git a/src/app/playlist.rs b/src/app/playlist.rs
index 7da75ca..4d97dba 100644
--- a/src/app/playlist.rs
+++ b/src/app/playlist.rs
@@ -1,5 +1,5 @@
 use core::clone::Clone;
-use std::collections::HashMap;
+use std::collections::{BTreeMap, HashMap};
 use std::path::PathBuf;
 use std::time::Duration;
 
@@ -38,13 +38,13 @@ pub mod v1 {
 
 	#[derive(Debug, Default, Serialize, Deserialize)]
 	#[native_model(id = 1, version = 1)]
-	#[native_db(primary_key(custom_id))]
+	#[native_db(primary_key(custom_id -> (&str, &str)))]
 	pub struct PlaylistModel {
 		#[secondary_key]
 		pub owner: String,
 		pub name: String,
 		pub duration: Duration,
-		pub num_songs_by_genre: HashMap<String, u32>,
+		pub num_songs_by_genre: BTreeMap<String, u32>,
 		pub virtual_paths: Vec<PathBuf>,
 	}
 
@@ -60,7 +60,7 @@ impl From<PlaylistModel> for PlaylistHeader {
 		Self {
 			name: p.name,
 			duration: p.duration,
-			num_songs_by_genre: p.num_songs_by_genre,
+			num_songs_by_genre: p.num_songs_by_genre.into_iter().collect(),
 		}
 	}
 }
@@ -126,7 +126,7 @@ impl Manager {
 					.filter_map(|s| s.duration.map(|d| d as u64))
 					.sum();
 
-				let mut num_songs_by_genre = HashMap::<String, u32>::new();
+				let mut num_songs_by_genre = BTreeMap::<String, u32>::new();
 				for song in &songs {
 					for genre in &song.genres {
 						*num_songs_by_genre.entry(genre.clone()).or_default() += 1;
@@ -158,7 +158,7 @@ impl Manager {
 			let name = name.to_owned();
 			move || {
 				let transaction = manager.db.r_transaction()?;
-				match transaction.get().primary::<PlaylistModel>((&owner, &name)) {
+				match transaction.get().primary::<PlaylistModel>((owner, name)) {
 					Ok(Some(p)) => Ok(Playlist::from(p)),
 					Ok(None) => Err(Error::PlaylistNotFound),
 					Err(e) => Err(Error::NativeDatabase(e)),
@@ -175,11 +175,15 @@ impl Manager {
 			let name = name.to_owned();
 			move || {
 				let transaction = manager.db.rw_transaction()?;
-				transaction.remove::<PlaylistModel>(PlaylistModel {
-					name: name.to_owned(),
-					owner: owner.to_owned(),
-					..Default::default()
-				})?;
+				let playlist = match transaction
+					.get()
+					.primary::<PlaylistModel>((owner.as_str(), name.as_str()))
+				{
+					Ok(Some(p)) => Ok(p),
+					Ok(None) => Err(Error::PlaylistNotFound),
+					Err(e) => Err(Error::NativeDatabase(e)),
+				}?;
+				transaction.remove::<PlaylistModel>(playlist)?;
 				transaction.commit()?;
 				Ok(())
 			}
@@ -278,11 +282,15 @@ mod test {
 	async fn delete_playlist_golden_path() {
 		let ctx = test::ContextBuilder::new(test_name!())
 			.user(TEST_USER, TEST_PASSWORD, false)
+			.mount(TEST_MOUNT_NAME, "test-data/small-collection")
 			.build()
 			.await;
 
+		ctx.scanner.run_scan().await.unwrap();
+		let songs = list_all_songs(&ctx).await;
+
 		ctx.playlist_manager
-			.save_playlist(TEST_PLAYLIST_NAME, TEST_USER, Vec::new())
+			.save_playlist(TEST_PLAYLIST_NAME, TEST_USER, songs)
 			.await
 			.unwrap();