1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use chrono::{DateTime, NaiveDateTime, Utc};
use uuid::Uuid;
use crate::error::Result;
use crate::models::{DavItem, HistoryItem, QueueItem};
/// Database abstraction for nzbdav storage.
///
/// Implementations exist for SQLite (standalone, behind `sqlite` feature)
/// and PostgreSQL (StackArr integration, in stackarr-core).
#[async_trait::async_trait]
pub trait DavDatabase: Send + Sync {
// ── DavItem operations ─────────────────────────────────────────────
/// Insert or replace a DAV item.
async fn insert_dav_item(&self, item: &DavItem) -> Result<()>;
/// Look up a DAV item by its UUID.
async fn get_dav_item_by_id(&self, id: Uuid) -> Result<Option<DavItem>>;
/// Look up a DAV item by its virtual filesystem path.
async fn get_dav_item_by_path(&self, path: &str) -> Result<Option<DavItem>>;
/// List direct children of a parent item.
async fn get_dav_children(&self, parent_id: Uuid) -> Result<Vec<DavItem>>;
/// List direct children by parent path (joins on parent).
async fn get_dav_children_by_path(&self, parent_path: &str) -> Result<Vec<DavItem>>;
/// Delete a DAV item (children cascade).
async fn delete_dav_item(&self, id: Uuid) -> Result<()>;
/// Delete all DAV items linked to a history item.
async fn delete_dav_items_by_history(&self, history_item_id: Uuid) -> Result<()>;
/// Move/rename a DAV item to a new path and parent.
async fn move_dav_item(
&self,
id: Uuid,
new_name: &str,
new_path: &str,
new_parent_id: Uuid,
) -> Result<()>;
/// Update health check timestamps on a DAV item.
async fn update_dav_health_check(
&self,
id: Uuid,
last: DateTime<Utc>,
next: DateTime<Utc>,
) -> Result<()>;
// ── Blob operations ────────────────────────────────────────────────
/// Retrieve file metadata blob (DavMultipartFile / DavNzbFile serialized as bincode).
async fn get_file_blob(&self, id: Uuid) -> Result<Vec<u8>>;
/// Store file metadata blob.
async fn put_file_blob(&self, id: Uuid, data: &[u8]) -> Result<()>;
/// Retrieve raw NZB XML blob.
async fn get_nzb_blob(&self, id: Uuid) -> Result<Vec<u8>>;
/// Store raw NZB XML blob.
async fn put_nzb_blob(&self, id: Uuid, data: &[u8]) -> Result<()>;
/// Delete a raw NZB XML blob.
async fn delete_nzb_blob(&self, id: Uuid) -> Result<()>;
// ── Queue operations ───────────────────────────────────────────────
/// List all queue items ordered by priority DESC, created_at ASC.
async fn list_queue_items(&self) -> Result<Vec<QueueItem>>;
/// Get the next eligible queue item, excluding the given IDs.
async fn get_next_queue_item(&self, exclude_ids: &[Uuid]) -> Result<Option<QueueItem>>;
/// Insert a queue item.
async fn insert_queue_item(&self, item: &QueueItem) -> Result<()>;
/// Delete a queue item.
async fn delete_queue_item(&self, id: Uuid) -> Result<()>;
/// Update the pause_until timestamp on a queue item.
async fn update_queue_pause_until(
&self,
id: Uuid,
pause_until: Option<NaiveDateTime>,
) -> Result<()>;
/// Count total queue items.
async fn count_queue_items(&self) -> Result<i64>;
// ── History operations ─────────────────────────────────────────────
/// Insert a history item.
async fn insert_history_item(&self, item: &HistoryItem) -> Result<()>;
/// List history items, newest first.
async fn list_history_items(&self, offset: i64, limit: i64) -> Result<Vec<HistoryItem>>;
/// Delete a history item.
async fn delete_history_item(&self, id: Uuid) -> Result<()>;
/// Delete all history items.
async fn delete_all_history_items(&self) -> Result<()>;
/// Count total history items.
async fn count_history_items(&self) -> Result<i64>;
// ── Config operations ──────────────────────────────────────────────
/// Load all config key-value pairs.
async fn load_config_items(&self) -> Result<Vec<(String, String)>>;
/// Set a config value (upsert).
async fn set_config_item(&self, key: &str, value: &str) -> Result<()>;
}