--- 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`.