Add a SQLite database backend #265
@ -10,9 +10,9 @@ use crate::{
|
||||
collection::album::AlbumDate,
|
||||
external::database::{
|
||||
serde::{
|
||||
common::{SerdeAlbumDate, V20250103},
|
||||
deserialize::{DeserializeAlbum, DeserializeArtist, DeserializeDatabase},
|
||||
serialize::{SerializeAlbum, SerializeArtist, SerializeDatabase},
|
||||
common::SerdeAlbumDate,
|
||||
deserialize::{DeserializeAlbum, DeserializeArtist},
|
||||
serialize::{SerializeAlbum, SerializeArtist},
|
||||
},
|
||||
sql::{Error, ISqlDatabaseBackend, ISqlTransactionBackend},
|
||||
},
|
||||
@ -151,29 +151,22 @@ impl ISqlTransactionBackend for SqlTransactionSqliteBackend<'_> {
|
||||
Self::execute(&mut stmt, ())
|
||||
}
|
||||
|
||||
fn insert_database_version(&self, version: &SerializeDatabase<'_>) -> Result<(), Error> {
|
||||
fn insert_database_version(&self, version: &str) -> Result<(), Error> {
|
||||
let mut stmt = self.prepare_cached(
|
||||
"INSERT INTO database_metadata (name, value)
|
||||
VALUES (?1, ?2)",
|
||||
)?;
|
||||
let version = match version {
|
||||
SerializeDatabase::V20250103(_) => V20250103,
|
||||
};
|
||||
Self::execute(&mut stmt, ("version", version))
|
||||
}
|
||||
|
||||
fn select_database_version<'a>(&self) -> Result<DeserializeDatabase, Error> {
|
||||
fn select_database_version<'a>(&self) -> Result<Option<String>, Error> {
|
||||
let mut stmt =
|
||||
self.prepare_cached("SELECT value FROM database_metadata WHERE name = 'version'")?;
|
||||
let mut rows = Self::query(&mut stmt, ())?;
|
||||
|
||||
match Self::next_row(&mut rows)? {
|
||||
Some(row) => match Self::get_value::<String>(row, 0)?.as_str() {
|
||||
V20250103 => Ok(DeserializeDatabase::V20250103(vec![])),
|
||||
s => Err(Error::SerDeError(format!("unknown database version: {s}"))),
|
||||
},
|
||||
None => Err(Error::SerDeError(String::from("missing database version"))),
|
||||
}
|
||||
Self::next_row(&mut rows)?
|
||||
.map(|row| Self::get_value(row, 0))
|
||||
.transpose()
|
||||
}
|
||||
|
||||
fn insert_artist(&self, artist: &SerializeArtist<'_>) -> Result<(), Error> {
|
||||
|
@ -13,6 +13,7 @@ use crate::{
|
||||
interface::database::{IDatabase, LoadError, SaveError},
|
||||
},
|
||||
external::database::serde::{
|
||||
common::V20250103,
|
||||
deserialize::{DeserializeAlbum, DeserializeArtist, DeserializeDatabase},
|
||||
serialize::{SerializeAlbum, SerializeArtist, SerializeDatabase},
|
||||
},
|
||||
@ -51,11 +52,10 @@ pub trait ISqlTransactionBackend {
|
||||
fn drop_albums_table(&self) -> Result<(), Error>;
|
||||
|
||||
/// Set the database version.
|
||||
#[allow(clippy::needless_lifetimes)] // Conflicts with automock.
|
||||
fn insert_database_version<'a>(&self, version: &SerializeDatabase<'a>) -> Result<(), Error>;
|
||||
fn insert_database_version(&self, version: &str) -> Result<(), Error>;
|
||||
|
||||
/// Get the database version.
|
||||
fn select_database_version(&self) -> Result<DeserializeDatabase, Error>;
|
||||
fn select_database_version(&self) -> Result<Option<String>, Error>;
|
||||
|
||||
/// Insert an artist into the artist table.
|
||||
#[allow(clippy::needless_lifetimes)] // Conflicts with automock.
|
||||
@ -154,15 +154,24 @@ impl<SDB: for<'conn> ISqlDatabaseBackend<'conn>> IDatabase for SqlDatabase<SDB>
|
||||
fn load(&mut self) -> Result<Collection, LoadError> {
|
||||
let tx = self.backend.transaction()?;
|
||||
|
||||
let mut database = tx.select_database_version()?;
|
||||
match database {
|
||||
DeserializeDatabase::V20250103(ref mut coll) => {
|
||||
coll.extend(tx.select_all_artists()?);
|
||||
let version = tx
|
||||
.select_database_version()?
|
||||
.ok_or_else(|| LoadError::SerDeError(String::from("missing database version")))?;
|
||||
|
||||
let database = match version.as_str() {
|
||||
V20250103 => {
|
||||
let mut coll = tx.select_all_artists()?;
|
||||
for artist in coll.iter_mut() {
|
||||
artist.albums.extend(tx.select_artist_albums(&artist.name)?);
|
||||
}
|
||||
DeserializeDatabase::V20250103(coll)
|
||||
}
|
||||
}
|
||||
s => {
|
||||
return Err(LoadError::SerDeError(format!(
|
||||
"unknown database version: {s}"
|
||||
)))
|
||||
}
|
||||
};
|
||||
|
||||
tx.commit()?;
|
||||
Ok(database.into())
|
||||
@ -175,9 +184,9 @@ impl<SDB: for<'conn> ISqlDatabaseBackend<'conn>> IDatabase for SqlDatabase<SDB>
|
||||
Self::drop_tables(&tx)?;
|
||||
Self::create_tables(&tx)?;
|
||||
|
||||
tx.insert_database_version(&database)?;
|
||||
match database {
|
||||
SerializeDatabase::V20250103(artists) => {
|
||||
tx.insert_database_version(V20250103)?;
|
||||
for artist in artists.iter() {
|
||||
tx.insert_artist(artist)?;
|
||||
for album in artist.albums.iter() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user