Skip to main content

post_archiver/importer/
collection.rs

1use std::hash::Hash;
2
3use rusqlite::params;
4
5use crate::{
6    error::Result,
7    manager::{PostArchiverConnection, PostArchiverManager, UpdateCollection},
8    CollectionId, FileMetaId,
9};
10
11impl<T> PostArchiverManager<T>
12where
13    T: PostArchiverConnection,
14{
15    /// Import a collection into the archive.
16    ///
17    /// If the collection already exists (by source), it updates its name and returns the existing ID.
18    ///
19    /// # Errors
20    ///
21    /// Returns `Error` if there was an error accessing the database.
22    pub fn import_collection(&self, collection: UnsyncCollection) -> Result<CollectionId> {
23        // find by source
24        if let Some(id) = self.find_collection_by_source(&collection.source)? {
25            self.bind(id)
26                .update(UpdateCollection::default().name(collection.name))?;
27            return Ok(id);
28        }
29
30        // insert
31        let mut ins_stmt = self.conn().prepare_cached(
32            "INSERT INTO collections (name, source, thumb) VALUES (?, ?, ?) RETURNING id",
33        )?;
34        let id: CollectionId = ins_stmt.query_row(
35            params![
36                collection.name,
37                collection.source,
38                Option::<FileMetaId>::None
39            ],
40            |row| row.get(0),
41        )?;
42        Ok(id)
43    }
44
45    /// Import multiple collections into the archive.
46    ///
47    /// This method takes an iterator of `UnsyncCollection` and imports each one.
48    ///
49    /// # Errors
50    ///
51    /// Returns `Error` if there was an error accessing the database.
52    pub fn import_collections(
53        &self,
54        collections: impl IntoIterator<Item = UnsyncCollection>,
55    ) -> Result<Vec<CollectionId>> {
56        collections
57            .into_iter()
58            .map(|collection| self.import_collection(collection))
59            .collect::<Result<Vec<CollectionId>>>()
60    }
61}
62
63/// Represents a collection that is not yet synced to the database.
64#[derive(Debug, Clone, PartialEq, Eq, Hash)]
65pub struct UnsyncCollection {
66    pub name: String,
67    pub source: String,
68}
69
70impl UnsyncCollection {
71    pub fn new(name: String, source: String) -> Self {
72        Self { name, source }
73    }
74    pub fn name(mut self, name: String) -> Self {
75        self.name = name;
76        self
77    }
78    pub fn source(mut self, source: String) -> Self {
79        self.source = source;
80        self
81    }
82}