Skip to main content

sofie_db/
publishing.rs

1use sofie_core::{Cast, Error, Instant, Result, SqlValue};
2
3use crate::behavior::{stored, stored_time};
4use crate::requested::{STAMP_REQUESTED, stamp_requested, stored_mut};
5use crate::{Aggregate, Behavior, Column, Field, Plan, Uses, Write};
6
7pub struct PublishLock;
8
9impl Behavior for PublishLock {
10    fn columns(&self) -> &'static [Field] {
11        const { &[Field::new("published_at", Instant::COLUMNS, true)] }
12    }
13
14    fn written(&self, write: &Write<'_>, values: &mut [SqlValue]) {
15        stamp_requested(write, &mut values[0]);
16    }
17
18    fn planned(&self, write: &Write<'_>, _plan: &mut Plan<'_>) -> Result<()> {
19        let published = write
20            .loaded("published_at")
21            .is_some_and(|value| *value != SqlValue::Null);
22        if published && !write.changed_fields().is_empty() {
23            return Err(Error::Rule(format!(
24                "a published {} cannot be changed; supersede it with a new one",
25                write.table.name
26            )));
27        }
28        Ok(())
29    }
30}
31
32pub trait Publishes: Aggregate {
33    const PUBLISHED_AT: Column<Self, Option<Instant>> = Column::new("published_at");
34
35    fn publish(&mut self) {
36        if !self.is_published() {
37            *stored_mut::<Self>(self, "published_at") = STAMP_REQUESTED;
38        }
39    }
40
41    fn is_published(&self) -> bool {
42        stored::<Self>(self, "published_at").is_some_and(|value| *value != SqlValue::Null)
43    }
44
45    fn published_at(&self) -> Option<Instant> {
46        stored_time::<Self>(self, "published_at")
47    }
48}
49
50impl<A: Uses<PublishLock>> Publishes for A {}
51
52/// Sent through the message table, so it is delivered after the commit.
53pub struct Broadcasts;
54
55impl Behavior for Broadcasts {
56    fn columns(&self) -> &'static [Field] {
57        &[]
58    }
59
60    fn written(&self, _write: &Write<'_>, _values: &mut [SqlValue]) {}
61
62    fn broadcasts(&self) -> bool {
63        true
64    }
65}