scylla_migrate/
migration.rs

1use anyhow::{Context, Result};
2use scylla::client::session::Session;
3use sha2::{Digest, Sha384};
4use std::borrow::Cow;
5
6/// Represents a single database migration
7///
8/// Each migration corresponds to a .cql file in the migrations directory.
9/// The file name format should be: TIMESTAMP_description.cql
10/// For example: "20240117000000_create_users.cql"
11#[derive(Debug)]
12pub struct Migration {
13    pub version: i64,
14    pub description: Cow<'static, str>,
15    pub cql: Cow<'static, str>,
16    pub checksum: Cow<'static, [u8]>,
17}
18
19impl Migration {
20    /// Creates a new Migration instance
21    pub fn new(version: i64, description: Cow<'static, str>, cql: Cow<'static, str>) -> Self {
22        let checksum = Cow::Owned(Vec::from(Sha384::digest(cql.as_bytes()).as_slice()));
23
24        Migration {
25            version,
26            description,
27            cql,
28            checksum,
29        }
30    }
31
32    pub async fn up(&self, session: &Session) -> Result<()> {
33        // Split the content into individual statements
34        let statements: Vec<_> = self
35            .cql
36            .split(';')
37            .map(|s| s.trim())
38            .filter(|s| !s.is_empty())
39            .collect();
40
41        for stmt in statements {
42            session
43                .query_unpaged(stmt, &[])
44                .await
45                .with_context(|| format!("Failed to execute migration statement: {}", stmt))?;
46        }
47
48        Ok(())
49    }
50}
51
52pub struct AppliedMigration {
53    pub checksum: Cow<'static, [u8]>,
54}