post_archiver/importer/
file_meta.rs1use std::{collections::HashMap, hash::Hash};
2
3use rusqlite::params;
4use serde_json::Value;
5
6use crate::{
7 error::Result,
8 manager::{
9 file_meta::FileMetaContent, PostArchiverConnection, PostArchiverManager, UpdateFileMeta,
10 },
11 FileMetaId, Post, PostId,
12};
13
14impl<T> PostArchiverManager<T>
15where
16 T: PostArchiverConnection,
17{
18 pub fn import_file_meta(&self, post: PostId, file_meta: &UnsyncFileMeta) -> Result<FileMetaId> {
27 if let Some(id) = self.find_file_meta(post, &file_meta.filename)? {
29 self.bind(id)
31 .update(UpdateFileMeta::default().extra(file_meta.extra.clone()))?;
32 return Ok(id);
33 }
34
35 let path = self.path.join(Post::directory(post));
36 if !path.exists() {
37 std::fs::create_dir_all(&path)?;
38 }
39 file_meta.data.write(&path.join(&file_meta.filename))?;
40
41 let mut ins_stmt = self.conn().prepare_cached(
43 "INSERT INTO file_metas (post, filename, mime, extra) VALUES (?, ?, ?, ?) RETURNING id",
44 )?;
45 Ok(ins_stmt.query_row(
46 params![
47 post,
48 file_meta.filename,
49 file_meta.mime,
50 serde_json::to_string(&file_meta.extra).unwrap()
51 ],
52 |row| row.get(0),
53 )?)
54 }
55}
56
57#[derive(Debug, Clone)]
59pub struct UnsyncFileMeta {
60 pub filename: String,
61 pub mime: String,
62 pub extra: HashMap<String, Value>,
63 pub data: FileMetaContent,
64}
65
66impl Hash for UnsyncFileMeta {
67 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
68 self.filename.hash(state);
69 self.mime.hash(state);
70 }
71}
72
73impl PartialEq for UnsyncFileMeta {
74 fn eq(&self, other: &Self) -> bool {
75 self.filename == other.filename && self.mime == other.mime && self.extra == other.extra
76 }
77}
78
79impl Eq for UnsyncFileMeta {}
80
81impl UnsyncFileMeta {
82 pub fn new(filename: String, mime: String, data: FileMetaContent) -> Self {
83 Self {
84 filename,
85 mime,
86 data: data.into(),
87 extra: HashMap::new(),
88 }
89 }
90
91 pub fn extra(mut self, extra: HashMap<String, Value>) -> Self {
92 self.extra = extra;
93 self
94 }
95}