musicbrainz-light 0.1.3

A lightweight MusicBrainz database importer and processor
Documentation
use sqlx::{
    PgPool,
    prelude::FromRow,
    types::chrono::{DateTime, Utc},
};

use crate::{MbLightError, error::MbLightResult};

#[derive(Debug, FromRow)]
pub struct ReplicationControl {
    pub current_schema_sequence: Option<i32>,
    pub current_replication_sequence: Option<i32>,
    pub last_replication_date: Option<DateTime<Utc>>,
}

impl ReplicationControl {
    pub async fn get(db: &PgPool) -> Result<Self, sqlx::Error> {
        sqlx::query_as(
            "SELECT current_schema_sequence, current_replication_sequence, last_replication_date FROM replication_control"
        )
        .fetch_one(db)
        .await
    }

    pub async fn update(self, db: &PgPool) -> MbLightResult<()> {
        sqlx::query(
            "UPDATE replication_control SET current_replication_sequence = $1, last_replication_date = NOW()",
        )
        .bind(self.next_replication_sequence()?)
        .execute(db)
        .await?;
        Ok(())
    }

    pub fn next_replication_sequence(&self) -> MbLightResult<i32> {
        self.current_replication_sequence
            .map(|seq| seq + 1)
            .ok_or(MbLightError::MissingRepplicationSequence)
    }

    pub fn is_next(&self, expected: i32) -> MbLightResult<bool> {
        Ok(self.next_replication_sequence()? + 1 == expected)
    }

    pub fn schema_sequence_match(&self, actual: i32) -> bool {
        self.current_schema_sequence == Some(actual)
    }

    pub fn next_replication_packet_url(&self, base: &str, token: &str) -> MbLightResult<String> {
        let seq = self.next_replication_sequence()?;
        Ok(format!("{base}/replication-{seq}-v2.tar.bz2?token={token}"))
    }
}