Skip to main content

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}