feat: funciones impuras migration_create, migration_up, migration_down, migration_status
Fase 2 del issue 0015. MigrationCreate (crea archivo .sql template con version auto-calculada), MigrationUp (aplica migraciones pendientes en transacciones individuales), MigrationDown (revierte ultimas N via down_sql de _migrations), MigrationGetStatus (cruza disco con BD, detecta orphaned). Tests de integracion: ciclo completo create->up->status->down->status. 26 tests, todos pasan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: migration_up
|
||||
kind: function
|
||||
lang: go
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "func MigrationUp(db *sql.DB, dir string) ([]Migration, error)"
|
||||
description: "Lee los archivos .sql del directorio, crea la tabla _migrations si no existe, y ejecuta las migraciones pendientes en orden de version. Cada migracion corre en su propia transaccion. Retorna la lista de migraciones aplicadas en esta llamada."
|
||||
tags: [migration, database, sql, schema, sqlite, apply, up]
|
||||
uses_functions: [migration_parse_go_infra]
|
||||
uses_types: [migration_go_infra]
|
||||
returns: [migration_go_infra]
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: ["database/sql", "fmt", "os", "path/filepath", "sort", "strings"]
|
||||
params:
|
||||
- name: db
|
||||
desc: "conexion *sql.DB abierta a la base de datos SQLite donde aplicar las migraciones"
|
||||
- name: dir
|
||||
desc: "path al directorio que contiene los archivos .sql de migracion (ej: apps/my_app/migrations)"
|
||||
output: "slice de Migration con las migraciones que fueron aplicadas en esta llamada (puede estar vacio si todo ya estaba aplicado)"
|
||||
tested: true
|
||||
tests:
|
||||
- "base de datos vacia aplica todas las migraciones"
|
||||
- "migraciones ya aplicadas se omiten"
|
||||
- "migracion con SQL invalido retorna error y deja las anteriores aplicadas"
|
||||
- "directorio sin archivos sql no aplica nada"
|
||||
test_file_path: "functions/infra/migration_up_test.go"
|
||||
file_path: "functions/infra/migration_up.go"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```go
|
||||
db, _ := SQLiteOpen("", "apps/my_app/operations.db")
|
||||
defer db.Close()
|
||||
|
||||
applied, err := MigrationUp(db, "apps/my_app/migrations")
|
||||
if err != nil {
|
||||
log.Fatalf("migration failed: %v", err)
|
||||
}
|
||||
for _, m := range applied {
|
||||
fmt.Printf("Applied: %03d_%s\n", m.Version, m.Name)
|
||||
}
|
||||
// Applied: 001_create_users
|
||||
// Applied: 002_add_roles
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Crea `_migrations` con `CREATE TABLE IF NOT EXISTS` — es idempotente. Cada migracion se ejecuta en una transaccion independiente: si falla la migracion 3, las 1 y 2 ya aplicadas permanecen. El `up_sql` y `down_sql` se guardan en `_migrations` para que el rollback funcione aunque el archivo sea modificado o eliminado posteriormente. SQLite con el driver mattn/go-sqlite3 soporta multiples sentencias en un solo `Exec`.
|
||||
Reference in New Issue
Block a user