toasty_cli/migration/
config.rs

1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4/// Configuration for migration operations.
5///
6/// Controls where migration files, snapshot files, and the history file are
7/// stored, how migration file names are prefixed (sequential numbers or
8/// timestamps), and optional behaviors like checksum verification and
9/// statement breakpoint comments.
10///
11/// The default configuration uses a `toasty/` base path with sequential
12/// numbering, no checksums, and statement breakpoints enabled.
13///
14/// # Examples
15///
16/// ```
17/// use toasty_cli::{MigrationConfig, MigrationPrefixStyle};
18///
19/// let config = MigrationConfig::new()
20///     .path("my_app/db")
21///     .prefix_style(MigrationPrefixStyle::Timestamp);
22///
23/// assert_eq!(
24///     config.get_migrations_dir(),
25///     std::path::PathBuf::from("my_app/db/migrations"),
26/// );
27/// assert_eq!(
28///     config.get_snapshots_dir(),
29///     std::path::PathBuf::from("my_app/db/snapshots"),
30/// );
31/// assert_eq!(
32///     config.get_history_file_path(),
33///     std::path::PathBuf::from("my_app/db/history.toml"),
34/// );
35/// ```
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct MigrationConfig {
38    /// Path to the migrations folder
39    pub path: PathBuf,
40
41    /// Style of migration file prefixes
42    pub prefix_style: MigrationPrefixStyle,
43
44    /// Whether the history file should store and verify checksums of the migration files so that
45    /// they may not be changed.
46    pub checksums: bool,
47
48    /// Whether to add statement breakpoint comments to generated SQL migration files.
49    /// These comments mark boundaries where SQL statements should be split for execution.
50    /// This is needed because different databases have different batching capabilities:
51    /// some (like PostgreSQL) can execute multiple statements in one batch, while others
52    /// require each statement to be executed separately.
53    pub statement_breakpoints: bool,
54}
55
56/// Controls the prefix format used when naming generated migration files.
57///
58/// The prefix appears at the start of the migration file name and determines
59/// the ordering of migration files on disk.
60///
61/// # Examples
62///
63/// ```
64/// use toasty_cli::MigrationPrefixStyle;
65///
66/// // Default is sequential
67/// let style = MigrationPrefixStyle::Sequential;
68/// assert_eq!(style, MigrationPrefixStyle::Sequential);
69/// ```
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
71pub enum MigrationPrefixStyle {
72    /// Sequential numbering (e.g., 0001_, 0002_, 0003_)
73    Sequential,
74
75    /// Timestamp-based (e.g., 20240112_153045_)
76    Timestamp,
77}
78
79impl Default for MigrationConfig {
80    fn default() -> Self {
81        Self {
82            path: PathBuf::from("toasty"),
83            prefix_style: MigrationPrefixStyle::Sequential,
84            checksums: false,
85            statement_breakpoints: true,
86        }
87    }
88}
89
90impl MigrationConfig {
91    /// Create a new MigrationConfig with default values
92    pub fn new() -> Self {
93        Self::default()
94    }
95
96    /// Set the migrations path
97    pub fn path(mut self, path: impl Into<PathBuf>) -> Self {
98        self.path = path.into();
99        self
100    }
101
102    /// Set the migration prefix style
103    pub fn prefix_style(mut self, style: MigrationPrefixStyle) -> Self {
104        self.prefix_style = style;
105        self
106    }
107
108    /// Returns the directory of the migration files derived from `path`.
109    pub fn get_migrations_dir(&self) -> PathBuf {
110        self.path.join("migrations")
111    }
112
113    /// Returns the directory of the snapshot files derived from `path`.
114    pub fn get_snapshots_dir(&self) -> PathBuf {
115        self.path.join("snapshots")
116    }
117
118    /// Get the path to the history file
119    pub fn get_history_file_path(&self) -> PathBuf {
120        self.path.join("history.toml")
121    }
122}