use crate::db::{queries::parse_query, schemas};
use surrealdb::opt::IntoQuery;
use surrealqlx::surrql;
#[must_use]
#[inline]
pub const fn add_to_song() -> impl IntoQuery {
surrql!("RELATE $id->analysis_to_song->$song")
}
#[must_use]
#[inline]
pub const fn read_for_song() -> impl IntoQuery {
surrql!("SELECT * FROM $song<-analysis_to_song.in")
}
#[must_use]
#[inline]
pub const fn read_for_songs() -> impl IntoQuery {
surrql!("array::flatten($songs<-analysis_to_song<-analysis)")
}
#[must_use]
#[inline]
pub const fn read_song() -> impl IntoQuery {
surrql!("SELECT * FROM $id->analysis_to_song.out")
}
#[must_use]
#[inline]
pub const fn read_songs() -> impl IntoQuery {
surrql!("SELECT * FROM array::flatten($ids->analysis_to_song->song)")
}
#[allow(clippy::module_name_repetitions)]
#[must_use]
#[inline]
pub const fn read_songs_without_analysis() -> impl IntoQuery {
surrql!("SELECT * FROM song WHERE count(<-analysis_to_song.in) = 0")
}
#[must_use]
#[inline]
pub fn nearest_neighbors(n: u32) -> impl IntoQuery {
parse_query(format!(
"SELECT * FROM {} WHERE id IS NOT $id AND features <|{n}|> $target",
schemas::analysis::TABLE_NAME
))
}
#[must_use]
#[inline]
pub fn nearest_neighbors_to_many(n: u32, use_embeddings: bool) -> impl IntoQuery {
parse_query(format!(
"SELECT * FROM {} WHERE id NOT IN $ids AND {} <|{n}|> $target",
schemas::analysis::TABLE_NAME,
if use_embeddings {
"embedding"
} else {
"features"
}
))
}
#[cfg(test)]
mod query_validation_tests {
use rstest::rstest;
use surrealdb::opt::IntoQuery;
use crate::db::queries::validate_query;
use super::*;
#[rstest]
#[case::add_to_song(add_to_song(), "RELATE $id->analysis_to_song->$song")]
#[case::read_for_song(read_for_song(), "SELECT * FROM $song<-analysis_to_song.in")]
#[case::read_for_songs(read_for_songs(), "array::flatten($songs<-analysis_to_song<-analysis)")]
#[case::read_song(read_song(), "SELECT * FROM $id->analysis_to_song.out")]
#[case::read_songs(
read_songs(),
"SELECT * FROM array::flatten($ids->analysis_to_song->song)"
)]
#[case::read_songs_without_analysis(
read_songs_without_analysis(),
"SELECT * FROM song WHERE count(<-analysis_to_song.in) = 0"
)]
#[case::nearest_neighbors(
nearest_neighbors(5),
"SELECT * FROM analysis WHERE id IS NOT $id AND features <|5|> $target"
)]
#[case::nearest_neighbors_to_many(
nearest_neighbors_to_many(5, false),
"SELECT * FROM analysis WHERE id NOT IN $ids AND features <|5|> $target"
)]
#[case::nearest_neighbors_to_many_use_embeddings(
nearest_neighbors_to_many(5, true),
"SELECT * FROM analysis WHERE id NOT IN $ids AND embedding <|5|> $target"
)]
fn test_queries(#[case] query: impl IntoQuery, #[case] expected: &str) {
validate_query(query, expected);
}
}