Files
comparador-notas/src/infrastructure/sqlite/migrations.rs
T
2026-03-04 18:33:32 -03:00

93 lines
2.7 KiB
Rust

use rusqlite::{Connection, Result};
/// Aplica todas as migrations necessárias para atualizar o banco
/// para a versão mais recente.
pub fn aplicar_migrations(conn: &Connection) -> Result<()> {
// Criar tabela de controle de versão se não existir
conn.execute_batch(
"CREATE TABLE IF NOT EXISTS schema_version (
versao INTEGER NOT NULL
);",
)?;
let versao_atual: i64 = conn
.query_row("SELECT versao FROM schema_version LIMIT 1;", [], |row| {
row.get(0)
})
.unwrap_or(0);
if versao_atual < 1 {
migration_v1(conn)?;
}
if versao_atual < 2 {
migration_v2(conn)?;
}
if versao_atual < 3 {
migration_v3(conn)?;
}
Ok(())
}
/// Migration v3: adicionar colunas de tipo de documento nos layouts.
fn migration_v3(conn: &Connection) -> Result<()> {
conn.execute_batch(
"BEGIN;
ALTER TABLE layouts ADD COLUMN indice_documento_tipo INTEGER;
ALTER TABLE layouts ADD COLUMN pos_documento_tipo TEXT;
UPDATE schema_version SET versao = 3;
COMMIT;",
)?;
Ok(())
}
/// Migration v2: adicionar índice único em layouts.nome.
///
/// Renomeia duplicatas (sufixo com id) antes de criar o índice para não falhar
/// em bancos que já possuem nomes repetidos.
fn migration_v2(conn: &Connection) -> Result<()> {
conn.execute_batch(
"BEGIN;
UPDATE layouts
SET nome = nome || ' (' || id || ')'
WHERE id NOT IN (
SELECT MIN(id) FROM layouts GROUP BY nome
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_layouts_nome ON layouts (nome);
UPDATE schema_version SET versao = 2;
COMMIT;",
)?;
Ok(())
}
/// Migration v1: criar tabela de layouts.
fn migration_v1(conn: &Connection) -> Result<()> {
conn.execute_batch(
"BEGIN;
CREATE TABLE IF NOT EXISTS layouts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nome TEXT NOT NULL,
tipo TEXT NOT NULL CHECK(tipo IN ('csv', 'xlsx')),
-- Campos CSV
delimitador TEXT,
encoding TEXT,
linha_cabecalho INTEGER,
indice_numero INTEGER,
indice_serie INTEGER,
indice_valor INTEGER,
indice_data INTEGER,
-- Campos XLSX
aba TEXT,
pos_numero TEXT,
pos_serie TEXT,
pos_valor TEXT,
pos_data TEXT
);
INSERT INTO schema_version (versao) VALUES (1);
COMMIT;",
)?;
Ok(())
}