Files
tuneparty_pre1_server/src/models.rs
skybldev 57d70e773f refactor: organize models and library, include detailed types in track JSON representation
- add basic searching query generators to `Artist`, `Collection`, `Track`
- add detailed variants of models
- split websocket message types to input/output-specific messages to constrain lifetimes
- organize imports
2026-10-31 01:46:07 -04:00

173 lines
4.7 KiB
Rust

use diesel::prelude::*;
use diesel::dsl::{AsSelect, Filter, Select, Eq, auto_type};
use diesel::sqlite::Sqlite;
use futures::task::waker;
use serde::{Deserialize, Serialize};
use crate::schema::{artists, collections, tracks};
use crate::library::Library;
type All<S, M> = Select<S, AsSelect<M, Sqlite>>;
#[derive(Debug, Clone, Queryable, Selectable, Identifiable)]
#[diesel(table_name = artists)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct Artist {
pub id: i32,
pub original_name: String,
pub display_name: String,
}
impl Artist {
pub fn all() -> All<artists::table, Self> {
artists::table.select(Self::as_select())
}
#[auto_type(no_type_alias)]
pub fn by_id(id: i32) -> _ {
let all: All<artists::table, Self> = Self::all();
let filter = artists::id.eq(id);
all.filter(filter)
}
#[auto_type(no_type_alias)]
pub fn by_original_name(name: &str) -> _ {
let all: All<artists::table, Self> = Self::all();
let filter = artists::original_name.eq(name);
all.filter(filter)
}
}
#[derive(Debug, Clone, Queryable, Selectable, Identifiable)]
#[diesel(table_name = collections)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct Collection {
pub id: i32,
pub artist_id: Option<i32>,
pub collection_type: String,
pub original_name: String,
pub display_name: String,
}
impl Collection {
pub fn all() -> All<collections::table, Self> {
collections::table.select(Self::as_select())
}
#[auto_type(no_type_alias)]
pub fn by_id(id: i32) -> _ {
let all: All<collections::table, Self> = Self::all();
let filter = collections::id.eq(id);
all.filter(filter)
}
#[auto_type(no_type_alias)]
pub fn by_original_name(name: &str) -> _ {
let all: All<collections::table, Self> = Self::all();
let filter = collections::original_name.eq(name);
all.filter(filter)
}
}
#[derive(
Debug, Clone, Queryable, Selectable, Identifiable, Associations, Serialize, Deserialize,
)]
#[diesel(table_name = tracks)]
#[diesel(belongs_to(Artist, foreign_key = artist_id))]
#[diesel(belongs_to(Collection, foreign_key = collection_id))]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct Track {
pub id: i32,
pub file_path: String,
pub artist_id: Option<i32>,
pub collection_id: Option<i32>,
pub original_title: Option<String>,
pub display_title: Option<String>,
pub track_number: Option<i32>,
pub genre: Option<String>,
pub track_datetime: Option<String>,
pub length_sec: i32,
}
impl Track {
pub fn all() -> All<tracks::table, Self> {
tracks::table.select(Self::as_select())
}
#[auto_type(no_type_alias)]
pub fn by_id(id: i32) -> _ {
let all: All<tracks::table, Self> = Self::all();
let filter = tracks::id.eq(id);
all.filter(filter)
}
#[auto_type(no_type_alias)]
pub fn by_original_title(title: &str) -> _ {
let all: All<tracks::table, Self> = Self::all();
let filter = tracks::original_title.eq(title);
all.filter(filter)
}
}
#[derive(Debug, Serialize)]
pub struct DetailedArtist {
pub id: i32,
pub original_name: String,
pub display_name: String,
}
#[derive(Debug, Serialize)]
pub struct DetailedCollection<'a> {
pub id: i32,
pub artist: Option<&'a DetailedArtist>,
pub collection_type: String,
pub original_name: String,
pub display_name: String,
}
#[derive(Debug, Serialize)]
pub struct DetailedTrack<'a> {
pub id: i32,
pub file_path: String,
pub artist: Option<&'a DetailedArtist>,
// a collection could be under another artist (e.g. mixtapes)
pub collection: Option<&'a DetailedCollection<'a>>,
pub original_title: Option<String>,
pub display_title: Option<String>,
pub track_number: Option<i32>,
pub genre: Option<String>,
pub track_datetime: Option<String>,
pub length_sec: i32,
}
#[derive(Debug, Clone, Insertable)]
#[diesel(table_name = artists)]
pub struct NewArtist<'a> {
pub original_name: &'a str,
pub display_name: &'a str,
}
#[derive(Debug, Clone, Insertable)]
#[diesel(table_name = collections)]
pub struct NewCollection<'a> {
pub artist_id: Option<i32>,
pub collection_type: &'a str,
pub original_name: &'a str,
pub display_name: &'a str,
}
#[derive(Debug, Clone, Insertable)]
#[diesel(table_name = tracks)]
pub struct NewTrack<'a> {
pub file_path: &'a str,
pub artist_id: Option<i32>,
pub collection_id: Option<i32>,
pub original_title: Option<&'a str>,
pub display_title: Option<&'a str>,
pub track_number: Option<i32>,
pub genre: Option<&'a str>,
pub track_datetime: Option<&'a str>,
pub length_sec: i32,
}