post_archiver/importer/
author.rs1use chrono::{DateTime, Utc};
2use rusqlite::params;
3
4use crate::{
5 error::Result,
6 manager::{PostArchiverConnection, PostArchiverManager, UpdateAuthor},
7 AuthorId, PlatformId,
8};
9
10impl<T> PostArchiverManager<T>
11where
12 T: PostArchiverConnection,
13{
14 pub fn import_author(&self, author: UnsyncAuthor) -> Result<AuthorId> {
22 let id = {
24 let mut found: Option<AuthorId> = None;
25 for alias in &author.aliases {
26 if let Some(id) = self.find_author_by_alias(&alias.source, alias.platform)? {
27 found = Some(id);
28 break;
29 }
30 }
31 found
32 };
33
34 let aliases = author
35 .aliases
36 .into_iter()
37 .map(|alias| (alias.source, alias.platform, alias.link))
38 .collect::<Vec<_>>();
39
40 match id {
41 Some(id) => {
42 let b = self.bind(id);
43 let mut upd = UpdateAuthor::default().name(author.name);
44 if let Some(updated) = author.updated {
45 upd = upd.updated(updated);
46 }
47 b.update(upd)?;
48
49 b.add_aliases(aliases)?;
50
51 Ok(id)
52 }
53 None => {
54 let mut stmt = self.conn().prepare_cached(
56 "INSERT INTO authors (name, updated) VALUES (?, ?) RETURNING id",
57 )?;
58 let id: AuthorId = stmt.query_row(
59 params![author.name, author.updated.unwrap_or_else(Utc::now)],
60 |row| row.get(0),
61 )?;
62
63 self.bind(id).add_aliases(aliases)?;
64
65 Ok(id)
66 }
67 }
68 }
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct UnsyncAuthor {
74 name: String,
75 updated: Option<DateTime<Utc>>,
76 aliases: Vec<UnsyncAlias>,
77}
78
79impl UnsyncAuthor {
80 pub fn new(name: String) -> Self {
81 Self {
82 name,
83 updated: None,
84 aliases: Vec::new(),
85 }
86 }
87
88 pub fn name(self, name: String) -> Self {
89 Self { name, ..self }
90 }
91 pub fn aliases(self, aliases: Vec<UnsyncAlias>) -> Self {
92 Self { aliases, ..self }
93 }
94 pub fn updated(self, updated: Option<DateTime<Utc>>) -> Self {
95 Self { updated, ..self }
96 }
97 pub fn sync<T>(self, manager: &PostArchiverManager<T>) -> Result<AuthorId>
105 where
106 T: PostArchiverConnection,
107 {
108 manager.import_author(self)
109 }
110}
111
112#[derive(Debug, Clone, PartialEq, Eq, Hash)]
117pub struct UnsyncAlias {
118 pub source: String,
119 pub platform: PlatformId,
120 pub link: Option<String>,
121}
122
123impl UnsyncAlias {
124 pub fn new(platform: PlatformId, source: String) -> Self {
125 Self {
126 link: None,
127 source,
128 platform,
129 }
130 }
131
132 pub fn source<S: Into<String>>(mut self, source: S) -> Self {
133 self.source = source.into();
134 self
135 }
136
137 pub fn platform(mut self, platform: PlatformId) -> Self {
138 self.platform = platform;
139 self
140 }
141
142 pub fn link<S: Into<String>>(mut self, link: S) -> Self {
143 self.link = Some(link.into());
144 self
145 }
146}