entertainarr_adapter_sqlite/
tvshow_episode_file.rs

1use anyhow::Context;
2use entertainarr_domain::media::entity::MediaFile;
3use entertainarr_domain::tvshow::entity::{ListEpisodeFileParams, TvShowEpisodeFile};
4
5use crate::Wrapper;
6use crate::prelude::HasAnyOf;
7
8const LIST_QUERY: &str = r#"select tef.tvshow_episode_id, mf.id, mf.disk, mf.filepath, mf.filename, mf.content_type, mf.file_size, mf.created_at, mf.updated_at
9from media_files as mf
10join tvshow_episode_files tef on tef.media_file_id = mf.id
11where true"#;
12
13impl entertainarr_domain::tvshow::prelude::TvShowEpisodeFileRepository for crate::Pool {
14    #[tracing::instrument(
15        skip_all,
16        fields(
17            otel.kind = "client",
18            db.system = "sqlite",
19            db.name = "tvshow",
20            db.operation = "select",
21            db.sql.table = "tvshow_episode_files",
22            db.query.text = tracing::field::Empty,
23            db.response.returned_rows = tracing::field::Empty,
24            error.type = tracing::field::Empty,
25            error.message = tracing::field::Empty,
26            error.stacktrace = tracing::field::Empty,
27        ),
28        err(Debug),
29    )]
30    async fn list<'a>(
31        &self,
32        params: ListEpisodeFileParams<'a>,
33    ) -> anyhow::Result<Vec<TvShowEpisodeFile>> {
34        let mut qb: sqlx::QueryBuilder<sqlx::Sqlite> = sqlx::QueryBuilder::new(LIST_QUERY);
35        if !params.episode_ids.is_empty() {
36            qb.push(" AND ")
37                .push_any("tef.tvshow_episode_id", params.episode_ids);
38        }
39        tracing::Span::current().record("db.query.text", qb.sql());
40        qb.build_query_as()
41            .fetch_all(self.as_ref())
42            .await
43            .inspect(crate::record_all)
44            .inspect_err(crate::record_error)
45            .map(Wrapper::list)
46            .context("unable to fetch episode files")
47    }
48}
49
50impl<'r> sqlx::FromRow<'r, sqlx::sqlite::SqliteRow> for crate::Wrapper<TvShowEpisodeFile> {
51    fn from_row(row: &'r sqlx::sqlite::SqliteRow) -> Result<Self, sqlx::Error> {
52        use sqlx::Row;
53
54        let mut idx = crate::IndexIter::default();
55
56        let tvshow_episode_id: u64 = row.try_get(idx.next())?;
57        let media_file = Wrapper::<MediaFile>::from_index_row(row, &mut idx)?;
58
59        Ok(Wrapper(TvShowEpisodeFile {
60            tvshow_episode_id,
61            media_file: media_file.inner(),
62        }))
63    }
64}