sample-amp/src/lib.rs

108 lines
3.1 KiB
Rust

use diesel::prelude::*;
use dotenvy::dotenv;
use models::{NewSample, Sample, Tag};
use std::{env, path::Path};
use crate::models::{Library, NewLibrary, NewSampleTag, NewTag, SampleTag};
pub mod models;
pub mod schema;
pub mod tag_terms;
pub fn establish_connection() -> SqliteConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
SqliteConnection::establish(&database_url)
.unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}
pub fn create_library(conn: &mut SqliteConnection, name: &str) -> Library {
use crate::schema::libraries;
let new_library = NewLibrary { name };
diesel::insert_into(libraries::table)
.values(&new_library)
.returning(Library::as_returning())
.get_result(conn)
.expect("Error saving new post")
}
pub fn get_tag<'a>(conn: &mut SqliteConnection, tag: &'a str) -> Option<Tag> {
use crate::schema::tags::dsl::*;
tags.filter(name.eq(&tag))
.select(Tag::as_select())
.first(conn)
.ok()
}
pub fn list_tags(conn: &mut SqliteConnection) -> Vec<Tag> {
use crate::schema::tags::dsl::*;
tags.select(Tag::as_select())
.get_results(conn)
.expect("can't list tags")
}
pub fn samples_with_tag<'a>(conn: &mut SqliteConnection, tag: &'a str) -> Vec<Sample> {
let tag = get_tag(conn, tag).expect("Expected tag to exist...");
let sample_ids = SampleTag::belonging_to(&tag).select(schema::samples_tags::sample_id);
schema::samples::table
.filter(schema::samples::id.eq_any(sample_ids))
.select(Sample::as_select())
.get_results(conn)
.expect("expected sample")
}
pub fn add_sample<'a>(
conn: &mut SqliteConnection,
path: &Path,
tags: impl Iterator<Item = &'a String>,
) -> (Sample, Vec<Tag>) {
use crate::schema::{samples, samples_tags, tags};
let name = path.file_name().expect("expected file name");
let new_sample = NewSample {
name: &name.to_string_lossy(),
path: &path.to_string_lossy(),
bpm: None,
key: None,
};
let sample = diesel::insert_into(samples::table)
.values(&new_sample)
.returning(Sample::as_returning())
.get_result(conn)
.expect("Error saving new sample");
let tags: Vec<Tag> = tags
.into_iter()
.map(|tag_name| {
let tag = get_tag(conn, tag_name).unwrap_or_else(|| {
let tag = NewTag { name: tag_name };
diesel::insert_into(tags::table)
.values(&tag)
.returning(Tag::as_returning())
.get_result(conn)
.expect("Error saving tag")
});
let sample_tag = NewSampleTag {
tag_id: tag.id,
sample_id: sample.id,
};
diesel::insert_into(samples_tags::table)
.values(&sample_tag)
.returning(SampleTag::as_returning())
.get_result(conn)
.expect("Error adding sample_tag");
tag
})
.collect();
(sample, tags)
}