Skip to content

Add migrations reset command#1051

Open
dereuromark wants to merge 8 commits into5.nextfrom
feature/migrations-reset-command
Open

Add migrations reset command#1051
dereuromark wants to merge 8 commits into5.nextfrom
feature/migrations-reset-command

Conversation

@dereuromark
Copy link
Member

@dereuromark dereuromark commented Mar 12, 2026

Summary

Implements the migrations reset command as requested in #972.

This is a "nuclear option" that:

  • Drops all tables in the database (including tracking tables like cake_migrations, phinxlog)
  • Re-runs all migrations from scratch

Features

  • Interactive Y/N confirmation (defaults to N) before dropping tables
  • --dry-run flag to preview what would be dropped
  • --no-lock flag to skip lock file generation
  • Supports --plugin, --connection, and --source options
  • Dispatches Migration.beforeReset and Migration.afterReset events
  • Handles foreign key constraints across MySQL, PostgreSQL, SQLite, and SQL Server

Usage

migrations reset              # Reset default connection
migrations reset -c test      # Reset test connection  
migrations reset --dry-run    # Preview without changes
migrations reset --no-lock    # Skip lock file generation

Closes #972

@dereuromark dereuromark marked this pull request as draft March 12, 2026 10:49
@dereuromark dereuromark marked this pull request as ready for review March 12, 2026 12:22
@dereuromark dereuromark requested a review from markstory March 12, 2026 12:23
@dereuromark dereuromark changed the base branch from 5.x to 5.next March 12, 2026 12:23
@dereuromark dereuromark added this to the 5.next milestone Mar 12, 2026
@dereuromark dereuromark force-pushed the feature/migrations-reset-command branch from 179590b to 415523f Compare March 12, 2026 12:26
Comment on lines +136 to +140
$continue = $io->askChoice(
'This will permanently delete all data. Do you want to continue?',
['y', 'n'],
'n',
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Thanks for making this safe by default.

@dereuromark dereuromark requested a review from markstory March 15, 2026 03:24
Comment on lines +283 to +284
// SQL Server doesn't support disabling FK checks globally.
// We drop all foreign key constraints instead.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? We have

        return 'EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"';

in cakephp/database for sqlserver's disableForeignKey method. Any reason we can't use that here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with dropping FK constraints instead of using NOCHECK CONSTRAINT all. The reason is that NOCHECK only disables constraint checking but doesn't allow dropping tables that are referenced by foreign keys.
Since we're dropping all tables in a reset, we need to actually remove the constraints first. After the reset, migrations recreate everything fresh anyway.

Implements the "nuclear option" for migrations as discussed in #972:
- Drops all application tables (excluding migration tracking tables)
- Re-runs all migrations from scratch
- Requires interactive Y/N confirmation for safety (default: N)
- Supports --dry-run mode to preview changes
- Dispatches Migration.beforeReset and Migration.afterReset events

This is useful during development when you want a fresh database
without manually rolling back or dropping tables.

Refs #972
- PostgreSQL: Use CASCADE in DROP TABLE statement
- SQL Server: Drop foreign key constraints first before dropping tables
- MySQL/SQLite: Continue using session-level FK check toggle
- Remove sessions from protected tables (true nuclear option)
- Rename protectedTables to trackingTables for clarity
- Clear seed records (cake_seeds) along with migration records
- Rename clearMigrationRecords to clearTrackingRecords
Instead of preserving tracking tables and clearing their records,
just drop everything and let migrations recreate the tables.
- Replace string operations on class names with instanceof checks
- Extract runMigrationsAndDispatch() to reduce code duplication
- Add disableForeignKeyConstraints/enableForeignKeyConstraints to AdapterInterface
- Implement FK methods in MysqlAdapter (SET FOREIGN_KEY_CHECKS)
- Implement FK methods in SqliteAdapter (PRAGMA foreign_keys)
- Implement FK methods in SqlserverAdapter (drop all FK constraints)
- PostgresAdapter uses no-op methods with CASCADE in dropTable
- Add FK methods to AdapterWrapper for delegation
- Refactor ResetCommand to use adapter methods instead of dialect-specific code
@dereuromark dereuromark force-pushed the feature/migrations-reset-command branch from e14c73c to 48ddf9e Compare March 17, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5.next: RFC - migrations reset/redo

2 participants