Remove database-json #267
@ -35,8 +35,8 @@ impl From<DeserializeDatabase> for Collection {
|
|||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
pub struct DeserializeArtist {
|
pub struct DeserializeArtist {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub sort: Option<String>,
|
|
||||||
pub musicbrainz: DeserializeMbRefOption,
|
pub musicbrainz: DeserializeMbRefOption,
|
||||||
|
pub sort: Option<String>,
|
||||||
pub properties: HashMap<String, Vec<String>>,
|
pub properties: HashMap<String, Vec<String>>,
|
||||||
pub albums: Vec<DeserializeAlbum>,
|
pub albums: Vec<DeserializeAlbum>,
|
||||||
}
|
}
|
||||||
@ -45,9 +45,9 @@ pub struct DeserializeArtist {
|
|||||||
pub struct DeserializeAlbum {
|
pub struct DeserializeAlbum {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub lib_id: SerdeAlbumLibId,
|
pub lib_id: SerdeAlbumLibId,
|
||||||
|
pub musicbrainz: DeserializeMbRefOption,
|
||||||
pub date: SerdeAlbumDate,
|
pub date: SerdeAlbumDate,
|
||||||
pub seq: u8,
|
pub seq: u8,
|
||||||
pub musicbrainz: DeserializeMbRefOption,
|
|
||||||
pub primary_type: Option<SerdeAlbumPrimaryType>,
|
pub primary_type: Option<SerdeAlbumPrimaryType>,
|
||||||
pub secondary_types: Vec<SerdeAlbumSecondaryType>,
|
pub secondary_types: Vec<SerdeAlbumSecondaryType>,
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@ -25,9 +25,9 @@ impl<'a> From<&'a Collection> for SerializeDatabase<'a> {
|
|||||||
#[derive(Debug, Serialize, PartialEq, Eq)]
|
#[derive(Debug, Serialize, PartialEq, Eq)]
|
||||||
pub struct SerializeArtist<'a> {
|
pub struct SerializeArtist<'a> {
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
pub sort: Option<&'a str>,
|
pub sort: &'a Option<String>,
|
||||||
pub musicbrainz: SerializeMbRefOption<'a>,
|
pub musicbrainz: SerializeMbRefOption<'a>,
|
||||||
pub properties: BTreeMap<&'a str, &'a Vec<String>>,
|
pub properties: &'a HashMap<String, Vec<String>>,
|
||||||
pub albums: Vec<SerializeAlbum<'a>>,
|
pub albums: Vec<SerializeAlbum<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,9 +35,9 @@ pub struct SerializeArtist<'a> {
|
|||||||
pub struct SerializeAlbum<'a> {
|
pub struct SerializeAlbum<'a> {
|
||||||
pub title: &'a str,
|
pub title: &'a str,
|
||||||
pub lib_id: SerdeAlbumLibId,
|
pub lib_id: SerdeAlbumLibId,
|
||||||
|
pub musicbrainz: SerializeMbRefOption<'a>,
|
||||||
pub date: SerdeAlbumDate,
|
pub date: SerdeAlbumDate,
|
||||||
pub seq: u8,
|
pub seq: u8,
|
||||||
pub musicbrainz: SerializeMbRefOption<'a>,
|
|
||||||
pub primary_type: Option<SerdeAlbumPrimaryType>,
|
pub primary_type: Option<SerdeAlbumPrimaryType>,
|
||||||
pub secondary_types: Vec<SerdeAlbumSecondaryType>,
|
pub secondary_types: Vec<SerdeAlbumSecondaryType>,
|
||||||
}
|
}
|
||||||
@ -75,15 +75,9 @@ impl<'a> From<&'a Artist> for SerializeArtist<'a> {
|
|||||||
fn from(artist: &'a Artist) -> Self {
|
fn from(artist: &'a Artist) -> Self {
|
||||||
SerializeArtist {
|
SerializeArtist {
|
||||||
name: &artist.meta.id.name,
|
name: &artist.meta.id.name,
|
||||||
sort: artist.meta.sort.as_deref(),
|
|
||||||
musicbrainz: (&artist.meta.id.mb_ref).into(),
|
musicbrainz: (&artist.meta.id.mb_ref).into(),
|
||||||
properties: artist
|
sort: &artist.meta.sort,
|
||||||
.meta
|
properties: &artist.meta.info.properties,
|
||||||
.info
|
|
||||||
.properties
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.as_ref(), v))
|
|
||||||
.collect(),
|
|
||||||
albums: artist.albums.iter().map(Into::into).collect(),
|
albums: artist.albums.iter().map(Into::into).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,9 +88,9 @@ impl<'a> From<&'a Album> for SerializeAlbum<'a> {
|
|||||||
SerializeAlbum {
|
SerializeAlbum {
|
||||||
title: &album.meta.id.title,
|
title: &album.meta.id.title,
|
||||||
lib_id: album.meta.id.lib_id.into(),
|
lib_id: album.meta.id.lib_id.into(),
|
||||||
|
musicbrainz: (&album.meta.id.mb_ref).into(),
|
||||||
date: album.meta.date.into(),
|
date: album.meta.date.into(),
|
||||||
seq: album.meta.seq.0,
|
seq: album.meta.seq.0,
|
||||||
musicbrainz: (&album.meta.id.mb_ref).into(),
|
|
||||||
primary_type: album.meta.info.primary_type.map(Into::into),
|
primary_type: album.meta.info.primary_type.map(Into::into),
|
||||||
secondary_types: album
|
secondary_types: album
|
||||||
.meta
|
.meta
|
||||||
|
@ -105,9 +105,9 @@ impl ISqlTransactionBackend for SqlTransactionSqliteBackend<'_> {
|
|||||||
fn create_artists_table(&self) -> Result<(), Error> {
|
fn create_artists_table(&self) -> Result<(), Error> {
|
||||||
let mut stmt = self.prepare(
|
let mut stmt = self.prepare(
|
||||||
"CREATE TABLE IF NOT EXISTS artists (
|
"CREATE TABLE IF NOT EXISTS artists (
|
||||||
name TEXT NOT NULL PRIMARY KEY,
|
name TEXT NOT NULL,
|
||||||
sort TEXT NULL,
|
|
||||||
mbid JSON NOT NULL DEFAULT '\"None\"',
|
mbid JSON NOT NULL DEFAULT '\"None\"',
|
||||||
|
sort TEXT NULL,
|
||||||
properties JSON NOT NULL DEFAULT '{}'
|
properties JSON NOT NULL DEFAULT '{}'
|
||||||
)",
|
)",
|
||||||
);
|
);
|
||||||
@ -131,8 +131,7 @@ impl ISqlTransactionBackend for SqlTransactionSqliteBackend<'_> {
|
|||||||
day INT NULL,
|
day INT NULL,
|
||||||
seq INT NOT NULL,
|
seq INT NOT NULL,
|
||||||
primary_type JSON NOT NULL DEFAULT 'null',
|
primary_type JSON NOT NULL DEFAULT 'null',
|
||||||
secondary_types JSON NOT NULL DEFAULT '[]',
|
secondary_types JSON NOT NULL DEFAULT '[]'
|
||||||
FOREIGN KEY (artist_name) REFERENCES artists(name) ON DELETE CASCADE ON UPDATE NO ACTION
|
|
||||||
)",
|
)",
|
||||||
);
|
);
|
||||||
Self::execute(&mut stmt, ())
|
Self::execute(&mut stmt, ())
|
||||||
@ -178,12 +177,18 @@ impl ISqlTransactionBackend for SqlTransactionSqliteBackend<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn select_all_artists(&self) -> Result<Vec<DeserializeArtist>, Error> {
|
fn select_all_artists(&self) -> Result<Vec<DeserializeArtist>, Error> {
|
||||||
let mut stmt = self.prepare_cached("SELECT name, sort, mbid, properties FROM artists");
|
let mut stmt = self.prepare_cached("SELECT name, mbid, sort, properties FROM artists");
|
||||||
let mut rows = Self::query(&mut stmt, ())?;
|
let mut rows = Self::query(&mut stmt, ())?;
|
||||||
|
|
||||||
let mut artists = vec![];
|
let mut artists = vec![];
|
||||||
while let Some(row) = Self::next_row(&mut rows)? {
|
while let Some(row) = Self::next_row(&mut rows)? {
|
||||||
artists.push(row.try_into()?);
|
artists.push(DeserializeArtist {
|
||||||
|
name: Self::get_value(row, 0)?,
|
||||||
|
musicbrainz: serde_json::from_str(&Self::get_value::<String>(row, 1)?)?,
|
||||||
|
sort: Self::get_value(row, 2)?,
|
||||||
|
properties: serde_json::from_str(&Self::get_value::<String>(row, 3)?)?,
|
||||||
|
albums: vec![],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(artists)
|
Ok(artists)
|
||||||
@ -214,52 +219,28 @@ impl ISqlTransactionBackend for SqlTransactionSqliteBackend<'_> {
|
|||||||
|
|
||||||
fn select_artist_albums(&self, artist_name: &str) -> Result<Vec<DeserializeAlbum>, Error> {
|
fn select_artist_albums(&self, artist_name: &str) -> Result<Vec<DeserializeAlbum>, Error> {
|
||||||
let mut stmt = self.prepare_cached(
|
let mut stmt = self.prepare_cached(
|
||||||
"SELECT title, lib_id, year, month, day, seq, mbid, primary_type, secondary_types
|
"SELECT title, lib_id, mbid, year, month, day, seq, primary_type, secondary_types
|
||||||
FROM albums WHERE artist_name = ?1",
|
FROM albums WHERE artist_name = ?1",
|
||||||
);
|
);
|
||||||
let mut rows = Self::query(&mut stmt, [artist_name])?;
|
let mut rows = Self::query(&mut stmt, [artist_name])?;
|
||||||
|
|
||||||
let mut albums = vec![];
|
let mut albums = vec![];
|
||||||
while let Some(row) = Self::next_row(&mut rows)? {
|
while let Some(row) = Self::next_row(&mut rows)? {
|
||||||
albums.push(row.try_into()?);
|
albums.push(DeserializeAlbum {
|
||||||
|
title: Self::get_value(row, 0)?,
|
||||||
|
lib_id: serde_json::from_str(&Self::get_value::<String>(row, 1)?)?,
|
||||||
|
musicbrainz: serde_json::from_str(&Self::get_value::<String>(row, 2)?)?,
|
||||||
|
date: SerdeAlbumDate(AlbumDate::new(
|
||||||
|
Self::get_value(row, 3)?,
|
||||||
|
Self::get_value(row, 4)?,
|
||||||
|
Self::get_value(row, 5)?,
|
||||||
|
)),
|
||||||
|
seq: Self::get_value(row, 6)?,
|
||||||
|
primary_type: serde_json::from_str(&Self::get_value::<String>(row, 7)?)?,
|
||||||
|
secondary_types: serde_json::from_str(&Self::get_value::<String>(row, 8)?)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(albums)
|
Ok(albums)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&Row<'_>> for DeserializeArtist {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn try_from(row: &Row<'_>) -> Result<Self, Self::Error> {
|
|
||||||
type Backend<'a> = SqlTransactionSqliteBackend<'a>;
|
|
||||||
Ok(DeserializeArtist {
|
|
||||||
name: Backend::get_value(row, 0)?,
|
|
||||||
sort: Backend::get_value(row, 1)?,
|
|
||||||
musicbrainz: serde_json::from_str(&Backend::get_value::<String>(row, 2)?)?,
|
|
||||||
properties: serde_json::from_str(&Backend::get_value::<String>(row, 3)?)?,
|
|
||||||
albums: vec![],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&Row<'_>> for DeserializeAlbum {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn try_from(row: &Row<'_>) -> Result<Self, Self::Error> {
|
|
||||||
type Backend<'a> = SqlTransactionSqliteBackend<'a>;
|
|
||||||
Ok(DeserializeAlbum {
|
|
||||||
title: Backend::get_value(row, 0)?,
|
|
||||||
lib_id: serde_json::from_str(&Backend::get_value::<String>(row, 1)?)?,
|
|
||||||
date: SerdeAlbumDate(AlbumDate::new(
|
|
||||||
Backend::get_value(row, 2)?,
|
|
||||||
Backend::get_value(row, 3)?,
|
|
||||||
Backend::get_value(row, 4)?,
|
|
||||||
)),
|
|
||||||
seq: Backend::get_value(row, 5)?,
|
|
||||||
musicbrainz: serde_json::from_str(&Backend::get_value::<String>(row, 6)?)?,
|
|
||||||
primary_type: serde_json::from_str(&Backend::get_value::<String>(row, 7)?)?,
|
|
||||||
secondary_types: serde_json::from_str(&Backend::get_value::<String>(row, 8)?)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
13
src/main.rs
13
src/main.rs
@ -11,7 +11,7 @@ use musichoard::{
|
|||||||
track::TrackFormat,
|
track::TrackFormat,
|
||||||
},
|
},
|
||||||
external::{
|
external::{
|
||||||
database::json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
database::sql::{backend::SqlDatabaseSqliteBackend, SqlDatabase},
|
||||||
library::beets::{
|
library::beets::{
|
||||||
executor::{ssh::BeetsLibrarySshExecutor, BeetsLibraryProcessExecutor},
|
executor::{ssh::BeetsLibrarySshExecutor, BeetsLibraryProcessExecutor},
|
||||||
BeetsLibrary,
|
BeetsLibrary,
|
||||||
@ -141,7 +141,10 @@ fn with_database<Library: ILibrary + 'static>(
|
|||||||
{
|
{
|
||||||
Ok(f) => {
|
Ok(f) => {
|
||||||
drop(f);
|
drop(f);
|
||||||
JsonDatabase::new(JsonDatabaseFileBackend::new(&db_opt.database_file_path))
|
let db_exec = SqlDatabaseSqliteBackend::new(&db_opt.database_file_path)
|
||||||
|
.expect("failed to initialise SQLite database backend");
|
||||||
|
SqlDatabase::new(db_exec)
|
||||||
|
.expect("failed to open new database")
|
||||||
.save(&vec![])
|
.save(&vec![])
|
||||||
.expect("failed to create empty database");
|
.expect("failed to create empty database");
|
||||||
}
|
}
|
||||||
@ -151,8 +154,10 @@ fn with_database<Library: ILibrary + 'static>(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
let db_exec = JsonDatabaseFileBackend::new(&db_opt.database_file_path);
|
let db_exec = SqlDatabaseSqliteBackend::new(&db_opt.database_file_path)
|
||||||
with(builder.set_database(JsonDatabase::new(db_exec)));
|
.expect("failed to initialise SQLite database backend");
|
||||||
|
let db = SqlDatabase::new(db_exec).expect("failed to open database");
|
||||||
|
with(builder.set_database(db));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
10
tests/lib.rs
10
tests/lib.rs
@ -8,7 +8,7 @@ mod testlib;
|
|||||||
|
|
||||||
use musichoard::{
|
use musichoard::{
|
||||||
external::{
|
external::{
|
||||||
database::json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
database::sql::{backend::SqlDatabaseSqliteBackend, SqlDatabase},
|
||||||
library::beets::{executor::BeetsLibraryProcessExecutor, BeetsLibrary},
|
library::beets::{executor::BeetsLibraryProcessExecutor, BeetsLibrary},
|
||||||
},
|
},
|
||||||
IMusicHoardBase, IMusicHoardDatabase, IMusicHoardLibrary, MusicHoard,
|
IMusicHoardBase, IMusicHoardDatabase, IMusicHoardLibrary, MusicHoard,
|
||||||
@ -28,8 +28,8 @@ fn merge_library_then_database() {
|
|||||||
.config(Some(&*library::beets::BEETS_TEST_CONFIG_PATH));
|
.config(Some(&*library::beets::BEETS_TEST_CONFIG_PATH));
|
||||||
let library = BeetsLibrary::new(executor);
|
let library = BeetsLibrary::new(executor);
|
||||||
|
|
||||||
let backend = JsonDatabaseFileBackend::new(&*database::json::DATABASE_TEST_FILE);
|
let backend = SqlDatabaseSqliteBackend::new(&*database::sql::DATABASE_TEST_FILE).unwrap();
|
||||||
let database = JsonDatabase::new(backend);
|
let database = SqlDatabase::new(backend).unwrap();
|
||||||
|
|
||||||
let mut music_hoard = MusicHoard::new(database, library);
|
let mut music_hoard = MusicHoard::new(database, library);
|
||||||
|
|
||||||
@ -51,8 +51,8 @@ fn merge_database_then_library() {
|
|||||||
.config(Some(&*library::beets::BEETS_TEST_CONFIG_PATH));
|
.config(Some(&*library::beets::BEETS_TEST_CONFIG_PATH));
|
||||||
let library = BeetsLibrary::new(executor);
|
let library = BeetsLibrary::new(executor);
|
||||||
|
|
||||||
let backend = JsonDatabaseFileBackend::new(&*database::json::DATABASE_TEST_FILE);
|
let backend = SqlDatabaseSqliteBackend::new(&*database::sql::DATABASE_TEST_FILE).unwrap();
|
||||||
let database = JsonDatabase::new(backend);
|
let database = SqlDatabase::new(backend).unwrap();
|
||||||
|
|
||||||
let mut music_hoard = MusicHoard::new(database, library);
|
let mut music_hoard = MusicHoard::new(database, library);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user