loadMigrations loads all migration files from the embedded filesystem
()
| 70 | |
| 71 | // loadMigrations loads all migration files from the embedded filesystem |
| 72 | func (m *Migrator) loadMigrations() ([]Migration, error) { |
| 73 | entries, err := migrationFiles.ReadDir("migrations") |
| 74 | if err != nil { |
| 75 | return nil, fmt.Errorf("failed to read migrations directory: %w", err) |
| 76 | } |
| 77 | |
| 78 | var migrations []Migration |
| 79 | for _, entry := range entries { |
| 80 | if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".sql") { |
| 81 | continue |
| 82 | } |
| 83 | |
| 84 | // Parse version from filename (e.g., "001_initial_schema.sql" -> version 1) |
| 85 | name := entry.Name() |
| 86 | parts := strings.SplitN(name, "_", 2) |
| 87 | if len(parts) != 2 { |
| 88 | log.Printf("Skipping migration file with invalid name format: %s", name) |
| 89 | continue |
| 90 | } |
| 91 | |
| 92 | version, err := strconv.Atoi(parts[0]) |
| 93 | if err != nil { |
| 94 | log.Printf("Skipping migration file with invalid version: %s", name) |
| 95 | continue |
| 96 | } |
| 97 | |
| 98 | // Read the migration SQL |
| 99 | content, err := migrationFiles.ReadFile(path.Join("migrations", name)) |
| 100 | if err != nil { |
| 101 | return nil, fmt.Errorf("failed to read migration file %s: %w", name, err) |
| 102 | } |
| 103 | |
| 104 | migrations = append(migrations, Migration{ |
| 105 | Version: version, |
| 106 | Name: strings.TrimSuffix(name, ".sql"), |
| 107 | SQL: string(content), |
| 108 | }) |
| 109 | } |
| 110 | |
| 111 | // Sort migrations by version |
| 112 | sort.Slice(migrations, func(i, j int) bool { |
| 113 | return migrations[i].Version < migrations[j].Version |
| 114 | }) |
| 115 | |
| 116 | return migrations, nil |
| 117 | } |
| 118 | |
| 119 | // Migrate runs all pending migrations |
| 120 | func (m *Migrator) Migrate(ctx context.Context) error { |