@@ -259,59 +259,52 @@ protected function migrateDownByVersion(string $version): void
259259 */
260260 public function migrateTo (string $ version ): void
261261 {
262+ $ allMigrations = $ this ->getAllMigrationFiles ();
263+ $ targetIndex = array_search ($ version , $ allMigrations , true );
264+
265+ if ($ targetIndex === false ) {
266+ throw new QueryException ("Migration version {$ version } not found " );
267+ }
268+
262269 $ history = $ this ->getMigrationHistory ();
263- $ currentVersion = $ this -> getMigrationVersion ( );
264-
265- if ( $ currentVersion === null ) {
266- // Apply all migrations up to version
267- $ allMigrations = $ this -> getAllMigrationFiles ();
268- $ targetIndex = array_search ($ version , $ allMigrations , true );
269- if ($ targetIndex === false ) {
270- throw new QueryException ( " Migration version { $ version } not found " ) ;
270+ $ appliedVersions = array_column ( $ history , ' version ' );
271+
272+ // Find the highest applied migration version (by order in allMigrations, not by apply_time)
273+ $ currentIndex = - 1 ;
274+ foreach ( $ appliedVersions as $ appliedVersion ) {
275+ $ index = array_search ($ appliedVersion , $ allMigrations , true );
276+ if ($ index !== false && $ index > $ currentIndex ) {
277+ $ currentIndex = $ index ;
271278 }
279+ }
272280
281+ if ($ currentIndex === -1 ) {
282+ // No migrations applied, apply all up to target version
273283 $ migrationsToApply = array_slice ($ allMigrations , 0 , $ targetIndex + 1 );
274284 foreach ($ migrationsToApply as $ migrationVersion ) {
275285 $ this ->migrateUp ($ migrationVersion );
276286 }
277- } elseif ($ currentVersion === $ version ) {
287+ } elseif ($ currentIndex === $ targetIndex ) {
278288 // Already at target version
279289 return ;
280- } else {
281- // Rollback or apply migrations
282- $ allMigrations = $ this ->getAllMigrationFiles ();
283- $ currentIndex = array_search ($ currentVersion , $ allMigrations , true );
284- $ targetIndex = array_search ($ version , $ allMigrations , true );
285-
286- if ($ targetIndex === false ) {
287- throw new QueryException ("Migration version {$ version } not found " );
288- }
289-
290- if ($ targetIndex < $ currentIndex ) {
291- // Rollback migrations in reverse order (newest first)
292- // We need to rollback from currentIndex down to targetIndex+1
293- $ migrationsToRollback = array_slice ($ allMigrations , $ targetIndex + 1 , $ currentIndex - $ targetIndex );
294-
295- // Get current history once before rollback loop
296- $ history = $ this ->getMigrationHistory ();
297- $ appliedVersions = array_column ($ history , 'version ' );
298-
299- // Rollback each migration that needs to be rolled back, in reverse order
300- foreach (array_reverse ($ migrationsToRollback ) as $ migrationVersion ) {
301- // Only rollback if migration is actually applied
302- if (in_array ($ migrationVersion , $ appliedVersions , true )) {
303- $ this ->migrateDownByVersion ($ migrationVersion );
304- // Remove from appliedVersions to avoid duplicate rollback attempts
305- $ appliedVersions = array_values (array_diff ($ appliedVersions , [$ migrationVersion ]));
306- }
307- }
308- } else {
309- // Apply
310- $ migrationsToApply = array_slice ($ allMigrations , $ currentIndex + 1 , $ targetIndex - $ currentIndex );
311- foreach ($ migrationsToApply as $ migrationVersion ) {
312- $ this ->migrateUp ($ migrationVersion );
290+ } elseif ($ targetIndex < $ currentIndex ) {
291+ // Rollback migrations in reverse order (newest first)
292+ // We need to rollback from currentIndex down to targetIndex+1
293+ $ migrationsToRollback = array_slice ($ allMigrations , $ targetIndex + 1 , $ currentIndex - $ targetIndex );
294+
295+ // Rollback each migration that needs to be rolled back, in reverse order
296+ foreach (array_reverse ($ migrationsToRollback ) as $ migrationVersion ) {
297+ // Only rollback if migration is actually applied
298+ if (in_array ($ migrationVersion , $ appliedVersions , true )) {
299+ $ this ->migrateDownByVersion ($ migrationVersion );
313300 }
314301 }
302+ } else {
303+ // Apply
304+ $ migrationsToApply = array_slice ($ allMigrations , $ currentIndex + 1 , $ targetIndex - $ currentIndex );
305+ foreach ($ migrationsToApply as $ migrationVersion ) {
306+ $ this ->migrateUp ($ migrationVersion );
307+ }
315308 }
316309 }
317310
0 commit comments