Skip to main content

postproject_core/
storage.rs

1//! Domain-shaped contracts implemented by persistence backends.
2
3use crate::{
4    Activity, Asset, AssetId, ExternalIdentifier, IdentifierScheme, Locator, MediaRoot,
5    MetadataAssertion, MetadataMatch, MetadataProperty, MetadataValue, ObjectRef,
6    OriginalMediaImport, Production, Representation, RepresentationId, RepresentationImport,
7    Resource, ResourceId, Result, Revision, RevisionContext, RevisionEvent, RevisionId,
8    TransactionId, TransactionState,
9};
10
11/// Read operations required from a production persistence backend.
12///
13/// The contract returns domain values and deliberately contains no generic CRUD,
14/// query language, connection, or database-row concepts.
15pub trait ProductionRead {
16    /// Returns the loaded production metadata and configured media roots.
17    fn production(&self) -> &Production;
18
19    /// Loads all assets in deterministic order.
20    ///
21    /// # Errors
22    ///
23    /// Returns a storage-domain error when persisted data cannot be read or
24    /// decoded safely.
25    fn assets(&self) -> Result<Vec<Asset>>;
26
27    /// Loads every representation belonging to an asset in deterministic order.
28    ///
29    /// # Errors
30    ///
31    /// Returns a storage-domain error when persisted data cannot be read or
32    /// decoded safely.
33    fn representations(&self, asset_id: AssetId) -> Result<Vec<Representation>>;
34
35    /// Loads resources used by a representation in structural order.
36    ///
37    /// # Errors
38    ///
39    /// Returns a storage-domain error when persisted data cannot be read or
40    /// decoded safely.
41    fn resources(&self, representation_id: RepresentationId) -> Result<Vec<Resource>>;
42
43    /// Loads every known locator belonging to a resource.
44    ///
45    /// # Errors
46    ///
47    /// Returns a storage-domain error when persisted data cannot be read or
48    /// decoded safely.
49    fn locators(&self, resource_id: ResourceId) -> Result<Vec<Locator>>;
50
51    /// Loads external identifiers attached to `target` in deterministic order.
52    ///
53    /// # Errors
54    ///
55    /// Returns a storage-domain error when persisted data cannot be read or
56    /// decoded safely, or when the target kind is not supported.
57    fn external_identifiers(&self, target: ObjectRef) -> Result<Vec<ExternalIdentifier>>;
58
59    /// Finds objects carrying the exact external scheme and value.
60    ///
61    /// # Errors
62    ///
63    /// Returns a domain error when the lookup value is invalid or persisted
64    /// data cannot be decoded safely.
65    fn find_by_external_identifier(
66        &self,
67        scheme: &IdentifierScheme,
68        value: &str,
69    ) -> Result<Vec<ObjectRef>>;
70
71    /// Loads all metadata assertions attached to `target` in deterministic order.
72    ///
73    /// # Errors
74    ///
75    /// Returns a domain error when the target kind is unsupported or persisted
76    /// data cannot be decoded safely.
77    fn metadata(&self, target: ObjectRef) -> Result<Vec<MetadataAssertion>>;
78
79    /// Loads every ordered value for one property on `target`.
80    ///
81    /// # Errors
82    ///
83    /// Returns a domain error when the target kind is unsupported or persisted
84    /// data cannot be decoded safely.
85    fn metadata_values(
86        &self,
87        target: ObjectRef,
88        property: &MetadataProperty,
89    ) -> Result<Vec<MetadataValue>>;
90
91    /// Finds every object carrying `property`, preserving value repetition.
92    ///
93    /// # Errors
94    ///
95    /// Returns a domain error when persisted data cannot be decoded safely.
96    fn query_by_metadata_property(&self, property: &MetadataProperty)
97    -> Result<Vec<MetadataMatch>>;
98
99    /// Loads all production activities in deterministic identity order.
100    ///
101    /// # Errors
102    ///
103    /// Returns a storage-domain error when persisted activity data cannot be
104    /// read or decoded safely.
105    fn activities(&self) -> Result<Vec<Activity>>;
106
107    /// Loads activities that produce `representation_id`.
108    ///
109    /// # Errors
110    ///
111    /// Returns a domain error when the representation is absent or persisted
112    /// activity data cannot be read safely.
113    fn activities_producing(&self, representation_id: RepresentationId) -> Result<Vec<Activity>>;
114
115    /// Loads activities that consume `representation_id`.
116    ///
117    /// # Errors
118    ///
119    /// Returns a domain error when the representation is absent or persisted
120    /// activity data cannot be read safely.
121    fn activities_consuming(&self, representation_id: RepresentationId) -> Result<Vec<Activity>>;
122
123    /// Returns every transitive provenance ancestor of `representation_id`.
124    ///
125    /// # Errors
126    ///
127    /// Returns a domain error when the representation is absent or persisted
128    /// provenance cannot be traversed safely.
129    fn ancestors(&self, representation_id: RepresentationId) -> Result<Vec<RepresentationId>>;
130
131    /// Returns every transitive provenance descendant of `representation_id`.
132    ///
133    /// # Errors
134    ///
135    /// Returns a domain error when the representation is absent or persisted
136    /// provenance cannot be traversed safely.
137    fn descendants(&self, representation_id: RepresentationId) -> Result<Vec<RepresentationId>>;
138
139    /// Returns the newest durable revision, or `None` for an empty journal.
140    ///
141    /// # Errors
142    ///
143    /// Returns a storage-domain error when persisted revision data is invalid.
144    fn latest_revision(&self) -> Result<Option<Revision>>;
145
146    /// Returns revisions after `sequence` in ascending order, capped by `limit`.
147    ///
148    /// # Errors
149    ///
150    /// Returns a domain error when `limit` is zero or excessive, or when
151    /// persisted revision data is invalid.
152    fn changes_since(&self, sequence: u64, limit: u32) -> Result<Vec<Revision>>;
153
154    /// Loads the semantic events for one revision in stable position order.
155    ///
156    /// # Errors
157    ///
158    /// Returns a domain error when the revision is absent or persisted event
159    /// data is invalid.
160    fn events_for_revision(&self, revision_id: RevisionId) -> Result<Vec<RevisionEvent>>;
161}
162
163/// Transactional mutation operations required from a persistence backend.
164pub trait ProductionStoreTransaction {
165    /// Returns this transaction's stable identity.
166    fn id(&self) -> TransactionId;
167
168    /// Returns the current lifecycle state.
169    fn state(&self) -> TransactionState;
170
171    /// Sets the origin and message for the revision created on commit.
172    ///
173    /// # Errors
174    ///
175    /// Returns a domain error when the transaction is already closed.
176    fn set_revision_context(&mut self, context: RevisionContext) -> Result<()>;
177
178    /// Stages one prepared original-media aggregate atomically.
179    ///
180    /// # Errors
181    ///
182    /// Returns a domain error when the transaction is closed or persistence
183    /// rejects the aggregate.
184    fn import_original(&mut self, import: &OriginalMediaImport) -> Result<()>;
185
186    /// Stages a representation and its newly imported resources on an existing asset.
187    ///
188    /// # Errors
189    ///
190    /// Returns a domain error when the transaction is closed, the owning asset
191    /// does not exist, or persistence rejects the aggregate.
192    fn add_representation(&mut self, import: &RepresentationImport) -> Result<()>;
193
194    /// Stages an explicitly confirmed resource locator.
195    ///
196    /// # Errors
197    ///
198    /// Returns a domain error when the transaction is closed or persistence
199    /// rejects the locator.
200    fn add_locator(&mut self, locator: &Locator) -> Result<()>;
201
202    /// Stages retirement of one superseded resource locator.
203    ///
204    /// # Errors
205    ///
206    /// Returns a domain error when the transaction is closed, the locator does
207    /// not exist, or persistence fails.
208    fn retire_locator(&mut self, locator_id: crate::LocatorId) -> Result<()>;
209
210    /// Stages a configured resolver search root.
211    ///
212    /// # Errors
213    ///
214    /// Returns a domain error when the transaction is closed or persistence
215    /// rejects the root.
216    fn add_media_root(&mut self, root: MediaRoot) -> Result<()>;
217
218    /// Enables or disables a configured resolver search root.
219    ///
220    /// Setting the existing state is an idempotent no-op.
221    ///
222    /// # Errors
223    ///
224    /// Returns a domain error when the transaction is closed, the root does not
225    /// exist, or persistence fails.
226    fn set_media_root_enabled(&mut self, root_id: crate::MediaRootId, enabled: bool) -> Result<()>;
227
228    /// Stages removal of a configured resolver search root.
229    ///
230    /// # Errors
231    ///
232    /// Returns a domain error when the transaction is closed, the root does not
233    /// exist, or persistence fails.
234    fn remove_media_root(&mut self, root_id: crate::MediaRootId) -> Result<()>;
235
236    /// Stages an external identifier attachment.
237    ///
238    /// # Errors
239    ///
240    /// Returns a domain error when the transaction is closed, the target does
241    /// not exist, the attachment already exists, or persistence fails.
242    fn add_external_identifier(
243        &mut self,
244        target: ObjectRef,
245        identifier: &ExternalIdentifier,
246    ) -> Result<()>;
247
248    /// Stages removal of one exact external identifier attachment.
249    ///
250    /// # Errors
251    ///
252    /// Returns a domain error when the transaction is closed, the attachment
253    /// does not exist, the target kind is unsupported, or persistence fails.
254    fn remove_external_identifier(
255        &mut self,
256        target: ObjectRef,
257        identifier: &ExternalIdentifier,
258    ) -> Result<()>;
259
260    /// Appends one value to an object's metadata property.
261    ///
262    /// # Errors
263    ///
264    /// Returns a domain error when the transaction is closed, the target does
265    /// not exist or is unsupported, encoding fails, or persistence fails.
266    fn add_metadata_value(
267        &mut self,
268        target: ObjectRef,
269        property: &MetadataProperty,
270        value: &MetadataValue,
271    ) -> Result<()>;
272
273    /// Atomically replaces all values of one metadata property.
274    ///
275    /// An empty value slice removes the property.
276    ///
277    /// # Errors
278    ///
279    /// Returns a domain error when the transaction is closed, the target does
280    /// not exist or is unsupported, encoding fails, or persistence fails.
281    fn replace_metadata_values(
282        &mut self,
283        target: ObjectRef,
284        property: &MetadataProperty,
285        values: &[MetadataValue],
286    ) -> Result<()>;
287
288    /// Removes all values of one metadata property.
289    ///
290    /// # Errors
291    ///
292    /// Returns a domain error when the transaction is closed, the property is
293    /// absent, the target kind is unsupported, or persistence fails.
294    fn remove_metadata_property(
295        &mut self,
296        target: ObjectRef,
297        property: &MetadataProperty,
298    ) -> Result<()>;
299
300    /// Stages a complete production activity with its input and output edges.
301    ///
302    /// # Errors
303    ///
304    /// Returns a domain error when the transaction is closed, a referenced
305    /// representation is absent, the activity already exists, its edges would
306    /// create a provenance cycle, or persistence fails.
307    fn create_activity(&mut self, activity: &Activity) -> Result<()>;
308
309    /// Atomically makes every staged mutation durable.
310    ///
311    /// # Errors
312    ///
313    /// Returns a domain error when the transaction is closed or commit fails.
314    fn commit(&mut self) -> Result<()>;
315
316    /// Explicitly discards every staged mutation.
317    ///
318    /// # Errors
319    ///
320    /// Returns a domain error when the transaction is closed or rollback fails.
321    fn rollback(&mut self) -> Result<()>;
322}
323
324/// A production persistence backend with explicit domain transactions.
325pub trait ProductionStore: ProductionRead {
326    /// Backend-specific transaction implementation borrowing this store.
327    type Transaction<'production>: ProductionStoreTransaction
328    where
329        Self: 'production;
330
331    /// Begins a transaction for domain mutations.
332    ///
333    /// # Errors
334    ///
335    /// Returns a storage-domain error when a transaction cannot be started.
336    fn begin_transaction(&mut self) -> Result<Self::Transaction<'_>>;
337}