rouchdb_core/adapter.rs
1use std::collections::HashMap;
2
3use async_trait::async_trait;
4
5use crate::document::*;
6use crate::error::Result;
7
8/// The trait all storage adapters must implement.
9///
10/// This mirrors PouchDB's internal adapter interface (underscore-prefixed
11/// methods in JavaScript). Each method corresponds to a CouchDB API endpoint.
12///
13/// Adapters are responsible for:
14/// - Storing and retrieving documents with full revision tree support
15/// - Tracking sequence numbers for the changes feed
16/// - Managing local (non-replicated) documents for checkpoints
17/// - Attachment storage and retrieval
18#[async_trait]
19pub trait Adapter: Send + Sync {
20 /// Get database information: name, document count, update sequence.
21 async fn info(&self) -> Result<DbInfo>;
22
23 /// Retrieve a single document by ID.
24 ///
25 /// Supports fetching specific revisions, open revisions (all leaves),
26 /// and including conflict information.
27 async fn get(&self, id: &str, opts: GetOptions) -> Result<crate::document::Document>;
28
29 /// Write multiple documents atomically.
30 ///
31 /// When `opts.new_edits` is `true` (default), the adapter generates new
32 /// revision IDs and checks for conflicts.
33 ///
34 /// When `opts.new_edits` is `false` (replication mode), the adapter
35 /// accepts revision IDs as-is and merges them into the existing revision
36 /// tree without conflict checks.
37 async fn bulk_docs(
38 &self,
39 docs: Vec<crate::document::Document>,
40 opts: BulkDocsOptions,
41 ) -> Result<Vec<DocResult>>;
42
43 /// Query all documents, optionally filtered by key range.
44 async fn all_docs(&self, opts: AllDocsOptions) -> Result<AllDocsResponse>;
45
46 /// Get changes since a given sequence number.
47 async fn changes(&self, opts: ChangesOptions) -> Result<ChangesResponse>;
48
49 /// Compare sets of document revisions to find which ones the adapter
50 /// is missing. Used during replication to avoid transferring data the
51 /// target already has.
52 async fn revs_diff(&self, revs: HashMap<String, Vec<String>>) -> Result<RevsDiffResponse>;
53
54 /// Fetch multiple documents by ID and revision in a single request.
55 /// Used during replication to efficiently retrieve missing documents.
56 async fn bulk_get(&self, docs: Vec<BulkGetItem>) -> Result<BulkGetResponse>;
57
58 /// Store an attachment on a document.
59 async fn put_attachment(
60 &self,
61 doc_id: &str,
62 att_id: &str,
63 rev: &str,
64 data: Vec<u8>,
65 content_type: &str,
66 ) -> Result<DocResult>;
67
68 /// Retrieve raw attachment data.
69 async fn get_attachment(
70 &self,
71 doc_id: &str,
72 att_id: &str,
73 opts: GetAttachmentOptions,
74 ) -> Result<Vec<u8>>;
75
76 /// Remove an attachment from a document.
77 ///
78 /// Creates a new revision of the document with the attachment removed.
79 async fn remove_attachment(&self, doc_id: &str, att_id: &str, rev: &str) -> Result<DocResult>;
80
81 /// Retrieve a local document (not replicated, used for checkpoints).
82 async fn get_local(&self, id: &str) -> Result<serde_json::Value>;
83
84 /// Write a local document (not replicated, used for checkpoints).
85 async fn put_local(&self, id: &str, doc: serde_json::Value) -> Result<()>;
86
87 /// Remove a local document.
88 async fn remove_local(&self, id: &str) -> Result<()>;
89
90 /// Compact the database: remove old revisions, clean up unreferenced
91 /// attachment data.
92 async fn compact(&self) -> Result<()>;
93
94 /// Destroy the database and all its data.
95 async fn destroy(&self) -> Result<()>;
96
97 /// Close the database, releasing any held resources.
98 /// Default implementation is a no-op.
99 async fn close(&self) -> Result<()> {
100 Ok(())
101 }
102
103 /// Purge (permanently remove) document revisions.
104 async fn purge(
105 &self,
106 _req: HashMap<String, Vec<String>>,
107 ) -> Result<crate::document::PurgeResponse> {
108 Err(crate::error::RouchError::BadRequest(
109 "purge not supported".into(),
110 ))
111 }
112
113 /// Get the security document for this database.
114 async fn get_security(&self) -> Result<crate::document::SecurityDocument> {
115 Ok(crate::document::SecurityDocument::default())
116 }
117
118 /// Set the security document for this database.
119 async fn put_security(&self, _doc: crate::document::SecurityDocument) -> Result<()> {
120 Ok(())
121 }
122}